diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 5612ef449..3f2489b46 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -179,6 +179,9 @@ preinterpret(const Packet& a); /* { return reinterpret_cast(a); } /** \internal \returns a + b (coeff-wise) */ template EIGEN_DEVICE_FUNC inline Packet padd(const Packet& a, const Packet& b) { return a+b; } +// Avoid compiler warning for boolean algebra. +template<> EIGEN_DEVICE_FUNC inline bool +padd(const bool& a, const bool& b) { return a || b; } /** \internal \returns a - b (coeff-wise) */ template EIGEN_DEVICE_FUNC inline Packet @@ -196,6 +199,9 @@ pconj(const Packet& a) { return numext::conj(a); } /** \internal \returns a * b (coeff-wise) */ template EIGEN_DEVICE_FUNC inline Packet pmul(const Packet& a, const Packet& b) { return a*b; } +// Avoid compiler warning for boolean algebra. +template<> EIGEN_DEVICE_FUNC inline bool +pmul(const bool& a, const bool& b) { return a && b; } /** \internal \returns a / b (coeff-wise) */ template EIGEN_DEVICE_FUNC inline Packet diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index ac0799467..16215ec72 100755 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -170,10 +170,10 @@ template<> struct packet_traits : default_packet_traits HasHalfPacket = 0, size=16, - HasAdd = 0, + HasAdd = 1, HasSub = 0, HasShift = 0, - HasMul = 0, + HasMul = 1, HasNegate = 0, HasAbs = 0, HasAbs2 = 0, @@ -249,6 +249,8 @@ template<> EIGEN_STRONG_INLINE Packet4f padd(const Packet4f& a, const template<> EIGEN_STRONG_INLINE Packet2d padd(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); } template<> EIGEN_STRONG_INLINE Packet4i padd(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); } +template<> EIGEN_STRONG_INLINE Packet16b padd(const Packet16b& a, const Packet16b& b) { return _mm_or_si128(a,b); } + template<> EIGEN_STRONG_INLINE Packet4f psub(const Packet4f& a, const Packet4f& b) { return _mm_sub_ps(a,b); } template<> EIGEN_STRONG_INLINE Packet2d psub(const Packet2d& a, const Packet2d& b) { return _mm_sub_pd(a,b); } template<> EIGEN_STRONG_INLINE Packet4i psub(const Packet4i& a, const Packet4i& b) { return _mm_sub_epi32(a,b); } @@ -290,6 +292,8 @@ template<> EIGEN_STRONG_INLINE Packet4i pmul(const Packet4i& a, const #endif } +template<> EIGEN_STRONG_INLINE Packet16b pmul(const Packet16b& a, const Packet16b& b) { return _mm_and_si128(a,b); } + template<> EIGEN_STRONG_INLINE Packet4f pdiv(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); } template<> EIGEN_STRONG_INLINE Packet2d pdiv(const Packet2d& a, const Packet2d& b) { return _mm_div_pd(a,b); } @@ -646,6 +650,7 @@ template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { return _mm_cvtss_f32(a); } template<> EIGEN_STRONG_INLINE double pfirst(const Packet2d& a) { return _mm_cvtsd_f64(a); } template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { return _mm_cvtsi128_si32(a); } +template<> EIGEN_STRONG_INLINE bool pfirst(const Packet16b& a) { int x = _mm_cvtsi128_si32(a); return static_cast(x & 1); } #endif template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) @@ -762,6 +767,7 @@ template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) Packet4i tmp0 = _mm_hadd_epi32(a,a); return pfirst(_mm_hadd_epi32(tmp0,tmp0)); } + #else template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) { @@ -769,8 +775,22 @@ template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) return pfirst(tmp) + pfirst(_mm_shuffle_epi32(tmp, 1)); } #endif + +#ifdef EIGEN_VECTORIZE_SSE4_1 +template<> EIGEN_STRONG_INLINE bool predux(const Packet16b& a) { + Packet16b tmp = _mm_or_si128(a, _mm_unpackhi_epi64(a,a)); + return _mm_extract_epi64(tmp, 0) != 0; +} +#else +template<> EIGEN_STRONG_INLINE bool predux(const Packet16b& a) { +Packet4i tmp = _mm_or_si128(a, _mm_unpackhi_epi64(a,a)); + return (pfirst(tmp) != 0) || (pfirst(_mm_shuffle_epi32(tmp, 1)) != 0); +} +#endif + // Other reduction functions: + // mul template<> EIGEN_STRONG_INLINE float predux_mul(const Packet4f& a) { @@ -987,6 +1007,19 @@ ptranspose(PacketBlock& kernel) { kernel.packet[3] = _mm_unpackhi_epi64(T2, T3); } +EIGEN_DEVICE_FUNC inline void +ptranspose(PacketBlock& kernel) { + __m128i T0 = _mm_unpacklo_epi8(kernel.packet[0], kernel.packet[1]); + __m128i T1 = _mm_unpackhi_epi8(kernel.packet[0], kernel.packet[1]); + __m128i T2 = _mm_unpacklo_epi8(kernel.packet[2], kernel.packet[3]); + __m128i T3 = _mm_unpackhi_epi8(kernel.packet[2], kernel.packet[3]); + kernel.packet[0] = _mm_unpacklo_epi16(T0, T2); + kernel.packet[1] = _mm_unpackhi_epi16(T0, T2); + kernel.packet[2] = _mm_unpacklo_epi16(T1, T3); + kernel.packet[3] = _mm_unpackhi_epi16(T1, T3); +} + + template<> EIGEN_STRONG_INLINE Packet4i pblend(const Selector<4>& ifPacket, const Packet4i& thenPacket, const Packet4i& elsePacket) { const __m128i zero = _mm_setzero_si128(); const __m128i select = _mm_set_epi32(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]); diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h index a2bc58c76..697816663 100644 --- a/Eigen/src/Core/functors/BinaryFunctors.h +++ b/Eigen/src/Core/functors/BinaryFunctors.h @@ -39,12 +39,12 @@ struct scalar_sum_op : binary_op_base EIGEN_SCALAR_BINARY_OP_PLUGIN } #endif - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const { return internal::padd(a,b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const { return internal::predux(a); } }; template @@ -56,15 +56,9 @@ struct functor_traits > { }; }; -/** \internal - * \brief Template specialization to deprecate the summation of boolean expressions. - * This is required to solve Bug 426. - * \sa DenseBase::count(), DenseBase::any(), ArrayBase::cast(), MatrixBase::cast() - */ -template<> struct scalar_sum_op : scalar_sum_op { - EIGEN_DEPRECATED - scalar_sum_op() {} -}; + +template<> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op::operator() (const bool& a, const bool& b) const { return a || b; } /** \internal @@ -83,12 +77,12 @@ struct scalar_product_op : binary_op_base EIGEN_SCALAR_BINARY_OP_PLUGIN } #endif - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const { return internal::pmul(a,b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const { return internal::predux_mul(a); } }; template @@ -100,6 +94,10 @@ struct functor_traits > { }; }; +template<> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op::operator() (const bool& a, const bool& b) const { return a && b; } + + /** \internal * \brief Template functor to compute the conjugate product of two scalars * @@ -116,11 +114,11 @@ struct scalar_conj_product_op : binary_op_base typedef typename ScalarBinaryOpTraits::ReturnType result_type; EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return conj_helper().pmul(a,b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const { return conj_helper().pmul(a,b); } }; template @@ -141,12 +139,12 @@ struct scalar_min_op : binary_op_base { typedef typename ScalarBinaryOpTraits::ReturnType result_type; EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::mini(a, b); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::mini(a, b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const { return internal::pmin(a,b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const { return internal::predux_min(a); } }; template @@ -167,12 +165,12 @@ struct scalar_max_op : binary_op_base { typedef typename ScalarBinaryOpTraits::ReturnType result_type; EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::maxi(a, b); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::maxi(a, b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const { return internal::pmax(a,b); } template - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const { return internal::predux_max(a); } }; template diff --git a/test/product_small.cpp b/test/product_small.cpp index b8ce37d90..93876dba4 100644 --- a/test/product_small.cpp +++ b/test/product_small.cpp @@ -56,6 +56,31 @@ test_lazy_single(int rows, int cols, int depth) VERIFY_IS_APPROX(C+=A.lazyProduct(B), ref_prod(D,A,B)); } +template +void test_dynamic_exact() +{ + int rows = internal::random(1,64); + int cols = internal::random(1,64); + int depth = internal::random(1,65); + + typedef Matrix MatrixX; + MatrixX A(rows,depth); A.setRandom(); + MatrixX B(depth,cols); B.setRandom(); + MatrixX C(rows,cols); C.setRandom(); + MatrixX D(C); + for(Index i=0;i typename internal::enable_if< ( (Rows ==1&&Depth!=1&&OA==ColMajor) || (Depth==1&&Rows !=1&&OA==RowMajor) @@ -78,7 +103,7 @@ void test_lazy_all_layout(int rows=Rows, int cols=Cols, int depth=Depth) CALL_SUBTEST(( test_lazy_single(rows,cols,depth) )); CALL_SUBTEST(( test_lazy_single(rows,cols,depth) )); CALL_SUBTEST(( test_lazy_single(rows,cols,depth) )); -} +} template void test_lazy_l1() @@ -291,6 +316,8 @@ EIGEN_DECLARE_TEST(product_small) CALL_SUBTEST_6( bug_1311<3>() ); CALL_SUBTEST_6( bug_1311<5>() ); + + CALL_SUBTEST_9( test_dynamic_exact() ); } CALL_SUBTEST_6( product_small_regressions<0>() ); diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h index d04dcae17..f107d1b19 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h @@ -456,7 +456,9 @@ struct TensorEvaluator, Devi // slice offsets and sizes. IsAligned = false, PacketAccess = TensorEvaluator::PacketAccess, - BlockAccess = TensorEvaluator::BlockAccess, + BlockAccess = TensorEvaluator::BlockAccess && + // FIXME: Temporary workaround for bug in slicing of bool tensors. + !internal::is_same::type, bool>::value, PreferBlockAccess = true, Layout = TensorEvaluator::Layout, CoordAccess = false, @@ -525,7 +527,6 @@ struct TensorEvaluator, Devi EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; } - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType data) { m_impl.evalSubExprsIfNeeded(NULL); if (!NumTraits::type>::RequireInitialization @@ -559,14 +560,14 @@ struct TensorEvaluator, Devi } return true; } - + #ifdef EIGEN_USE_THREADS template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalSubExprsIfNeededAsync( EvaluatorPointerType data, EvalSubExprsCallback done) { m_impl.evalSubExprsIfNeededAsync(nullptr, [done](bool) { done(true); }); } -#endif // EIGEN_USE_THREADS +#endif // EIGEN_USE_THREADS EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() { m_impl.cleanup(); diff --git a/unsupported/test/cxx11_tensor_block_eval.cpp b/unsupported/test/cxx11_tensor_block_eval.cpp index 226c495aa..a7a49fa1f 100644 --- a/unsupported/test/cxx11_tensor_block_eval.cpp +++ b/unsupported/test/cxx11_tensor_block_eval.cpp @@ -233,7 +233,7 @@ static void test_eval_tensor_binary_expr_block() { rhs.setRandom(); VerifyBlockEvaluator( - lhs + rhs, [&dims]() { return RandomBlock(dims, 1, 10); }); + lhs * rhs, [&dims]() { return RandomBlock(dims, 1, 10); }); } template @@ -274,7 +274,7 @@ static void test_eval_tensor_broadcast() { // Check that desc.destination() memory is not shared between two broadcast // materializations. VerifyBlockEvaluator( - input.broadcast(bcast) + input.square().broadcast(bcast), + input.broadcast(bcast) * input.square().broadcast(bcast), [&bcasted_dims]() { return SkewedInnerBlock(bcasted_dims); }); } @@ -509,7 +509,7 @@ static void test_eval_tensor_reshape_with_bcast() { DSizes dims(dim, dim); VerifyBlockEvaluator( - lhs.reshape(reshapeLhs).broadcast(bcastLhs) + + lhs.reshape(reshapeLhs).broadcast(bcastLhs) * rhs.reshape(reshapeRhs).broadcast(bcastRhs), [dims]() { return SkewedInnerBlock(dims); }); } @@ -529,11 +529,11 @@ static void test_eval_tensor_forced_eval() { DSizes dims(dim, dim); VerifyBlockEvaluator( - (lhs.broadcast(bcastLhs) + rhs.broadcast(bcastRhs)).eval().reshape(dims), + (lhs.broadcast(bcastLhs) * rhs.broadcast(bcastRhs)).eval().reshape(dims), [dims]() { return SkewedInnerBlock(dims); }); VerifyBlockEvaluator( - (lhs.broadcast(bcastLhs) + rhs.broadcast(bcastRhs)).eval().reshape(dims), + (lhs.broadcast(bcastLhs) * rhs.broadcast(bcastRhs)).eval().reshape(dims), [dims]() { return RandomBlock(dims, 1, 50); }); } @@ -755,7 +755,39 @@ static void test_assign_to_tensor_shuffle() { #define CALL_SUBTEST_PART(PART) \ CALL_SUBTEST_##PART -#define CALL_SUBTESTS_DIMS_LAYOUTS(PART, NAME) \ +#define CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(PART, NAME) \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())) + +#define CALL_SUBTESTS_DIMS_LAYOUTS(PART, NAME) \ CALL_SUBTEST_PART(PART)((NAME())); \ CALL_SUBTEST_PART(PART)((NAME())); \ CALL_SUBTEST_PART(PART)((NAME())); \ @@ -767,36 +799,38 @@ static void test_assign_to_tensor_shuffle() { CALL_SUBTEST_PART(PART)((NAME())); \ CALL_SUBTEST_PART(PART)((NAME())) -#define CALL_SUBTESTS_LAYOUTS(PART, NAME) \ +#define CALL_SUBTESTS_LAYOUTS_TYPES(PART, NAME) \ CALL_SUBTEST_PART(PART)((NAME())); \ - CALL_SUBTEST_PART(PART)((NAME())) + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())) EIGEN_DECLARE_TEST(cxx11_tensor_block_eval) { // clang-format off - CALL_SUBTESTS_DIMS_LAYOUTS(1, test_eval_tensor_block); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(1, test_eval_tensor_block); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(1, test_eval_tensor_binary_expr_block); CALL_SUBTESTS_DIMS_LAYOUTS(1, test_eval_tensor_unary_expr_block); - CALL_SUBTESTS_DIMS_LAYOUTS(1, test_eval_tensor_binary_expr_block); CALL_SUBTESTS_DIMS_LAYOUTS(2, test_eval_tensor_binary_with_unary_expr_block); - CALL_SUBTESTS_DIMS_LAYOUTS(2, test_eval_tensor_broadcast); - CALL_SUBTESTS_DIMS_LAYOUTS(2, test_eval_tensor_reshape); - CALL_SUBTESTS_DIMS_LAYOUTS(3, test_eval_tensor_cast); - CALL_SUBTESTS_DIMS_LAYOUTS(3, test_eval_tensor_select); - CALL_SUBTESTS_DIMS_LAYOUTS(3, test_eval_tensor_padding); - CALL_SUBTESTS_DIMS_LAYOUTS(4, test_eval_tensor_chipping); - CALL_SUBTESTS_DIMS_LAYOUTS(4, test_eval_tensor_generator); - CALL_SUBTESTS_DIMS_LAYOUTS(4, test_eval_tensor_reverse); - CALL_SUBTESTS_DIMS_LAYOUTS(5, test_eval_tensor_slice); - CALL_SUBTESTS_DIMS_LAYOUTS(5, test_eval_tensor_shuffle); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(2, test_eval_tensor_broadcast); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(2, test_eval_tensor_reshape); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(3, test_eval_tensor_cast); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(3, test_eval_tensor_select); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(3, test_eval_tensor_padding); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(4, test_eval_tensor_chipping); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(4, test_eval_tensor_generator); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(4, test_eval_tensor_reverse); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(5, test_eval_tensor_slice); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(5, test_eval_tensor_shuffle); - CALL_SUBTESTS_LAYOUTS(6, test_eval_tensor_reshape_with_bcast); - CALL_SUBTESTS_LAYOUTS(6, test_eval_tensor_forced_eval); - CALL_SUBTESTS_LAYOUTS(6, test_eval_tensor_chipping_of_bcast); + CALL_SUBTESTS_LAYOUTS_TYPES(6, test_eval_tensor_reshape_with_bcast); + CALL_SUBTESTS_LAYOUTS_TYPES(6, test_eval_tensor_forced_eval); + CALL_SUBTESTS_LAYOUTS_TYPES(6, test_eval_tensor_chipping_of_bcast); - CALL_SUBTESTS_DIMS_LAYOUTS(7, test_assign_to_tensor); - CALL_SUBTESTS_DIMS_LAYOUTS(7, test_assign_to_tensor_reshape); - CALL_SUBTESTS_DIMS_LAYOUTS(7, test_assign_to_tensor_chipping); - CALL_SUBTESTS_DIMS_LAYOUTS(8, test_assign_to_tensor_slice); - CALL_SUBTESTS_DIMS_LAYOUTS(8, test_assign_to_tensor_shuffle); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(7, test_assign_to_tensor); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(7, test_assign_to_tensor_reshape); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(7, test_assign_to_tensor_chipping); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(8, test_assign_to_tensor_slice); + CALL_SUBTESTS_DIMS_LAYOUTS_TYPES(8, test_assign_to_tensor_shuffle); // Force CMake to split this test. // EIGEN_SUFFIXES;1;2;3;4;5;6;7;8 diff --git a/unsupported/test/cxx11_tensor_block_io.cpp b/unsupported/test/cxx11_tensor_block_io.cpp index a6f7a44cd..52f7dde9b 100644 --- a/unsupported/test/cxx11_tensor_block_io.cpp +++ b/unsupported/test/cxx11_tensor_block_io.cpp @@ -415,7 +415,15 @@ static void test_block_io_squeeze_ones() { CALL_SUBTEST((NAME())); \ CALL_SUBTEST((NAME())); \ CALL_SUBTEST((NAME())); \ - CALL_SUBTEST((NAME())) + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())); \ + CALL_SUBTEST((NAME())) EIGEN_DECLARE_TEST(cxx11_tensor_block_io) { // clang-format off diff --git a/unsupported/test/cxx11_tensor_contraction.cpp b/unsupported/test/cxx11_tensor_contraction.cpp index 2fd128121..3b5c6a13c 100644 --- a/unsupported/test/cxx11_tensor_contraction.cpp +++ b/unsupported/test/cxx11_tensor_contraction.cpp @@ -562,36 +562,40 @@ static void test_large_contraction_with_output_kernel() { EIGEN_DECLARE_TEST(cxx11_tensor_contraction) { - CALL_SUBTEST(test_evals()); - CALL_SUBTEST(test_evals()); - CALL_SUBTEST(test_scalar()); - CALL_SUBTEST(test_scalar()); - CALL_SUBTEST(test_multidims()); - CALL_SUBTEST(test_multidims()); - CALL_SUBTEST(test_holes()); - CALL_SUBTEST(test_holes()); - CALL_SUBTEST(test_full_redux()); - CALL_SUBTEST(test_full_redux()); - CALL_SUBTEST(test_contraction_of_contraction()); - CALL_SUBTEST(test_contraction_of_contraction()); - CALL_SUBTEST(test_expr()); - CALL_SUBTEST(test_expr()); - CALL_SUBTEST(test_out_of_order_contraction()); - CALL_SUBTEST(test_out_of_order_contraction()); - CALL_SUBTEST(test_consistency()); - CALL_SUBTEST(test_consistency()); - CALL_SUBTEST(test_large_contraction()); - CALL_SUBTEST(test_large_contraction()); - CALL_SUBTEST(test_matrix_vector()); - CALL_SUBTEST(test_matrix_vector()); - CALL_SUBTEST(test_tensor_vector()); - CALL_SUBTEST(test_tensor_vector()); - CALL_SUBTEST(test_small_blocking_factors()); - CALL_SUBTEST(test_small_blocking_factors()); - CALL_SUBTEST(test_tensor_product()); - CALL_SUBTEST(test_tensor_product()); - CALL_SUBTEST(test_const_inputs()); - CALL_SUBTEST(test_const_inputs()); - CALL_SUBTEST(test_large_contraction_with_output_kernel()); - CALL_SUBTEST(test_large_contraction_with_output_kernel()); + CALL_SUBTEST_1(test_evals()); + CALL_SUBTEST_1(test_evals()); + CALL_SUBTEST_1(test_scalar()); + CALL_SUBTEST_1(test_scalar()); + CALL_SUBTEST_2(test_multidims()); + CALL_SUBTEST_2(test_multidims()); + CALL_SUBTEST_2(test_holes()); + CALL_SUBTEST_2(test_holes()); + CALL_SUBTEST_3(test_full_redux()); + CALL_SUBTEST_3(test_full_redux()); + CALL_SUBTEST_3(test_contraction_of_contraction()); + CALL_SUBTEST_3(test_contraction_of_contraction()); + CALL_SUBTEST_4(test_expr()); + CALL_SUBTEST_4(test_expr()); + CALL_SUBTEST_4(test_out_of_order_contraction()); + CALL_SUBTEST_4(test_out_of_order_contraction()); + CALL_SUBTEST_5(test_consistency()); + CALL_SUBTEST_5(test_consistency()); + CALL_SUBTEST_5(test_large_contraction()); + CALL_SUBTEST_5(test_large_contraction()); + CALL_SUBTEST_6(test_matrix_vector()); + CALL_SUBTEST_6(test_matrix_vector()); + CALL_SUBTEST_6(test_tensor_vector()); + CALL_SUBTEST_6(test_tensor_vector()); + CALL_SUBTEST_7(test_small_blocking_factors()); + CALL_SUBTEST_7(test_small_blocking_factors()); + CALL_SUBTEST_7(test_tensor_product()); + CALL_SUBTEST_7(test_tensor_product()); + CALL_SUBTEST_8(test_const_inputs()); + CALL_SUBTEST_8(test_const_inputs()); + CALL_SUBTEST_8(test_large_contraction_with_output_kernel()); + CALL_SUBTEST_8(test_large_contraction_with_output_kernel()); + + // Force CMake to split this test. + // EIGEN_SUFFIXES;1;2;3;4;5;6;7;8 + } diff --git a/unsupported/test/cxx11_tensor_expr.cpp b/unsupported/test/cxx11_tensor_expr.cpp index d56da28d8..6dc44996a 100644 --- a/unsupported/test/cxx11_tensor_expr.cpp +++ b/unsupported/test/cxx11_tensor_expr.cpp @@ -195,26 +195,23 @@ static void test_constants() static void test_boolean() { - Tensor vec(31); - std::iota(vec.data(), vec.data() + 31, 0); + const int kSize = 31; + Tensor vec(kSize); + std::iota(vec.data(), vec.data() + kSize, 0); // Test ||. Tensor bool1 = vec < vec.constant(1) || vec > vec.constant(4); - VERIFY_IS_EQUAL(bool1[0], true); - VERIFY_IS_EQUAL(bool1[1], false); - VERIFY_IS_EQUAL(bool1[2], false); - VERIFY_IS_EQUAL(bool1[3], false); - VERIFY_IS_EQUAL(bool1[4], false); - VERIFY_IS_EQUAL(bool1[5], true); + for (int i = 0; i < kSize; ++i) { + bool expected = i < 1 || i > 4; + VERIFY_IS_EQUAL(bool1[i], expected); + } // Test &&, including cast of operand vec. Tensor bool2 = vec.cast() && vec < vec.constant(4); - VERIFY_IS_EQUAL(bool2[0], false); - VERIFY_IS_EQUAL(bool2[1], true); - VERIFY_IS_EQUAL(bool2[2], true); - VERIFY_IS_EQUAL(bool2[3], true); - VERIFY_IS_EQUAL(bool2[4], false); - VERIFY_IS_EQUAL(bool2[5], false); + for (int i = 0; i < kSize; ++i) { + bool expected = bool(i) && i < 4; + VERIFY_IS_EQUAL(bool2[i], expected); + } // Compilation tests: // Test Tensor against results of cast or comparison; verifies that diff --git a/unsupported/test/cxx11_tensor_morphing.cpp b/unsupported/test/cxx11_tensor_morphing.cpp index eb708737d..f01b95357 100644 --- a/unsupported/test/cxx11_tensor_morphing.cpp +++ b/unsupported/test/cxx11_tensor_morphing.cpp @@ -64,7 +64,7 @@ static void test_static_reshape() { #endif } -template +template static void test_reshape_in_expr() { MatrixXf m1(2,3*5*7*11); MatrixXf m2(3*5*7*11,13); @@ -113,19 +113,19 @@ static void test_reshape_as_lvalue() } } -template +template static void test_simple_slice() { - Tensor tensor(2,3,5,7,11); + Tensor tensor(2,3,5,7,11); tensor.setRandom(); - Tensor slice1(1,1,1,1,1); + Tensor slice1(1,1,1,1,1); Eigen::DSizes indices(1,2,3,4,5); Eigen::DSizes sizes(1,1,1,1,1); slice1 = tensor.slice(indices, sizes); VERIFY_IS_EQUAL(slice1(0,0,0,0,0), tensor(1,2,3,4,5)); - Tensor slice2(1,1,2,2,3); + Tensor slice2(1,1,2,2,3); Eigen::DSizes indices2(1,1,3,4,5); Eigen::DSizes sizes2(1,1,2,2,3); slice2 = tensor.slice(indices2, sizes2); @@ -138,20 +138,20 @@ static void test_simple_slice() } } -template +template static void test_const_slice() { - const float b[1] = {42}; - TensorMap > m(b, 1); + const T b[1] = {42}; + TensorMap > m(b, 1); DSizes offsets; offsets[0] = 0; - TensorRef > slice_ref(m.slice(offsets, m.dimensions())); + TensorRef > slice_ref(m.slice(offsets, m.dimensions())); VERIFY_IS_EQUAL(slice_ref(0), 42); } -template +template static void test_slice_in_expr() { - typedef Matrix Mtx; + typedef Matrix Mtx; Mtx m1(7,7); Mtx m2(3,3); m1.setRandom(); @@ -159,10 +159,10 @@ static void test_slice_in_expr() { Mtx m3 = m1.block(1, 2, 3, 3) * m2.block(0, 2, 3, 1); - TensorMap> tensor1(m1.data(), 7, 7); - TensorMap> tensor2(m2.data(), 3, 3); - Tensor tensor3(3,1); - typedef Tensor::DimensionPair DimPair; + TensorMap> tensor1(m1.data(), 7, 7); + TensorMap> tensor2(m2.data(), 3, 3); + Tensor tensor3(3,1); + typedef typename Tensor::DimensionPair DimPair; array contract_along{{DimPair(1, 0)}}; Eigen::DSizes indices1(1,2); @@ -179,28 +179,28 @@ static void test_slice_in_expr() { } // Take an arbitrary slice of an arbitrarily sized tensor. - TensorMap> tensor4(m1.data(), 7, 7); - Tensor tensor6 = tensor4.reshape(DSizes(7*7)).exp().slice(DSizes(0), DSizes(35)); + TensorMap> tensor4(m1.data(), 7, 7); + Tensor tensor6 = tensor4.reshape(DSizes(7*7)).exp().slice(DSizes(0), DSizes(35)); for (int i = 0; i < 35; ++i) { VERIFY_IS_APPROX(tensor6(i), expf(tensor4.data()[i])); } } -template +template static void test_slice_as_lvalue() { - Tensor tensor1(2,2,7); + Tensor tensor1(2,2,7); tensor1.setRandom(); - Tensor tensor2(2,2,7); + Tensor tensor2(2,2,7); tensor2.setRandom(); - Tensor tensor3(4,3,5); + Tensor tensor3(4,3,5); tensor3.setRandom(); - Tensor tensor4(4,3,2); + Tensor tensor4(4,3,2); tensor4.setRandom(); - Tensor tensor5(10,13,12); + Tensor tensor5(10,13,12); tensor5.setRandom(); - Tensor result(4,5,7); + Tensor result(4,5,7); Eigen::DSizes sizes12(2,2,7); Eigen::DSizes first_slice(0,0,0); result.slice(first_slice, sizes12) = tensor1; @@ -246,10 +246,10 @@ static void test_slice_as_lvalue() } } -template +template static void test_slice_raw_data() { - Tensor tensor(3,5,7,11); + Tensor tensor(3,5,7,11); tensor.setRandom(); Eigen::DSizes offsets(1,2,3,4); @@ -276,7 +276,7 @@ static void test_slice_raw_data() extents = Eigen::DSizes(1,2,1,1); auto slice3 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice()); VERIFY_IS_EQUAL(slice3.dimensions().TotalSize(), 2); - VERIFY_IS_EQUAL(slice3.data(), static_cast(0)); + VERIFY_IS_EQUAL(slice3.data(), static_cast(0)); if (DataLayout == ColMajor) { offsets = Eigen::DSizes(0,2,3,4); @@ -341,15 +341,15 @@ static void test_slice_raw_data() } -template +template static void test_strided_slice() { - typedef Tensor Tensor5f; + typedef Tensor Tensor5f; typedef Eigen::DSizes Index5; - typedef Tensor Tensor2f; + typedef Tensor Tensor2f; typedef Eigen::DSizes Index2; - Tensor tensor(2,3,5,7,11); - Tensor tensor2(7,11); + Tensor tensor(2,3,5,7,11); + Tensor tensor2(7,11); tensor.setRandom(); tensor2.setRandom(); @@ -435,13 +435,13 @@ static void test_strided_slice() } } -template +template static void test_strided_slice_write() { - typedef Tensor Tensor2f; + typedef Tensor Tensor2f; typedef Eigen::DSizes Index2; - Tensor tensor(7,11),tensor2(7,11); + Tensor tensor(7,11),tensor2(7,11); tensor.setRandom(); tensor2=tensor; Tensor2f slice(2,3); @@ -461,15 +461,14 @@ static void test_strided_slice_write() } } - -template +template static void test_composition() { - Eigen::Tensor matrix(7, 11); + Eigen::Tensor matrix(7, 11); matrix.setRandom(); const DSizes newDims(1, 1, 11); - Eigen::Tensor tensor = + Eigen::Tensor tensor = matrix.slice(DSizes(2, 0), DSizes(1, 11)).reshape(newDims); VERIFY_IS_EQUAL(tensor.dimensions().TotalSize(), 11); @@ -481,29 +480,27 @@ static void test_composition() } } +#define CALL_SUBTEST_PART(PART) \ + CALL_SUBTEST_##PART + +#define CALL_SUBTESTS_TYPES_LAYOUTS(PART, NAME) \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())); \ + CALL_SUBTEST_PART(PART)((NAME())) EIGEN_DECLARE_TEST(cxx11_tensor_morphing) { CALL_SUBTEST_1(test_simple_reshape()); CALL_SUBTEST_1(test_static_reshape()); - CALL_SUBTEST_1(test_reshape_in_expr()); CALL_SUBTEST_1(test_reshape_as_lvalue()); + CALL_SUBTEST_1(test_reshape_in_expr()); + CALL_SUBTEST_1(test_const_slice()); - CALL_SUBTEST_1(test_simple_slice()); - CALL_SUBTEST_1(test_simple_slice()); - CALL_SUBTEST_1(test_const_slice()); - CALL_SUBTEST_2(test_slice_in_expr()); - CALL_SUBTEST_3(test_slice_in_expr()); - CALL_SUBTEST_4(test_slice_as_lvalue()); - CALL_SUBTEST_4(test_slice_as_lvalue()); - CALL_SUBTEST_5(test_slice_raw_data()); - CALL_SUBTEST_5(test_slice_raw_data()); - - CALL_SUBTEST_6(test_strided_slice_write()); - CALL_SUBTEST_6(test_strided_slice()); - CALL_SUBTEST_6(test_strided_slice_write()); - CALL_SUBTEST_6(test_strided_slice()); - - CALL_SUBTEST_7(test_composition()); - CALL_SUBTEST_7(test_composition()); + CALL_SUBTESTS_TYPES_LAYOUTS(2, test_simple_slice); + CALL_SUBTESTS_TYPES_LAYOUTS(3, test_slice_as_lvalue); + CALL_SUBTESTS_TYPES_LAYOUTS(4, test_slice_raw_data); + CALL_SUBTESTS_TYPES_LAYOUTS(5, test_strided_slice_write); + CALL_SUBTESTS_TYPES_LAYOUTS(6, test_strided_slice); + CALL_SUBTESTS_TYPES_LAYOUTS(7, test_composition); }