Loading Eigen/src/Core/MathFunctions.h +8 −35 Original line number Diff line number Diff line Loading @@ -527,41 +527,14 @@ struct pow_impl<ScalarX, ScalarY, true> { } }; enum { meta_floor_log2_terminate, meta_floor_log2_move_up, meta_floor_log2_move_down, meta_floor_log2_bogus }; template <unsigned int n, int lower, int upper> struct meta_floor_log2_selector { enum { middle = (lower + upper) / 2, value = (upper <= lower + 1) ? int(meta_floor_log2_terminate) : (n < (1 << middle)) ? int(meta_floor_log2_move_down) : (n == 0) ? int(meta_floor_log2_bogus) : int(meta_floor_log2_move_up) }; }; template <unsigned int n, int lower = 0, int upper = sizeof(unsigned int) * CHAR_BIT - 1, int selector = meta_floor_log2_selector<n, lower, upper>::value> struct meta_floor_log2 {}; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down> : std::integral_constant<int, meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value> { }; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up> : std::integral_constant<int, meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value> { }; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate> : std::integral_constant<int, (n >= ((unsigned int)(1) << (lower + 1))) ? lower + 1 : lower> {}; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus> { // no value, error at compile time }; constexpr int floor_log2(unsigned int value) { int result = 0; while (value > 1) { value >>= 1; ++result; } return result; } template <typename BitsType, typename EnableIf = void> struct count_bits_impl { Loading Eigen/src/Core/RandomImpl.h +1 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ inline Scalar random() { // TODO: replace or provide alternatives to this, e.g. std::random_device struct eigen_random_device { using ReturnType = int; static constexpr int Entropy = meta_floor_log2<(unsigned int)(RAND_MAX) + 1>::value; static constexpr int Entropy = floor_log2((unsigned int)(RAND_MAX) + 1); static constexpr ReturnType Highest = RAND_MAX; static EIGEN_DEVICE_FUNC inline ReturnType run() { return std::rand(); } }; Loading Eigen/src/Core/util/MoreMeta.h +13 −14 Original line number Diff line number Diff line Loading @@ -241,31 +241,30 @@ constexpr auto arg_sum(Ts... ts) { /* generic array reductions */ // can't reuse standard reduce() interface above because Intel's Compiler // *really* doesn't like it, so we just reimplement the stuff // (start from N - 1 and work down to 0 because specialization for // n == N - 1 also doesn't work in Intel's compiler, so it goes into // an infinite loop) template <typename Reducer, typename T, std::size_t N, std::size_t n = N - 1> struct h_array_reduce { EIGEN_DEVICE_FUNC constexpr static auto run(const array<T, N>& arr, T identity) { return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr)); template <typename Reducer, typename T, std::size_t N> struct array_reducer { EIGEN_DEVICE_FUNC constexpr static auto run(const array<T, N>& arr, T) { auto result = Reducer::run(arr[0], arr[1]); for (std::size_t i = 2; i < N; ++i) { result = Reducer::run(result, arr[i]); } return result; } }; template <typename Reducer, typename T, std::size_t N> struct h_array_reduce<Reducer, T, N, 0> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, N>& arr, T) { return array_get<0>(arr); } template <typename Reducer, typename T> struct array_reducer<Reducer, T, 1> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, 1>& arr, T) { return arr[0]; } }; template <typename Reducer, typename T> struct h_array_reduce<Reducer, T, 0> { struct array_reducer<Reducer, T, 0> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, 0>&, T identity) { return identity; } }; template <typename Reducer, typename T, std::size_t N> EIGEN_DEVICE_FUNC constexpr auto array_reduce(const array<T, N>& arr, T identity) { return h_array_reduce<Reducer, T, N>::run(arr, identity); return array_reducer<Reducer, T, N>::run(arr, identity); } /* standard array reductions */ Loading Eigen/src/Core/util/Serializer.h +24 −38 Original line number Diff line number Diff line Loading @@ -123,46 +123,23 @@ class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> namespace internal { // Recursive serialization implementation helper. template <size_t N, typename... Types> struct serialize_impl; template <size_t N, typename T1, typename... Ts> struct serialize_impl<N, T1, Ts...> { using Serializer = Eigen::Serializer<std::decay_t<T1>>; static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const T1& value, const Ts&... args) { Serializer serializer; size_t size = serializer.size(value); return size + serialize_impl<N - 1, Ts...>::serialize_size(args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size_one(const Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.size(arg); } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const T1& value, const Ts&... args) { Serializer serializer; dest = serializer.serialize(dest, end, value); return serialize_impl<N - 1, Ts...>::serialize(dest, end, args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize_one(uint8_t* dest, uint8_t* end, const Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.serialize(dest, end, arg); } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, T1& value, Ts&... args) { Serializer serializer; src = serializer.deserialize(src, end, value); return serialize_impl<N - 1, Ts...>::deserialize(src, end, args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize_one(const uint8_t* src, const uint8_t* end, Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.deserialize(src, end, arg); } }; // Base case. template <> struct serialize_impl<0> { static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size() { return 0; } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* /*end*/) { return dest; } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* /*end*/) { return src; } }; } // namespace internal Loading @@ -174,7 +151,10 @@ struct serialize_impl<0> { */ template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::serialize_size(args...); size_t size = 0; int unused[] = {0, (size += internal::serialize_size_one(args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return size; } /** Loading @@ -187,7 +167,10 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) */ template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::serialize(dest, end, args...); EIGEN_UNUSED_VARIABLE(end); int unused[] = {0, (dest = internal::serialize_one(dest, end, args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return dest; } /** Loading @@ -201,7 +184,10 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::deserialize(src, end, args...); EIGEN_UNUSED_VARIABLE(end); int unused[] = {0, (src = internal::deserialize_one(src, end, args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return src; } } // namespace Eigen Loading test/meta.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,13 @@ struct dummy_c {}; struct dummy_d {}; struct dummy_e {}; struct widening_sum_op { template <typename A, typename B> EIGEN_DEVICE_FUNC constexpr static long long run(A a, B b) { return static_cast<long long>(a) + static_cast<long long>(b); } }; // dummy operation for testing apply template <typename A, typename B> struct dummy_op; Loading Loading @@ -221,11 +228,28 @@ static void test_arg_reductions() { static void test_array_reductions() { array<int, 6> a{{4, 8, 15, 16, 23, 42}}; array<int, 6> b{{42, 23, 16, 15, 8, 4}}; array<unsigned char, 0> empty{}; array<unsigned char, 1> singleton{{200}}; array<unsigned char, 2> narrow{{200, 100}}; array<unsigned char, 3> custom{{200, 100, 50}}; VERIFY_IS_EQUAL((array_sum(a)), 108); VERIFY_IS_EQUAL((array_sum(b)), 108); VERIFY_IS_EQUAL((array_prod(a)), 7418880); VERIFY_IS_EQUAL((array_prod(b)), 7418880); VERIFY((std::is_same<decltype(array_sum(empty)), unsigned char>::value)); VERIFY((std::is_same<decltype(array_sum(singleton)), unsigned char>::value)); VERIFY((std::is_same<decltype(array_sum(narrow)), int>::value)); VERIFY((std::is_same<decltype(array_prod(narrow)), int>::value)); VERIFY_IS_EQUAL((array_sum(empty)), 0); VERIFY_IS_EQUAL((array_prod(empty)), 1); VERIFY_IS_EQUAL((array_sum(singleton)), 200); VERIFY_IS_EQUAL((array_prod(singleton)), 200); VERIFY_IS_EQUAL((array_sum(narrow)), 300); VERIFY_IS_EQUAL((array_prod(narrow)), 20000); VERIFY( (std::is_same<decltype(array_reduce<widening_sum_op>(custom, static_cast<unsigned char>(0))), long long>::value)); VERIFY_IS_EQUAL((array_reduce<widening_sum_op>(custom, static_cast<unsigned char>(0))), 350); } EIGEN_DECLARE_TEST(meta) { Loading Loading
Eigen/src/Core/MathFunctions.h +8 −35 Original line number Diff line number Diff line Loading @@ -527,41 +527,14 @@ struct pow_impl<ScalarX, ScalarY, true> { } }; enum { meta_floor_log2_terminate, meta_floor_log2_move_up, meta_floor_log2_move_down, meta_floor_log2_bogus }; template <unsigned int n, int lower, int upper> struct meta_floor_log2_selector { enum { middle = (lower + upper) / 2, value = (upper <= lower + 1) ? int(meta_floor_log2_terminate) : (n < (1 << middle)) ? int(meta_floor_log2_move_down) : (n == 0) ? int(meta_floor_log2_bogus) : int(meta_floor_log2_move_up) }; }; template <unsigned int n, int lower = 0, int upper = sizeof(unsigned int) * CHAR_BIT - 1, int selector = meta_floor_log2_selector<n, lower, upper>::value> struct meta_floor_log2 {}; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down> : std::integral_constant<int, meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value> { }; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up> : std::integral_constant<int, meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value> { }; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate> : std::integral_constant<int, (n >= ((unsigned int)(1) << (lower + 1))) ? lower + 1 : lower> {}; template <unsigned int n, int lower, int upper> struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus> { // no value, error at compile time }; constexpr int floor_log2(unsigned int value) { int result = 0; while (value > 1) { value >>= 1; ++result; } return result; } template <typename BitsType, typename EnableIf = void> struct count_bits_impl { Loading
Eigen/src/Core/RandomImpl.h +1 −1 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ inline Scalar random() { // TODO: replace or provide alternatives to this, e.g. std::random_device struct eigen_random_device { using ReturnType = int; static constexpr int Entropy = meta_floor_log2<(unsigned int)(RAND_MAX) + 1>::value; static constexpr int Entropy = floor_log2((unsigned int)(RAND_MAX) + 1); static constexpr ReturnType Highest = RAND_MAX; static EIGEN_DEVICE_FUNC inline ReturnType run() { return std::rand(); } }; Loading
Eigen/src/Core/util/MoreMeta.h +13 −14 Original line number Diff line number Diff line Loading @@ -241,31 +241,30 @@ constexpr auto arg_sum(Ts... ts) { /* generic array reductions */ // can't reuse standard reduce() interface above because Intel's Compiler // *really* doesn't like it, so we just reimplement the stuff // (start from N - 1 and work down to 0 because specialization for // n == N - 1 also doesn't work in Intel's compiler, so it goes into // an infinite loop) template <typename Reducer, typename T, std::size_t N, std::size_t n = N - 1> struct h_array_reduce { EIGEN_DEVICE_FUNC constexpr static auto run(const array<T, N>& arr, T identity) { return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr)); template <typename Reducer, typename T, std::size_t N> struct array_reducer { EIGEN_DEVICE_FUNC constexpr static auto run(const array<T, N>& arr, T) { auto result = Reducer::run(arr[0], arr[1]); for (std::size_t i = 2; i < N; ++i) { result = Reducer::run(result, arr[i]); } return result; } }; template <typename Reducer, typename T, std::size_t N> struct h_array_reduce<Reducer, T, N, 0> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, N>& arr, T) { return array_get<0>(arr); } template <typename Reducer, typename T> struct array_reducer<Reducer, T, 1> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, 1>& arr, T) { return arr[0]; } }; template <typename Reducer, typename T> struct h_array_reduce<Reducer, T, 0> { struct array_reducer<Reducer, T, 0> { EIGEN_DEVICE_FUNC constexpr static T run(const array<T, 0>&, T identity) { return identity; } }; template <typename Reducer, typename T, std::size_t N> EIGEN_DEVICE_FUNC constexpr auto array_reduce(const array<T, N>& arr, T identity) { return h_array_reduce<Reducer, T, N>::run(arr, identity); return array_reducer<Reducer, T, N>::run(arr, identity); } /* standard array reductions */ Loading
Eigen/src/Core/util/Serializer.h +24 −38 Original line number Diff line number Diff line Loading @@ -123,46 +123,23 @@ class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> namespace internal { // Recursive serialization implementation helper. template <size_t N, typename... Types> struct serialize_impl; template <size_t N, typename T1, typename... Ts> struct serialize_impl<N, T1, Ts...> { using Serializer = Eigen::Serializer<std::decay_t<T1>>; static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const T1& value, const Ts&... args) { Serializer serializer; size_t size = serializer.size(value); return size + serialize_impl<N - 1, Ts...>::serialize_size(args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size_one(const Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.size(arg); } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const T1& value, const Ts&... args) { Serializer serializer; dest = serializer.serialize(dest, end, value); return serialize_impl<N - 1, Ts...>::serialize(dest, end, args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize_one(uint8_t* dest, uint8_t* end, const Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.serialize(dest, end, arg); } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, T1& value, Ts&... args) { Serializer serializer; src = serializer.deserialize(src, end, value); return serialize_impl<N - 1, Ts...>::deserialize(src, end, args...); template <typename Arg> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize_one(const uint8_t* src, const uint8_t* end, Arg& arg) { Serializer<std::decay_t<Arg>> serializer; return serializer.deserialize(src, end, arg); } }; // Base case. template <> struct serialize_impl<0> { static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size() { return 0; } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* /*end*/) { return dest; } static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* /*end*/) { return src; } }; } // namespace internal Loading @@ -174,7 +151,10 @@ struct serialize_impl<0> { */ template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::serialize_size(args...); size_t size = 0; int unused[] = {0, (size += internal::serialize_size_one(args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return size; } /** Loading @@ -187,7 +167,10 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) */ template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::serialize(dest, end, args...); EIGEN_UNUSED_VARIABLE(end); int unused[] = {0, (dest = internal::serialize_one(dest, end, args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return dest; } /** Loading @@ -201,7 +184,10 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* template <typename... Args> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, Args&... args) { return internal::serialize_impl<sizeof...(args), Args...>::deserialize(src, end, args...); EIGEN_UNUSED_VARIABLE(end); int unused[] = {0, (src = internal::deserialize_one(src, end, args), 0)...}; EIGEN_UNUSED_VARIABLE(unused); return src; } } // namespace Eigen Loading
test/meta.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,13 @@ struct dummy_c {}; struct dummy_d {}; struct dummy_e {}; struct widening_sum_op { template <typename A, typename B> EIGEN_DEVICE_FUNC constexpr static long long run(A a, B b) { return static_cast<long long>(a) + static_cast<long long>(b); } }; // dummy operation for testing apply template <typename A, typename B> struct dummy_op; Loading Loading @@ -221,11 +228,28 @@ static void test_arg_reductions() { static void test_array_reductions() { array<int, 6> a{{4, 8, 15, 16, 23, 42}}; array<int, 6> b{{42, 23, 16, 15, 8, 4}}; array<unsigned char, 0> empty{}; array<unsigned char, 1> singleton{{200}}; array<unsigned char, 2> narrow{{200, 100}}; array<unsigned char, 3> custom{{200, 100, 50}}; VERIFY_IS_EQUAL((array_sum(a)), 108); VERIFY_IS_EQUAL((array_sum(b)), 108); VERIFY_IS_EQUAL((array_prod(a)), 7418880); VERIFY_IS_EQUAL((array_prod(b)), 7418880); VERIFY((std::is_same<decltype(array_sum(empty)), unsigned char>::value)); VERIFY((std::is_same<decltype(array_sum(singleton)), unsigned char>::value)); VERIFY((std::is_same<decltype(array_sum(narrow)), int>::value)); VERIFY((std::is_same<decltype(array_prod(narrow)), int>::value)); VERIFY_IS_EQUAL((array_sum(empty)), 0); VERIFY_IS_EQUAL((array_prod(empty)), 1); VERIFY_IS_EQUAL((array_sum(singleton)), 200); VERIFY_IS_EQUAL((array_prod(singleton)), 200); VERIFY_IS_EQUAL((array_sum(narrow)), 300); VERIFY_IS_EQUAL((array_prod(narrow)), 20000); VERIFY( (std::is_same<decltype(array_reduce<widening_sum_op>(custom, static_cast<unsigned char>(0))), long long>::value)); VERIFY_IS_EQUAL((array_reduce<widening_sum_op>(custom, static_cast<unsigned char>(0))), 350); } EIGEN_DECLARE_TEST(meta) { Loading