diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 97938fdba..b0468dd64 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -480,7 +480,7 @@ struct dense_assignment_loop dstAlignment = alignable ? Aligned : int(dstIsAligned) }; const Scalar *dst_ptr = &kernel.dstEvaluator().coeffRef(0,0); - if((!bool(dstIsAligned)) && (Index(dst_ptr) % sizeof(Scalar))>0) + if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) { // the pointer is not aligend-on scalar, so alignment is not possible return dense_assignment_loop::run(kernel); diff --git a/blas/level3_impl.h b/blas/level3_impl.h index b3b727675..563101dfc 100644 --- a/blas/level3_impl.h +++ b/blas/level3_impl.h @@ -50,12 +50,18 @@ int EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScal if(info) return xerbla_(SCALAR_SUFFIX_UP"GEMM ",&info,6); + if (*m == 0 || *n == 0) + return 0; + if(beta!=Scalar(1)) { if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero(); else matrix(c, *m, *n, *ldc) *= beta; } + if(*k == 0) + return 0; + internal::gemm_blocking_space blocking(*m,*n,*k,1,true); int code = OP(*opa) | (OP(*opb) << 2); diff --git a/unsupported/Eigen/AlignedVector3 b/unsupported/Eigen/AlignedVector3 index 1fce00525..93b017437 100644 --- a/unsupported/Eigen/AlignedVector3 +++ b/unsupported/Eigen/AlignedVector3 @@ -193,6 +193,12 @@ template class AlignedVector3 namespace internal { +template +struct eval, Dense> +{ + typedef const AlignedVector3<_Scalar>& type; +}; + template struct evaluator > : evaluator >::type diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h index 165bd8a89..ca712f9c5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h @@ -492,6 +492,7 @@ class TensorBase protected: template friend class Tensor; + template friend class TensorFixedSize; template friend class TensorBase; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast(this); } @@ -508,6 +509,7 @@ class TensorBase : public TensorBase friend class Tensor; + template friend class TensorFixedSize; template friend class TensorBase; EIGEN_DEVICE_FUNC diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h b/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h index 76998b690..5e511dc4b 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h @@ -197,6 +197,23 @@ class TensorFixedSize : public TensorBase + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TensorFixedSize(const TensorBase& other) + { + typedef TensorAssignOp Assign; + Assign assign(*this, other.derived()); + internal::TensorExecutor::run(assign, DefaultDevice()); + } + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE TensorFixedSize(const TensorBase& other) + { + typedef TensorAssignOp Assign; + Assign assign(*this, other.derived()); + internal::TensorExecutor::run(assign, DefaultDevice()); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize& operator=(const TensorFixedSize& other) { diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h index 4c5e784c9..47fefff92 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h @@ -62,8 +62,11 @@ struct TensorIntDivisor { // fast ln2 const int leading_zeros = count_leading_zeros(divider); - const int log_div = N - (leading_zeros+1); - + int log_div = N - leading_zeros; + // If divider is a power of two then log_div is 1 more than it should be. + if ((1ull << (log_div-1)) == divider) { + log_div--; + } multiplier = (static_cast(1) << (N+log_div)) / divider - (static_cast(1) << N) + 1; shift1 = log_div > 1 ? 1 : log_div; shift2 = log_div > 1 ? log_div-1 : 0; diff --git a/unsupported/test/alignedvector3.cpp b/unsupported/test/alignedvector3.cpp index 0e6226ad3..911996413 100644 --- a/unsupported/test/alignedvector3.cpp +++ b/unsupported/test/alignedvector3.cpp @@ -59,6 +59,11 @@ void alignedvector3() f2.normalize(); r2.normalize(); VERIFY_IS_APPROX(f2,r2); + + std::stringstream ss1, ss2; + ss1 << f1; + ss2 << r1; + VERIFY(ss1.str()==ss2.str()); } void test_alignedvector3() diff --git a/unsupported/test/cxx11_tensor_fixed_size.cpp b/unsupported/test/cxx11_tensor_fixed_size.cpp index 8a27f5ad8..5252e4d72 100644 --- a/unsupported/test/cxx11_tensor_fixed_size.cpp +++ b/unsupported/test/cxx11_tensor_fixed_size.cpp @@ -31,12 +31,20 @@ static void test_1d() vec1(4) = 23.0; vec2(4) = 4.0; vec1(5) = 42.0; vec2(5) = 5.0; - float data3[6]; - TensorMap > > vec3(data3, 6); - vec3 = vec1.sqrt(); - float data4[6]; - TensorMap, RowMajor> > vec4(data4, 6); - vec4 = vec2.sqrt(); + // Test against shallow copy. + TensorFixedSize > copy = vec1; + VERIFY_IS_NOT_EQUAL(vec1.data(), copy.data()); + for (int i = 0; i < 6; ++i) { + VERIFY_IS_APPROX(vec1(i), copy(i)); + } + copy = vec1; + VERIFY_IS_NOT_EQUAL(vec1.data(), copy.data()); + for (int i = 0; i < 6; ++i) { + VERIFY_IS_APPROX(vec1(i), copy(i)); + } + + TensorFixedSize > vec3 = vec1.sqrt(); + TensorFixedSize, RowMajor> vec4 = vec2.sqrt(); VERIFY_IS_EQUAL((vec3.size()), 6); VERIFY_IS_EQUAL(vec3.rank(), 1); @@ -66,6 +74,30 @@ static void test_1d() VERIFY_IS_APPROX(vec3(5), 42.0f + 5.0f); } +static void test_tensor_map() +{ + TensorFixedSize > vec1; + TensorFixedSize, RowMajor> vec2; + + vec1(0) = 4.0; vec2(0) = 0.0; + vec1(1) = 8.0; vec2(1) = 1.0; + vec1(2) = 15.0; vec2(2) = 2.0; + vec1(3) = 16.0; vec2(3) = 3.0; + vec1(4) = 23.0; vec2(4) = 4.0; + vec1(5) = 42.0; vec2(5) = 5.0; + + float data3[6]; + TensorMap > > vec3(data3, 6); + vec3 = vec1.sqrt() + vec2; + + VERIFY_IS_APPROX(vec3(0), sqrtf(4.0)); + VERIFY_IS_APPROX(vec3(1), sqrtf(8.0) + 1.0f); + VERIFY_IS_APPROX(vec3(2), sqrtf(15.0) + 2.0f); + VERIFY_IS_APPROX(vec3(3), sqrtf(16.0) + 3.0f); + VERIFY_IS_APPROX(vec3(4), sqrtf(23.0) + 4.0f); + VERIFY_IS_APPROX(vec3(5), sqrtf(42.0) + 5.0f); +} + static void test_2d() { float data1[6]; @@ -192,6 +224,7 @@ static void test_array() void test_cxx11_tensor_fixed_size() { CALL_SUBTEST(test_1d()); + CALL_SUBTEST(test_tensor_map()); CALL_SUBTEST(test_2d()); CALL_SUBTEST(test_3d()); CALL_SUBTEST(test_array()); diff --git a/unsupported/test/cxx11_tensor_intdiv.cpp b/unsupported/test/cxx11_tensor_intdiv.cpp index a50356c74..134329034 100644 --- a/unsupported/test/cxx11_tensor_intdiv.cpp +++ b/unsupported/test/cxx11_tensor_intdiv.cpp @@ -68,10 +68,23 @@ void test_unsigned_64bit() } +void test_specific() +{ + // A particular combination that exposed a bug in the past. + int64_t div = 209715200; + int64_t num = 3238002688; + Eigen::internal::TensorIntDivisor divider = + Eigen::internal::TensorIntDivisor(div); + int64_t result = num/div; + int64_t result_op = divider.divide(num); + VERIFY_IS_EQUAL(result, result_op); +} + void test_cxx11_tensor_intdiv() { CALL_SUBTEST_1(test_signed_32bit()); CALL_SUBTEST_2(test_unsigned_32bit()); CALL_SUBTEST_3(test_signed_64bit()); CALL_SUBTEST_4(test_unsigned_64bit()); + CALL_SUBTEST_5(test_specific()); }