genbattle / dkm

A generic C++11 k-means clustering implementation
MIT License
209 stars 47 forks source link

static_assert(__which < 0, /* needs to be dependent */ #17

Open thorstink opened 4 years ago

thorstink commented 4 years ago

Hi,

I was building your library on a 64bit x86 machine with GCC, no issues. Cross-compiling for a 32bit ARM platform however gives a very confusing error:

In file included from /usr/arm-linux-gnueabihf/include/c++/8/random:49,
                 from /mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:9,
                 from /mnt/project_ws/src/pasta/camera/applications/tracking/src/pattern_extractor.cc:8:
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h: In instantiation of ‘struct std::__detail::_Select_uint_least_t<99, 1>’:
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:114:40:   required from ‘struct std::__detail::_Mod<long long unsigned int, 18446744073709551615, 25214903917, 11, false, false>’
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:147:48:   required from ‘_Tp std::__detail::__mod(_Tp) [with _Tp = long long unsigned int; _Tp __m = 18446744073709551615; _Tp __a = 25214903917; _Tp __c = 11]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:325:50:   required from ‘std::linear_congruential_engine<_UIntType, __a, __c, __m>::result_type std::linear_congruential_engine<_UIntType, __a, __c, __m>::operator()() [with _UIntType = long long unsigned int; _UIntType __a = 25214903917; _UIntType __c = 11; _UIntType __m = 18446744073709551615; std::linear_congruential_engine<_UIntType, __a, __c, __m>::result_type = long long unsigned int]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/uniform_int_dist.h:243:31:   required from ‘std::uniform_int_distribution<_IntType>::result_type std::uniform_int_distribution<_IntType>::operator()(_UniformRandomNumberGenerator&, const std::uniform_int_distribution<_IntType>::param_type&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long long unsigned int, 25214903917, 11, 18446744073709551615>; _IntType = unsigned int; std::uniform_int_distribution<_IntType>::result_type = unsigned int]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/uniform_int_dist.h:166:51:   required from ‘std::uniform_int_distribution<_IntType>::result_type std::uniform_int_distribution<_IntType>::operator()(_UniformRandomNumberGenerator&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long long unsigned int, 25214903917, 11, 18446744073709551615>; _IntType = unsigned int; std::uniform_int_distribution<_IntType>::result_type = unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:81:43:   required from ‘std::vector<std::array<_Tp, _Nm> > dkm::details::random_plusplus(const std::vector<std::array<_Tp, _Nm> >&, uint32_t, uint64_t) [with T = float; unsigned int N = 3; uint32_t = unsigned int; uint64_t = long long unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:278:65:   required from ‘std::tuple<std::vector<std::array<_Tp, _Nm>, std::allocator<std::array<_Tp, _Nm> > >, std::vector<unsigned int, std::allocator<unsigned int> > > dkm::kmeans_lloyd(const std::vector<std::array<_Tp, _Nm> >&, const dkm::clustering_parameters<T>&) [with T = float; unsigned int N = 3]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:316:22:   required from ‘std::tuple<std::vector<std::array<_Tp, _Nm>, std::allocator<std::array<_Tp, _Nm> > >, std::vector<unsigned int, std::allocator<unsigned int> > > dkm::kmeans_lloyd(const std::vector<std::array<_Tp, _Nm> >&, uint32_t, uint64_t, T) [with T = float; unsigned int N = 3; uint32_t = unsigned int; uint64_t = long long unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/pattern_extractor.cc:47:48:   required from here
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:84:24: error: static assertion failed: sorry, would be too much trouble for a slow result
  static_assert(__which < 0, /* needs to be dependent */
                ~~~~~~~~^~~
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h: In instantiation of ‘struct std::__detail::_Mod<long long unsigned int, 18446744073709551615, 25214903917, 11, false, false>’:
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:147:48:   required from ‘_Tp std::__detail::__mod(_Tp) [with _Tp = long long unsigned int; _Tp __m = 18446744073709551615; _Tp __a = 25214903917; _Tp __c = 11]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:325:50:   required from ‘std::linear_congruential_engine<_UIntType, __a, __c, __m>::result_type std::linear_congruential_engine<_UIntType, __a, __c, __m>::operator()() [with _UIntType = long long unsigned int; _UIntType __a = 25214903917; _UIntType __c = 11; _UIntType __m = 18446744073709551615; std::linear_congruential_engine<_UIntType, __a, __c, __m>::result_type = long long unsigned int]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/uniform_int_dist.h:243:31:   required from ‘std::uniform_int_distribution<_IntType>::result_type std::uniform_int_distribution<_IntType>::operator()(_UniformRandomNumberGenerator&, const std::uniform_int_distribution<_IntType>::param_type&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long long unsigned int, 25214903917, 11, 18446744073709551615>; _IntType = unsigned int; std::uniform_int_distribution<_IntType>::result_type = unsigned int]’
/usr/arm-linux-gnueabihf/include/c++/8/bits/uniform_int_dist.h:166:51:   required from ‘std::uniform_int_distribution<_IntType>::result_type std::uniform_int_distribution<_IntType>::operator()(_UniformRandomNumberGenerator&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long long unsigned int, 25214903917, 11, 18446744073709551615>; _IntType = unsigned int; std::uniform_int_distribution<_IntType>::result_type = unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:81:43:   required from ‘std::vector<std::array<_Tp, _Nm> > dkm::details::random_plusplus(const std::vector<std::array<_Tp, _Nm> >&, uint32_t, uint64_t) [with T = float; unsigned int N = 3; uint32_t = unsigned int; uint64_t = long long unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:278:65:   required from ‘std::tuple<std::vector<std::array<_Tp, _Nm>, std::allocator<std::array<_Tp, _Nm> > >, std::vector<unsigned int, std::allocator<unsigned int> > > dkm::kmeans_lloyd(const std::vector<std::array<_Tp, _Nm> >&, const dkm::clustering_parameters<T>&) [with T = float; unsigned int N = 3]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/dkm.hpp:316:22:   required from ‘std::tuple<std::vector<std::array<_Tp, _Nm>, std::allocator<std::array<_Tp, _Nm> > >, std::vector<unsigned int, std::allocator<unsigned int> > > dkm::kmeans_lloyd(const std::vector<std::array<_Tp, _Nm> >&, uint32_t, uint64_t, T) [with T = float; unsigned int N = 3; uint32_t = unsigned int; uint64_t = long long unsigned int]’
/mnt/project_ws/src/pasta/camera/applications/tracking/src/pattern_extractor.cc:47:48:   required from here
/usr/arm-linux-gnueabihf/include/c++/8/bits/random.h:114:40: error: no type named ‘type’ in ‘struct std::__detail::_Select_uint_least_t<99, 1>’
            + std::__lg(__m) + 2>::type _Tp2;
                                        ^~~~
make[2]: *** [CMakeFiles/tracking.dir/build.make:89: CMakeFiles/tracking.dir/src/pattern_extractor.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:137: CMakeFiles/tracking.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

Changing line 76 in dkm.hpp from

  // std::linear_congruential_engine<uint64_t, 6364136223846793005, 1442695040888963407, UINT64_MAX> rand_engine(seed);

to

  std::linear_congruential_engine<std::uint_fast32_t, 48271, 0, 2147483647> rand_engine(seed);

I can put a pull request if you like, but if you have a particular preference for some other random engine, I can also put that one in.

genbattle commented 4 years ago

This seems fine, if you put it in a PR I'm happy to merge it, otherwise I can make the change myself in the next few days.