1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #define EIGEN_DEBUG_ASSIGN 11 #include "main.h" 12 #include <typeinfo> 13 14 std::string demangle_traversal(int t) 15 { 16 if(t==DefaultTraversal) return "DefaultTraversal"; 17 if(t==LinearTraversal) return "LinearTraversal"; 18 if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal"; 19 if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal"; 20 if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal"; 21 return "?"; 22 } 23 std::string demangle_unrolling(int t) 24 { 25 if(t==NoUnrolling) return "NoUnrolling"; 26 if(t==InnerUnrolling) return "InnerUnrolling"; 27 if(t==CompleteUnrolling) return "CompleteUnrolling"; 28 return "?"; 29 } 30 31 template<typename Dst, typename Src> 32 bool test_assign(const Dst&, const Src&, int traversal, int unrolling) 33 { 34 internal::assign_traits<Dst,Src>::debug(); 35 bool res = internal::assign_traits<Dst,Src>::Traversal==traversal 36 && internal::assign_traits<Dst,Src>::Unrolling==unrolling; 37 if(!res) 38 { 39 std::cerr << " Expected Traversal == " << demangle_traversal(traversal) 40 << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n"; 41 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) 42 << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n"; 43 } 44 return res; 45 } 46 47 template<typename Dst, typename Src> 48 bool test_assign(int traversal, int unrolling) 49 { 50 internal::assign_traits<Dst,Src>::debug(); 51 bool res = internal::assign_traits<Dst,Src>::Traversal==traversal 52 && internal::assign_traits<Dst,Src>::Unrolling==unrolling; 53 if(!res) 54 { 55 std::cerr << " Expected Traversal == " << demangle_traversal(traversal) 56 << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n"; 57 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) 58 << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n"; 59 } 60 return res; 61 } 62 63 template<typename Xpr> 64 bool test_redux(const Xpr&, int traversal, int unrolling) 65 { 66 typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,Xpr> traits; 67 bool res = traits::Traversal==traversal && traits::Unrolling==unrolling; 68 if(!res) 69 { 70 std::cerr << " Expected Traversal == " << demangle_traversal(traversal) 71 << " got " << demangle_traversal(traits::Traversal) << "\n"; 72 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling) 73 << " got " << demangle_unrolling(traits::Unrolling) << "\n"; 74 } 75 return res; 76 } 77 78 template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable> struct vectorization_logic 79 { 80 enum { 81 PacketSize = internal::packet_traits<Scalar>::size 82 }; 83 static void run() 84 { 85 86 typedef Matrix<Scalar,PacketSize,1> Vector1; 87 typedef Matrix<Scalar,Dynamic,1> VectorX; 88 typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX; 89 typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11; 90 typedef Matrix<Scalar,2*PacketSize,2*PacketSize> Matrix22; 91 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44; 92 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u; 93 typedef Matrix<Scalar,4*PacketSize,16,ColMajor> Matrix44c; 94 typedef Matrix<Scalar,4*PacketSize,16,RowMajor> Matrix44r; 95 96 typedef Matrix<Scalar, 97 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1), 98 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1) 99 > Matrix1; 100 101 typedef Matrix<Scalar, 102 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1), 103 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1), 104 DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u; 105 106 // this type is made such that it can only be vectorized when viewed as a linear 1D vector 107 typedef Matrix<Scalar, 108 (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1), 109 (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3) 110 > Matrix3; 111 112 #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 113 VERIFY(test_assign(Vector1(),Vector1(), 114 InnerVectorizedTraversal,CompleteUnrolling)); 115 VERIFY(test_assign(Vector1(),Vector1()+Vector1(), 116 InnerVectorizedTraversal,CompleteUnrolling)); 117 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()), 118 InnerVectorizedTraversal,CompleteUnrolling)); 119 VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(), 120 InnerVectorizedTraversal,CompleteUnrolling)); 121 122 123 VERIFY(test_assign(Vector1(),Vector1(), 124 InnerVectorizedTraversal,CompleteUnrolling)); 125 VERIFY(test_assign(Vector1(),Vector1()+Vector1(), 126 InnerVectorizedTraversal,CompleteUnrolling)); 127 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()), 128 InnerVectorizedTraversal,CompleteUnrolling)); 129 130 VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(), 131 InnerVectorizedTraversal,InnerUnrolling)); 132 133 VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(), 134 LinearTraversal,NoUnrolling)); 135 136 VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(), 137 LinearTraversal,CompleteUnrolling)); 138 139 VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3), 140 InnerVectorizedTraversal,CompleteUnrolling)); 141 142 VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1), 143 InnerVectorizedTraversal,CompleteUnrolling)); 144 145 if(PacketSize>1) 146 { 147 typedef Matrix<Scalar,3,3,ColMajor> Matrix33c; 148 VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1), 149 LinearTraversal,CompleteUnrolling)); 150 VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1), 151 LinearTraversal,CompleteUnrolling)); 152 153 VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()), 154 LinearVectorizedTraversal,CompleteUnrolling)); 155 156 VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(), 157 LinearTraversal,NoUnrolling)); 158 159 VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(10,4), 160 DefaultTraversal,CompleteUnrolling)); 161 } 162 163 VERIFY(test_redux(Matrix3(), 164 LinearVectorizedTraversal,CompleteUnrolling)); 165 166 VERIFY(test_redux(Matrix44(), 167 LinearVectorizedTraversal,NoUnrolling)); 168 169 VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2), 170 DefaultTraversal,CompleteUnrolling)); 171 172 VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2), 173 LinearVectorizedTraversal,CompleteUnrolling)); 174 175 VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1), 176 LinearVectorizedTraversal,CompleteUnrolling)); 177 178 VERIFY((test_assign< 179 Map<Matrix22, Aligned, OuterStride<3*PacketSize> >, 180 Matrix22 181 >(InnerVectorizedTraversal,CompleteUnrolling))); 182 183 VERIFY((test_assign< 184 Map<Matrix22, Aligned, InnerStride<3*PacketSize> >, 185 Matrix22 186 >(DefaultTraversal,CompleteUnrolling))); 187 188 VERIFY((test_assign(Matrix11(), Matrix11()*Matrix11(), InnerVectorizedTraversal, CompleteUnrolling))); 189 #endif 190 191 VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3), 192 SliceVectorizedTraversal,NoUnrolling)); 193 194 VERIFY(test_redux(VectorX(10), 195 LinearVectorizedTraversal,NoUnrolling)); 196 197 198 } 199 }; 200 201 template<typename Scalar> struct vectorization_logic<Scalar,false> 202 { 203 static void run() {} 204 }; 205 206 void test_vectorization_logic() 207 { 208 209 #ifdef EIGEN_VECTORIZE 210 211 CALL_SUBTEST( vectorization_logic<float>::run() ); 212 CALL_SUBTEST( vectorization_logic<double>::run() ); 213 CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() ); 214 CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() ); 215 216 if(internal::packet_traits<float>::Vectorizable) 217 { 218 VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(), 219 LinearTraversal,CompleteUnrolling)); 220 221 VERIFY(test_redux(Matrix<float,5,2>(), 222 DefaultTraversal,CompleteUnrolling)); 223 } 224 225 if(internal::packet_traits<double>::Vectorizable) 226 { 227 VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(), 228 LinearTraversal,CompleteUnrolling)); 229 230 VERIFY(test_redux(Matrix<double,7,3>(), 231 DefaultTraversal,CompleteUnrolling)); 232 } 233 #endif // EIGEN_VECTORIZE 234 235 } 236