MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
tlayout.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_TEMPLATE_LAYOUT
13#define MFEM_TEMPLATE_LAYOUT
14
15#include "../config/tconfig.hpp"
16#include "../fem/fespace.hpp"
17
18namespace mfem
19{
20
21// Layout classes
22
23template <int N1, int S1>
24struct OffsetStridedLayout1D;
25template <int N1, int S1, int N2, int S2>
26struct StridedLayout2D;
27
28template <int N1, int S1>
30{
31 static const int rank = 1;
32 static const int dim_1 = N1;
33 static const int size = N1;
34
35 MFEM_HOST_DEVICE static inline int ind(int i1)
36 {
37 return S1*i1;
38 }
39
40 template <int M1>
42 {
43 return OffsetStridedLayout1D<M1,S1>(S1*o1);
44 }
45
46 // reshape methods
47
48 template <int N1_1, int N1_2>
50 {
51 // S1*i1 == S1*(i1_1+N1_1*i1_2)
52 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
54 }
55};
56
57template <int N1, int S1, int N2, int S2>
58struct OffsetStridedLayout2D;
59
60template <int N1, int S1>
62{
63 static const int rank = 1;
64 static const int dim_1 = N1;
65 static const int size = N1;
66
67 int offset;
68
70 OffsetStridedLayout1D(int offset_) : offset(offset_) { }
71 MFEM_HOST_DEVICE inline int ind(int i1) const
72 {
73 return offset+S1*i1;
74 }
75
76 template <int M1>
78 {
80 }
81
82 // reshape methods
83
84 template <int N1_1, int N1_2>
86 {
87 // S1*i1 == S1*(i1_1+N1_1*i1_2)
88 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
90 }
91};
92
93template <int N1, int S1, int N2, int S2, int N3, int S3>
94struct StridedLayout3D;
95template <int N1, int S1, int N2, int S2, int N3, int S3, int N4, int S4>
96struct StridedLayout4D;
97
98template <int N1, int S1, int N2, int S2>
100{
101 static const int rank = 2;
102 static const int dim_1 = N1;
103 static const int dim_2 = N2;
104 static const int size = N1*N2;
105
106 MFEM_HOST_DEVICE static inline int ind(int i1, int i2)
107 {
108 return (S1*i1+S2*i2);
109 }
111 {
112 return OffsetStridedLayout1D<N2,S2>(S1*i1);
113 }
115 {
116 return OffsetStridedLayout1D<N1,S1>(S2*i2);
117 }
118
119 template <int M1, int M2>
121 {
122 return OffsetStridedLayout2D<M1,S1,M2,S2>(S1*o1+S2*o2);
123 }
124
125 // reshape methods
126
127 template <int N1_1, int N1_2>
129 {
130 // S1*i1+S2*i2 == S1*(i1_1+N1_1*i1_2)+S2*i2
131 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
133 }
134 template <int N2_1, int N2_2>
136 {
137 // S1*i1+S2*i2 == S1*i1+S2*(i2_1*N2_1*i2_2)
138 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2, "invalid dimensions");
140 }
141 template <int N1_1, int N1_2, int N2_1, int N2_2>
143 {
144 // S1*i1+S2*i2 == S1*(i1_1+N1_1*i1_2)+S2*(i2_1+N2_1*i2_2)
145 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
146 "invalid dimensions");
148 }
149 static StridedLayout1D<N1*N2,(S1<S2)?S1:S2> merge_12()
150 {
151 // use: (S1*i1+S2*i2) == (S1*(i1+S2/S1*i2))
152 // or (S1*i1+S2*i2) == (S2*(S1/S2*i1+i2))
153 // assuming: S2 == S1*N1 || S1 == S2*N2
154 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2, "invalid reshape");
156 }
161};
162
163template <int N1, int S1, int N2, int S2, int N3, int S3>
164struct OffsetStridedLayout3D;
165template <int N1, int S1, int N2, int S2, int N3, int S3, int N4, int S4>
166struct OffsetStridedLayout4D;
167
168template <int N1, int S1, int N2, int S2>
170{
171 static const int rank = 2;
172 static const int dim_1 = N1;
173 static const int dim_2 = N2;
174 static const int size = N1*N2;
175
177
179 OffsetStridedLayout2D(int offset_) : offset(offset_) { }
180 MFEM_HOST_DEVICE inline int ind(int i1, int i2) const
181 {
182 return offset+S1*i1+S2*i2;
183 }
185 {
187 }
189 {
191 }
192
193 template <int M1, int M2>
195 {
196 return OffsetStridedLayout2D<M1,S1,M2,S2>(offset+S1*o1+S2*o2);
197 }
198
199 // reshape methods
200
201 template <int N1_1, int N1_2>
203 {
204 // S1*i1+S2*i2 == S1*(i1_1+N1_1*i1_2)+S2*i2
205 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
207 }
208 template <int N2_1, int N2_2>
210 {
211 // S1*i1+S2*i2 == S1*i1+S2*(i2_1*N2_1*i2_2)
212 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2, "invalid dimensions");
214 }
215 template <int N1_1, int N1_2, int N2_1, int N2_2>
217 split_12() const
218 {
219 // S1*i1+S2*i2 == S1*(i1_1+N1_1*i1_2)+S2*(i2_1+N2_1*i2_2)
220 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1 && N2_1*N2_2 == N2,
221 "invalid dimensions");
223 N1_1,S1,N1_2,S1*N1_1,N2_1,S2,N2_2,S2*N2_1>(offset);
224 }
225 OffsetStridedLayout1D<N1*N2,(S1<S2)?S1:S2> merge_12() const
226 {
227 // use: (S1*i1+S2*i2) == (S1*(i1+S2/S1*i2))
228 // or (S1*i1+S2*i2) == (S2*(S1/S2*i1+i2))
229 // assuming: S2 == S1*N1 || S1 == S2*N2
230 MFEM_STATIC_ASSERT(S2 == S1*N1 || S1 == S2*N2, "invalid reshape");
232 }
237};
238
239template <int N1, int S1, int N2, int S2, int N3, int S3>
241{
242 static const int rank = 3;
243 static const int dim_1 = N1;
244 static const int dim_2 = N2;
245 static const int dim_3 = N3;
246 static const int size = N1*N2*N3;
247
248 static inline int ind(int i1, int i2, int i3)
249 {
250 return S1*i1+S2*i2+S3*i3;
251 }
264
265 // reshape methods
266
268 {
269 // use: (S1*i1+S2*i2+S3*i3) == (S1*(i1+S2/S1*i2)+S3*i3)
270 // assuming: S2 == S1*N1
271 MFEM_STATIC_ASSERT(S2 == S1*N1, "invalid reshape");
273 // alternative:
274 // use: (S1*i1+S2*i2+S3*i3) == (S2*(S1/S2*i1+i2)+S3*i3)
275 // assuming: S1 == S2*N2
276 // result is: StridedLayout2D<N1*N2,S2,N3,S3>
277 }
279 {
280 // use: (S1*i1+S2*i2+S3*i3) == (S1*i1+S2*(i2+S3/S2*i3))
281 // assuming: S3 == S2*N2
282 MFEM_STATIC_ASSERT(S3 == S2*N2, "invalid reshape");
284 }
285
286 template <int N1_1, int N1_2>
288 {
289 // S1*i1+S2*i2+S3*i3 == S1*(i1_1+N1_1*i1_2)+S2*i2+S3*i3
290 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
292 }
293 template <int N2_1, int N2_2>
295 {
296 // S1*i1+S2*i2+S3*i3 == S1*i1+S2*(i2_1+N2_1*i2_2)+S3*i3
297 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2, "invalid dimensions");
299 }
300 template <int N3_1, int N3_2>
302 {
303 // S1*i1+S2*i2+S3*i3 == S1*i1+S2*i2+S3*(i3_1+N3_1*i3_2)
304 MFEM_STATIC_ASSERT(N3_1*N3_2 == N3, "invalid dimensions");
306 }
307
320};
321
322template <int N1, int S1, int N2, int S2, int N3, int S3>
324{
325 static const int rank = 3;
326 static const int dim_1 = N1;
327 static const int dim_2 = N2;
328 static const int dim_3 = N3;
329 static const int size = N1*N2*N3;
330
332
334 OffsetStridedLayout3D(int offset_) : offset(offset_) { }
335 inline int ind(int i1, int i2, int i3) const
336 {
337 return offset+S1*i1+S2*i2+S3*i3;
338 }
351
352 // reshape methods
353
355 {
356 // use: (S1*i1+S2*i2+S3*i3) == (S1*(i1+S2/S1*i2)+S3*i3)
357 // assuming: S2 == S1*N1
358 MFEM_STATIC_ASSERT(S2 == S1*N1, "invalid reshape");
360 }
362 {
363 // use: (S1*i1+S2*i2+S3*i3) == (S1*i1+S2*(i2+S3/S2*i3))
364 // assuming: S3 == S2*N2
365 MFEM_STATIC_ASSERT(S3 == S2*N2, "invalid reshape");
367 }
368
369 template <int N1_1, int N1_2>
371 {
372 // S1*i1+S2*i2+S3*i3 == S1*(i1_1+N1_1*i1_2)+S2*i2+S3*i3
373 MFEM_STATIC_ASSERT(N1_1*N1_2 == N1, "invalid dimensions");
375 }
376 template <int N2_1, int N2_2>
378 {
379 // S1*i1+S2*i2+S3*i3 == S1*i1+S2*(i2_1+N2_1*i2_2)+S3*i3
380 MFEM_STATIC_ASSERT(N2_1*N2_2 == N2, "invalid dimensions");
382 }
383};
384
385template <int N1, int S1, int N2, int S2, int N3, int S3, int N4, int S4>
387{
388 static const int rank = 4;
389 static const int dim_1 = N1;
390 static const int dim_2 = N2;
391 static const int dim_3 = N3;
392 static const int dim_4 = N4;
393 static const int size = N1*N2*N3*N4;
394
395 static inline int ind(int i1, int i2, int i3, int i4)
396 {
397 return S1*i1+S2*i2+S3*i3+S4*i4;
398 }
400 {
401 return OffsetStridedLayout2D<N1,S1,N4,S4>(S2*i2+S3*i3);
402 }
404 {
405 return OffsetStridedLayout2D<N2,S2,N3,S3>(S1*i1+S4*i4);
406 }
411
413 {
414 // use: (S1*i1+S2*i2+S3*i3+S4*i4) == (S1*(i1+S2/S1*i2)+S3*i3+S4*i4)
415 // assuming S2 == S1*N1
416 MFEM_STATIC_ASSERT(S2 == S1*N1, "invalid reshape");
418 }
420 {
421 // use: (S1*i1+S2*i2+S3*i3+S4*i4) == (S1*i1+S2*i2+S3*(i3+S4/S3*i4))
422 // assuming S4 == S3*N3
423 MFEM_STATIC_ASSERT(S4 == S3*N3, "invalid reshape");
425 }
426};
427
428template <int N1, int S1, int N2, int S2, int N3, int S3, int N4, int S4>
430{
431 static const int rank = 4;
432 static const int dim_1 = N1;
433 static const int dim_2 = N2;
434 static const int dim_3 = N3;
435 static const int dim_4 = N4;
436 static const int size = N1*N2*N3*N4;
437
439
441 OffsetStridedLayout4D(int offset_) : offset(offset_) { }
442 inline int ind(int i1, int i2, int i3, int i4) const
443 {
444 return offset+S1*i1+S2*i2+S3*i3+S4*i4;
445 }
446};
447
448template <int N1, int N2>
450 : public StridedLayout2D<N1,1,N2,N1> { };
451
452template <int N1, int N2, int N3>
454 : public StridedLayout3D<N1,1,N2,N1,N3,N1*N2> { };
455
456template <int N1, int N2, int N3, int N4>
458 : public StridedLayout4D<N1,1,N2,N1,N3,N1*N2,N4,N1*N2*N3> { };
459
460
461// Vector layout classes
462
464{
465public:
466 static const int vec_dim = 0; // 0 - dynamic
467
468protected:
471
472 void Init(Ordering::Type ordering, int scalar_size, int num_comp)
473 {
474 num_components = num_comp;
475 if (ordering == Ordering::byNODES)
476 {
477 scal_stride = 1;
478 comp_stride = scalar_size;
479 }
480 else
481 {
482 scal_stride = num_comp;
483 comp_stride = 1;
484 }
485 }
486
487public:
488 DynamicVectorLayout(Ordering::Type ordering, int scalar_size, int num_comp)
489 {
490 Init(ordering, scalar_size, num_comp);
491 }
493 {
494 Init(fes.GetOrdering(), fes.GetNDofs(), fes.GetVDim());
495 }
496 // default copy constructor
497
498 int NumComponents() const { return num_components; }
499
500 int ind(int scalar_idx, int comp_idx) const
501 {
502 return scal_stride * scalar_idx + comp_stride * comp_idx;
503 }
504
505 static bool Matches(const FiniteElementSpace &fes)
506 {
507 return true;
508 }
509};
510
511// The default value (NumComp = 0) indicates that the number of components is
512// dynamic, i.e. it will be specified at run-time.
513template <Ordering::Type Ord, int NumComp = 0>
515{
516public:
517 static const int vec_dim = NumComp;
518
519protected:
521
522public:
523 VectorLayout(int scalar_size_, int num_comp_ = NumComp)
524 : num_components(num_comp_),
525 scalar_size(scalar_size_)
526 {
527 MFEM_ASSERT(NumComp == 0 || num_components == NumComp,
528 "invalid number of components");
529 }
530
532 : num_components(fes.GetVDim()),
533 scalar_size(fes.GetNDofs())
534 {
535 MFEM_ASSERT(fes.GetOrdering() == Ord, "ordering mismatch");
536 MFEM_ASSERT(NumComp == 0 || num_components == NumComp,
537 "invalid number of components");
538 }
539 // default copy constructor
540
541 int NumComponents() const { return (NumComp ? NumComp : num_components); }
542
543 int ind(int scalar_idx, int comp_idx) const
544 {
545 if (Ord == Ordering::byNODES)
546 {
547 return scalar_idx + comp_idx * scalar_size;
548 }
549 else
550 {
551 return comp_idx + (NumComp ? NumComp : num_components) * scalar_idx;
552 }
553 }
554
555 static bool Matches(const FiniteElementSpace &fes)
556 {
557 return (Ord == fes.GetOrdering() &&
558 (NumComp == 0 || NumComp == fes.GetVDim()));
559 }
560};
561
563{
564public:
565 static const int vec_dim = 1;
566
568
570 {
571 MFEM_ASSERT(fes.GetVDim() == 1, "invalid number of components");
572 }
573
574 int NumComponents() const { return 1; }
575
576 int ind(int scalar_idx, int comp_idx) const { return scalar_idx; }
577
578 static bool Matches(const FiniteElementSpace &fes)
579 {
580 return (fes.GetVDim() == 1);
581 }
582};
583
584} // namespace mfem
585
586#endif // MFEM_TEMPLATE_LAYOUT
DynamicVectorLayout(Ordering::Type ordering, int scalar_size, int num_comp)
Definition tlayout.hpp:488
static bool Matches(const FiniteElementSpace &fes)
Definition tlayout.hpp:505
static const int vec_dim
Definition tlayout.hpp:466
int ind(int scalar_idx, int comp_idx) const
Definition tlayout.hpp:500
DynamicVectorLayout(const FiniteElementSpace &fes)
Definition tlayout.hpp:492
void Init(Ordering::Type ordering, int scalar_size, int num_comp)
Definition tlayout.hpp:472
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:208
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Definition fespace.hpp:823
Ordering::Type GetOrdering() const
Return the ordering method.
Definition fespace.hpp:854
int GetVDim() const
Returns the vector dimension of the finite element space.
Definition fespace.hpp:819
Type
Ordering methods:
Definition ordering.hpp:17
ScalarLayout(const FiniteElementSpace &fes)
Definition tlayout.hpp:569
int NumComponents() const
Definition tlayout.hpp:574
static bool Matches(const FiniteElementSpace &fes)
Definition tlayout.hpp:578
static const int vec_dim
Definition tlayout.hpp:565
int ind(int scalar_idx, int comp_idx) const
Definition tlayout.hpp:576
static const int vec_dim
Definition tlayout.hpp:517
static bool Matches(const FiniteElementSpace &fes)
Definition tlayout.hpp:555
VectorLayout(int scalar_size_, int num_comp_=NumComp)
Definition tlayout.hpp:523
int NumComponents() const
Definition tlayout.hpp:541
int ind(int scalar_idx, int comp_idx) const
Definition tlayout.hpp:543
VectorLayout(const FiniteElementSpace &fes)
Definition tlayout.hpp:531
OffsetStridedLayout1D< M1, S1 > sub(int o1) const
Definition tlayout.hpp:77
static const int rank
Definition tlayout.hpp:63
OffsetStridedLayout2D< N1_1, S1, N1_2, S1 *N1_1 > split_1() const
Definition tlayout.hpp:85
static const int size
Definition tlayout.hpp:65
static const int dim_1
Definition tlayout.hpp:64
MFEM_HOST_DEVICE int ind(int i1) const
Definition tlayout.hpp:71
OffsetStridedLayout1D(int offset_)
Definition tlayout.hpp:70
OffsetStridedLayout3D< N1_1, S1, N1_2, S1 *N1_1, N2, S2 > split_1() const
Definition tlayout.hpp:202
OffsetStridedLayout2D< M1, S1, M2, S2 > sub(int o1, int o2) const
Definition tlayout.hpp:194
OffsetStridedLayout2D(int offset_)
Definition tlayout.hpp:179
OffsetStridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2_1, S2, N2_2, S2 *N2_1 > split_12() const
Definition tlayout.hpp:217
static const int dim_2
Definition tlayout.hpp:173
OffsetStridedLayout1D< N1 *N2,(S1< S2)?S1:S2 > merge_12() const
Definition tlayout.hpp:225
MFEM_HOST_DEVICE int ind(int i1, int i2) const
Definition tlayout.hpp:180
OffsetStridedLayout2D< N2, S2, N1, S1 > transpose_12() const
Definition tlayout.hpp:233
static const int size
Definition tlayout.hpp:174
OffsetStridedLayout1D< N1, S1 > ind2(int i2) const
Definition tlayout.hpp:188
OffsetStridedLayout1D< N2, S2 > ind1(int i1) const
Definition tlayout.hpp:184
static const int rank
Definition tlayout.hpp:171
OffsetStridedLayout3D< N1, S1, N2_1, S2, N2_2, S2 *N2_1 > split_2() const
Definition tlayout.hpp:209
static const int dim_1
Definition tlayout.hpp:172
OffsetStridedLayout4D< N1, S1, N2_1, S2, N2_2, S2 *N2_1, N3, S3 > split_2() const
Definition tlayout.hpp:377
static const int dim_3
Definition tlayout.hpp:328
OffsetStridedLayout2D< N1 *N2, S1, N3, S3 > merge_12() const
Definition tlayout.hpp:354
static const int rank
Definition tlayout.hpp:325
int ind(int i1, int i2, int i3) const
Definition tlayout.hpp:335
static const int size
Definition tlayout.hpp:329
OffsetStridedLayout2D< N1, S1, N2, S2 > ind3(int i3) const
Definition tlayout.hpp:347
static const int dim_2
Definition tlayout.hpp:327
OffsetStridedLayout2D< N2, S2, N3, S3 > ind1(int i1) const
Definition tlayout.hpp:339
OffsetStridedLayout3D(int offset_)
Definition tlayout.hpp:334
static const int dim_1
Definition tlayout.hpp:326
OffsetStridedLayout2D< N1, S1, N3, S3 > ind2(int i2) const
Definition tlayout.hpp:343
OffsetStridedLayout2D< N1, S1, N2 *N3, S2 > merge_23() const
Definition tlayout.hpp:361
OffsetStridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2, S2, N3, S3 > split_1() const
Definition tlayout.hpp:370
static const int size
Definition tlayout.hpp:436
static const int dim_1
Definition tlayout.hpp:432
static const int dim_2
Definition tlayout.hpp:433
static const int dim_3
Definition tlayout.hpp:434
static const int rank
Definition tlayout.hpp:431
int ind(int i1, int i2, int i3, int i4) const
Definition tlayout.hpp:442
static const int dim_4
Definition tlayout.hpp:435
OffsetStridedLayout4D(int offset_)
Definition tlayout.hpp:441
static const int size
Definition tlayout.hpp:33
static MFEM_HOST_DEVICE int ind(int i1)
Definition tlayout.hpp:35
static const int rank
Definition tlayout.hpp:31
static StridedLayout2D< N1_1, S1, N1_2, S1 *N1_1 > split_1()
Definition tlayout.hpp:49
static OffsetStridedLayout1D< M1, S1 > sub(int o1)
Definition tlayout.hpp:41
static const int dim_1
Definition tlayout.hpp:32
static OffsetStridedLayout1D< N1, S1 > ind2(int i2)
Definition tlayout.hpp:114
static StridedLayout1D< N1 *N2,(S1< S2)?S1:S2 > merge_12()
Definition tlayout.hpp:149
static MFEM_HOST_DEVICE int ind(int i1, int i2)
Definition tlayout.hpp:106
static StridedLayout2D< N2, S2, N1, S1 > transpose_12()
Definition tlayout.hpp:157
static OffsetStridedLayout1D< N2, S2 > ind1(int i1)
Definition tlayout.hpp:110
static StridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2_1, S2, N2_2, S2 *N2_1 > split_12()
Definition tlayout.hpp:142
static const int dim_1
Definition tlayout.hpp:102
static const int rank
Definition tlayout.hpp:101
static StridedLayout3D< N1_1, S1, N1_2, S1 *N1_1, N2, S2 > split_1()
Definition tlayout.hpp:128
static OffsetStridedLayout2D< M1, S1, M2, S2 > sub(int o1, int o2)
Definition tlayout.hpp:120
static const int size
Definition tlayout.hpp:104
static StridedLayout3D< N1, S1, N2_1, S2, N2_2, S2 *N2_1 > split_2()
Definition tlayout.hpp:135
static const int dim_2
Definition tlayout.hpp:103
static StridedLayout3D< N3, S3, N2, S2, N1, S1 > transpose_13()
Definition tlayout.hpp:312
static StridedLayout3D< N2, S2, N1, S1, N3, S3 > transpose_12()
Definition tlayout.hpp:308
static OffsetStridedLayout2D< N1, S1, N2, S2 > ind3(int i3)
Definition tlayout.hpp:260
static StridedLayout4D< N1, S1, N2_1, S2, N2_2, S2 *N2_1, N3, S3 > split_2()
Definition tlayout.hpp:294
static const int rank
Definition tlayout.hpp:242
static const int dim_1
Definition tlayout.hpp:243
static StridedLayout2D< N1, S1, N2 *N3, S2 > merge_23()
Definition tlayout.hpp:278
static const int size
Definition tlayout.hpp:246
static StridedLayout2D< N1 *N2, S1, N3, S3 > merge_12()
Definition tlayout.hpp:267
static const int dim_3
Definition tlayout.hpp:245
static const int dim_2
Definition tlayout.hpp:244
static int ind(int i1, int i2, int i3)
Definition tlayout.hpp:248
static StridedLayout4D< N1, S1, N2, S2, N3_1, S3, N3_2, S3 *N3_1 > split_3()
Definition tlayout.hpp:301
static StridedLayout3D< N1, S1, N3, S3, N2, S2 > transpose_23()
Definition tlayout.hpp:316
static StridedLayout4D< N1_1, S1, N1_2, S1 *N1_1, N2, S2, N3, S3 > split_1()
Definition tlayout.hpp:287
static OffsetStridedLayout2D< N2, S2, N3, S3 > ind1(int i1)
Definition tlayout.hpp:252
static OffsetStridedLayout2D< N1, S1, N3, S3 > ind2(int i2)
Definition tlayout.hpp:256
static const int dim_2
Definition tlayout.hpp:390
static OffsetStridedLayout2D< N2, S2, N3, S3 > ind14(int i1, int i4)
Definition tlayout.hpp:403
static int ind(int i1, int i2, int i3, int i4)
Definition tlayout.hpp:395
static StridedLayout3D< N1, S1, N2, S2, N3 *N4, S3 > merge_34()
Definition tlayout.hpp:419
static const int dim_1
Definition tlayout.hpp:389
static OffsetStridedLayout2D< N1, S1, N4, S4 > ind23(int i2, int i3)
Definition tlayout.hpp:399
static const int rank
Definition tlayout.hpp:388
static const int dim_3
Definition tlayout.hpp:391
static const int dim_4
Definition tlayout.hpp:392
static OffsetStridedLayout3D< N1, S1, N2, S2, N3, S3 > ind4(int i4)
Definition tlayout.hpp:407
static const int size
Definition tlayout.hpp:393
static StridedLayout3D< N1 *N2, S1, N3, S3, N4, S4 > merge_12()
Definition tlayout.hpp:412