1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44
45 #ifndef KOKKOS_EXPERIMENTAL_VIEWLAYOUTTILE_HPP
46 #define KOKKOS_EXPERIMENTAL_VIEWLAYOUTTILE_HPP
47
48 #include <Kokkos_Layout.hpp>
49 #include <Kokkos_View.hpp>
50
51 //----------------------------------------------------------------------------
52 //----------------------------------------------------------------------------
53
54 namespace Kokkos {
55
56 // View offset and mapping for tiled view's
57
58 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
59 unsigned ArgN1>
60 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
61 OuterP, InnerP, ArgN0, ArgN1, 0, 0, 0, 0, 0, 0, true> >
62 : public std::true_type {};
63
64 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
65 unsigned ArgN1, unsigned ArgN2>
66 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
67 OuterP, InnerP, ArgN0, ArgN1, ArgN2, 0, 0, 0, 0, 0, true> >
68 : public std::true_type {};
69
70 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
71 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3>
72 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
73 OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, 0, 0, 0, 0, true> >
74 : public std::true_type {};
75
76 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
77 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3, unsigned ArgN4>
78 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
79 OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, 0, 0, 0, true> >
80 : public std::true_type {};
81
82 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
83 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3, unsigned ArgN4,
84 unsigned ArgN5>
85 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
86 OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, 0, 0, true> >
87 : public std::true_type {};
88
89 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
90 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3, unsigned ArgN4,
91 unsigned ArgN5, unsigned ArgN6>
92 struct is_array_layout<Kokkos::Experimental::LayoutTiled<
93 OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, 0, true> >
94 : public std::true_type {};
95
96 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
97 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3, unsigned ArgN4,
98 unsigned ArgN5, unsigned ArgN6, unsigned ArgN7>
99 struct is_array_layout<
100 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, ArgN0, ArgN1, ArgN2,
101 ArgN3, ArgN4, ArgN5, ArgN6, ArgN7, true> >
102 : public std::true_type {};
103
104 template <class L>
105 struct is_array_layout_tiled : public std::false_type {};
106
107 template <Kokkos::Iterate OuterP, Kokkos::Iterate InnerP, unsigned ArgN0,
108 unsigned ArgN1, unsigned ArgN2, unsigned ArgN3, unsigned ArgN4,
109 unsigned ArgN5, unsigned ArgN6, unsigned ArgN7, bool IsPowerTwo>
110 struct is_array_layout_tiled<Kokkos::Experimental::LayoutTiled<
111 OuterP, InnerP, ArgN0, ArgN1, ArgN2, ArgN3, ArgN4, ArgN5, ArgN6, ArgN7,
112 IsPowerTwo> > : public std::true_type {
113 }; // Last template parameter "true" meaning this currently only supports
114 // powers-of-two
115
116 namespace Impl {
117
118 template <class Dimension, class Layout>
119 struct ViewOffset<
120 Dimension, Layout,
121 typename std::enable_if<((Dimension::rank <= 8) && (Dimension::rank >= 2) &&
122 is_array_layout<Layout>::value &&
123 is_array_layout_tiled<Layout>::value)>::type> {
124 public:
125 static constexpr Kokkos::Iterate outer_pattern = Layout::outer_pattern;
126 static constexpr Kokkos::Iterate inner_pattern = Layout::inner_pattern;
127
128 static constexpr int VORank = Dimension::rank;
129
130 static constexpr unsigned SHIFT_0 =
131 Kokkos::Impl::integral_power_of_two(Layout::N0);
132 static constexpr unsigned SHIFT_1 =
133 Kokkos::Impl::integral_power_of_two(Layout::N1);
134 static constexpr unsigned SHIFT_2 =
135 Kokkos::Impl::integral_power_of_two(Layout::N2);
136 static constexpr unsigned SHIFT_3 =
137 Kokkos::Impl::integral_power_of_two(Layout::N3);
138 static constexpr unsigned SHIFT_4 =
139 Kokkos::Impl::integral_power_of_two(Layout::N4);
140 static constexpr unsigned SHIFT_5 =
141 Kokkos::Impl::integral_power_of_two(Layout::N5);
142 static constexpr unsigned SHIFT_6 =
143 Kokkos::Impl::integral_power_of_two(Layout::N6);
144 static constexpr unsigned SHIFT_7 =
145 Kokkos::Impl::integral_power_of_two(Layout::N7);
146 static constexpr int MASK_0 = Layout::N0 - 1;
147 static constexpr int MASK_1 = Layout::N1 - 1;
148 static constexpr int MASK_2 = Layout::N2 - 1;
149 static constexpr int MASK_3 = Layout::N3 - 1;
150 static constexpr int MASK_4 = Layout::N4 - 1;
151 static constexpr int MASK_5 = Layout::N5 - 1;
152 static constexpr int MASK_6 = Layout::N6 - 1;
153 static constexpr int MASK_7 = Layout::N7 - 1;
154
155 static constexpr unsigned SHIFT_2T = SHIFT_0 + SHIFT_1;
156 static constexpr unsigned SHIFT_3T = SHIFT_0 + SHIFT_1 + SHIFT_2;
157 static constexpr unsigned SHIFT_4T = SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3;
158 static constexpr unsigned SHIFT_5T =
159 SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4;
160 static constexpr unsigned SHIFT_6T =
161 SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4 + SHIFT_5;
162 static constexpr unsigned SHIFT_7T =
163 SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4 + SHIFT_5 + SHIFT_6;
164 static constexpr unsigned SHIFT_8T = SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 +
165 SHIFT_4 + SHIFT_5 + SHIFT_6 + SHIFT_7;
166
167 // Is an irregular layout that does not have uniform striding for each index.
168 using is_mapping_plugin = std::true_type;
169 using is_regular = std::false_type;
170
171 using size_type = size_t;
172 using dimension_type = Dimension;
173 using array_layout = Layout;
174
175 dimension_type m_dim;
176 size_type m_tile_N0; // Num tiles dim 0
177 size_type m_tile_N1;
178 size_type m_tile_N2;
179 size_type m_tile_N3;
180 size_type m_tile_N4;
181 size_type m_tile_N5;
182 size_type m_tile_N6;
183 size_type m_tile_N7;
184
185 //----------------------------------------
186
187 #define DEBUG_OUTPUT_CHECK 0
188
189 // Rank 2
190 template <typename I0, typename I1>
operator ()Kokkos::Impl::ViewOffset191 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0,
192 I1 const& i1) const {
193 auto tile_offset =
194 (outer_pattern == (Kokkos::Iterate::Left))
195 ? (((i0 >> SHIFT_0) + m_tile_N0 * ((i1 >> SHIFT_1))) << SHIFT_2T)
196 : (((m_tile_N1 * (i0 >> SHIFT_0) + (i1 >> SHIFT_1))) << SHIFT_2T);
197 // ( num_tiles[1] * ti0 + ti1 ) * FTD
198
199 auto local_offset = (inner_pattern == (Kokkos::Iterate::Left))
200 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0))
201 : (((i0 & MASK_0) << SHIFT_1) + (i1 & MASK_1));
202 // ( tile_dim[1] * li0 + li1 )
203
204 #if DEBUG_OUTPUT_CHECK
205 std::cout << "Am I Outer Left? "
206 << (outer_pattern == (Kokkos::Iterate::Left)) << std::endl;
207 std::cout << "Am I Inner Left? "
208 << (inner_pattern == (Kokkos::Iterate::Left)) << std::endl;
209 std::cout << "i0 = " << i0 << " i1 = " << i1
210 << "\ntilei0 = " << (i0 >> SHIFT_0)
211 << " tilei1 = " << (i1 >> SHIFT_1)
212 << "locali0 = " << (i0 & MASK_0)
213 << "\nlocali1 = " << (i1 & MASK_1) << std::endl;
214 #endif
215
216 return tile_offset + local_offset;
217 }
218
219 // Rank 3
220 template <typename I0, typename I1, typename I2>
operator ()Kokkos::Impl::ViewOffset221 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
222 I2 const& i2) const {
223 auto tile_offset =
224 (outer_pattern == Kokkos::Iterate::Left)
225 ? (((i0 >> SHIFT_0) +
226 m_tile_N0 * ((i1 >> SHIFT_1) + m_tile_N1 * (i2 >> SHIFT_2)))
227 << SHIFT_3T)
228 : ((m_tile_N2 * (m_tile_N1 * (i0 >> SHIFT_0) + (i1 >> SHIFT_1)) +
229 (i2 >> SHIFT_2))
230 << SHIFT_3T);
231
232 auto local_offset = (inner_pattern == Kokkos::Iterate::Left)
233 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
234 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)))
235 : (((i0 & MASK_0) << (SHIFT_2 + SHIFT_1)) +
236 ((i1 & MASK_1) << (SHIFT_2)) + (i2 & MASK_2));
237
238 #if DEBUG_OUTPUT_CHECK
239 std::cout << "Am I Outer Left? "
240 << (outer_pattern == (Kokkos::Iterate::Left)) << std::endl;
241 std::cout << "Am I Inner Left? "
242 << (inner_pattern == (Kokkos::Iterate::Left)) << std::endl;
243 std::cout << "i0 = " << i0 << " i1 = " << i1 << " i2 = " << i2
244 << "\ntilei0 = " << (i0 >> SHIFT_0)
245 << " tilei1 = " << (i1 >> SHIFT_1)
246 << " tilei2 = " << (i2 >> SHIFT_2)
247 << "\nlocali0 = " << (i0 & MASK_0)
248 << "locali1 = " << (i1 & MASK_1) << "locali2 = " << (i2 & MASK_2)
249 << std::endl;
250 #endif
251
252 return tile_offset + local_offset;
253 }
254
255 // Rank 4
256 template <typename I0, typename I1, typename I2, typename I3>
operator ()Kokkos::Impl::ViewOffset257 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
258 I2 const& i2,
259 I3 const& i3) const {
260 auto tile_offset =
261 (outer_pattern == Kokkos::Iterate::Left)
262 ? (((i0 >> SHIFT_0) +
263 m_tile_N0 * ((i1 >> SHIFT_1) +
264 m_tile_N1 * ((i2 >> SHIFT_2) +
265 m_tile_N2 * (i3 >> SHIFT_3))))
266 << SHIFT_4T)
267 : ((m_tile_N3 * (m_tile_N2 * (m_tile_N1 * (i0 >> SHIFT_0) +
268 (i1 >> SHIFT_1)) +
269 (i2 >> SHIFT_2)) +
270 (i3 >> SHIFT_3))
271 << SHIFT_4T);
272
273 auto local_offset =
274 (inner_pattern == Kokkos::Iterate::Left)
275 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
276 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)) +
277 ((i3 & MASK_3) << (SHIFT_0 + SHIFT_1 + SHIFT_2)))
278 : (((i0 & MASK_0) << (SHIFT_3 + SHIFT_2 + SHIFT_1)) +
279 ((i1 & MASK_1) << (SHIFT_3 + SHIFT_2)) +
280 ((i2 & MASK_2) << (SHIFT_3)) + (i3 & MASK_3));
281
282 return tile_offset + local_offset;
283 }
284
285 // Rank 5
286 template <typename I0, typename I1, typename I2, typename I3, typename I4>
operator ()Kokkos::Impl::ViewOffset287 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
288 I2 const& i2, I3 const& i3,
289 I4 const& i4) const {
290 auto tile_offset =
291 (outer_pattern == Kokkos::Iterate::Left)
292 ? (((i0 >> SHIFT_0) +
293 m_tile_N0 *
294 ((i1 >> SHIFT_1) +
295 m_tile_N1 * ((i2 >> SHIFT_2) +
296 m_tile_N2 * ((i3 >> SHIFT_3) +
297 m_tile_N3 * (i4 >> SHIFT_4)))))
298 << SHIFT_5T)
299 : ((m_tile_N4 *
300 (m_tile_N3 * (m_tile_N2 * (m_tile_N1 * (i0 >> SHIFT_0) +
301 (i1 >> SHIFT_1)) +
302 (i2 >> SHIFT_2)) +
303 (i3 >> SHIFT_3)) +
304 (i4 >> SHIFT_4))
305 << SHIFT_5T);
306
307 auto local_offset =
308 (inner_pattern == Kokkos::Iterate::Left)
309 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
310 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)) +
311 ((i3 & MASK_3) << (SHIFT_0 + SHIFT_1 + SHIFT_2)) +
312 ((i4 & MASK_4) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3)))
313 : (((i0 & MASK_0) << (SHIFT_4 + SHIFT_3 + SHIFT_2 + SHIFT_1)) +
314 ((i1 & MASK_1) << (SHIFT_4 + SHIFT_3 + SHIFT_2)) +
315 ((i2 & MASK_2) << (SHIFT_4 + SHIFT_3)) +
316 ((i3 & MASK_3) << (SHIFT_4)) + (i4 & MASK_4));
317
318 return tile_offset + local_offset;
319 }
320
321 // Rank 6
322 template <typename I0, typename I1, typename I2, typename I3, typename I4,
323 typename I5>
operator ()Kokkos::Impl::ViewOffset324 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
325 I2 const& i2, I3 const& i3,
326 I4 const& i4,
327 I5 const& i5) const {
328 auto tile_offset =
329 (outer_pattern == Kokkos::Iterate::Left)
330 ? (((i0 >> SHIFT_0) +
331 m_tile_N0 *
332 ((i1 >> SHIFT_1) +
333 m_tile_N1 *
334 ((i2 >> SHIFT_2) +
335 m_tile_N2 *
336 ((i3 >> SHIFT_3) +
337 m_tile_N3 * ((i4 >> SHIFT_4) +
338 m_tile_N4 * (i5 >> SHIFT_5))))))
339 << SHIFT_6T)
340 : ((m_tile_N5 *
341 (m_tile_N4 *
342 (m_tile_N3 *
343 (m_tile_N2 * (m_tile_N1 * (i0 >> SHIFT_0) +
344 (i1 >> SHIFT_1)) +
345 (i2 >> SHIFT_2)) +
346 (i3 >> SHIFT_3)) +
347 (i4 >> SHIFT_4)) +
348 (i5 >> SHIFT_5))
349 << SHIFT_6T);
350
351 auto local_offset =
352 (inner_pattern == Kokkos::Iterate::Left)
353 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
354 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)) +
355 ((i3 & MASK_3) << (SHIFT_0 + SHIFT_1 + SHIFT_2)) +
356 ((i4 & MASK_4) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3)) +
357 ((i5 & MASK_5)
358 << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4)))
359 : (((i0 & MASK_0)
360 << (SHIFT_5 + SHIFT_4 + SHIFT_3 + SHIFT_2 + SHIFT_1)) +
361 ((i1 & MASK_1) << (SHIFT_5 + SHIFT_4 + SHIFT_3 + SHIFT_2)) +
362 ((i2 & MASK_2) << (SHIFT_5 + SHIFT_4 + SHIFT_3)) +
363 ((i3 & MASK_3) << (SHIFT_5 + SHIFT_4)) +
364 ((i4 & MASK_4) << (SHIFT_5)) + (i5 & MASK_5));
365
366 return tile_offset + local_offset;
367 }
368
369 // Rank 7
370 template <typename I0, typename I1, typename I2, typename I3, typename I4,
371 typename I5, typename I6>
operator ()Kokkos::Impl::ViewOffset372 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
373 I2 const& i2, I3 const& i3,
374 I4 const& i4, I5 const& i5,
375 I6 const& i6) const {
376 auto tile_offset =
377 (outer_pattern == Kokkos::Iterate::Left)
378 ? (((i0 >> SHIFT_0) +
379 m_tile_N0 *
380 ((i1 >> SHIFT_1) +
381 m_tile_N1 *
382 ((i2 >> SHIFT_2) +
383 m_tile_N2 *
384 ((i3 >> SHIFT_3) +
385 m_tile_N3 *
386 ((i4 >> SHIFT_4) +
387 m_tile_N4 *
388 ((i5 >> SHIFT_5) +
389 m_tile_N5 * (i6 >> SHIFT_6)))))))
390 << SHIFT_7T)
391 : ((m_tile_N6 *
392 (m_tile_N5 *
393 (m_tile_N4 *
394 (m_tile_N3 *
395 (m_tile_N2 * (m_tile_N1 * (i0 >> SHIFT_0) +
396 (i1 >> SHIFT_1)) +
397 (i2 >> SHIFT_2)) +
398 (i3 >> SHIFT_3)) +
399 (i4 >> SHIFT_4)) +
400 (i5 >> SHIFT_5)) +
401 (i6 >> SHIFT_6))
402 << SHIFT_7T);
403
404 auto local_offset =
405 (inner_pattern == Kokkos::Iterate::Left)
406 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
407 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)) +
408 ((i3 & MASK_3) << (SHIFT_0 + SHIFT_1 + SHIFT_2)) +
409 ((i4 & MASK_4) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3)) +
410 ((i5 & MASK_5)
411 << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4)) +
412 ((i6 & MASK_6)
413 << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4 + SHIFT_5)))
414 : (((i0 & MASK_0) << (SHIFT_6 + SHIFT_5 + SHIFT_4 + SHIFT_3 +
415 SHIFT_2 + SHIFT_1)) +
416 ((i1 & MASK_1)
417 << (SHIFT_6 + SHIFT_5 + SHIFT_4 + SHIFT_3 + SHIFT_2)) +
418 ((i2 & MASK_2) << (SHIFT_6 + SHIFT_5 + SHIFT_4 + SHIFT_3)) +
419 ((i3 & MASK_3) << (SHIFT_6 + SHIFT_5 + SHIFT_4)) +
420 ((i4 & MASK_4) << (SHIFT_6 + SHIFT_5)) +
421 ((i5 & MASK_5) << (SHIFT_6)) + (i6 & MASK_6));
422
423 return tile_offset + local_offset;
424 }
425
426 // Rank 8
427 template <typename I0, typename I1, typename I2, typename I3, typename I4,
428 typename I5, typename I6, typename I7>
operator ()Kokkos::Impl::ViewOffset429 KOKKOS_INLINE_FUNCTION size_type operator()(I0 const& i0, I1 const& i1,
430 I2 const& i2, I3 const& i3,
431 I4 const& i4, I5 const& i5,
432 I6 const& i6,
433 I7 const& i7) const {
434 auto tile_offset =
435 (outer_pattern == Kokkos::Iterate::Left)
436 ? (((i0 >> SHIFT_0) +
437 m_tile_N0 *
438 ((i1 >> SHIFT_1) +
439 m_tile_N1 *
440 ((i2 >> SHIFT_2) +
441 m_tile_N2 *
442 ((i3 >> SHIFT_3) +
443 m_tile_N3 *
444 ((i4 >> SHIFT_4) +
445 m_tile_N4 *
446 ((i5 >> SHIFT_5) +
447 m_tile_N5 *
448 ((i6 >> SHIFT_6) +
449 m_tile_N6 * (i7 >> SHIFT_7))))))))
450 << SHIFT_8T)
451 : ((m_tile_N7 *
452 (m_tile_N6 *
453 (m_tile_N5 *
454 (m_tile_N4 *
455 (m_tile_N3 *
456 (m_tile_N2 *
457 (m_tile_N1 * (i0 >> SHIFT_0) +
458 (i1 >> SHIFT_1)) +
459 (i2 >> SHIFT_2)) +
460 (i3 >> SHIFT_3)) +
461 (i4 >> SHIFT_4)) +
462 (i5 >> SHIFT_5)) +
463 (i6 >> SHIFT_6)) +
464 (i7 >> SHIFT_7))
465 << SHIFT_8T);
466
467 auto local_offset =
468 (inner_pattern == Kokkos::Iterate::Left)
469 ? ((i0 & MASK_0) + ((i1 & MASK_1) << SHIFT_0) +
470 ((i2 & MASK_2) << (SHIFT_0 + SHIFT_1)) +
471 ((i3 & MASK_3) << (SHIFT_0 + SHIFT_1 + SHIFT_2)) +
472 ((i4 & MASK_4) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3)) +
473 ((i5 & MASK_5)
474 << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 + SHIFT_4)) +
475 ((i6 & MASK_6) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 +
476 SHIFT_4 + SHIFT_5)) +
477 ((i7 & MASK_7) << (SHIFT_0 + SHIFT_1 + SHIFT_2 + SHIFT_3 +
478 SHIFT_4 + SHIFT_5 + SHIFT_6)))
479 : (((i0 & MASK_0) << (SHIFT_7 + SHIFT_6 + SHIFT_5 + SHIFT_4 +
480 SHIFT_3 + SHIFT_2 + SHIFT_1)) +
481 ((i1 & MASK_1) << (SHIFT_7 + SHIFT_6 + SHIFT_5 + SHIFT_4 +
482 SHIFT_3 + SHIFT_2)) +
483 ((i2 & MASK_2)
484 << (SHIFT_7 + SHIFT_6 + SHIFT_5 + SHIFT_4 + SHIFT_3)) +
485 ((i3 & MASK_3) << (SHIFT_7 + SHIFT_6 + SHIFT_5 + SHIFT_4)) +
486 ((i4 & MASK_4) << (SHIFT_7 + SHIFT_6 + SHIFT_5)) +
487 ((i5 & MASK_5) << (SHIFT_7 + SHIFT_6)) +
488 ((i6 & MASK_6) << (SHIFT_7)) + (i7 & MASK_7));
489
490 return tile_offset + local_offset;
491 }
492
493 //----------------------------------------
494
layoutKokkos::Impl::ViewOffset495 KOKKOS_INLINE_FUNCTION constexpr array_layout layout() const {
496 return array_layout(m_dim.N0, m_dim.N1, m_dim.N2, m_dim.N2, m_dim.N3,
497 m_dim.N4, m_dim.N5, m_dim.N6, m_dim.N7);
498 }
499
dimension_0Kokkos::Impl::ViewOffset500 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_0() const {
501 return m_dim.N0;
502 }
dimension_1Kokkos::Impl::ViewOffset503 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_1() const {
504 return m_dim.N1;
505 }
dimension_2Kokkos::Impl::ViewOffset506 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_2() const {
507 return m_dim.N2;
508 }
dimension_3Kokkos::Impl::ViewOffset509 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_3() const {
510 return m_dim.N3;
511 }
dimension_4Kokkos::Impl::ViewOffset512 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_4() const {
513 return m_dim.N4;
514 }
dimension_5Kokkos::Impl::ViewOffset515 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_5() const {
516 return m_dim.N5;
517 }
dimension_6Kokkos::Impl::ViewOffset518 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_6() const {
519 return m_dim.N6;
520 }
dimension_7Kokkos::Impl::ViewOffset521 KOKKOS_INLINE_FUNCTION constexpr size_type dimension_7() const {
522 return m_dim.N7;
523 }
524
sizeKokkos::Impl::ViewOffset525 KOKKOS_INLINE_FUNCTION constexpr size_type size() const {
526 return m_dim.N0 * m_dim.N1 * m_dim.N2 * m_dim.N3 * m_dim.N4 * m_dim.N5 *
527 m_dim.N6 * m_dim.N7;
528 }
529
530 // Strides are meaningless due to irregularity
stride_0Kokkos::Impl::ViewOffset531 KOKKOS_INLINE_FUNCTION constexpr size_type stride_0() const { return 0; }
stride_1Kokkos::Impl::ViewOffset532 KOKKOS_INLINE_FUNCTION constexpr size_type stride_1() const { return 0; }
stride_2Kokkos::Impl::ViewOffset533 KOKKOS_INLINE_FUNCTION constexpr size_type stride_2() const { return 0; }
stride_3Kokkos::Impl::ViewOffset534 KOKKOS_INLINE_FUNCTION constexpr size_type stride_3() const { return 0; }
stride_4Kokkos::Impl::ViewOffset535 KOKKOS_INLINE_FUNCTION constexpr size_type stride_4() const { return 0; }
stride_5Kokkos::Impl::ViewOffset536 KOKKOS_INLINE_FUNCTION constexpr size_type stride_5() const { return 0; }
stride_6Kokkos::Impl::ViewOffset537 KOKKOS_INLINE_FUNCTION constexpr size_type stride_6() const { return 0; }
stride_7Kokkos::Impl::ViewOffset538 KOKKOS_INLINE_FUNCTION constexpr size_type stride_7() const { return 0; }
539
540 // Stride with [ rank ] value is the total length
541 template <typename iType>
strideKokkos::Impl::ViewOffset542 KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
543 s[0] = 0;
544 if (0 < dimension_type::rank) {
545 s[1] = 0;
546 }
547 if (1 < dimension_type::rank) {
548 s[2] = 0;
549 }
550 if (2 < dimension_type::rank) {
551 s[3] = 0;
552 }
553 if (3 < dimension_type::rank) {
554 s[4] = 0;
555 }
556 if (4 < dimension_type::rank) {
557 s[5] = 0;
558 }
559 if (5 < dimension_type::rank) {
560 s[6] = 0;
561 }
562 if (6 < dimension_type::rank) {
563 s[7] = 0;
564 }
565 if (7 < dimension_type::rank) {
566 s[8] = 0;
567 }
568 }
569
spanKokkos::Impl::ViewOffset570 KOKKOS_INLINE_FUNCTION constexpr size_type span() const {
571 // Rank2: ( NumTile0 * ( NumTile1 ) ) * TileSize, etc
572 return (VORank == 2)
573 ? (m_tile_N0 * m_tile_N1) << SHIFT_2T
574 : (VORank == 3)
575 ? (m_tile_N0 * m_tile_N1 * m_tile_N2) << SHIFT_3T
576 : (VORank == 4)
577 ? (m_tile_N0 * m_tile_N1 * m_tile_N2 * m_tile_N3)
578 << SHIFT_4T
579 : (VORank == 5)
580 ? (m_tile_N0 * m_tile_N1 * m_tile_N2 *
581 m_tile_N3 * m_tile_N4)
582 << SHIFT_5T
583 : (VORank == 6)
584 ? (m_tile_N0 * m_tile_N1 * m_tile_N2 *
585 m_tile_N3 * m_tile_N4 * m_tile_N5)
586 << SHIFT_6T
587 : (VORank == 7)
588 ? (m_tile_N0 * m_tile_N1 *
589 m_tile_N2 * m_tile_N3 *
590 m_tile_N4 * m_tile_N5 *
591 m_tile_N6)
592 << SHIFT_7T
593 : (m_tile_N0 * m_tile_N1 *
594 m_tile_N2 * m_tile_N3 *
595 m_tile_N4 * m_tile_N5 *
596 m_tile_N6 * m_tile_N7)
597 << SHIFT_8T;
598 }
599
span_is_contiguousKokkos::Impl::ViewOffset600 KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
601 return true;
602 }
603
604 //----------------------------------------
605 #ifdef KOKKOS_IMPL_WINDOWS_CUDA
ViewOffsetKokkos::Impl::ViewOffset606 KOKKOS_FUNCTION ViewOffset() {}
ViewOffsetKokkos::Impl::ViewOffset607 KOKKOS_FUNCTION ViewOffset(const ViewOffset& src) {
608 m_dim = src.m_dim;
609 m_tile_N0 = src.m_tile_N0;
610 m_tile_N1 = src.m_tile_N1;
611 m_tile_N2 = src.m_tile_N2;
612 m_tile_N3 = src.m_tile_N3;
613 m_tile_N4 = src.m_tile_N4;
614 m_tile_N5 = src.m_tile_N5;
615 m_tile_N6 = src.m_tile_N6;
616 m_tile_N7 = src.m_tile_N7;
617 }
operator =Kokkos::Impl::ViewOffset618 KOKKOS_FUNCTION ViewOffset& operator=(const ViewOffset& src) {
619 m_dim = src.m_dim;
620 m_tile_N0 = src.m_tile_N0;
621 m_tile_N1 = src.m_tile_N1;
622 m_tile_N2 = src.m_tile_N2;
623 m_tile_N3 = src.m_tile_N3;
624 m_tile_N4 = src.m_tile_N4;
625 m_tile_N5 = src.m_tile_N5;
626 m_tile_N6 = src.m_tile_N6;
627 m_tile_N7 = src.m_tile_N7;
628 return *this;
629 }
630 #else
631 KOKKOS_DEFAULTED_FUNCTION ~ViewOffset() = default;
632 KOKKOS_DEFAULTED_FUNCTION ViewOffset() = default;
633 KOKKOS_DEFAULTED_FUNCTION ViewOffset(const ViewOffset&) = default;
634 KOKKOS_DEFAULTED_FUNCTION ViewOffset& operator=(const ViewOffset&) = default;
635 #endif
636
637 template <unsigned TrivialScalarSize>
ViewOffsetKokkos::Impl::ViewOffset638 KOKKOS_INLINE_FUNCTION constexpr ViewOffset(
639 std::integral_constant<unsigned, TrivialScalarSize> const&,
640 array_layout const arg_layout)
641 : m_dim(arg_layout.dimension[0], arg_layout.dimension[1],
642 arg_layout.dimension[2], arg_layout.dimension[3],
643 arg_layout.dimension[4], arg_layout.dimension[5],
644 arg_layout.dimension[6], arg_layout.dimension[7]),
645 m_tile_N0((arg_layout.dimension[0] + MASK_0) >>
646 SHIFT_0 /* number of tiles in first dimension */),
647 m_tile_N1((arg_layout.dimension[1] + MASK_1) >> SHIFT_1),
648 m_tile_N2((VORank > 2) ? (arg_layout.dimension[2] + MASK_2) >> SHIFT_2
649 : 0),
650 m_tile_N3((VORank > 3) ? (arg_layout.dimension[3] + MASK_3) >> SHIFT_3
651 : 0),
652 m_tile_N4((VORank > 4) ? (arg_layout.dimension[4] + MASK_4) >> SHIFT_4
653 : 0),
654 m_tile_N5((VORank > 5) ? (arg_layout.dimension[5] + MASK_5) >> SHIFT_5
655 : 0),
656 m_tile_N6((VORank > 6) ? (arg_layout.dimension[6] + MASK_6) >> SHIFT_6
657 : 0),
658 m_tile_N7((VORank > 7) ? (arg_layout.dimension[7] + MASK_7) >> SHIFT_7
659 : 0) {}
660 };
661
662 // FIXME Remove the out-of-class definitions when we require C++17
663 #define KOKKOS_ITERATE_VIEW_OFFSET_ENABLE \
664 typename std::enable_if<((Dimension::rank <= 8) && (Dimension::rank >= 2) && \
665 is_array_layout<Layout>::value && \
666 is_array_layout_tiled<Layout>::value)>::type
667 template <class Dimension, class Layout>
668 constexpr Kokkos::Iterate ViewOffset<
669 Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::outer_pattern;
670 template <class Dimension, class Layout>
671 constexpr Kokkos::Iterate ViewOffset<
672 Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::inner_pattern;
673 template <class Dimension, class Layout>
674 constexpr int
675 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::VORank;
676 template <class Dimension, class Layout>
677 constexpr unsigned
678 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_0;
679 template <class Dimension, class Layout>
680 constexpr unsigned
681 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_1;
682 template <class Dimension, class Layout>
683 constexpr unsigned
684 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_2;
685 template <class Dimension, class Layout>
686 constexpr unsigned
687 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_3;
688 template <class Dimension, class Layout>
689 constexpr unsigned
690 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_4;
691 template <class Dimension, class Layout>
692 constexpr unsigned
693 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_5;
694 template <class Dimension, class Layout>
695 constexpr unsigned
696 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_6;
697 template <class Dimension, class Layout>
698 constexpr unsigned
699 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_7;
700 template <class Dimension, class Layout>
701 constexpr int
702 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_0;
703 template <class Dimension, class Layout>
704 constexpr int
705 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_1;
706 template <class Dimension, class Layout>
707 constexpr int
708 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_2;
709 template <class Dimension, class Layout>
710 constexpr int
711 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_3;
712 template <class Dimension, class Layout>
713 constexpr int
714 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_4;
715 template <class Dimension, class Layout>
716 constexpr int
717 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_5;
718 template <class Dimension, class Layout>
719 constexpr int
720 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_6;
721 template <class Dimension, class Layout>
722 constexpr int
723 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::MASK_7;
724 template <class Dimension, class Layout>
725 constexpr unsigned
726 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_2T;
727 template <class Dimension, class Layout>
728 constexpr unsigned
729 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_3T;
730 template <class Dimension, class Layout>
731 constexpr unsigned
732 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_4T;
733 template <class Dimension, class Layout>
734 constexpr unsigned
735 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_5T;
736 template <class Dimension, class Layout>
737 constexpr unsigned
738 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_6T;
739 template <class Dimension, class Layout>
740 constexpr unsigned
741 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_7T;
742 template <class Dimension, class Layout>
743 constexpr unsigned
744 ViewOffset<Dimension, Layout, KOKKOS_ITERATE_VIEW_OFFSET_ENABLE>::SHIFT_8T;
745 #undef KOKKOS_ITERATE_VIEW_OFFSET_ENABLE
746
747 //----------------------------------------
748
749 // ViewMapping assign method needed in order to return a 'subview' tile as a
750 // proper View The outer iteration pattern determines the mapping of the pointer
751 // offset to the beginning of requested tile The inner iteration pattern is
752 // needed for the layout of the tile's View to be returned Rank 2
753 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
754 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
755 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
756 typename iType1>
757 class ViewMapping<
758 typename std::enable_if<(N2 == 0 && N3 == 0 && N4 == 0 && N5 == 0 &&
759 N6 == 0 && N7 == 0)>::type // void
760 ,
761 Kokkos::ViewTraits<
762 T**,
763 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4,
764 N5, N6, N7, true>,
765 P...>,
766 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
767 N6, N7, true>,
768 iType0, iType1> {
769 public:
770 using src_layout =
771 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
772 N6, N7, true>;
773 using src_traits = Kokkos::ViewTraits<T**, src_layout, P...>;
774
775 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
776 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
777 using array_layout =
778 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
779 Kokkos::LayoutRight>::type;
780 using traits = Kokkos::ViewTraits<T[N0][N1], array_layout, P...>;
781 using type = Kokkos::View<T[N0][N1], array_layout, P...>;
782
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1)783 KOKKOS_INLINE_FUNCTION static void assign(
784 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
785 const src_layout&, const iType0 i_tile0, const iType1 i_tile1) {
786 using dst_map_type = ViewMapping<traits, void>;
787 using src_map_type = ViewMapping<src_traits, void>;
788 using dst_handle_type = typename dst_map_type::handle_type;
789 using dst_offset_type = typename dst_map_type::offset_type;
790 using src_offset_type = typename src_map_type::offset_type;
791
792 dst = dst_map_type(
793 dst_handle_type(
794 src.m_impl_handle +
795 (is_outer_left ? ((i_tile0 + src.m_impl_offset.m_tile_N0 * i_tile1)
796 << src_offset_type::SHIFT_2T)
797 : ((src.m_impl_offset.m_tile_N1 * i_tile0 + i_tile1)
798 << src_offset_type::SHIFT_2T)) // offset to start
799 // of the tile
800 ),
801 dst_offset_type());
802 }
803 };
804
805 // Rank 3
806 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
807 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
808 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
809 typename iType1, typename iType2>
810 class ViewMapping<typename std::enable_if<(N3 == 0 && N4 == 0 && N5 == 0 &&
811 N6 == 0 && N7 == 0)>::type // void
812 ,
813 Kokkos::ViewTraits<
814 T***,
815 Kokkos::Experimental::LayoutTiled<
816 OuterP, InnerP, N0, N1, N2, N3, N4, N5, N6, N7, true>,
817 P...>,
818 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
819 N3, N4, N5, N6, N7, true>,
820 iType0, iType1, iType2> {
821 public:
822 using src_layout =
823 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
824 N6, N7, true>;
825 using src_traits = Kokkos::ViewTraits<T***, src_layout, P...>;
826
827 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
828 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
829 using array_layout =
830 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
831 Kokkos::LayoutRight>::type;
832 using traits = Kokkos::ViewTraits<T[N0][N1][N2], array_layout, P...>;
833 using type = Kokkos::View<T[N0][N1][N2], array_layout, P...>;
834
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2)835 KOKKOS_INLINE_FUNCTION static void assign(
836 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
837 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
838 const iType2 i_tile2) {
839 using dst_map_type = ViewMapping<traits, void>;
840 using src_map_type = ViewMapping<src_traits, void>;
841 using dst_handle_type = typename dst_map_type::handle_type;
842 using dst_offset_type = typename dst_map_type::offset_type;
843 using src_offset_type = typename src_map_type::offset_type;
844
845 dst = dst_map_type(
846 dst_handle_type(
847 src.m_impl_handle +
848 (is_outer_left
849 ? ((i_tile0 +
850 src.m_impl_offset.m_tile_N0 *
851 (i_tile1 + src.m_impl_offset.m_tile_N1 * i_tile2))
852 << src_offset_type::SHIFT_3T)
853 : ((src.m_impl_offset.m_tile_N2 *
854 (src.m_impl_offset.m_tile_N1 * i_tile0 + i_tile1) +
855 i_tile2)
856 << src_offset_type::SHIFT_3T))) // offset to start of the
857 // tile
858 ,
859 dst_offset_type());
860 }
861 };
862
863 // Rank 4
864 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
865 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
866 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
867 typename iType1, typename iType2, typename iType3>
868 class ViewMapping<typename std::enable_if<(N4 == 0 && N5 == 0 && N6 == 0 &&
869 N7 == 0)>::type // void
870 ,
871 Kokkos::ViewTraits<
872 T****,
873 Kokkos::Experimental::LayoutTiled<
874 OuterP, InnerP, N0, N1, N2, N3, N4, N5, N6, N7, true>,
875 P...>,
876 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
877 N3, N4, N5, N6, N7, true>,
878 iType0, iType1, iType2, iType3> {
879 public:
880 using src_layout =
881 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
882 N6, N7, true>;
883 using src_traits = Kokkos::ViewTraits<T****, src_layout, P...>;
884
885 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
886 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
887 using array_layout =
888 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
889 Kokkos::LayoutRight>::type;
890 using traits = Kokkos::ViewTraits<T[N0][N1][N2][N3], array_layout, P...>;
891 using type = Kokkos::View<T[N0][N1][N2][N3], array_layout, P...>;
892
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2,const iType3 i_tile3)893 KOKKOS_INLINE_FUNCTION static void assign(
894 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
895 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
896 const iType2 i_tile2, const iType3 i_tile3) {
897 using dst_map_type = ViewMapping<traits, void>;
898 using src_map_type = ViewMapping<src_traits, void>;
899 using dst_handle_type = typename dst_map_type::handle_type;
900 using dst_offset_type = typename dst_map_type::offset_type;
901 using src_offset_type = typename src_map_type::offset_type;
902
903 dst = dst_map_type(
904 dst_handle_type(
905 src.m_impl_handle +
906 (is_outer_left
907 ? ((i_tile0 +
908 src.m_impl_offset.m_tile_N0 *
909 (i_tile1 + src.m_impl_offset.m_tile_N1 *
910 (i_tile2 + src.m_impl_offset.m_tile_N2 *
911 i_tile3)))
912 << src_offset_type::SHIFT_4T)
913 : ((src.m_impl_offset.m_tile_N3 *
914 (src.m_impl_offset.m_tile_N2 *
915 (src.m_impl_offset.m_tile_N1 * i_tile0 +
916 i_tile1) +
917 i_tile2) +
918 i_tile3)
919 << src_offset_type::SHIFT_4T))) // offset to start of the
920 // tile
921 ,
922 dst_offset_type());
923 }
924 };
925
926 // Rank 5
927 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
928 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
929 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
930 typename iType1, typename iType2, typename iType3, typename iType4>
931 class ViewMapping<
932 typename std::enable_if<(N5 == 0 && N6 == 0 && N7 == 0)>::type // void
933 ,
934 Kokkos::ViewTraits<
935 T*****,
936 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4,
937 N5, N6, N7, true>,
938 P...>,
939 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
940 N6, N7, true>,
941 iType0, iType1, iType2, iType3, iType4> {
942 public:
943 using src_layout =
944 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
945 N6, N7, true>;
946 using src_traits = Kokkos::ViewTraits<T*****, src_layout, P...>;
947
948 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
949 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
950 using array_layout =
951 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
952 Kokkos::LayoutRight>::type;
953 using traits = Kokkos::ViewTraits<T[N0][N1][N2][N3][N4], array_layout, P...>;
954 using type = Kokkos::View<T[N0][N1][N2][N3][N4], array_layout, P...>;
955
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2,const iType3 i_tile3,const iType4 i_tile4)956 KOKKOS_INLINE_FUNCTION static void assign(
957 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
958 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
959 const iType2 i_tile2, const iType3 i_tile3, const iType4 i_tile4) {
960 using dst_map_type = ViewMapping<traits, void>;
961 using src_map_type = ViewMapping<src_traits, void>;
962 using dst_handle_type = typename dst_map_type::handle_type;
963 using dst_offset_type = typename dst_map_type::offset_type;
964 using src_offset_type = typename src_map_type::offset_type;
965
966 dst = dst_map_type(
967 dst_handle_type(
968 src.m_impl_handle +
969 (is_outer_left
970 ? ((i_tile0 +
971 src.m_impl_offset.m_tile_N0 *
972 (i_tile1 +
973 src.m_impl_offset.m_tile_N1 *
974 (i_tile2 +
975 src.m_impl_offset.m_tile_N2 *
976 (i_tile3 +
977 src.m_impl_offset.m_tile_N3 * i_tile4))))
978 << src_offset_type::SHIFT_5T)
979 : ((src.m_impl_offset.m_tile_N4 *
980 (src.m_impl_offset.m_tile_N3 *
981 (src.m_impl_offset.m_tile_N2 *
982 (src.m_impl_offset.m_tile_N1 * i_tile0 +
983 i_tile1) +
984 i_tile2) +
985 i_tile3) +
986 i_tile4)
987 << src_offset_type::SHIFT_5T))) // offset to start of the
988 // tile
989 ,
990 dst_offset_type());
991 }
992 };
993
994 // Rank 6
995 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
996 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
997 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
998 typename iType1, typename iType2, typename iType3, typename iType4,
999 typename iType5>
1000 class ViewMapping<typename std::enable_if<(N6 == 0 && N7 == 0)>::type // void
1001 ,
1002 Kokkos::ViewTraits<
1003 T******,
1004 Kokkos::Experimental::LayoutTiled<
1005 OuterP, InnerP, N0, N1, N2, N3, N4, N5, N6, N7, true>,
1006 P...>,
1007 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1008 N3, N4, N5, N6, N7, true>,
1009 iType0, iType1, iType2, iType3, iType4, iType5> {
1010 public:
1011 using src_layout =
1012 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1013 N6, N7, true>;
1014 using src_traits = Kokkos::ViewTraits<T******, src_layout, P...>;
1015
1016 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
1017 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
1018 using array_layout =
1019 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
1020 Kokkos::LayoutRight>::type;
1021 using traits =
1022 Kokkos::ViewTraits<T[N0][N1][N2][N3][N4][N5], array_layout, P...>;
1023 using type = Kokkos::View<T[N0][N1][N2][N3][N4][N5], array_layout, P...>;
1024
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2,const iType3 i_tile3,const iType4 i_tile4,const iType5 i_tile5)1025 KOKKOS_INLINE_FUNCTION static void assign(
1026 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
1027 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
1028 const iType2 i_tile2, const iType3 i_tile3, const iType4 i_tile4,
1029 const iType5 i_tile5) {
1030 using dst_map_type = ViewMapping<traits, void>;
1031 using src_map_type = ViewMapping<src_traits, void>;
1032 using dst_handle_type = typename dst_map_type::handle_type;
1033 using dst_offset_type = typename dst_map_type::offset_type;
1034 using src_offset_type = typename src_map_type::offset_type;
1035
1036 dst = dst_map_type(
1037 dst_handle_type(
1038 src.m_impl_handle +
1039 (is_outer_left
1040 ? ((i_tile0 +
1041 src.m_impl_offset.m_tile_N0 *
1042 (i_tile1 +
1043 src.m_impl_offset.m_tile_N1 *
1044 (i_tile2 +
1045 src.m_impl_offset.m_tile_N2 *
1046 (i_tile3 +
1047 src.m_impl_offset.m_tile_N3 *
1048 (i_tile4 + src.m_impl_offset.m_tile_N4 *
1049 i_tile5)))))
1050 << src_offset_type::SHIFT_6T)
1051 : ((src.m_impl_offset.m_tile_N5 *
1052 (src.m_impl_offset.m_tile_N4 *
1053 (src.m_impl_offset.m_tile_N3 *
1054 (src.m_impl_offset.m_tile_N2 *
1055 (src.m_impl_offset.m_tile_N1 * i_tile0 +
1056 i_tile1) +
1057 i_tile2) +
1058 i_tile3) +
1059 i_tile4) +
1060 i_tile5)
1061 << src_offset_type::SHIFT_6T))) // offset to start of the
1062 // tile
1063 ,
1064 dst_offset_type());
1065 }
1066 };
1067
1068 // Rank 7
1069 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1070 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1071 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
1072 typename iType1, typename iType2, typename iType3, typename iType4,
1073 typename iType5, typename iType6>
1074 class ViewMapping<typename std::enable_if<(N7 == 0)>::type // void
1075 ,
1076 Kokkos::ViewTraits<
1077 T*******,
1078 Kokkos::Experimental::LayoutTiled<
1079 OuterP, InnerP, N0, N1, N2, N3, N4, N5, N6, N7, true>,
1080 P...>,
1081 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1082 N3, N4, N5, N6, N7, true>,
1083 iType0, iType1, iType2, iType3, iType4, iType5, iType6> {
1084 public:
1085 using src_layout =
1086 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1087 N6, N7, true>;
1088 using src_traits = Kokkos::ViewTraits<T*******, src_layout, P...>;
1089
1090 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
1091 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
1092 using array_layout =
1093 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
1094 Kokkos::LayoutRight>::type;
1095 using traits =
1096 Kokkos::ViewTraits<T[N0][N1][N2][N3][N4][N5][N6], array_layout, P...>;
1097 using type = Kokkos::View<T[N0][N1][N2][N3][N4][N5][N6], array_layout, P...>;
1098
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2,const iType3 i_tile3,const iType4 i_tile4,const iType5 i_tile5,const iType6 i_tile6)1099 KOKKOS_INLINE_FUNCTION static void assign(
1100 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
1101 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
1102 const iType2 i_tile2, const iType3 i_tile3, const iType4 i_tile4,
1103 const iType5 i_tile5, const iType6 i_tile6) {
1104 using dst_map_type = ViewMapping<traits, void>;
1105 using src_map_type = ViewMapping<src_traits, void>;
1106 using dst_handle_type = typename dst_map_type::handle_type;
1107 using dst_offset_type = typename dst_map_type::offset_type;
1108 using src_offset_type = typename src_map_type::offset_type;
1109
1110 dst = dst_map_type(
1111 dst_handle_type(
1112 src.m_impl_handle +
1113 (is_outer_left
1114 ? ((i_tile0 +
1115 src.m_impl_offset.m_tile_N0 *
1116 (i_tile1 +
1117 src.m_impl_offset.m_tile_N1 *
1118 (i_tile2 +
1119 src.m_impl_offset.m_tile_N2 *
1120 (i_tile3 +
1121 src.m_impl_offset.m_tile_N3 *
1122 (i_tile4 +
1123 src.m_impl_offset.m_tile_N4 *
1124 (i_tile5 +
1125 src.m_impl_offset.m_tile_N5 *
1126 i_tile6))))))
1127 << src_offset_type::SHIFT_7T)
1128 : ((src.m_impl_offset.m_tile_N6 *
1129 (src.m_impl_offset.m_tile_N5 *
1130 (src.m_impl_offset.m_tile_N4 *
1131 (src.m_impl_offset.m_tile_N3 *
1132 (src.m_impl_offset.m_tile_N2 *
1133 (src.m_impl_offset.m_tile_N1 *
1134 i_tile0 +
1135 i_tile1) +
1136 i_tile2) +
1137 i_tile3) +
1138 i_tile4) +
1139 i_tile5) +
1140 i_tile6)
1141 << src_offset_type::SHIFT_7T))) // offset to start of the
1142 // tile
1143 ,
1144 dst_offset_type());
1145 }
1146 };
1147
1148 // Rank 8
1149 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1150 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1151 unsigned N5, unsigned N6, unsigned N7, class... P, typename iType0,
1152 typename iType1, typename iType2, typename iType3, typename iType4,
1153 typename iType5, typename iType6, typename iType7>
1154 class ViewMapping<typename std::enable_if<(N0 != 0 && N1 != 0 && N2 != 0 &&
1155 N3 != 0 && N4 != 0 && N5 != 0 &&
1156 N6 != 0 && N7 != 0)>::type // void
1157 ,
1158 Kokkos::ViewTraits<
1159 T********,
1160 Kokkos::Experimental::LayoutTiled<
1161 OuterP, InnerP, N0, N1, N2, N3, N4, N5, N6, N7, true>,
1162 P...>,
1163 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1164 N3, N4, N5, N6, N7, true>,
1165 iType0, iType1, iType2, iType3, iType4, iType5, iType6,
1166 iType7> {
1167 public:
1168 using src_layout =
1169 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1170 N6, N7, true>;
1171 using src_traits = Kokkos::ViewTraits<T********, src_layout, P...>;
1172
1173 static constexpr bool is_outer_left = (OuterP == Kokkos::Iterate::Left);
1174 static constexpr bool is_inner_left = (InnerP == Kokkos::Iterate::Left);
1175 using array_layout =
1176 typename std::conditional<is_inner_left, Kokkos::LayoutLeft,
1177 Kokkos::LayoutRight>::type;
1178 using traits =
1179 Kokkos::ViewTraits<T[N0][N1][N2][N3][N4][N5][N6][N7], array_layout, P...>;
1180 using type =
1181 Kokkos::View<T[N0][N1][N2][N3][N4][N5][N6][N7], array_layout, P...>;
1182
assign(ViewMapping<traits,void> & dst,const ViewMapping<src_traits,void> & src,const src_layout &,const iType0 i_tile0,const iType1 i_tile1,const iType2 i_tile2,const iType3 i_tile3,const iType4 i_tile4,const iType5 i_tile5,const iType6 i_tile6,const iType7 i_tile7)1183 KOKKOS_INLINE_FUNCTION static void assign(
1184 ViewMapping<traits, void>& dst, const ViewMapping<src_traits, void>& src,
1185 const src_layout&, const iType0 i_tile0, const iType1 i_tile1,
1186 const iType2 i_tile2, const iType3 i_tile3, const iType4 i_tile4,
1187 const iType5 i_tile5, const iType6 i_tile6, const iType7 i_tile7) {
1188 using dst_map_type = ViewMapping<traits, void>;
1189 using src_map_type = ViewMapping<src_traits, void>;
1190 using dst_handle_type = typename dst_map_type::handle_type;
1191 using dst_offset_type = typename dst_map_type::offset_type;
1192 using src_offset_type = typename src_map_type::offset_type;
1193
1194 dst = dst_map_type(
1195 dst_handle_type(
1196 src.m_impl_handle +
1197 (is_outer_left
1198 ? ((i_tile0 +
1199 src.m_impl_offset.m_tile_N0 *
1200 (i_tile1 +
1201 src.m_impl_offset.m_tile_N1 *
1202 (i_tile2 +
1203 src.m_impl_offset.m_tile_N2 *
1204 (i_tile3 +
1205 src.m_impl_offset.m_tile_N3 *
1206 (i_tile4 +
1207 src.m_impl_offset.m_tile_N4 *
1208 (i_tile5 +
1209 src.m_impl_offset.m_tile_N5 *
1210 (i_tile6 +
1211 src.m_impl_offset.m_tile_N6 *
1212 i_tile7)))))))
1213 << src_offset_type::SHIFT_8T)
1214 : ((src.m_impl_offset.m_tile_N7 *
1215 (src.m_impl_offset.m_tile_N6 *
1216 (src.m_impl_offset.m_tile_N5 *
1217 (src.m_impl_offset.m_tile_N4 *
1218 (src.m_impl_offset.m_tile_N3 *
1219 (src.m_impl_offset.m_tile_N2 *
1220 (src.m_impl_offset.m_tile_N1 *
1221 i_tile0 +
1222 i_tile1) +
1223 i_tile2) +
1224 i_tile3) +
1225 i_tile4) +
1226 i_tile5) +
1227 i_tile6) +
1228 i_tile7)
1229 << src_offset_type::SHIFT_8T))) // offset to start of the
1230 // tile
1231 ,
1232 dst_offset_type());
1233 }
1234 };
1235
1236 } /* namespace Impl */
1237 } /* namespace Kokkos */
1238
1239 //----------------------------------------
1240
1241 namespace Kokkos {
1242
1243 // Rank 2
1244 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1245 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1246 unsigned N5, unsigned N6, unsigned N7, class... P>
1247 KOKKOS_INLINE_FUNCTION Kokkos::View<
1248 T[N0][N1],
1249 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1250 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1251 P...>
tile_subview(const Kokkos::View<T **,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1)1252 tile_subview(const Kokkos::View<
1253 T**,
1254 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1255 N3, N4, N5, N6, N7, true>,
1256 P...>& src,
1257 const size_t i_tile0, const size_t i_tile1) {
1258 // Force the specialized ViewMapping for extracting a tile
1259 // by using the first subview argument as the layout.
1260 using array_layout =
1261 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1262 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1263 using SrcLayout =
1264 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1265 N6, N7, true>;
1266
1267 return Kokkos::View<T[N0][N1], array_layout, P...>(src, SrcLayout(), i_tile0,
1268 i_tile1);
1269 }
1270
1271 // Rank 3
1272 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1273 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1274 unsigned N5, unsigned N6, unsigned N7, class... P>
1275 KOKKOS_INLINE_FUNCTION Kokkos::View<
1276 T[N0][N1][N2],
1277 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1278 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1279 P...>
tile_subview(const Kokkos::View<T ***,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2)1280 tile_subview(const Kokkos::View<
1281 T***,
1282 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1283 N3, N4, N5, N6, N7, true>,
1284 P...>& src,
1285 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2) {
1286 // Force the specialized ViewMapping for extracting a tile
1287 // by using the first subview argument as the layout.
1288 using array_layout =
1289 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1290 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1291 using SrcLayout =
1292 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1293 N6, N7, true>;
1294
1295 return Kokkos::View<T[N0][N1][N2], array_layout, P...>(
1296 src, SrcLayout(), i_tile0, i_tile1, i_tile2);
1297 }
1298
1299 // Rank 4
1300 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1301 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1302 unsigned N5, unsigned N6, unsigned N7, class... P>
1303 KOKKOS_INLINE_FUNCTION Kokkos::View<
1304 T[N0][N1][N2][N3],
1305 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1306 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1307 P...>
tile_subview(const Kokkos::View<T ****,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2,const size_t i_tile3)1308 tile_subview(const Kokkos::View<
1309 T****,
1310 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1311 N3, N4, N5, N6, N7, true>,
1312 P...>& src,
1313 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2,
1314 const size_t i_tile3) {
1315 // Force the specialized ViewMapping for extracting a tile
1316 // by using the first subview argument as the layout.
1317 using array_layout =
1318 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1319 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1320 using SrcLayout =
1321 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1322 N6, N7, true>;
1323
1324 return Kokkos::View<T[N0][N1][N2][N3], array_layout, P...>(
1325 src, SrcLayout(), i_tile0, i_tile1, i_tile2, i_tile3);
1326 }
1327
1328 // Rank 5
1329 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1330 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1331 unsigned N5, unsigned N6, unsigned N7, class... P>
1332 KOKKOS_INLINE_FUNCTION Kokkos::View<
1333 T[N0][N1][N2][N3][N4],
1334 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1335 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1336 P...>
tile_subview(const Kokkos::View<T *****,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2,const size_t i_tile3,const size_t i_tile4)1337 tile_subview(const Kokkos::View<
1338 T*****,
1339 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1340 N3, N4, N5, N6, N7, true>,
1341 P...>& src,
1342 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2,
1343 const size_t i_tile3, const size_t i_tile4) {
1344 // Force the specialized ViewMapping for extracting a tile
1345 // by using the first subview argument as the layout.
1346 using array_layout =
1347 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1348 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1349 using SrcLayout =
1350 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1351 N6, N7, true>;
1352
1353 return Kokkos::View<T[N0][N1][N2][N3][N4], array_layout, P...>(
1354 src, SrcLayout(), i_tile0, i_tile1, i_tile2, i_tile3, i_tile4);
1355 }
1356
1357 // Rank 6
1358 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1359 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1360 unsigned N5, unsigned N6, unsigned N7, class... P>
1361 KOKKOS_INLINE_FUNCTION Kokkos::View<
1362 T[N0][N1][N2][N3][N4][N5],
1363 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1364 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1365 P...>
tile_subview(const Kokkos::View<T ******,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2,const size_t i_tile3,const size_t i_tile4,const size_t i_tile5)1366 tile_subview(const Kokkos::View<
1367 T******,
1368 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1369 N3, N4, N5, N6, N7, true>,
1370 P...>& src,
1371 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2,
1372 const size_t i_tile3, const size_t i_tile4, const size_t i_tile5) {
1373 // Force the specialized ViewMapping for extracting a tile
1374 // by using the first subview argument as the layout.
1375 using array_layout =
1376 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1377 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1378 using SrcLayout =
1379 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1380 N6, N7, true>;
1381
1382 return Kokkos::View<T[N0][N1][N2][N3][N4][N5], array_layout, P...>(
1383 src, SrcLayout(), i_tile0, i_tile1, i_tile2, i_tile3, i_tile4, i_tile5);
1384 }
1385
1386 // Rank 7
1387 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1388 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1389 unsigned N5, unsigned N6, unsigned N7, class... P>
1390 KOKKOS_INLINE_FUNCTION Kokkos::View<
1391 T[N0][N1][N2][N3][N4][N5][N6],
1392 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1393 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1394 P...>
tile_subview(const Kokkos::View<T *******,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2,const size_t i_tile3,const size_t i_tile4,const size_t i_tile5,const size_t i_tile6)1395 tile_subview(const Kokkos::View<
1396 T*******,
1397 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1398 N3, N4, N5, N6, N7, true>,
1399 P...>& src,
1400 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2,
1401 const size_t i_tile3, const size_t i_tile4, const size_t i_tile5,
1402 const size_t i_tile6) {
1403 // Force the specialized ViewMapping for extracting a tile
1404 // by using the first subview argument as the layout.
1405 using array_layout =
1406 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1407 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1408 using SrcLayout =
1409 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1410 N6, N7, true>;
1411
1412 return Kokkos::View<T[N0][N1][N2][N3][N4][N5][N6], array_layout, P...>(
1413 src, SrcLayout(), i_tile0, i_tile1, i_tile2, i_tile3, i_tile4, i_tile5,
1414 i_tile6);
1415 }
1416
1417 // Rank 8
1418 template <typename T, Kokkos::Iterate OuterP, Kokkos::Iterate InnerP,
1419 unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
1420 unsigned N5, unsigned N6, unsigned N7, class... P>
1421 KOKKOS_INLINE_FUNCTION Kokkos::View<
1422 T[N0][N1][N2][N3][N4][N5][N6][N7],
1423 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1424 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type,
1425 P...>
tile_subview(const Kokkos::View<T ********,Kokkos::Experimental::LayoutTiled<OuterP,InnerP,N0,N1,N2,N3,N4,N5,N6,N7,true>,P...> & src,const size_t i_tile0,const size_t i_tile1,const size_t i_tile2,const size_t i_tile3,const size_t i_tile4,const size_t i_tile5,const size_t i_tile6,const size_t i_tile7)1426 tile_subview(const Kokkos::View<
1427 T********,
1428 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2,
1429 N3, N4, N5, N6, N7, true>,
1430 P...>& src,
1431 const size_t i_tile0, const size_t i_tile1, const size_t i_tile2,
1432 const size_t i_tile3, const size_t i_tile4, const size_t i_tile5,
1433 const size_t i_tile6, const size_t i_tile7) {
1434 // Force the specialized ViewMapping for extracting a tile
1435 // by using the first subview argument as the layout.
1436 using array_layout =
1437 typename std::conditional<(InnerP == Kokkos::Iterate::Left),
1438 Kokkos::LayoutLeft, Kokkos::LayoutRight>::type;
1439 using SrcLayout =
1440 Kokkos::Experimental::LayoutTiled<OuterP, InnerP, N0, N1, N2, N3, N4, N5,
1441 N6, N7, true>;
1442
1443 return Kokkos::View<T[N0][N1][N2][N3][N4][N5][N6][N7], array_layout, P...>(
1444 src, SrcLayout(), i_tile0, i_tile1, i_tile2, i_tile3, i_tile4, i_tile5,
1445 i_tile6, i_tile7);
1446 }
1447
1448 } /* namespace Kokkos */
1449 //----------------------------------------------------------------------------
1450 //----------------------------------------------------------------------------
1451
1452 #endif /* #ifndef KOKKOS_EXPERIENTAL_VIEWLAYOUTTILE_HPP */
1453