blob: 59f88cfe38a76fbe8331fc359c315822729fedec [file] [log] [blame]
Gael Guennebaudcb71dc42009-01-07 22:20:03 +00001// This file is part of Eigen, a lightweight C++ template library
Benoit Jacob6347b1d2009-05-22 20:25:33 +02002// for linear algebra.
Gael Guennebaudcb71dc42009-01-07 22:20:03 +00003//
Gael Guennebaud836da912015-12-11 10:06:28 +01004// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
Gael Guennebaudcb71dc42009-01-07 22:20:03 +00005//
Benoit Jacob69124cf2012-07-13 14:42:47 -04006// 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/.
Gael Guennebaudcb71dc42009-01-07 22:20:03 +00009
Gael Guennebaude68e1652016-05-24 21:54:03 +020010#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
Gael Guennebaud836da912015-12-11 10:06:28 +010018#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
19#undef EIGEN_DEFAULT_TO_ROW_MAJOR
20#endif
Benoit Jacob27f52502010-02-27 19:04:22 -050021#define EIGEN_DEBUG_ASSIGN
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000022#include "main.h"
23#include <typeinfo>
24
Gael Guennebaud2cf6d302018-09-20 11:38:19 +020025// 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.
Sean McBrided70b4862023-01-17 18:58:34 +000029#if EIGEN_GNUC_STRICT_AT_LEAST(6,0,0)
Gael Guennebaud2cf6d302018-09-20 11:38:19 +020030 #pragma GCC diagnostic ignored "-Wignored-attributes"
31#endif
32
Gael Guennebaud0fc89542015-10-27 10:38:49 +010033using internal::demangle_flags;
34using internal::demangle_traversal;
35using internal::demangle_unrolling;
Gael Guennebaud51ec1882010-07-08 23:30:16 +020036
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000037template<typename Dst, typename Src>
Benoit Jacob94c706d2009-11-18 11:57:07 -050038bool test_assign(const Dst&, const Src&, int traversal, int unrolling)
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000039{
Christoph Hertzberge3c82892018-09-21 21:15:51 +020040 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Dst,Src);
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020041 typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar,typename Src::Scalar> > traits;
Antonio Sánchez27d8f292022-03-03 19:54:15 +000042 // If traversal or unrolling are negative, ignore.
43 bool res = traversal > -1 ? traits::Traversal==traversal : true;
44 if (unrolling > -1) {
45 if(unrolling==InnerUnrolling+CompleteUnrolling) {
46 res = res && (int(traits::Unrolling)==InnerUnrolling || int(traits::Unrolling)==CompleteUnrolling);
47 } else {
48 res = res && int(traits::Unrolling)==unrolling;
49 }
50 }
Gael Guennebaud51ec1882010-07-08 23:30:16 +020051 if(!res)
52 {
Gael Guennebauda3950242014-03-12 18:14:58 +010053 std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010054 std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010055 std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010056 std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010057 traits::debug();
Gael Guennebaud51ec1882010-07-08 23:30:16 +020058 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
Gael Guennebauda3950242014-03-12 18:14:58 +010059 << " got " << demangle_traversal(traits::Traversal) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020060 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
Gael Guennebauda3950242014-03-12 18:14:58 +010061 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020062 }
63 return res;
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000064}
65
Benoit Jacobb1f666d2010-02-26 20:12:51 -050066template<typename Dst, typename Src>
67bool test_assign(int traversal, int unrolling)
68{
Christoph Hertzberge3c82892018-09-21 21:15:51 +020069 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Dst,Src);
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020070 typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar,typename Src::Scalar> > traits;
Gael Guennebauda3950242014-03-12 18:14:58 +010071 bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
Gael Guennebaud51ec1882010-07-08 23:30:16 +020072 if(!res)
73 {
Gael Guennebauda3950242014-03-12 18:14:58 +010074 std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010075 std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010076 std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010077 std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010078 traits::debug();
Gael Guennebaud51ec1882010-07-08 23:30:16 +020079 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
Gael Guennebauda3950242014-03-12 18:14:58 +010080 << " got " << demangle_traversal(traits::Traversal) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020081 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
Gael Guennebauda3950242014-03-12 18:14:58 +010082 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020083 }
84 return res;
Benoit Jacobb1f666d2010-02-26 20:12:51 -050085}
86
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000087template<typename Xpr>
Benoit Jacob94c706d2009-11-18 11:57:07 -050088bool test_redux(const Xpr&, int traversal, int unrolling)
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000089{
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020090 typedef typename Xpr::Scalar Scalar;
91 typedef internal::redux_traits<internal::scalar_sum_op<Scalar,Scalar>,internal::redux_evaluator<Xpr> > traits;
Gael Guennebauda3950242014-03-12 18:14:58 +010092
Gael Guennebaud51ec1882010-07-08 23:30:16 +020093 bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
94 if(!res)
95 {
Gael Guennebauda3950242014-03-12 18:14:58 +010096 std::cerr << demangle_flags(Xpr::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010097 std::cerr << demangle_flags(internal::evaluator<Xpr>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010098 traits::debug();
99
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200100 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
101 << " got " << demangle_traversal(traits::Traversal) << "\n";
102 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
103 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
104 }
105 return res;
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000106}
107
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200108template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable>
109struct vectorization_logic
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200110{
Christoph Hertzberg4f440b82014-07-14 14:36:20 +0200111 typedef internal::packet_traits<Scalar> PacketTraits;
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200112
113 typedef typename internal::packet_traits<Scalar>::type PacketType;
114 typedef typename internal::unpacket_traits<PacketType>::half HalfPacketType;
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200115 enum {
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200116 PacketSize = internal::unpacket_traits<PacketType>::size,
117 HalfPacketSize = internal::unpacket_traits<HalfPacketType>::size
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200118 };
119 static void run()
120 {
121
122 typedef Matrix<Scalar,PacketSize,1> Vector1;
123 typedef Matrix<Scalar,Dynamic,1> VectorX;
124 typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;
125 typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
Gael Guennebaud91716f02018-09-21 14:32:24 +0200126 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?8:2*PacketSize,(Matrix11::Flags&RowMajorBit)?2*PacketSize:8> Matrix22;
Gael Guennebaud64356a62011-01-04 14:18:07 +0100127 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;
128 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u;
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200129 typedef Matrix<Scalar,4*PacketSize,4*PacketSize,ColMajor> Matrix44c;
130 typedef Matrix<Scalar,4*PacketSize,4*PacketSize,RowMajor> Matrix44r;
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200131
132 typedef Matrix<Scalar,
Gael Guennebaud91716f02018-09-21 14:32:24 +0200133 (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
134 (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200135 > Matrix1;
136
137 typedef Matrix<Scalar,
Gael Guennebaud91716f02018-09-21 14:32:24 +0200138 (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
139 (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200140 DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
141
Gael Guennebaud64356a62011-01-04 14:18:07 +0100142 // this type is made such that it can only be vectorized when viewed as a linear 1D vector
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200143 typedef Matrix<Scalar,
Gael Guennebaud91716f02018-09-21 14:32:24 +0200144 (PacketSize==16 ? 4 : PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
145 (PacketSize==16 ? 12 : PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200146 > Matrix3;
Gael Guennebaud501bc602011-05-19 21:52:40 +0200147
148 #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200149 VERIFY(test_assign(Vector1(),Vector1(),
150 InnerVectorizedTraversal,CompleteUnrolling));
151 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
152 InnerVectorizedTraversal,CompleteUnrolling));
153 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
154 InnerVectorizedTraversal,CompleteUnrolling));
155 VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
156 InnerVectorizedTraversal,CompleteUnrolling));
157
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200158 VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),
159 InnerVectorizedTraversal,InnerUnrolling));
160
161 VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200162 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearTraversal,
163 EIGEN_UNALIGNED_VECTORIZE ? InnerUnrolling : NoUnrolling));
164
165 VERIFY(test_assign(Matrix1(),Matrix1()+Matrix1(),
Rasmus Munk Larsenf64b2952021-06-10 17:17:39 -0700166 (int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal,
Gael Guennebaude68e1652016-05-24 21:54:03 +0200167 CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200168
169 VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
Rasmus Munk Larsenf64b2952021-06-10 17:17:39 -0700170 EIGEN_UNALIGNED_VECTORIZE ? ((int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal)
Gael Guennebaude68e1652016-05-24 21:54:03 +0200171 : LinearTraversal, CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200172
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200173 VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),
174 InnerVectorizedTraversal,CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700175
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200176 VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),
177 InnerVectorizedTraversal,CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700178
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200179 if(PacketSize>1)
180 {
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200181 typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
Gael Guennebaude68e1652016-05-24 21:54:03 +0200182 typedef Matrix<Scalar,3,1,ColMajor> Vector3;
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200183 VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
184 LinearTraversal,CompleteUnrolling));
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000185 // Vectorization depends on too many factors - ignore.
186 VERIFY(test_assign(Vector3(),Vector3()+Vector3(), -1, CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700187
188 VERIFY(test_assign(Matrix3(),Matrix3().cwiseProduct(Matrix3()),
189 LinearVectorizedTraversal,CompleteUnrolling));
190
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000191 // Vectorization depends on too many factors - ignore.
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200192 VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000193 -1, NoUnrolling));
Gael Guennebaude68e1652016-05-24 21:54:03 +0200194
195 VERIFY(test_assign(Matrix11(), Matrix11()+Matrix11(),InnerVectorizedTraversal,CompleteUnrolling));
196
Benoit Steiner25d05c42016-04-12 14:13:25 -0700197
Gael Guennebaud91716f02018-09-21 14:32:24 +0200198 VERIFY(test_assign(Matrix11(),Matrix<Scalar,21,21>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,21,21>().template block<PacketSize,PacketSize>(3,2),
Gael Guennebaud5ca24572016-07-06 22:25:24 +0200199 (EIGEN_UNALIGNED_VECTORIZE) ? InnerVectorizedTraversal : DefaultTraversal, CompleteUnrolling|InnerUnrolling));
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200200
201 VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
202 InnerVectorizedTraversal,CompleteUnrolling));
203
204 VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
205 InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200206 }
Benoit Steiner25d05c42016-04-12 14:13:25 -0700207
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200208 VERIFY(test_redux(Vector1(),
209 LinearVectorizedTraversal,CompleteUnrolling));
210
Gael Guennebaud9c3aed92017-12-14 14:24:33 +0100211 VERIFY(test_redux(Vector1().array()*Vector1().array(),
212 LinearVectorizedTraversal,CompleteUnrolling));
213
214 VERIFY(test_redux((Vector1().array()*Vector1().array()).col(0),
215 LinearVectorizedTraversal,CompleteUnrolling));
216
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200217 VERIFY(test_redux(Matrix<Scalar,PacketSize,3>(),
218 LinearVectorizedTraversal,CompleteUnrolling));
219
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200220 VERIFY(test_redux(Matrix3(),
221 LinearVectorizedTraversal,CompleteUnrolling));
222
223 VERIFY(test_redux(Matrix44(),
224 LinearVectorizedTraversal,NoUnrolling));
225
Gael Guennebaudb00e48a2018-09-21 13:45:56 +0200226 if(PacketSize>1) {
227 VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),
228 SliceVectorizedTraversal,CompleteUnrolling));
229
230 VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?2:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:2>(1,2),
231 DefaultTraversal,CompleteUnrolling));
232 }
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200233
234 VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),
235 LinearVectorizedTraversal,CompleteUnrolling));
236
237 VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),
238 LinearVectorizedTraversal,CompleteUnrolling));
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200239
Gael Guennebaud501bc602011-05-19 21:52:40 +0200240 VERIFY((test_assign<
Gael Guennebaud1f502432015-08-06 15:31:07 +0200241 Map<Matrix22, AlignedMax, OuterStride<3*PacketSize> >,
Gael Guennebaud501bc602011-05-19 21:52:40 +0200242 Matrix22
243 >(InnerVectorizedTraversal,CompleteUnrolling)));
244
245 VERIFY((test_assign<
Erik Schultheisc20e9082021-12-10 19:27:01 +0000246 Map<Matrix<Scalar, internal::plain_enum_max(2,PacketSize), internal::plain_enum_max(2, PacketSize)>, AlignedMax, InnerStride<3*PacketSize> >,
247 Matrix<Scalar, internal::plain_enum_max(2, PacketSize), internal::plain_enum_max(2, PacketSize)>
Gael Guennebaud5ca24572016-07-06 22:25:24 +0200248 >(DefaultTraversal,PacketSize>=8?InnerUnrolling:CompleteUnrolling)));
Gael Guennebaud501bc602011-05-19 21:52:40 +0200249
Erik Schultheisc20e9082021-12-10 19:27:01 +0000250 VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize, internal::plain_enum_min(2, PacketSize)>()*Matrix<Scalar, internal::plain_enum_min(2, PacketSize),PacketSize>(),
Gael Guennebaud1330f8b2015-03-13 21:15:50 +0100251 InnerVectorizedTraversal, CompleteUnrolling)));
Gael Guennebaud501bc602011-05-19 21:52:40 +0200252 #endif
253
254 VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),
255 SliceVectorizedTraversal,NoUnrolling));
256
257 VERIFY(test_redux(VectorX(10),
258 LinearVectorizedTraversal,NoUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200259 }
260};
261
262template<typename Scalar> struct vectorization_logic<Scalar,false>
263{
264 static void run() {}
265};
266
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200267template<typename Scalar, bool Enable = !internal::is_same<typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half,
268 typename internal::packet_traits<Scalar>::type>::value >
269struct vectorization_logic_half
270{
271 typedef internal::packet_traits<Scalar> PacketTraits;
272 typedef typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half PacketType;
273 enum {
274 PacketSize = internal::unpacket_traits<PacketType>::size
275 };
276 static void run()
277 {
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000278 // Some half-packets have a byte size < EIGEN_MIN_ALIGN_BYTES (e.g. Packet2f),
279 // which causes many of these tests to fail since they don't vectorize if
280 // EIGEN_UNALIGNED_VECTORIZE is 0 (the matrix is assumed unaligned).
281 // Adjust the matrix sizes to account for these alignment issues.
282 constexpr int PacketBytes = sizeof(Scalar)*PacketSize;
283 constexpr int MinVSize = EIGEN_UNALIGNED_VECTORIZE ? PacketSize
284 : PacketBytes >= EIGEN_MIN_ALIGN_BYTES ? PacketSize
285 : (EIGEN_MIN_ALIGN_BYTES + sizeof(Scalar) - 1) / sizeof(Scalar);
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200286
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000287 typedef Matrix<Scalar,MinVSize,1> Vector1;
288 typedef Matrix<Scalar,MinVSize,MinVSize> Matrix11;
289 typedef Matrix<Scalar,5*MinVSize,7,ColMajor> Matrix57;
290 typedef Matrix<Scalar,3*MinVSize,5,ColMajor> Matrix35;
291 typedef Matrix<Scalar,5*MinVSize,7,DontAlign|ColMajor> Matrix57u;
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200292
293 typedef Matrix<Scalar,
Gael Guennebaud91716f02018-09-21 14:32:24 +0200294 (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
295 (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200296 > Matrix1;
297
298 typedef Matrix<Scalar,
Gael Guennebaud91716f02018-09-21 14:32:24 +0200299 (PacketSize==16 ? 8 : PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
300 (PacketSize==16 ? 2 : PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200301 DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
302
303 // this type is made such that it can only be vectorized when viewed as a linear 1D vector
304 typedef Matrix<Scalar,
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000305 (MinVSize==16 ? 4 : MinVSize==8 ? 4 : MinVSize==4 ? 6 : MinVSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
306 (MinVSize==16 ? 12 : MinVSize==8 ? 6 : MinVSize==4 ? 2 : MinVSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200307 > Matrix3;
308
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000309#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200310 VERIFY(test_assign(Vector1(),Vector1(),
311 InnerVectorizedTraversal,CompleteUnrolling));
312 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
313 InnerVectorizedTraversal,CompleteUnrolling));
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000314 VERIFY(test_assign(Vector1(),Vector1().template segment<MinVSize>(0).derived(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200315 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal,CompleteUnrolling));
316 VERIFY(test_assign(Vector1(),Scalar(2.1)*Vector1()-Vector1(),
317 InnerVectorizedTraversal,CompleteUnrolling));
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000318 VERIFY(test_assign(Vector1(),(Scalar(2.1)*Vector1().template segment<MinVSize>(0)-Vector1().template segment<MinVSize>(0)).derived(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200319 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal,CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200320 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
321 InnerVectorizedTraversal,CompleteUnrolling));
322 VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
323 InnerVectorizedTraversal,CompleteUnrolling));
324
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200325 VERIFY(test_assign(Matrix57(),Matrix57()+Matrix57(),
326 InnerVectorizedTraversal,InnerUnrolling));
327
328 VERIFY(test_assign(Matrix57u(),Matrix57()+Matrix57(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200329 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearTraversal,
330 EIGEN_UNALIGNED_VECTORIZE ? InnerUnrolling : NoUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200331
332 VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
Rasmus Munk Larsen13fb5ab2021-06-15 09:09:31 -0700333 EIGEN_UNALIGNED_VECTORIZE ? ((int(Matrix1::InnerSizeAtCompileTime) % int(PacketSize))==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : LinearTraversal,CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200334
335 if(PacketSize>1)
336 {
337 typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
338 VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
339 LinearTraversal,CompleteUnrolling));
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000340
341 // Unrolling depends on read costs and unroll limits, which vary - ignore.
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200342 VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000343 PacketTraits::HasDiv ? LinearVectorizedTraversal : LinearTraversal, -1));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200344
345 VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
Gael Guennebaudaab749b2018-12-06 16:55:00 +0100346 sizeof(Scalar)==16 ? InnerVectorizedTraversal : (EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200347 NoUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200348
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000349 VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<MinVSize,MinVSize>(2,3)+Matrix<Scalar,17,17>().template block<MinVSize,MinVSize>(8,4),
Gael Guennebaud91716f02018-09-21 14:32:24 +0200350 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : DefaultTraversal,InnerUnrolling+CompleteUnrolling));
351
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200352
353 VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
354 InnerVectorizedTraversal,CompleteUnrolling));
355
356 VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
357 InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200358 }
359
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200360 VERIFY(test_redux(Vector1(),
361 LinearVectorizedTraversal,CompleteUnrolling));
362
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000363 VERIFY(test_redux(Matrix<Scalar,MinVSize,3>(),
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200364 LinearVectorizedTraversal,CompleteUnrolling));
365
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200366 VERIFY(test_redux(Matrix3(),
367 LinearVectorizedTraversal,CompleteUnrolling));
368
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200369 VERIFY(test_redux(Matrix35(),
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200370 LinearVectorizedTraversal,CompleteUnrolling));
371
Gael Guennebaudb00e48a2018-09-21 13:45:56 +0200372 VERIFY(test_redux(Matrix57().template block<PacketSize==1?2:PacketSize,3>(1,0),
373 SliceVectorizedTraversal,CompleteUnrolling));
374
375 if(PacketSize>1) {
376 VERIFY(test_redux(Matrix57().template block<PacketSize,2>(1,0),
377 DefaultTraversal,CompleteUnrolling));
378 }
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200379
380 VERIFY((test_assign<
David Tellenbach6e95c0c2021-12-27 23:50:32 +0000381 Map<Matrix<Scalar, internal::plain_enum_max(2, PacketSize), internal::plain_enum_max(2, PacketSize)>,
382 AlignedMax, InnerStride<3 * PacketSize> >,
383 Matrix<Scalar, internal::plain_enum_max(2, PacketSize), internal::plain_enum_max(2, PacketSize)> >(
384 DefaultTraversal, PacketSize > 4 ? InnerUnrolling : CompleteUnrolling)));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200385
Antonio Sánchez27d8f292022-03-03 19:54:15 +0000386 VERIFY((test_assign(Matrix57(), Matrix<Scalar, 5 * MinVSize, 3>() * Matrix<Scalar, 3, 7>(),
David Tellenbach6e95c0c2021-12-27 23:50:32 +0000387 InnerVectorizedTraversal, InnerUnrolling + CompleteUnrolling)));
388#endif
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200389 }
390};
391
392template<typename Scalar> struct vectorization_logic_half<Scalar,false>
393{
394 static void run() {}
395};
396
Gael Guennebaud82f0ce22018-07-17 14:46:15 +0200397EIGEN_DECLARE_TEST(vectorization_logic)
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000398{
399
400#ifdef EIGEN_VECTORIZE
401
Christoph Hertzberg4f440b82014-07-14 14:36:20 +0200402 CALL_SUBTEST( vectorization_logic<int>::run() );
Gael Guennebaud501bc602011-05-19 21:52:40 +0200403 CALL_SUBTEST( vectorization_logic<float>::run() );
404 CALL_SUBTEST( vectorization_logic<double>::run() );
405 CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );
406 CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200407
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200408 CALL_SUBTEST( vectorization_logic_half<int>::run() );
409 CALL_SUBTEST( vectorization_logic_half<float>::run() );
410 CALL_SUBTEST( vectorization_logic_half<double>::run() );
411 CALL_SUBTEST( vectorization_logic_half<std::complex<float> >::run() );
412 CALL_SUBTEST( vectorization_logic_half<std::complex<double> >::run() );
413
Benoit Jacob47160402010-10-25 10:15:22 -0400414 if(internal::packet_traits<float>::Vectorizable)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200415 {
416 VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200417 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200418
419 VERIFY(test_redux(Matrix<float,5,2>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200420 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : DefaultTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200421 }
422
Benoit Jacob47160402010-10-25 10:15:22 -0400423 if(internal::packet_traits<double>::Vectorizable)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200424 {
425 VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200426 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200427
428 VERIFY(test_redux(Matrix<double,7,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200429 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : DefaultTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200430 }
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000431#endif // EIGEN_VECTORIZE
432
433}