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