vectorization_logic.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@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 #ifdef EIGEN_TEST_PART_1
11 #define EIGEN_UNALIGNED_VECTORIZE 1
12 #endif
13 
14 #ifdef EIGEN_TEST_PART_2
15 #define EIGEN_UNALIGNED_VECTORIZE 0
16 #endif
17 
18 #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
19 #undef EIGEN_DEFAULT_TO_ROW_MAJOR
20 #endif
21 #define EIGEN_DEBUG_ASSIGN
22 #include "main.h"
23 #include <typeinfo>
24 
25 // Disable "ignoring attributes on template argument"
26 // for packet_traits<Packet*>
27 // => The only workaround would be to wrap _m128 and the likes
28 // within wrappers.
29 #if EIGEN_GNUC_AT_LEAST(6,0)
30  #pragma GCC diagnostic ignored "-Wignored-attributes"
31 #endif
32 
33 using internal::demangle_flags;
34 using internal::demangle_traversal;
35 using internal::demangle_unrolling;
36 
37 template<typename Dst, typename Src>
38 bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
39 {
41  typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar,typename Src::Scalar> > traits;
42  bool res = traits::Traversal==traversal;
43  if(unrolling==InnerUnrolling+CompleteUnrolling)
44  res = res && (int(traits::Unrolling)==InnerUnrolling || int(traits::Unrolling)==CompleteUnrolling);
45  else
46  res = res && int(traits::Unrolling)==unrolling;
47  if(!res)
48  {
49  std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
50  std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
51  std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
52  std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
53  traits::debug();
54  std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
55  << " got " << demangle_traversal(traits::Traversal) << "\n";
56  std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
57  << " got " << demangle_unrolling(traits::Unrolling) << "\n";
58  }
59  return res;
60 }
61 
62 template<typename Dst, typename Src>
63 bool test_assign(int traversal, int unrolling)
64 {
66  typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar,typename Src::Scalar> > traits;
67  bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
68  if(!res)
69  {
70  std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
71  std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
72  std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
73  std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
74  traits::debug();
75  std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
76  << " got " << demangle_traversal(traits::Traversal) << "\n";
77  std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
78  << " got " << demangle_unrolling(traits::Unrolling) << "\n";
79  }
80  return res;
81 }
82 
83 template<typename Xpr>
84 bool test_redux(const Xpr&, int traversal, int unrolling)
85 {
86  typedef typename Xpr::Scalar Scalar;
87  typedef internal::redux_traits<internal::scalar_sum_op<Scalar,Scalar>,internal::redux_evaluator<Xpr> > traits;
88 
89  bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
90  if(!res)
91  {
92  std::cerr << demangle_flags(Xpr::Flags) << std::endl;
93  std::cerr << demangle_flags(internal::evaluator<Xpr>::Flags) << std::endl;
94  traits::debug();
95 
96  std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
97  << " got " << demangle_traversal(traits::Traversal) << "\n";
98  std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
99  << " got " << demangle_unrolling(traits::Unrolling) << "\n";
100  }
101  return res;
102 }
103 
104 template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable>
106 {
107  typedef internal::packet_traits<Scalar> PacketTraits;
108 
111  enum {
114  };
115  static void run()
116  {
117 
120  typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;
121  typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
127 
128  typedef Matrix<Scalar,
129  (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
130  (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
131  > Matrix1;
132 
133  typedef Matrix<Scalar,
134  (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
135  (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
136  DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
137 
138  // this type is made such that it can only be vectorized when viewed as a linear 1D vector
139  typedef Matrix<Scalar,
140  (PacketSize==16 ? 4 : PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
141  (PacketSize==16 ? 12 : PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
142  > Matrix3;
143 
144  #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
149  VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
151  VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
153 
154  VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),
156 
157  VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),
160 
162  (int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal,
164 
165  VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
166  EIGEN_UNALIGNED_VECTORIZE ? ((int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal)
167  : LinearTraversal, CompleteUnrolling));
168 
169  VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),
171 
172  VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),
174 
175  if(PacketSize>1)
176  {
177  typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
179  VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
180  LinearTraversal,CompleteUnrolling));
182  sizeof(Scalar)==16 ? InnerVectorizedTraversal : (EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal), CompleteUnrolling));
183  VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
184  EIGEN_UNALIGNED_VECTORIZE ? (sizeof(Scalar)==16 ? InnerVectorizedTraversal : LinearVectorizedTraversal)
185  : (sizeof(Scalar)==16 ? SliceVectorizedTraversal : LinearTraversal),
186  ((!EIGEN_UNALIGNED_VECTORIZE) && (sizeof(Scalar)==16)) ? NoUnrolling : CompleteUnrolling));
187 
188  VERIFY(test_assign(Matrix3(),Matrix3().cwiseProduct(Matrix3()),
189  LinearVectorizedTraversal,CompleteUnrolling));
190 
192  sizeof(Scalar)==16 ? InnerVectorizedTraversal :
193  EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal :
194  LinearTraversal,
195  NoUnrolling));
196 
197  VERIFY(test_assign(Matrix11(), Matrix11()+Matrix11(),InnerVectorizedTraversal,CompleteUnrolling));
198 
199 
200  VERIFY(test_assign(Matrix11(),Matrix<Scalar,21,21>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,21,21>().template block<PacketSize,PacketSize>(3,2),
202 
203  VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
204  InnerVectorizedTraversal,CompleteUnrolling));
205 
206  VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
207  InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
208  }
209 
211  LinearVectorizedTraversal,CompleteUnrolling));
212 
214  LinearVectorizedTraversal,CompleteUnrolling));
215 
217  LinearVectorizedTraversal,CompleteUnrolling));
218 
220  LinearVectorizedTraversal,CompleteUnrolling));
221 
222  VERIFY(test_redux(Matrix3(),
223  LinearVectorizedTraversal,CompleteUnrolling));
224 
225  VERIFY(test_redux(Matrix44(),
226  LinearVectorizedTraversal,NoUnrolling));
227 
228  if(PacketSize>1) {
229  VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),
231 
232  VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?2:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:2>(1,2),
234  }
235 
236  VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),
237  LinearVectorizedTraversal,CompleteUnrolling));
238 
239  VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),
240  LinearVectorizedTraversal,CompleteUnrolling));
241 
244  Matrix22
246 
249  Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
251 
252  VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize,EIGEN_PLAIN_ENUM_MIN(2,PacketSize)>()*Matrix<Scalar,EIGEN_PLAIN_ENUM_MIN(2,PacketSize),PacketSize>(),
253  InnerVectorizedTraversal, CompleteUnrolling)));
254  #endif
255 
256  VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),
257  SliceVectorizedTraversal,NoUnrolling));
258 
260  LinearVectorizedTraversal,NoUnrolling));
261  }
262 };
263 
264 template<typename Scalar> struct vectorization_logic<Scalar,false>
265 {
266  static void run() {}
267 };
268 
272 {
273  typedef internal::packet_traits<Scalar> PacketTraits;
275  enum {
277  };
278  static void run()
279  {
280 
282  typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
286 
287  typedef Matrix<Scalar,
288  (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
289  (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
290  > Matrix1;
291 
292  typedef Matrix<Scalar,
293  (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
294  (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
295  DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
296 
297  // this type is made such that it can only be vectorized when viewed as a linear 1D vector
298  typedef Matrix<Scalar,
299  (PacketSize==16 ? 4 : PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
300  (PacketSize==16 ? 12 : PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
301  > Matrix3;
302 
303  #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
308  VERIFY(test_assign(Vector1(),Vector1().template segment<PacketSize>(0).derived(),
312  VERIFY(test_assign(Vector1(),(Scalar(2.1)*Vector1().template segment<PacketSize>(0)-Vector1().template segment<PacketSize>(0)).derived(),
314  VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
316  VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
318 
319  VERIFY(test_assign(Matrix57(),Matrix57()+Matrix57(),
321 
322  VERIFY(test_assign(Matrix57u(),Matrix57()+Matrix57(),
325 
326  VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
327  EIGEN_UNALIGNED_VECTORIZE ? ((int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : LinearTraversal,CompleteUnrolling));
328 
329  if(PacketSize>1)
330  {
331  typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
332  VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
333  LinearTraversal,CompleteUnrolling));
334  VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
335  EIGEN_UNALIGNED_VECTORIZE ? (sizeof(Scalar)==16 ? InnerVectorizedTraversal : LinearVectorizedTraversal)
336  : (sizeof(Scalar)==16 ? SliceVectorizedTraversal : LinearTraversal),
337  ((!EIGEN_UNALIGNED_VECTORIZE) && (sizeof(Scalar)==16)) ? NoUnrolling : CompleteUnrolling));
338 
339  VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),
340  PacketTraits::HasDiv ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
341 
343  sizeof(Scalar)==16 ? InnerVectorizedTraversal : (EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal),
344  NoUnrolling));
345 
346  VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(8,4),
348 
349 
350  VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
351  InnerVectorizedTraversal,CompleteUnrolling));
352 
353  VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
354  InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
355  }
356 
358  LinearVectorizedTraversal,CompleteUnrolling));
359 
361  LinearVectorizedTraversal,CompleteUnrolling));
362 
363  VERIFY(test_redux(Matrix3(),
364  LinearVectorizedTraversal,CompleteUnrolling));
365 
366  VERIFY(test_redux(Matrix35(),
367  LinearVectorizedTraversal,CompleteUnrolling));
368 
369  VERIFY(test_redux(Matrix57().template block<PacketSize==1?2:PacketSize,3>(1,0),
371 
372  if(PacketSize>1) {
373  VERIFY(test_redux(Matrix57().template block<PacketSize,2>(1,0),
375  }
376 
379  Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
381 
383  InnerVectorizedTraversal, InnerUnrolling+CompleteUnrolling)));
384  #endif
385  }
386 };
387 
388 template<typename Scalar> struct vectorization_logic_half<Scalar,false>
389 {
390  static void run() {}
391 };
392 
394 {
395 
396 #ifdef EIGEN_VECTORIZE
397 
401  CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );
402  CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );
403 
407  CALL_SUBTEST( vectorization_logic_half<std::complex<float> >::run() );
408  CALL_SUBTEST( vectorization_logic_half<std::complex<double> >::run() );
409 
410  if(internal::packet_traits<float>::Vectorizable)
411  {
414 
417  }
418 
419  if(internal::packet_traits<double>::Vectorizable)
420  {
423 
426  }
427 #endif // EIGEN_VECTORIZE
428 
429 }
int array[24]
internal::packet_traits< Scalar >::type PacketType
SCALAR Scalar
Definition: bench_gemm.cpp:46
internal::packet_traits< Scalar > PacketTraits
m m block(1, 0, 2, 2)<< 4
Eigen::Vector3d Vector3
Definition: Vector.h:43
Eigen::Matrix< double, 1, 1 > Vector1
Definition: testEvent.cpp:33
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:94
Matrix< Scalar, Dynamic, 1 > VectorX
Definition: sparse_lu.cpp:41
#define EIGEN_PLAIN_ENUM_MAX(a, b)
Definition: Macros.h:1289
const unsigned int RowMajorBit
Definition: Constants.h:66
internal::unpacket_traits< typename internal::packet_traits< Scalar >::type >::half PacketType
static constexpr bool debug
Eigen::Matrix< double, 1, 1 > Matrix1
Definition: timeRot2.cpp:78
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
m row(1)
Convenience specialization of Stride to specify only an inner stride See class Map for some examples...
Definition: Stride.h:95
internal::unpacket_traits< PacketType >::half HalfPacketType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp< internal::scalar_quotient_op< Scalar >, const Derived, const OtherDerived > cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS< OtherDerived > &other) const
#define EIGEN_UNALIGNED_VECTORIZE
bool test_assign(const Dst &, const Src &, int traversal, int unrolling)
#define CALL_SUBTEST(FUNC)
Definition: main.h:399
#define VERIFY(a)
Definition: main.h:380
#define EIGEN_PLAIN_ENUM_MIN(a, b)
Definition: Macros.h:1288
m col(1)
The matrix class, also used for vectors and row-vectors.
bool test_redux(const Xpr &, int traversal, int unrolling)
Convenience specialization of Stride to specify only an outer stride See class Map for some examples...
Definition: Stride.h:106
EIGEN_DECLARE_TEST(vectorization_logic)
internal::packet_traits< Scalar > PacketTraits
#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0, TYPE1)
Definition: StaticAssert.h:192


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:40:43