From 4b36c3591f247d4be38e5a12dbed7ac0d1ad2bff Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Fri, 10 Oct 2014 15:43:21 -0700 Subject: Fixed the tensor shuffling test --- .../Eigen/CXX11/src/Tensor/TensorDimensions.h | 133 ++++++++++++++++++++- .../Eigen/CXX11/src/Tensor/TensorExecutor.h | 8 +- unsupported/test/CMakeLists.txt | 2 +- unsupported/test/cxx11_tensor_fixed_size.cpp | 2 +- unsupported/test/cxx11_tensor_shuffling.cpp | 9 +- 5 files changed, 141 insertions(+), 13 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h index 11590b474..732c6b344 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h @@ -37,8 +37,7 @@ template struct IndexPair { Index second; }; - -// Boiler plate code +// Boilerplate code namespace internal { template struct dget { @@ -110,6 +109,11 @@ struct Sizes : internal::numeric_list { } }; +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_prod(const Sizes&) { + return Sizes::total_size; +} + #else template @@ -136,9 +140,21 @@ template Sizes(DenseIndex... indices) { } explicit Sizes(std::initializer_list l) { // todo: add assertion } +#else + EIGEN_DEVICE_FUNC explicit Sizes(const DenseIndex i0) { + } + EIGEN_DEVICE_FUNC explicit Sizes(const DenseIndex i0, const DenseIndex i1) { + } + EIGEN_DEVICE_FUNC explicit Sizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2) { + } + EIGEN_DEVICE_FUNC explicit Sizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2, const DenseIndex i3) { + } + EIGEN_DEVICE_FUNC explicit Sizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2, const DenseIndex i3, const DenseIndex i4) { + } #endif template Sizes& operator = (const T& other) { @@ -156,9 +172,14 @@ template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_prod(const Sizes&) { + return Sizes::total_size; +}; + #endif -// Boiler plate +// Boilerplate namespace internal { template struct tensor_index_linearization_helper @@ -243,6 +264,112 @@ struct DSizes : array { }; + + +// Boilerplate +namespace internal { +template +struct tensor_vsize_index_linearization_helper +{ + static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + Index run(array const& indices, std::vector const& dimensions) + { + return array_get(indices) + + array_get(dimensions) * + tensor_vsize_index_linearization_helper::run(indices, dimensions); + } +}; + +template +struct tensor_vsize_index_linearization_helper +{ + static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + Index run(array const& indices, std::vector const&) + { + return array_get(indices); + } +}; +} // end namespace internal + +template +struct VSizes : std::vector { + typedef std::vector Base; + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t TotalSize() const { + return internal::array_prod(*static_cast(this)); + } + + EIGEN_DEVICE_FUNC VSizes() { } + EIGEN_DEVICE_FUNC explicit VSizes(const std::vector& a) : Base(a) { } + + template + EIGEN_DEVICE_FUNC explicit VSizes(const array& a) { + this->resize(NumDims); + for (int i = 0; i < NumDims; ++i) { + (*this)[i] = a[i]; + } + } + + EIGEN_DEVICE_FUNC explicit VSizes(const DenseIndex i0) { + this->resize(1); + (*this)[0] = i0; + } + EIGEN_DEVICE_FUNC explicit VSizes(const DenseIndex i0, const DenseIndex i1) { + this->resize(2); + (*this)[0] = i0; + (*this)[1] = i1; + } + EIGEN_DEVICE_FUNC explicit VSizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2) { + this->resize(3); + (*this)[0] = i0; + (*this)[1] = i1; + (*this)[2] = i2; + } + EIGEN_DEVICE_FUNC explicit VSizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2, const DenseIndex i3) { + this->resize(4); + (*this)[0] = i0; + (*this)[1] = i1; + (*this)[2] = i2; + (*this)[3] = i3; + } + EIGEN_DEVICE_FUNC explicit VSizes(const DenseIndex i0, const DenseIndex i1, const DenseIndex i2, const DenseIndex i3, const DenseIndex i4) { + this->resize(5); + (*this)[0] = i0; + (*this)[1] = i1; + (*this)[2] = i2; + (*this)[3] = i3; + (*this)[4] = i4; + } + + VSizes& operator = (const std::vector& other) { + *static_cast(this) = other; + return *this; + } + + // A constexpr would be so much better here + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t IndexOfColMajor(const array& indices) const { + return internal::tensor_vsize_index_linearization_helper::run(indices, *static_cast(this)); + } + template + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t IndexOfRowMajor(const array& indices) const { + return internal::tensor_vsize_index_linearization_helper::run(indices, *static_cast(this)); + } +}; + + +// Boilerplate +namespace internal { +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex array_prod(const VSizes& sizes) { + DenseIndex total_size = 1; + for (int i = 0; i < sizes.size(); ++i) { + total_size *= sizes[i]; + } + return total_size; +} +} + namespace internal { template struct array_size > { diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h index 84768ca09..10f5a5ee7 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h @@ -39,7 +39,7 @@ class TensorExecutor const bool needs_assign = evaluator.evalSubExprsIfNeeded(NULL); if (needs_assign) { - const Index size = evaluator.dimensions().TotalSize(); + const Index size = array_prod(evaluator.dimensions()); for (Index i = 0; i < size; ++i) { evaluator.evalScalar(i); } @@ -60,7 +60,7 @@ class TensorExecutor const bool needs_assign = evaluator.evalSubExprsIfNeeded(NULL); if (needs_assign) { - const Index size = evaluator.dimensions().TotalSize(); + const Index size = array_prod(evaluator.dimensions()); static const int PacketSize = unpacket_traits::PacketReturnType>::size; const int VectorizedSize = (size / PacketSize) * PacketSize; @@ -122,7 +122,7 @@ class TensorExecutor const bool needs_assign = evaluator.evalSubExprsIfNeeded(NULL); if (needs_assign) { - const Index size = evaluator.dimensions().TotalSize(); + const Index size = array_prod(evaluator.dimensions()); static const int PacketSize = Vectorizable ? unpacket_traits::size : 1; @@ -176,7 +176,7 @@ class TensorExecutor const int num_blocks = getNumCudaMultiProcessors() * maxCudaThreadsPerMultiProcessor() / maxCudaThreadsPerBlock(); const int block_size = maxCudaThreadsPerBlock(); - const Index size = evaluator.dimensions().TotalSize(); + const Index size = array_prod(evaluator.dimensions()); EigenMetaKernel > <<>>(evaluator, size); assert(cudaGetLastError() == cudaSuccess); } diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index 1c4d0838a..ac2ccaf27 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -119,7 +119,7 @@ if(EIGEN_TEST_CXX11) ei_add_test(cxx11_tensor_morphing "-std=c++0x") ei_add_test(cxx11_tensor_padding "-std=c++0x") ei_add_test(cxx11_tensor_reduction "-std=c++0x") -# ei_add_test(cxx11_tensor_shuffling "-std=c++0x") + ei_add_test(cxx11_tensor_shuffling "-std=c++0x") ei_add_test(cxx11_tensor_striding "-std=c++0x") # ei_add_test(cxx11_tensor_device "-std=c++0x") ei_add_test(cxx11_tensor_thread_pool "-std=c++0x") diff --git a/unsupported/test/cxx11_tensor_fixed_size.cpp b/unsupported/test/cxx11_tensor_fixed_size.cpp index d270486f2..b0501aaa3 100644 --- a/unsupported/test/cxx11_tensor_fixed_size.cpp +++ b/unsupported/test/cxx11_tensor_fixed_size.cpp @@ -179,7 +179,7 @@ static void test_array() for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j) { for (int k = 0; k < 7; ++k) { - VERIFY_IS_APPROX(mat3(array(i,j,k)), powf(val, 3.5f)); + VERIFY_IS_APPROX(mat3(i,j,k), powf(val, 3.5f)); val += 1.0; } } diff --git a/unsupported/test/cxx11_tensor_shuffling.cpp b/unsupported/test/cxx11_tensor_shuffling.cpp index 5ab8b6821..39c623499 100644 --- a/unsupported/test/cxx11_tensor_shuffling.cpp +++ b/unsupported/test/cxx11_tensor_shuffling.cpp @@ -12,6 +12,7 @@ #include using Eigen::Tensor; +using Eigen::array; static void test_simple_shuffling() { @@ -80,10 +81,10 @@ static void test_expr_shuffling() Tensor result(5,7,3,2); - array src_slice_dim(Eigen::array(2,3,1,7)); - array src_slice_start(Eigen::array(0,0,0,0)); - array dst_slice_dim(Eigen::array(1,7,3,2)); - array dst_slice_start(Eigen::array(0,0,0,0)); + array src_slice_dim{{2,3,1,7}}; + array src_slice_start{{0,0,0,0}}; + array dst_slice_dim{{1,7,3,2}}; + array dst_slice_start{{0,0,0,0}}; for (int i = 0; i < 5; ++i) { result.slice(dst_slice_start, dst_slice_dim) = -- cgit v1.2.3