blob: 2d0a8ceb62854b93bd7bfa5e4d89916210f4b788 [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.
29#if EIGEN_GNUC_AT_LEAST(6,0)
30 #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{
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020040 typedef internal::copy_using_evaluator_traits<internal::evaluator<Dst>,internal::evaluator<Src>, internal::assign_op<typename Dst::Scalar,typename Src::Scalar> > traits;
Gael Guennebaud512ba0a2016-04-13 18:16:35 +020041 bool res = traits::Traversal==traversal;
42 if(unrolling==InnerUnrolling+CompleteUnrolling)
Gael Guennebauda95e1a22016-04-13 22:00:38 +020043 res = res && (int(traits::Unrolling)==InnerUnrolling || int(traits::Unrolling)==CompleteUnrolling);
Gael Guennebaud512ba0a2016-04-13 18:16:35 +020044 else
Gael Guennebauda95e1a22016-04-13 22:00:38 +020045 res = res && int(traits::Unrolling)==unrolling;
Gael Guennebaud51ec1882010-07-08 23:30:16 +020046 if(!res)
47 {
Gael Guennebauda3950242014-03-12 18:14:58 +010048 std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010049 std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010050 std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010051 std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010052 traits::debug();
Gael Guennebaud51ec1882010-07-08 23:30:16 +020053 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
Gael Guennebauda3950242014-03-12 18:14:58 +010054 << " got " << demangle_traversal(traits::Traversal) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020055 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
Gael Guennebauda3950242014-03-12 18:14:58 +010056 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020057 }
58 return res;
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000059}
60
Benoit Jacobb1f666d2010-02-26 20:12:51 -050061template<typename Dst, typename Src>
62bool test_assign(int traversal, int unrolling)
63{
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020064 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 +010065 bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
Gael Guennebaud51ec1882010-07-08 23:30:16 +020066 if(!res)
67 {
Gael Guennebauda3950242014-03-12 18:14:58 +010068 std::cerr << "Src: " << demangle_flags(Src::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010069 std::cerr << " " << demangle_flags(internal::evaluator<Src>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010070 std::cerr << "Dst: " << demangle_flags(Dst::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010071 std::cerr << " " << demangle_flags(internal::evaluator<Dst>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010072 traits::debug();
Gael Guennebaud51ec1882010-07-08 23:30:16 +020073 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
Gael Guennebauda3950242014-03-12 18:14:58 +010074 << " got " << demangle_traversal(traits::Traversal) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020075 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
Gael Guennebauda3950242014-03-12 18:14:58 +010076 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
Gael Guennebaud51ec1882010-07-08 23:30:16 +020077 }
78 return res;
Benoit Jacobb1f666d2010-02-26 20:12:51 -050079}
80
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000081template<typename Xpr>
Benoit Jacob94c706d2009-11-18 11:57:07 -050082bool test_redux(const Xpr&, int traversal, int unrolling)
Gael Guennebaudcb71dc42009-01-07 22:20:03 +000083{
Gael Guennebaud66e99ab2016-06-06 15:11:41 +020084 typedef typename Xpr::Scalar Scalar;
85 typedef internal::redux_traits<internal::scalar_sum_op<Scalar,Scalar>,internal::redux_evaluator<Xpr> > traits;
Gael Guennebauda3950242014-03-12 18:14:58 +010086
Gael Guennebaud51ec1882010-07-08 23:30:16 +020087 bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;
88 if(!res)
89 {
Gael Guennebauda3950242014-03-12 18:14:58 +010090 std::cerr << demangle_flags(Xpr::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010091 std::cerr << demangle_flags(internal::evaluator<Xpr>::Flags) << std::endl;
Gael Guennebauda3950242014-03-12 18:14:58 +010092 traits::debug();
93
Gael Guennebaud51ec1882010-07-08 23:30:16 +020094 std::cerr << " Expected Traversal == " << demangle_traversal(traversal)
95 << " got " << demangle_traversal(traits::Traversal) << "\n";
96 std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)
97 << " got " << demangle_unrolling(traits::Unrolling) << "\n";
98 }
99 return res;
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000100}
101
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200102template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable>
103struct vectorization_logic
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200104{
Christoph Hertzberg4f440b82014-07-14 14:36:20 +0200105 typedef internal::packet_traits<Scalar> PacketTraits;
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200106
107 typedef typename internal::packet_traits<Scalar>::type PacketType;
108 typedef typename internal::unpacket_traits<PacketType>::half HalfPacketType;
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200109 enum {
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200110 PacketSize = internal::unpacket_traits<PacketType>::size,
111 HalfPacketSize = internal::unpacket_traits<HalfPacketType>::size
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200112 };
113 static void run()
114 {
115
116 typedef Matrix<Scalar,PacketSize,1> Vector1;
117 typedef Matrix<Scalar,Dynamic,1> VectorX;
118 typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;
119 typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
120 typedef Matrix<Scalar,2*PacketSize,2*PacketSize> Matrix22;
Gael Guennebaud64356a62011-01-04 14:18:07 +0100121 typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;
122 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 +0200123 typedef Matrix<Scalar,4*PacketSize,4*PacketSize,ColMajor> Matrix44c;
124 typedef Matrix<Scalar,4*PacketSize,4*PacketSize,RowMajor> Matrix44r;
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200125
126 typedef Matrix<Scalar,
127 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
128 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
129 > Matrix1;
130
131 typedef Matrix<Scalar,
132 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
133 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
134 DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
135
Gael Guennebaud64356a62011-01-04 14:18:07 +0100136 // 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 +0200137 typedef Matrix<Scalar,
Gael Guennebaud64356a62011-01-04 14:18:07 +0100138 (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
139 (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200140 > Matrix3;
Gael Guennebaud501bc602011-05-19 21:52:40 +0200141
142 #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200143 VERIFY(test_assign(Vector1(),Vector1(),
144 InnerVectorizedTraversal,CompleteUnrolling));
145 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
146 InnerVectorizedTraversal,CompleteUnrolling));
147 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
148 InnerVectorizedTraversal,CompleteUnrolling));
149 VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
150 InnerVectorizedTraversal,CompleteUnrolling));
151
152
153 VERIFY(test_assign(Vector1(),Vector1(),
154 InnerVectorizedTraversal,CompleteUnrolling));
155 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
156 InnerVectorizedTraversal,CompleteUnrolling));
157 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
158 InnerVectorizedTraversal,CompleteUnrolling));
159
160 VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),
161 InnerVectorizedTraversal,InnerUnrolling));
162
163 VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200164 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearTraversal,
165 EIGEN_UNALIGNED_VECTORIZE ? InnerUnrolling : NoUnrolling));
166
167 VERIFY(test_assign(Matrix1(),Matrix1()+Matrix1(),
168 (Matrix1::InnerSizeAtCompileTime % PacketSize)==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal,
169 CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200170
171 VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200172 EIGEN_UNALIGNED_VECTORIZE ? ((Matrix1::InnerSizeAtCompileTime % PacketSize)==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal)
173 : LinearTraversal, CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200174
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200175 VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),
176 InnerVectorizedTraversal,CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700177
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200178 VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),
179 InnerVectorizedTraversal,CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700180
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200181 if(PacketSize>1)
182 {
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200183 typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
Gael Guennebaude68e1652016-05-24 21:54:03 +0200184 typedef Matrix<Scalar,3,1,ColMajor> Vector3;
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200185 VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
186 LinearTraversal,CompleteUnrolling));
Gael Guennebaude68e1652016-05-24 21:54:03 +0200187 VERIFY(test_assign(Vector3(),Vector3()+Vector3(),
188 EIGEN_UNALIGNED_VECTORIZE ? (HalfPacketSize==1 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : (HalfPacketSize==1 ? InnerVectorizedTraversal : LinearTraversal), CompleteUnrolling));
Gael Guennebaudaa2b46a2010-07-23 16:29:29 +0200189 VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200190 EIGEN_UNALIGNED_VECTORIZE ? (HalfPacketSize==1 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : (HalfPacketSize==1 ? SliceVectorizedTraversal : LinearTraversal),
191 ((!EIGEN_UNALIGNED_VECTORIZE) && HalfPacketSize==1) ? NoUnrolling : CompleteUnrolling));
Benoit Steiner25d05c42016-04-12 14:13:25 -0700192
193 VERIFY(test_assign(Matrix3(),Matrix3().cwiseProduct(Matrix3()),
194 LinearVectorizedTraversal,CompleteUnrolling));
195
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200196 VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200197 HalfPacketSize==1 ? InnerVectorizedTraversal :
198 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal :
199 LinearTraversal,
200 NoUnrolling));
201
202 VERIFY(test_assign(Matrix11(), Matrix11()+Matrix11(),InnerVectorizedTraversal,CompleteUnrolling));
203
Benoit Steiner25d05c42016-04-12 14:13:25 -0700204
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200205 VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(8,4),
Gael Guennebaud5ca24572016-07-06 22:25:24 +0200206 (EIGEN_UNALIGNED_VECTORIZE) ? InnerVectorizedTraversal : DefaultTraversal, CompleteUnrolling|InnerUnrolling));
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200207
208 VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
209 InnerVectorizedTraversal,CompleteUnrolling));
210
211 VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
212 InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200213 }
Benoit Steiner25d05c42016-04-12 14:13:25 -0700214
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200215 VERIFY(test_redux(Vector1(),
216 LinearVectorizedTraversal,CompleteUnrolling));
217
Gael Guennebaud9c3aed92017-12-14 14:24:33 +0100218 VERIFY(test_redux(Vector1().array()*Vector1().array(),
219 LinearVectorizedTraversal,CompleteUnrolling));
220
221 VERIFY(test_redux((Vector1().array()*Vector1().array()).col(0),
222 LinearVectorizedTraversal,CompleteUnrolling));
223
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200224 VERIFY(test_redux(Matrix<Scalar,PacketSize,3>(),
225 LinearVectorizedTraversal,CompleteUnrolling));
226
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200227 VERIFY(test_redux(Matrix3(),
228 LinearVectorizedTraversal,CompleteUnrolling));
229
230 VERIFY(test_redux(Matrix44(),
231 LinearVectorizedTraversal,NoUnrolling));
232
Gael Guennebaudb00e48a2018-09-21 13:45:56 +0200233 if(PacketSize>1) {
234 VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),
235 SliceVectorizedTraversal,CompleteUnrolling));
236
237 VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?2:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:2>(1,2),
238 DefaultTraversal,CompleteUnrolling));
239 }
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200240
241 VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),
242 LinearVectorizedTraversal,CompleteUnrolling));
243
244 VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),
245 LinearVectorizedTraversal,CompleteUnrolling));
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200246
Gael Guennebaud501bc602011-05-19 21:52:40 +0200247 VERIFY((test_assign<
Gael Guennebaud1f502432015-08-06 15:31:07 +0200248 Map<Matrix22, AlignedMax, OuterStride<3*PacketSize> >,
Gael Guennebaud501bc602011-05-19 21:52:40 +0200249 Matrix22
250 >(InnerVectorizedTraversal,CompleteUnrolling)));
251
252 VERIFY((test_assign<
Gael Guennebaud1f502432015-08-06 15:31:07 +0200253 Map<Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>, AlignedMax, InnerStride<3*PacketSize> >,
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200254 Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
Gael Guennebaud5ca24572016-07-06 22:25:24 +0200255 >(DefaultTraversal,PacketSize>=8?InnerUnrolling:CompleteUnrolling)));
Gael Guennebaud501bc602011-05-19 21:52:40 +0200256
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200257 VERIFY((test_assign(Matrix11(), Matrix<Scalar,PacketSize,EIGEN_PLAIN_ENUM_MIN(2,PacketSize)>()*Matrix<Scalar,EIGEN_PLAIN_ENUM_MIN(2,PacketSize),PacketSize>(),
Gael Guennebaud1330f8b2015-03-13 21:15:50 +0100258 InnerVectorizedTraversal, CompleteUnrolling)));
Gael Guennebaud501bc602011-05-19 21:52:40 +0200259 #endif
260
261 VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),
262 SliceVectorizedTraversal,NoUnrolling));
263
264 VERIFY(test_redux(VectorX(10),
265 LinearVectorizedTraversal,NoUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200266 }
267};
268
269template<typename Scalar> struct vectorization_logic<Scalar,false>
270{
271 static void run() {}
272};
273
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200274template<typename Scalar, bool Enable = !internal::is_same<typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half,
275 typename internal::packet_traits<Scalar>::type>::value >
276struct vectorization_logic_half
277{
278 typedef internal::packet_traits<Scalar> PacketTraits;
279 typedef typename internal::unpacket_traits<typename internal::packet_traits<Scalar>::type>::half PacketType;
280 enum {
281 PacketSize = internal::unpacket_traits<PacketType>::size
282 };
283 static void run()
284 {
285
286 typedef Matrix<Scalar,PacketSize,1> Vector1;
287 typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;
288 typedef Matrix<Scalar,5*PacketSize,7,ColMajor> Matrix57;
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200289 typedef Matrix<Scalar,3*PacketSize,5,ColMajor> Matrix35;
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200290 typedef Matrix<Scalar,5*PacketSize,7,DontAlign|ColMajor> Matrix57u;
291// typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;
292// typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u;
293// typedef Matrix<Scalar,4*PacketSize,4*PacketSize,ColMajor> Matrix44c;
294// typedef Matrix<Scalar,4*PacketSize,4*PacketSize,RowMajor> Matrix44r;
295
296 typedef Matrix<Scalar,
297 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
298 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)
299 > Matrix1;
300
301 typedef Matrix<Scalar,
302 (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),
303 (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),
304 DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;
305
306 // this type is made such that it can only be vectorized when viewed as a linear 1D vector
307 typedef Matrix<Scalar,
308 (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),
309 (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)
310 > Matrix3;
311
312 #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT
313 VERIFY(test_assign(Vector1(),Vector1(),
314 InnerVectorizedTraversal,CompleteUnrolling));
315 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
316 InnerVectorizedTraversal,CompleteUnrolling));
Gael Guennebaude68e1652016-05-24 21:54:03 +0200317 VERIFY(test_assign(Vector1(),Vector1().template segment<PacketSize>(0).derived(),
318 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal,CompleteUnrolling));
319 VERIFY(test_assign(Vector1(),Scalar(2.1)*Vector1()-Vector1(),
320 InnerVectorizedTraversal,CompleteUnrolling));
321 VERIFY(test_assign(Vector1(),(Scalar(2.1)*Vector1().template segment<PacketSize>(0)-Vector1().template segment<PacketSize>(0)).derived(),
322 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearVectorizedTraversal,CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200323 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
324 InnerVectorizedTraversal,CompleteUnrolling));
325 VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),
326 InnerVectorizedTraversal,CompleteUnrolling));
327
328
329 VERIFY(test_assign(Vector1(),Vector1(),
330 InnerVectorizedTraversal,CompleteUnrolling));
331 VERIFY(test_assign(Vector1(),Vector1()+Vector1(),
332 InnerVectorizedTraversal,CompleteUnrolling));
333 VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),
334 InnerVectorizedTraversal,CompleteUnrolling));
335
336 VERIFY(test_assign(Matrix57(),Matrix57()+Matrix57(),
337 InnerVectorizedTraversal,InnerUnrolling));
338
339 VERIFY(test_assign(Matrix57u(),Matrix57()+Matrix57(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200340 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : LinearTraversal,
341 EIGEN_UNALIGNED_VECTORIZE ? InnerUnrolling : NoUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200342
343 VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200344 EIGEN_UNALIGNED_VECTORIZE ? ((Matrix1::InnerSizeAtCompileTime % PacketSize)==0 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : LinearTraversal,CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200345
346 if(PacketSize>1)
347 {
348 typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;
349 VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),
350 LinearTraversal,CompleteUnrolling));
351 VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200352 EIGEN_UNALIGNED_VECTORIZE ? (PacketSize==1 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : LinearTraversal,CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200353
354 VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),
355 PacketTraits::HasDiv ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
356
357 VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200358 EIGEN_UNALIGNED_VECTORIZE ? (PacketSize==1 ? InnerVectorizedTraversal : LinearVectorizedTraversal) : LinearTraversal,
359 NoUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200360
361 VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(8,4),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200362 EIGEN_UNALIGNED_VECTORIZE ? InnerVectorizedTraversal : DefaultTraversal,PacketSize>4?InnerUnrolling:CompleteUnrolling));
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200363
364 VERIFY(test_assign(Vector1(),Matrix11()*Vector1(),
365 InnerVectorizedTraversal,CompleteUnrolling));
366
367 VERIFY(test_assign(Matrix11(),Matrix11().lazyProduct(Matrix11()),
368 InnerVectorizedTraversal,InnerUnrolling+CompleteUnrolling));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200369 }
370
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200371 VERIFY(test_redux(Vector1(),
372 LinearVectorizedTraversal,CompleteUnrolling));
373
374 VERIFY(test_redux(Matrix<Scalar,PacketSize,3>(),
375 LinearVectorizedTraversal,CompleteUnrolling));
376
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200377 VERIFY(test_redux(Matrix3(),
378 LinearVectorizedTraversal,CompleteUnrolling));
379
Gael Guennebaud512ba0a2016-04-13 18:16:35 +0200380 VERIFY(test_redux(Matrix35(),
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200381 LinearVectorizedTraversal,CompleteUnrolling));
382
Gael Guennebaudb00e48a2018-09-21 13:45:56 +0200383 VERIFY(test_redux(Matrix57().template block<PacketSize==1?2:PacketSize,3>(1,0),
384 SliceVectorizedTraversal,CompleteUnrolling));
385
386 if(PacketSize>1) {
387 VERIFY(test_redux(Matrix57().template block<PacketSize,2>(1,0),
388 DefaultTraversal,CompleteUnrolling));
389 }
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200390
391 VERIFY((test_assign<
392 Map<Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>, AlignedMax, InnerStride<3*PacketSize> >,
393 Matrix<Scalar,EIGEN_PLAIN_ENUM_MAX(2,PacketSize),EIGEN_PLAIN_ENUM_MAX(2,PacketSize)>
394 >(DefaultTraversal,CompleteUnrolling)));
395
396 VERIFY((test_assign(Matrix57(), Matrix<Scalar,5*PacketSize,3>()*Matrix<Scalar,3,7>(),
Gael Guennebaud5ca24572016-07-06 22:25:24 +0200397 InnerVectorizedTraversal, InnerUnrolling|CompleteUnrolling)));
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200398 #endif
399 }
400};
401
402template<typename Scalar> struct vectorization_logic_half<Scalar,false>
403{
404 static void run() {}
405};
406
Gael Guennebaud82f0ce22018-07-17 14:46:15 +0200407EIGEN_DECLARE_TEST(vectorization_logic)
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000408{
409
410#ifdef EIGEN_VECTORIZE
411
Christoph Hertzberg4f440b82014-07-14 14:36:20 +0200412 CALL_SUBTEST( vectorization_logic<int>::run() );
Gael Guennebaud501bc602011-05-19 21:52:40 +0200413 CALL_SUBTEST( vectorization_logic<float>::run() );
414 CALL_SUBTEST( vectorization_logic<double>::run() );
415 CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );
416 CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200417
Gael Guennebaudfebcce32015-08-07 20:05:31 +0200418 CALL_SUBTEST( vectorization_logic_half<int>::run() );
419 CALL_SUBTEST( vectorization_logic_half<float>::run() );
420 CALL_SUBTEST( vectorization_logic_half<double>::run() );
421 CALL_SUBTEST( vectorization_logic_half<std::complex<float> >::run() );
422 CALL_SUBTEST( vectorization_logic_half<std::complex<double> >::run() );
423
Benoit Jacob47160402010-10-25 10:15:22 -0400424 if(internal::packet_traits<float>::Vectorizable)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200425 {
426 VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200427 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200428
429 VERIFY(test_redux(Matrix<float,5,2>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200430 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : DefaultTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200431 }
432
Benoit Jacob47160402010-10-25 10:15:22 -0400433 if(internal::packet_traits<double>::Vectorizable)
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200434 {
435 VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200436 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : LinearTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200437
438 VERIFY(test_redux(Matrix<double,7,3>(),
Gael Guennebaude68e1652016-05-24 21:54:03 +0200439 EIGEN_UNALIGNED_VECTORIZE ? LinearVectorizedTraversal : DefaultTraversal,CompleteUnrolling));
Gael Guennebaud51ec1882010-07-08 23:30:16 +0200440 }
Gael Guennebaudcb71dc42009-01-07 22:20:03 +0000441#endif // EIGEN_VECTORIZE
442
443}