diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-02-26 20:12:51 -0500 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-02-26 20:12:51 -0500 |
commit | b1f666d007ee4dc22f48dd65f900ee3659dd1f7d (patch) | |
tree | 29c6de6cb4b2bf92a9f54b1f67c7ef5aa2773b24 /test | |
parent | 32115bff1e2b99641e09e0fe182d2d5cc11413ec (diff) |
Fix Map-with-Stride and cover it by new unit tests.
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/map.cpp | 14 | ||||
-rw-r--r-- | test/mapstride.cpp | 139 | ||||
-rw-r--r-- | test/vectorization_logic.cpp | 17 |
4 files changed, 164 insertions, 7 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c6b359ce9..072f63e1d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -115,6 +115,7 @@ ei_add_test(miscmatrices) ei_add_test(commainitializer) ei_add_test(smallvectors) ei_add_test(map) +ei_add_test(mapstride) ei_add_test(array) ei_add_test(array_for_matrix) ei_add_test(array_replicate) diff --git a/test/map.cpp b/test/map.cpp index 603b6159b..acaa8fecc 100644 --- a/test/map.cpp +++ b/test/map.cpp @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -42,8 +42,8 @@ template<typename VectorType> void map_class_vector(const VectorType& m) VectorType ma1 = Map<VectorType, Aligned>(array1, size); VectorType ma2 = Map<VectorType, Aligned>(array2, size); VectorType ma3 = Map<VectorType>(array3unaligned, size); - VERIFY_IS_APPROX(ma1, ma2); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma3); VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size))); ei_aligned_delete(array1, size); @@ -70,9 +70,9 @@ template<typename MatrixType> void map_class_matrix(const MatrixType& m) Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols); MatrixType ma1 = Map<MatrixType>(array1, rows, cols); MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols); - VERIFY_IS_APPROX(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma2); MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma3); ei_aligned_delete(array1, size); ei_aligned_delete(array2, size); @@ -97,8 +97,8 @@ template<typename VectorType> void map_static_methods(const VectorType& m) VectorType ma1 = VectorType::Map(array1, size); VectorType ma2 = VectorType::MapAligned(array2, size); VectorType ma3 = VectorType::Map(array3unaligned, size); - VERIFY_IS_APPROX(ma1, ma2); - VERIFY_IS_APPROX(ma1, ma3); + VERIFY_IS_EQUAL(ma1, ma2); + VERIFY_IS_EQUAL(ma1, ma3); ei_aligned_delete(array1, size); ei_aligned_delete(array2, size); diff --git a/test/mapstride.cpp b/test/mapstride.cpp new file mode 100644 index 000000000..7a1605681 --- /dev/null +++ b/test/mapstride.cpp @@ -0,0 +1,139 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see <http://www.gnu.org/licenses/>. + +#include "main.h" + +template<typename VectorType> void map_class_vector(const VectorType& m) +{ + typedef typename VectorType::Scalar Scalar; + + int size = m.size(); + + VectorType v = VectorType::Random(size); + + int arraysize = 3*size; + + Scalar* array = ei_aligned_new<Scalar>(arraysize); + + { + Map<VectorType, Aligned, InnerStride<3> > map(array, size); + map = v; + for(int i = 0; i < size; ++i) + { + VERIFY(array[3*i] == v[i]); + VERIFY(map[i] == v[i]); + } + } + + { + Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2)); + map = v; + for(int i = 0; i < size; ++i) + { + VERIFY(array[2*i] == v[i]); + VERIFY(map[i] == v[i]); + } + } + + ei_aligned_delete(array, arraysize); +} + +template<typename MatrixType> void map_class_matrix(const MatrixType& _m) +{ + typedef typename MatrixType::Scalar Scalar; + + int rows = _m.rows(), cols = _m.cols(); + + MatrixType m = MatrixType::Random(rows,cols); + + int arraysize = 2*(rows+4)*(cols+4); + + Scalar* array = ei_aligned_new<Scalar>(arraysize); + + // test no inner stride and some dynamic outer stride + { + Map<MatrixType, Aligned, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1)); + map = m; + VERIFY(map.outerStride() == map.innerSize()+1); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices, + // this allows to hit the special case where it's vectorizable. + { + enum { + InnerSize = MatrixType::InnerSizeAtCompileTime, + OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4 + }; + Map<MatrixType, Aligned, OuterStride<OuterStrideAtCompileTime> > + map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4)); + map = m; + VERIFY(map.outerStride() == map.innerSize()+4); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + // test both inner stride and outer stride + { + Map<MatrixType, Aligned, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2)); + map = m; + VERIFY(map.outerStride() == 2*map.innerSize()+1); + VERIFY(map.innerStride() == 2); + for(int i = 0; i < m.outerSize(); ++i) + for(int j = 0; j < m.innerSize(); ++j) + { + VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j)); + VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j)); + } + } + + ei_aligned_delete(array, arraysize); +} + +void test_mapstride() +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( map_class_vector(Vector4d()) ); + CALL_SUBTEST_3( map_class_vector(RowVector4f()) ); + CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) ); + CALL_SUBTEST_5( map_class_vector(VectorXi(12)) ); + + CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) ); + CALL_SUBTEST_2( map_class_matrix(Matrix4d()) ); + CALL_SUBTEST_3( map_class_matrix(Matrix<float,3,5>()) ); + CALL_SUBTEST_3( map_class_matrix(Matrix<float,4,8>()) ); + CALL_SUBTEST_4( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) ); + CALL_SUBTEST_5( map_class_matrix(MatrixXi(5,5)));//ei_random<int>(1,10),ei_random<int>(1,10))) ); + } +} diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp index 5d86df7b3..ae9911831 100644 --- a/test/vectorization_logic.cpp +++ b/test/vectorization_logic.cpp @@ -33,6 +33,14 @@ bool test_assign(const Dst&, const Src&, int traversal, int unrolling) && ei_assign_traits<Dst,Src>::Unrolling==unrolling; } +template<typename Dst, typename Src> +bool test_assign(int traversal, int unrolling) +{ + ei_assign_traits<Dst,Src>::debug(); + return ei_assign_traits<Dst,Src>::Traversal==traversal + && ei_assign_traits<Dst,Src>::Unrolling==unrolling; +} + template<typename Xpr> bool test_redux(const Xpr&, int traversal, int unrolling) { @@ -86,6 +94,15 @@ void test_vectorization_logic() VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3), SliceVectorizedTraversal,NoUnrolling)); + VERIFY((test_assign< + Map<Matrix<float,4,8>, Aligned, OuterStride<12> >, + Matrix<float,4,8> + >(InnerVectorizedTraversal,CompleteUnrolling))); + + VERIFY((test_assign< + Map<Matrix<float,4,8>, Aligned, InnerStride<12> >, + Matrix<float,4,8> + >(DefaultTraversal,CompleteUnrolling))); VERIFY(test_redux(VectorXf(10), LinearVectorizedTraversal,NoUnrolling)); |