5
5
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6
6
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
8
// Eigen is free software; you can redistribute it and/or
9
// modify it under the terms of the GNU Lesser General Public
10
// License as published by the Free Software Foundation; either
11
// version 3 of the License, or (at your option) any later version.
13
// Alternatively, you can redistribute it and/or
14
// modify it under the terms of the GNU General Public License as
15
// published by the Free Software Foundation; either version 2 of
16
// the License, or (at your option) any later version.
18
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
19
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
21
// GNU General Public License for more details.
23
// You should have received a copy of the GNU Lesser General Public
24
// License and a copy of the GNU General Public License along with
25
// Eigen. If not, see <http://www.gnu.org/licenses/>.
8
// This Source Code Form is subject to the terms of the Mozilla
9
// Public License v. 2.0. If a copy of the MPL was not distributed
10
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
27
12
#ifndef EIGEN_ASSIGN_H
28
13
#define EIGEN_ASSIGN_H
30
17
namespace internal {
32
19
/***************************************************************************
152
139
inner = Index % Derived1::InnerSizeAtCompileTime
155
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
142
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
157
144
dst.copyCoeffByOuterInner(outer, inner, src);
158
145
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
162
149
template<typename Derived1, typename Derived2, int Stop>
163
150
struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
165
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
152
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
168
155
template<typename Derived1, typename Derived2, int Index, int Stop>
169
156
struct assign_DefaultTraversal_InnerUnrolling
171
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
158
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
173
160
dst.copyCoeffByOuterInner(outer, Index, src);
174
161
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
178
165
template<typename Derived1, typename Derived2, int Stop>
179
166
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
181
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
168
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
184
171
/***********************
188
175
template<typename Derived1, typename Derived2, int Index, int Stop>
189
176
struct assign_LinearTraversal_CompleteUnrolling
191
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
178
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
193
180
dst.copyCoeff(Index, src);
194
181
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
198
185
template<typename Derived1, typename Derived2, int Stop>
199
186
struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
201
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
188
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
204
191
/**************************
214
201
JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
217
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
204
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
219
206
dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src);
220
207
assign_innervec_CompleteUnrolling<Derived1, Derived2,
225
212
template<typename Derived1, typename Derived2, int Stop>
226
213
struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
228
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
215
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
231
218
template<typename Derived1, typename Derived2, int Index, int Stop>
232
219
struct assign_innervec_InnerUnrolling
234
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer)
221
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer)
236
223
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
237
224
assign_innervec_InnerUnrolling<Derived1, Derived2,
242
229
template<typename Derived1, typename Derived2, int Stop>
243
230
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
245
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
232
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {}
248
235
/***************************************************************************
252
239
template<typename Derived1, typename Derived2,
253
240
int Traversal = assign_traits<Derived1, Derived2>::Traversal,
254
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling>
241
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling,
242
int Version = Specialized>
255
243
struct assign_impl;
257
245
/************************
258
246
*** Default traversal ***
259
247
************************/
261
template<typename Derived1, typename Derived2, int Unrolling>
262
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling>
249
template<typename Derived1, typename Derived2, int Unrolling, int Version>
250
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version>
264
inline static void run(Derived1 &, const Derived2 &) { }
252
static inline void run(Derived1 &, const Derived2 &) { }
267
template<typename Derived1, typename Derived2>
268
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
255
template<typename Derived1, typename Derived2, int Version>
256
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version>
270
258
typedef typename Derived1::Index Index;
271
inline static void run(Derived1 &dst, const Derived2 &src)
259
static inline void run(Derived1 &dst, const Derived2 &src)
273
261
const Index innerSize = dst.innerSize();
274
262
const Index outerSize = dst.outerSize();
281
template<typename Derived1, typename Derived2>
282
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling>
269
template<typename Derived1, typename Derived2, int Version>
270
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version>
284
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
272
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
286
274
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
291
template<typename Derived1, typename Derived2>
292
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling>
279
template<typename Derived1, typename Derived2, int Version>
280
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version>
294
282
typedef typename Derived1::Index Index;
295
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
283
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
297
285
const Index outerSize = dst.outerSize();
298
286
for(Index outer = 0; outer < outerSize; ++outer)
305
293
*** Linear traversal ***
306
294
***********************/
308
template<typename Derived1, typename Derived2>
309
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling>
296
template<typename Derived1, typename Derived2, int Version>
297
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version>
311
299
typedef typename Derived1::Index Index;
312
inline static void run(Derived1 &dst, const Derived2 &src)
300
static inline void run(Derived1 &dst, const Derived2 &src)
314
302
const Index size = dst.size();
315
303
for(Index i = 0; i < size; ++i)
320
template<typename Derived1, typename Derived2>
321
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling>
308
template<typename Derived1, typename Derived2, int Version>
309
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version>
323
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
311
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
325
313
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
331
319
*** Inner vectorization ***
332
320
**************************/
334
template<typename Derived1, typename Derived2>
335
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling>
322
template<typename Derived1, typename Derived2, int Version>
323
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version>
337
325
typedef typename Derived1::Index Index;
338
inline static void run(Derived1 &dst, const Derived2 &src)
326
static inline void run(Derived1 &dst, const Derived2 &src)
340
328
const Index innerSize = dst.innerSize();
341
329
const Index outerSize = dst.outerSize();
349
template<typename Derived1, typename Derived2>
350
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling>
337
template<typename Derived1, typename Derived2, int Version>
338
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version>
352
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
340
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
354
342
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
359
template<typename Derived1, typename Derived2>
360
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling>
347
template<typename Derived1, typename Derived2, int Version>
348
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version>
362
350
typedef typename Derived1::Index Index;
363
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
351
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
365
353
const Index outerSize = dst.outerSize();
366
354
for(Index outer = 0; outer < outerSize; ++outer)
401
template<typename Derived1, typename Derived2>
402
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
389
template<typename Derived1, typename Derived2, int Version>
390
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version>
404
392
typedef typename Derived1::Index Index;
405
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
393
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
407
395
const Index size = dst.size();
408
396
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
412
400
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
414
402
const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0
415
: first_aligned(&dst.coeffRef(0), size);
403
: internal::first_aligned(&dst.coeffRef(0), size);
416
404
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
418
406
unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
429
template<typename Derived1, typename Derived2>
430
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling>
417
template<typename Derived1, typename Derived2, int Version>
418
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version>
432
420
typedef typename Derived1::Index Index;
433
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
421
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
435
423
enum { size = Derived1::SizeAtCompileTime,
436
424
packetSize = packet_traits<typename Derived1::Scalar>::size,
445
433
*** Slice vectorization ***
446
434
***************************/
448
template<typename Derived1, typename Derived2>
449
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
436
template<typename Derived1, typename Derived2, int Version>
437
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version>
451
439
typedef typename Derived1::Index Index;
452
inline static void run(Derived1 &dst, const Derived2 &src)
440
static inline void run(Derived1 &dst, const Derived2 &src)
454
442
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
463
451
const Index outerSize = dst.outerSize();
464
452
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
465
453
Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
466
: first_aligned(&dst.coeffRef(0,0), innerSize);
454
: internal::first_aligned(&dst.coeffRef(0,0), innerSize);
468
456
for(Index outer = 0; outer < outerSize; ++outer)
532
520
template<typename Derived, typename OtherDerived>
533
521
struct assign_selector<Derived,OtherDerived,false,false> {
534
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
522
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
536
524
template<typename Derived, typename OtherDerived>
537
525
struct assign_selector<Derived,OtherDerived,true,false> {
538
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
526
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
540
528
template<typename Derived, typename OtherDerived>
541
529
struct assign_selector<Derived,OtherDerived,false,true> {
542
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
530
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
544
532
template<typename Derived, typename OtherDerived>
545
533
struct assign_selector<Derived,OtherDerived,true,true> {
546
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
534
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
549
537
} // end namespace internal