mapstride.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #include "main.h"
00026 
00027 template<int Alignment,typename VectorType> void map_class_vector(const VectorType& m)
00028 {
00029   typedef typename VectorType::Index Index;
00030   typedef typename VectorType::Scalar Scalar;
00031 
00032   Index size = m.size();
00033 
00034   VectorType v = VectorType::Random(size);
00035 
00036   Index arraysize = 3*size;
00037   
00038   Scalar* a_array = internal::aligned_new<Scalar>(arraysize+1);
00039   Scalar* array = a_array;
00040   if(Alignment!=Aligned)
00041     array = (Scalar*)(ptrdiff_t(a_array) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));
00042 
00043   {
00044     Map<VectorType, Alignment, InnerStride<3> > map(array, size);
00045     map = v;
00046     for(int i = 0; i < size; ++i)
00047     {
00048       VERIFY(array[3*i] == v[i]);
00049       VERIFY(map[i] == v[i]);
00050     }
00051   }
00052 
00053   {
00054     Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2));
00055     map = v;
00056     for(int i = 0; i < size; ++i)
00057     {
00058       VERIFY(array[2*i] == v[i]);
00059       VERIFY(map[i] == v[i]);
00060     }
00061   }
00062 
00063   internal::aligned_delete(a_array, arraysize+1);
00064 }
00065 
00066 template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixType& _m)
00067 {
00068   typedef typename MatrixType::Index Index;
00069   typedef typename MatrixType::Scalar Scalar;
00070 
00071   Index rows = _m.rows(), cols = _m.cols();
00072 
00073   MatrixType m = MatrixType::Random(rows,cols);
00074 
00075   Index arraysize = 2*(rows+4)*(cols+4);
00076 
00077   Scalar* a_array = internal::aligned_new<Scalar>(arraysize+1);
00078   Scalar* array = a_array;
00079   if(Alignment!=Aligned)
00080     array = (Scalar*)(ptrdiff_t(a_array) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));
00081 
00082   // test no inner stride and some dynamic outer stride
00083   {
00084     Map<MatrixType, Alignment, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1));
00085     map = m;
00086     VERIFY(map.outerStride() == map.innerSize()+1);
00087     for(int i = 0; i < m.outerSize(); ++i)
00088       for(int j = 0; j < m.innerSize(); ++j)
00089       {
00090         VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
00091         VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
00092       }
00093   }
00094 
00095   // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices,
00096   // this allows to hit the special case where it's vectorizable.
00097   {
00098     enum {
00099       InnerSize = MatrixType::InnerSizeAtCompileTime,
00100       OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4
00101     };
00102     Map<MatrixType, Alignment, OuterStride<OuterStrideAtCompileTime> >
00103       map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4));
00104     map = m;
00105     VERIFY(map.outerStride() == map.innerSize()+4);
00106     for(int i = 0; i < m.outerSize(); ++i)
00107       for(int j = 0; j < m.innerSize(); ++j)
00108       {
00109         VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));
00110         VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
00111       }
00112   }
00113 
00114   // test both inner stride and outer stride
00115   {
00116     Map<MatrixType, Alignment, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2));
00117     map = m;
00118     VERIFY(map.outerStride() == 2*map.innerSize()+1);
00119     VERIFY(map.innerStride() == 2);
00120     for(int i = 0; i < m.outerSize(); ++i)
00121       for(int j = 0; j < m.innerSize(); ++j)
00122       {
00123         VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j));
00124         VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
00125       }
00126   }
00127 
00128   internal::aligned_delete(a_array, arraysize+1);
00129 }
00130 
00131 void test_mapstride()
00132 {
00133   for(int i = 0; i < g_repeat; i++) {
00134     EIGEN_UNUSED int maxn = 30;
00135     CALL_SUBTEST_1( map_class_vector<Aligned>(Matrix<float, 1, 1>()) );
00136     CALL_SUBTEST_1( map_class_vector<Unaligned>(Matrix<float, 1, 1>()) );
00137     CALL_SUBTEST_2( map_class_vector<Aligned>(Vector4d()) );
00138     CALL_SUBTEST_2( map_class_vector<Unaligned>(Vector4d()) );
00139     CALL_SUBTEST_3( map_class_vector<Aligned>(RowVector4f()) );
00140     CALL_SUBTEST_3( map_class_vector<Unaligned>(RowVector4f()) );
00141     CALL_SUBTEST_4( map_class_vector<Aligned>(VectorXcf(internal::random<int>(1,maxn))) );
00142     CALL_SUBTEST_4( map_class_vector<Unaligned>(VectorXcf(internal::random<int>(1,maxn))) );
00143     CALL_SUBTEST_5( map_class_vector<Aligned>(VectorXi(internal::random<int>(1,maxn))) );
00144     CALL_SUBTEST_5( map_class_vector<Unaligned>(VectorXi(internal::random<int>(1,maxn))) );
00145 
00146     CALL_SUBTEST_1( map_class_matrix<Aligned>(Matrix<float, 1, 1>()) );
00147     CALL_SUBTEST_1( map_class_matrix<Unaligned>(Matrix<float, 1, 1>()) );
00148     CALL_SUBTEST_2( map_class_matrix<Aligned>(Matrix4d()) );
00149     CALL_SUBTEST_2( map_class_matrix<Unaligned>(Matrix4d()) );
00150     CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,3,5>()) );
00151     CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,3,5>()) );
00152     CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,4,8>()) );
00153     CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,4,8>()) );
00154     CALL_SUBTEST_4( map_class_matrix<Aligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00155     CALL_SUBTEST_4( map_class_matrix<Unaligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00156     CALL_SUBTEST_5( map_class_matrix<Aligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00157     CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00158     CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00159     CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
00160   }
00161 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:52