esa / pagmo2

A C++ platform to perform parallel computations of optimisation tasks (global and local) via the asynchronous generalized island model.
https://esa.github.io/pagmo2/
GNU General Public License v3.0
804 stars 159 forks source link

Fix for GLIBCXX_DEBUG compilation error in 'hv3d::compute' #530

Closed SzGaa closed 1 year ago

SzGaa commented 1 year ago

Compilation failure with GLIBCXX_DEBUG flag.

Issue caused by: std::multiset<vector_double, decltype(cmp_zero_comp)>::iterator != std::multiset::iterator fails for __gnu_debug::_Safe_iterator

Error Message:

C:\Tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\bin\c++.exe -DBOOST_ALLOW_DEPRECATED_HEADERS -DBOOST_SERIALIZATION_DYN_LINK -DBOOST_SERIALIZATION_NO_LIB -DTBB_USE_DEBUG -Dpagmo_EXPORTS -IC:/Libs/pagmo2/include -IC:/Libs/pagmo2/build-debug-23Q1r0/include -isystem D:/Frontier/Libraries/boost-1.81.0/mgw122/include/boost-1_81 -isystem C:/Tools/msys2/msys2-20221216/mingw64/include -fuse-ld=lld -fdiagnostics-color=always -g -D_GLIBCXX_DEBUG -fvisibility=hidden -fno-keep-inline-dllexport -fdiagnostics-color=auto -ftemplate-depth=1024 -fdiagnostics-show-template-tree -Wno-attributes -Waddress-of-packed-member -Wall -Wextra -Wnon-virtual-dtor -Wlogical-op -Wconversion -Wdeprecated -Wold-style-cast -Wdisabled-optimization -ftemplate-backtrace-limit=0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wsuggest-attribute=format -Wodr -Wsuggest-final-types -Wsuggest-final-methods -Wsuggest-override -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference -Wrestrict -Waligned-new -Wcast-align=strict -Wno-maybe-uninitialized -mthreads -Wa,-mbig-obj -std=c++20 -MD -MT CMakeFiles/pagmo.dir/src/utils/hv_algos/hv_hv3d.cpp.obj -MF CMakeFiles\pagmo.dir\src\utils\hv_algos\hv_hv3d.cpp.obj.d -o CMakeFiles/pagmo.dir/src/utils/hv_algos/hv_hv3d.cpp.obj -c C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp
C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp: In member function 'virtual double pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const':
C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp:135:33: error: no match for 'operator=' (operand types are 'std::__debug::multiset<std::__debug::vector<double> >::iterator' and 'std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::iterator')
  135 |         p = T.insert(points[idx]);
      |                                 ^
In file included from c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\deque:42,
                 from c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\deque:70,
                 from C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp:31:
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\safe_iterator.h:570:7: note: candidate: '__gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>& __gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>::operator=(const __gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>&) [with _Iterator = std::_Rb_tree_const_iterator<std::__debug::vector<double> >; _Sequence = std::__debug::multiset<std::__debug::vector<double> >]'
  570 |       operator=(const _Safe_iterator&) = default;
      |       ^~~~~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\safe_iterator.h:570:17: note:   no known conversion for argument 1 from 'std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::iterator' to 'const __gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::__debug::vector<double> >, std::__debug::multiset<std::__debug::vector<double> >, std::bidirectional_iterator_tag>&'
  570 |       operator=(const _Safe_iterator&) = default;
      |                 ^~~~~~~~~~~~~~~~~~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\safe_iterator.h:574:7: note: candidate: '__gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>& __gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>::operator=(__gnu_debug::_Safe_iterator<_Iterator, _Sequence, std::bidirectional_iterator_tag>&&) [with _Iterator = std::_Rb_tree_const_iterator<std::__debug::vector<double> >; _Sequence = std::__debug::multiset<std::__debug::vector<double> >]'
  574 |       operator=(_Safe_iterator&&) = default;
      |       ^~~~~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\safe_iterator.h:574:17: note:   no known conversion for argument 1 from 'std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::iterator' to '__gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::__debug::vector<double> >, std::__debug::multiset<std::__debug::vector<double> >, std::bidirectional_iterator_tag>&&'
  574 |       operator=(_Safe_iterator&&) = default;
      |                 ^~~~~~~~~~~~~~~~
C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp:139:20: error: 'std::_Rb_tree_const_iterator<std::__debug::vector<double> >' is an inaccessible base of '__gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::__debug::vector<double> >, std::__debug::multiset<std::__debug::vector<double> >, std::bidirectional_iterator_tag>'
  139 |             T.erase(p);           // disregard the point from further calculation
      |             ~~~~~~~^~~
In file included from c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\set:42,
                 from c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\set:67,
                 from C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp:34:
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:339:34: note:   initializing argument 1 of 'std::__debug::multiset<_Key, _Cmp, _Allocator>::_Base_iterator std::__debug::multiset<_Key, _Cmp, _Allocator>::erase(_Base_const_iterator) [with _Key = std::__debug::vector<double>; _Compare = pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>; _Allocator = std::allocator<std::__debug::vector<double> >; _Base_iterator = std::_Rb_tree<std::__debug::vector<double>, std::__debug::vector<double>, std::_Identity<std::__debug::vector<double> >, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>, std::allocator<std::__debug::vector<double> > >::const_iterator; _Base_const_iterator = std::_Rb_tree<std::__debug::vector<double>, std::__debug::vector<double>, std::_Identity<std::__debug::vector<double> >, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>, std::allocator<std::__debug::vector<double> > >::const_iterator]'
  339 |       erase(_Base_const_iterator __position)
      |             ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
C:/Libs/pagmo2/src/utils/hv_algos/hv_hv3d.cpp:155:20: error: no matching function for call to 'std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::erase(std::reverse_iterator<__gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::__debug::vector<double> >, std::__debug::multiset<std::__debug::vector<double> >, std::bidirectional_iterator_tag> >::iterator_type, std::reverse_iterator<__gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::__debug::vector<double> >, std::__debug::multiset<std::__debug::vector<double> >, std::bidirectional_iterator_tag> >::iterator_type)'
  155 |             T.erase(rev_it.base(), erase_begin.base());
      |             ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:332:7: note: candidate: 'std::__debug::multiset<_Key, _Cmp, _Allocator>::iterator std::__debug::multiset<_Key, _Cmp, _Allocator>::erase(const_iterator) [with _Key = std::__debug::vector<double>; _Compare = pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>; _Allocator = std::allocator<std::__debug::vector<double> >; iterator = std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::iterator; const_iterator = std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::const_iterator]'
  332 |       erase(const_iterator __position)
      |       ^~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:332:7: note:   candidate expects 1 argument, 2 provided
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:339:7: note: candidate: 'std::__debug::multiset<_Key, _Cmp, _Allocator>::_Base_iterator std::__debug::multiset<_Key, _Cmp, _Allocator>::erase(_Base_const_iterator) [with _Key = std::__debug::vector<double>; _Compare = pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>; _Allocator = std::allocator<std::__debug::vector<double> >; _Base_iterator = std::_Rb_tree<std::__debug::vector<double>, std::__debug::vector<double>, std::_Identity<std::__debug::vector<double> >, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>, std::allocator<std::__debug::vector<double> > >::const_iterator; _Base_const_iterator = std::_Rb_tree<std::__debug::vector<double>, std::__debug::vector<double>, std::_Identity<std::__debug::vector<double> >, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>, std::allocator<std::__debug::vector<double> > >::const_iterator]'
  339 |       erase(_Base_const_iterator __position)
      |       ^~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:339:7: note:   candidate expects 1 argument, 2 provided
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:356:7: note: candidate: 'std::__debug::multiset<_Key, _Cmp, _Allocator>::size_type std::__debug::multiset<_Key, _Cmp, _Allocator>::erase(const key_type&) [with _Key = std::__debug::vector<double>; _Compare = pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>; _Allocator = std::allocator<std::__debug::vector<double> >; size_type = long long unsigned int; key_type = std::__debug::vector<double>]'
  356 |       erase(const key_type& __x)
      |       ^~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:356:7: note:   candidate expects 1 argument, 2 provided
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:374:7: note: candidate: 'std::__debug::multiset<_Key, _Cmp, _Allocator>::iterator std::__debug::multiset<_Key, _Cmp, _Allocator>::erase(const_iterator, const_iterator) [with _Key = std::__debug::vector<double>; _Compare = pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>; _Allocator = std::allocator<std::__debug::vector<double> >; iterator = std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::iterator; const_iterator = std::__debug::multiset<std::__debug::vector<double>, pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)> >::const_iterator]'
  374 |       erase(const_iterator __first, const_iterator __last)
      |       ^~~~~
c:\tools\mingw64\winlibs-x86_64-posix-seh-gcc-12.2.0-mingw-w64ucrt-10.0.0-r3\mingw64\include\c++\12.2.0\debug\multiset.h:374:28: note:   no known conversion for argument 1 from '_Safe_iterator<[...],multiset<[...],std::less<std::__debug::vector<double> >>,[...]>' to '_Safe_iterator<[...],multiset<[...],pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>>,[...]>'
  _Safe_iterator<
    [...],
    multiset<
      [...],
      [std::less<std::__debug::vector<double> > != pagmo::hv3d::compute(std::__debug::vector<std::__debug::vector<double> >&, const pagmo::vector_double&) const::<lambda(const pagmo::vector_double&, const pagmo::vector_double&)>]>,
    [...]>
  374 |       erase(const_iterator __first, const_iterator __last)
      |             ~~~~~~~~~~~~~~~^~~~~~~
[86/88] Building CXX object CMakeFiles/pagmo.dir/src/detail/bfe_impl.cpp.obj
ninja: build stopped: subcommand failed.

Solution #1:

$ git diff
diff --git a/src/utils/hv_algos/hv_hv3d.cpp b/src/utils/hv_algos/hv_hv3d.cpp
index d03bbf10..fffec75d 100644
--- a/src/utils/hv_algos/hv_hv3d.cpp
+++ b/src/utils/hv_algos/hv_hv3d.cpp
@@ -128,8 +128,8 @@ double hv3d::compute(std::vector<vector_double> &points, const vector_double &r_
     T.insert(points[0]);
     A = std::abs((points[0][0] - r_point[0]) * (points[0][1] - r_point[1]));

-    std::multiset<vector_double>::iterator p;
-    std::multiset<vector_double>::iterator q;
+    std::multiset<vector_double, decltype(cmp_zero_comp)>::iterator p;
+    std::multiset<vector_double, decltype(cmp_zero_comp)>::iterator q;
     // for (std::vector<vector_double>::size_type idx = 1; idx < points.size(); ++idx) {
     for (decltype(points.size()) idx = 1u; idx < points.size(); ++idx) {
         p = T.insert(points[idx]);
@@ -140,11 +140,11 @@ double hv3d::compute(std::vector<vector_double> &points, const vector_double &r_
         } else {
             V += A * std::abs(z3 - (*p)[2]);
             z3 = (*p)[2];
-            std::multiset<vector_double>::reverse_iterator rev_it(q);
+            std::multiset<vector_double, decltype(cmp_zero_comp)>::reverse_iterator rev_it(q);
             ++rev_it;

-            std::multiset<vector_double>::reverse_iterator erase_begin(rev_it);
-            std::multiset<vector_double>::reverse_iterator rev_it_pred;
+            std::multiset<vector_double, decltype(cmp_zero_comp)>::reverse_iterator erase_begin(rev_it);
+            std::multiset<vector_double, decltype(cmp_zero_comp)>::reverse_iterator rev_it_pred;
             while ((*rev_it)[1] >= (*p)[1]) {
                 rev_it_pred = rev_it;
                 ++rev_it_pred;

Solution #2:

pull-request made..


[ ] Proper testing required

bluescarni commented 1 year ago

Thanks @SzGaa and good catch. std::make_reverse_iterator is not an issue, as pagmo2 is based on C++17.

Merging.