Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_CopyViews.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
19 static_assert(false,
20  "Including non-public Kokkos header files is not allowed.");
21 #endif
22 #ifndef KOKKOS_COPYVIEWS_HPP_
23 #define KOKKOS_COPYVIEWS_HPP_
24 #include <string>
25 #include <sstream>
26 #include <Kokkos_Parallel.hpp>
27 #include <KokkosExp_MDRangePolicy.hpp>
28 #include <Kokkos_Layout.hpp>
29 #include <impl/Kokkos_HostSpace_ZeroMemset.hpp>
30 
31 //----------------------------------------------------------------------------
32 //----------------------------------------------------------------------------
33 
34 namespace Kokkos {
35 
36 namespace Impl {
37 
38 template <class Layout>
39 struct ViewFillLayoutSelector {};
40 
41 template <>
42 struct ViewFillLayoutSelector<Kokkos::LayoutLeft> {
43  static const Kokkos::Iterate iterate = Kokkos::Iterate::Left;
44 };
45 
46 template <>
47 struct ViewFillLayoutSelector<Kokkos::LayoutRight> {
48  static const Kokkos::Iterate iterate = Kokkos::Iterate::Right;
49 };
50 
51 } // namespace Impl
52 } // namespace Kokkos
53 
54 namespace Kokkos {
55 namespace Impl {
56 
57 template <class ViewType, class Layout, class ExecSpace, typename iType>
58 struct ViewFill<ViewType, Layout, ExecSpace, 0, iType> {
59  using ST = typename ViewType::non_const_value_type;
60  ViewFill(const ViewType& a, const ST& val, const ExecSpace& space) {
61  Kokkos::Impl::DeepCopy<typename ViewType::memory_space, Kokkos::HostSpace,
62  ExecSpace>(space, a.data(), &val, sizeof(ST));
63  }
64 };
65 
66 template <class ViewType, class Layout, class ExecSpace, typename iType>
67 struct ViewFill<ViewType, Layout, ExecSpace, 1, iType> {
68  ViewType a;
69  typename ViewType::const_value_type val;
71 
72  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
73  const ExecSpace& space)
74  : a(a_), val(val_) {
75  Kokkos::parallel_for("Kokkos::ViewFill-1D",
76  policy_type(space, 0, a.extent(0)), *this);
77  }
78 
79  KOKKOS_INLINE_FUNCTION
80  void operator()(const iType& i) const { a(i) = val; };
81 };
82 
83 template <class ViewType, class Layout, class ExecSpace, typename iType>
84 struct ViewFill<ViewType, Layout, ExecSpace, 2, iType> {
85  ViewType a;
86  typename ViewType::const_value_type val;
87 
88  using iterate_type = Kokkos::Rank<2, ViewFillLayoutSelector<Layout>::iterate,
89  ViewFillLayoutSelector<Layout>::iterate>;
90  using policy_type =
91  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
92 
93  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
94  const ExecSpace& space)
95  : a(a_), val(val_) {
96  Kokkos::parallel_for("Kokkos::ViewFill-2D",
97  policy_type(space, {0, 0}, {a.extent(0), a.extent(1)}),
98  *this);
99  }
100 
101  KOKKOS_INLINE_FUNCTION
102  void operator()(const iType& i0, const iType& i1) const { a(i0, i1) = val; };
103 };
104 
105 template <class ViewType, class Layout, class ExecSpace, typename iType>
106 struct ViewFill<ViewType, Layout, ExecSpace, 3, iType> {
107  ViewType a;
108  typename ViewType::const_value_type val;
109 
110  using iterate_type = Kokkos::Rank<3, ViewFillLayoutSelector<Layout>::iterate,
111  ViewFillLayoutSelector<Layout>::iterate>;
112  using policy_type =
113  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
114 
115  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
116  const ExecSpace& space)
117  : a(a_), val(val_) {
118  Kokkos::parallel_for(
119  "Kokkos::ViewFill-3D",
120  policy_type(space, {0, 0, 0}, {a.extent(0), a.extent(1), a.extent(2)}),
121  *this);
122  }
123 
124  KOKKOS_INLINE_FUNCTION
125  void operator()(const iType& i0, const iType& i1, const iType& i2) const {
126  a(i0, i1, i2) = val;
127  };
128 };
129 
130 template <class ViewType, class Layout, class ExecSpace, typename iType>
131 struct ViewFill<ViewType, Layout, ExecSpace, 4, iType> {
132  ViewType a;
133  typename ViewType::const_value_type val;
134 
135  using iterate_type = Kokkos::Rank<4, ViewFillLayoutSelector<Layout>::iterate,
136  ViewFillLayoutSelector<Layout>::iterate>;
137  using policy_type =
138  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
139 
140  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
141  const ExecSpace& space)
142  : a(a_), val(val_) {
143  Kokkos::parallel_for(
144  "Kokkos::ViewFill-4D",
145  policy_type(space, {0, 0, 0, 0},
146  {a.extent(0), a.extent(1), a.extent(2), a.extent(3)}),
147  *this);
148  }
149 
150  KOKKOS_INLINE_FUNCTION
151  void operator()(const iType& i0, const iType& i1, const iType& i2,
152  const iType& i3) const {
153  a(i0, i1, i2, i3) = val;
154  };
155 };
156 
157 template <class ViewType, class Layout, class ExecSpace, typename iType>
158 struct ViewFill<ViewType, Layout, ExecSpace, 5, iType> {
159  ViewType a;
160  typename ViewType::const_value_type val;
161 
162  using iterate_type = Kokkos::Rank<5, ViewFillLayoutSelector<Layout>::iterate,
163  ViewFillLayoutSelector<Layout>::iterate>;
164  using policy_type =
165  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
166 
167  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
168  const ExecSpace& space)
169  : a(a_), val(val_) {
170  Kokkos::parallel_for("Kokkos::ViewFill-5D",
171  policy_type(space, {0, 0, 0, 0, 0},
172  {a.extent(0), a.extent(1), a.extent(2),
173  a.extent(3), a.extent(4)}),
174  *this);
175  }
176 
177  KOKKOS_INLINE_FUNCTION
178  void operator()(const iType& i0, const iType& i1, const iType& i2,
179  const iType& i3, const iType& i4) const {
180  a(i0, i1, i2, i3, i4) = val;
181  };
182 };
183 
184 template <class ViewType, class Layout, class ExecSpace, typename iType>
185 struct ViewFill<ViewType, Layout, ExecSpace, 6, iType> {
186  ViewType a;
187  typename ViewType::const_value_type val;
188 
189  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
190  ViewFillLayoutSelector<Layout>::iterate>;
191  using policy_type =
192  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
193 
194  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
195  const ExecSpace& space)
196  : a(a_), val(val_) {
197  Kokkos::parallel_for("Kokkos::ViewFill-6D",
198  policy_type(space, {0, 0, 0, 0, 0, 0},
199  {a.extent(0), a.extent(1), a.extent(2),
200  a.extent(3), a.extent(4), a.extent(5)}),
201  *this);
202  }
203 
204  KOKKOS_INLINE_FUNCTION
205  void operator()(const iType& i0, const iType& i1, const iType& i2,
206  const iType& i3, const iType& i4, const iType& i5) const {
207  a(i0, i1, i2, i3, i4, i5) = val;
208  };
209 };
210 
211 template <class ViewType, class Layout, class ExecSpace, typename iType>
212 struct ViewFill<ViewType, Layout, ExecSpace, 7, iType> {
213  ViewType a;
214  typename ViewType::const_value_type val;
215 
216  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
217  ViewFillLayoutSelector<Layout>::iterate>;
218  using policy_type =
219  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
220 
221  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
222  const ExecSpace& space)
223  : a(a_), val(val_) {
224  Kokkos::parallel_for("Kokkos::ViewFill-7D",
225  policy_type(space, {0, 0, 0, 0, 0, 0},
226  {a.extent(0), a.extent(1), a.extent(2),
227  a.extent(3), a.extent(5), a.extent(6)}),
228  *this);
229  }
230 
231  KOKKOS_INLINE_FUNCTION
232  void operator()(const iType& i0, const iType& i1, const iType& i3,
233  const iType& i4, const iType& i5, const iType& i6) const {
234  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
235  a(i0, i1, i2, i3, i4, i5, i6) = val;
236  };
237 };
238 
239 template <class ViewType, class Layout, class ExecSpace, typename iType>
240 struct ViewFill<ViewType, Layout, ExecSpace, 8, iType> {
241  ViewType a;
242  typename ViewType::const_value_type val;
243 
244  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
245  ViewFillLayoutSelector<Layout>::iterate>;
246  using policy_type =
247  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
248 
249  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
250  const ExecSpace& space)
251  : a(a_), val(val_) {
252  Kokkos::parallel_for("Kokkos::ViewFill-8D",
253  policy_type(space, {0, 0, 0, 0, 0, 0},
254  {a.extent(0), a.extent(1), a.extent(3),
255  a.extent(5), a.extent(6), a.extent(7)}),
256  *this);
257  }
258 
259  KOKKOS_INLINE_FUNCTION
260  void operator()(const iType& i0, const iType& i1, const iType& i3,
261  const iType& i5, const iType& i6, const iType& i7) const {
262  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
263  for (iType i4 = 0; i4 < iType(a.extent(4)); i4++)
264  a(i0, i1, i2, i3, i4, i5, i6, i7) = val;
265  };
266 };
267 
268 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
269  typename iType>
270 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 1, iType> {
271  ViewTypeA a;
272  ViewTypeB b;
273 
275  using value_type = typename ViewTypeA::value_type;
276 
277  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
278  const ExecSpace space = ExecSpace())
279  : a(a_), b(b_) {
280  Kokkos::parallel_for("Kokkos::ViewCopy-1D",
281  policy_type(space, 0, a.extent(0)), *this);
282  }
283 
284  KOKKOS_INLINE_FUNCTION
285  void operator()(const iType& i0) const {
286  a(i0) = static_cast<value_type>(b(i0));
287  };
288 };
289 
290 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
291  typename iType>
292 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 2, iType> {
293  ViewTypeA a;
294  ViewTypeB b;
295  static const Kokkos::Iterate outer_iteration_pattern =
296  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
297  static const Kokkos::Iterate inner_iteration_pattern =
298  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
299  using iterate_type =
300  Kokkos::Rank<2, outer_iteration_pattern, inner_iteration_pattern>;
301  using policy_type =
302  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
303  using value_type = typename ViewTypeA::value_type;
304 
305  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
306  const ExecSpace space = ExecSpace())
307  : a(a_), b(b_) {
308  Kokkos::parallel_for("Kokkos::ViewCopy-2D",
309  policy_type(space, {0, 0}, {a.extent(0), a.extent(1)}),
310  *this);
311  }
312 
313  KOKKOS_INLINE_FUNCTION
314  void operator()(const iType& i0, const iType& i1) const {
315  a(i0, i1) = static_cast<value_type>(b(i0, i1));
316  };
317 };
318 
319 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
320  typename iType>
321 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 3, iType> {
322  ViewTypeA a;
323  ViewTypeB b;
324 
325  static const Kokkos::Iterate outer_iteration_pattern =
326  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
327  static const Kokkos::Iterate inner_iteration_pattern =
328  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
329  using iterate_type =
330  Kokkos::Rank<3, outer_iteration_pattern, inner_iteration_pattern>;
331  using policy_type =
332  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
333  using value_type = typename ViewTypeA::value_type;
334 
335  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
336  const ExecSpace space = ExecSpace())
337  : a(a_), b(b_) {
338  Kokkos::parallel_for(
339  "Kokkos::ViewCopy-3D",
340  policy_type(space, {0, 0, 0}, {a.extent(0), a.extent(1), a.extent(2)}),
341  *this);
342  }
343 
344  KOKKOS_INLINE_FUNCTION
345  void operator()(const iType& i0, const iType& i1, const iType& i2) const {
346  a(i0, i1, i2) = static_cast<value_type>(b(i0, i1, i2));
347  };
348 };
349 
350 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
351  typename iType>
352 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 4, iType> {
353  ViewTypeA a;
354  ViewTypeB b;
355 
356  static const Kokkos::Iterate outer_iteration_pattern =
357  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
358  static const Kokkos::Iterate inner_iteration_pattern =
359  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
360  using iterate_type =
361  Kokkos::Rank<4, outer_iteration_pattern, inner_iteration_pattern>;
362  using policy_type =
363  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
364 
365  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
366  const ExecSpace space = ExecSpace())
367  : a(a_), b(b_) {
368  Kokkos::parallel_for(
369  "Kokkos::ViewCopy-4D",
370  policy_type(space, {0, 0, 0, 0},
371  {a.extent(0), a.extent(1), a.extent(2), a.extent(3)}),
372  *this);
373  }
374 
375  KOKKOS_INLINE_FUNCTION
376  void operator()(const iType& i0, const iType& i1, const iType& i2,
377  const iType& i3) const {
378  a(i0, i1, i2, i3) = b(i0, i1, i2, i3);
379  };
380 };
381 
382 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
383  typename iType>
384 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 5, iType> {
385  ViewTypeA a;
386  ViewTypeB b;
387 
388  static const Kokkos::Iterate outer_iteration_pattern =
389  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
390  static const Kokkos::Iterate inner_iteration_pattern =
391  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
392  using iterate_type =
393  Kokkos::Rank<5, outer_iteration_pattern, inner_iteration_pattern>;
394  using policy_type =
395  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
396 
397  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
398  const ExecSpace space = ExecSpace())
399  : a(a_), b(b_) {
400  Kokkos::parallel_for("Kokkos::ViewCopy-5D",
401  policy_type(space, {0, 0, 0, 0, 0},
402  {a.extent(0), a.extent(1), a.extent(2),
403  a.extent(3), a.extent(4)}),
404  *this);
405  }
406 
407  KOKKOS_INLINE_FUNCTION
408  void operator()(const iType& i0, const iType& i1, const iType& i2,
409  const iType& i3, const iType& i4) const {
410  a(i0, i1, i2, i3, i4) = b(i0, i1, i2, i3, i4);
411  };
412 };
413 
414 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
415  typename iType>
416 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 6, iType> {
417  ViewTypeA a;
418  ViewTypeB b;
419 
420  static const Kokkos::Iterate outer_iteration_pattern =
421  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
422  static const Kokkos::Iterate inner_iteration_pattern =
423  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
424  using iterate_type =
425  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
426  using policy_type =
427  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
428 
429  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
430  const ExecSpace space = ExecSpace())
431  : a(a_), b(b_) {
432  Kokkos::parallel_for("Kokkos::ViewCopy-6D",
433  policy_type(space, {0, 0, 0, 0, 0, 0},
434  {a.extent(0), a.extent(1), a.extent(2),
435  a.extent(3), a.extent(4), a.extent(5)}),
436  *this);
437  }
438 
439  KOKKOS_INLINE_FUNCTION
440  void operator()(const iType& i0, const iType& i1, const iType& i2,
441  const iType& i3, const iType& i4, const iType& i5) const {
442  a(i0, i1, i2, i3, i4, i5) = b(i0, i1, i2, i3, i4, i5);
443  };
444 };
445 
446 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
447  typename iType>
448 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 7, iType> {
449  ViewTypeA a;
450  ViewTypeB b;
451 
452  static const Kokkos::Iterate outer_iteration_pattern =
453  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
454  static const Kokkos::Iterate inner_iteration_pattern =
455  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
456  using iterate_type =
457  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
458  using policy_type =
459  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
460 
461  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
462  const ExecSpace space = ExecSpace())
463  : a(a_), b(b_) {
464  Kokkos::parallel_for("Kokkos::ViewCopy-7D",
465  policy_type(space, {0, 0, 0, 0, 0, 0},
466  {a.extent(0), a.extent(1), a.extent(3),
467  a.extent(4), a.extent(5), a.extent(6)}),
468  *this);
469  }
470 
471  KOKKOS_INLINE_FUNCTION
472  void operator()(const iType& i0, const iType& i1, const iType& i3,
473  const iType& i4, const iType& i5, const iType& i6) const {
474  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
475  a(i0, i1, i2, i3, i4, i5, i6) = b(i0, i1, i2, i3, i4, i5, i6);
476  };
477 };
478 
479 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
480  typename iType>
481 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 8, iType> {
482  ViewTypeA a;
483  ViewTypeB b;
484 
485  static const Kokkos::Iterate outer_iteration_pattern =
486  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
487  static const Kokkos::Iterate inner_iteration_pattern =
488  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
489  using iterate_type =
490  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
491  using policy_type =
492  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
493 
494  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
495  const ExecSpace space = ExecSpace())
496  : a(a_), b(b_) {
497  Kokkos::parallel_for("Kokkos::ViewCopy-8D",
498  policy_type(space, {0, 0, 0, 0, 0, 0},
499  {a.extent(0), a.extent(1), a.extent(3),
500  a.extent(5), a.extent(6), a.extent(7)}),
501  *this);
502  }
503 
504  KOKKOS_INLINE_FUNCTION
505  void operator()(const iType& i0, const iType& i1, const iType& i3,
506  const iType& i5, const iType& i6, const iType& i7) const {
507  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
508  for (iType i4 = 0; i4 < iType(a.extent(4)); i4++)
509  a(i0, i1, i2, i3, i4, i5, i6, i7) = b(i0, i1, i2, i3, i4, i5, i6, i7);
510  };
511 };
512 
513 } // namespace Impl
514 } // namespace Kokkos
515 
516 namespace Kokkos {
517 namespace Impl {
518 
519 template <class ExecutionSpace, class DstType, class SrcType>
520 void view_copy(const ExecutionSpace& space, const DstType& dst,
521  const SrcType& src) {
522  using dst_memory_space = typename DstType::memory_space;
523  using src_memory_space = typename SrcType::memory_space;
524 
525  enum {
526  ExecCanAccessSrc =
528  };
529  enum {
530  ExecCanAccessDst =
532  };
533 
534  if (!(ExecCanAccessSrc && ExecCanAccessDst)) {
535  Kokkos::Impl::throw_runtime_exception(
536  "Kokkos::Impl::view_copy called with invalid execution space");
537  } else {
538  // Figure out iteration order in case we need it
539  int64_t strides[DstType::rank + 1];
540  dst.stride(strides);
541  Kokkos::Iterate iterate;
542  if (Kokkos::is_layouttiled<typename DstType::array_layout>::value) {
543  iterate = Kokkos::layout_iterate_type_selector<
544  typename DstType::array_layout>::outer_iteration_pattern;
545  } else if (std::is_same<typename DstType::array_layout,
546  Kokkos::LayoutRight>::value) {
547  iterate = Kokkos::Iterate::Right;
548  } else if (std::is_same<typename DstType::array_layout,
549  Kokkos::LayoutLeft>::value) {
550  iterate = Kokkos::Iterate::Left;
551  } else if (std::is_same<typename DstType::array_layout,
552  Kokkos::LayoutStride>::value) {
553  if (strides[0] > strides[DstType::rank - 1])
554  iterate = Kokkos::Iterate::Right;
555  else
556  iterate = Kokkos::Iterate::Left;
557  } else {
558  if (std::is_same<typename DstType::execution_space::array_layout,
559  Kokkos::LayoutRight>::value)
560  iterate = Kokkos::Iterate::Right;
561  else
562  iterate = Kokkos::Iterate::Left;
563  }
564 
565  if ((dst.span() >= size_t(std::numeric_limits<int>::max())) ||
566  (src.span() >= size_t(std::numeric_limits<int>::max()))) {
567  if (iterate == Kokkos::Iterate::Right)
568  Kokkos::Impl::ViewCopy<
569  typename DstType::uniform_runtime_nomemspace_type,
570  typename SrcType::uniform_runtime_const_nomemspace_type,
571  Kokkos::LayoutRight, ExecutionSpace, DstType::rank, int64_t>(
572  dst, src, space);
573  else
574  Kokkos::Impl::ViewCopy<
575  typename DstType::uniform_runtime_nomemspace_type,
576  typename SrcType::uniform_runtime_const_nomemspace_type,
577  Kokkos::LayoutLeft, ExecutionSpace, DstType::rank, int64_t>(
578  dst, src, space);
579  } else {
580  if (iterate == Kokkos::Iterate::Right)
581  Kokkos::Impl::ViewCopy<
582  typename DstType::uniform_runtime_nomemspace_type,
583  typename SrcType::uniform_runtime_const_nomemspace_type,
584  Kokkos::LayoutRight, ExecutionSpace, DstType::rank, int>(dst, src,
585  space);
586  else
587  Kokkos::Impl::ViewCopy<
588  typename DstType::uniform_runtime_nomemspace_type,
589  typename SrcType::uniform_runtime_const_nomemspace_type,
590  Kokkos::LayoutLeft, ExecutionSpace, DstType::rank, int>(dst, src,
591  space);
592  }
593  }
594 }
595 
596 template <class DstType, class SrcType>
597 void view_copy(const DstType& dst, const SrcType& src) {
598  using dst_execution_space = typename DstType::execution_space;
599  using src_execution_space = typename SrcType::execution_space;
600  using dst_memory_space = typename DstType::memory_space;
601  using src_memory_space = typename SrcType::memory_space;
602 
603  enum {
604  DstExecCanAccessSrc =
605  Kokkos::SpaceAccessibility<dst_execution_space,
606  src_memory_space>::accessible
607  };
608 
609  enum {
610  SrcExecCanAccessDst =
611  Kokkos::SpaceAccessibility<src_execution_space,
612  dst_memory_space>::accessible
613  };
614 
615  if (!DstExecCanAccessSrc && !SrcExecCanAccessDst) {
616  std::ostringstream ss;
617  ss << "Error: Kokkos::deep_copy with no available copy mechanism: "
618  << "from source view (\"" << src.label() << "\") to destination view (\""
619  << dst.label() << "\").\n"
620  << "There is no common execution space that can access both source's "
621  "space\n"
622  << "(" << src_memory_space().name() << ") and destination's space ("
623  << dst_memory_space().name() << "), "
624  << "so source and destination\n"
625  << "must be contiguous and have the same layout.\n";
626  Kokkos::Impl::throw_runtime_exception(ss.str());
627  }
628 
629  // Figure out iteration order in case we need it
630  int64_t strides[DstType::rank + 1];
631  dst.stride(strides);
632  Kokkos::Iterate iterate;
633  if (Kokkos::is_layouttiled<typename DstType::array_layout>::value) {
634  iterate = Kokkos::layout_iterate_type_selector<
635  typename DstType::array_layout>::outer_iteration_pattern;
636  } else if (std::is_same<typename DstType::array_layout,
637  Kokkos::LayoutRight>::value) {
638  iterate = Kokkos::Iterate::Right;
639  } else if (std::is_same<typename DstType::array_layout,
640  Kokkos::LayoutLeft>::value) {
641  iterate = Kokkos::Iterate::Left;
642  } else if (std::is_same<typename DstType::array_layout,
643  Kokkos::LayoutStride>::value) {
644  if (strides[0] > strides[DstType::rank - 1])
645  iterate = Kokkos::Iterate::Right;
646  else
647  iterate = Kokkos::Iterate::Left;
648  } else {
649  if (std::is_same<typename DstType::execution_space::array_layout,
650  Kokkos::LayoutRight>::value)
651  iterate = Kokkos::Iterate::Right;
652  else
653  iterate = Kokkos::Iterate::Left;
654  }
655 
656  if ((dst.span() >= size_t(std::numeric_limits<int>::max())) ||
657  (src.span() >= size_t(std::numeric_limits<int>::max()))) {
658  if (DstExecCanAccessSrc) {
659  if (iterate == Kokkos::Iterate::Right)
660  Kokkos::Impl::ViewCopy<
661  typename DstType::uniform_runtime_nomemspace_type,
662  typename SrcType::uniform_runtime_const_nomemspace_type,
663  Kokkos::LayoutRight, dst_execution_space, DstType::rank, int64_t>(
664  dst, src);
665  else
666  Kokkos::Impl::ViewCopy<
667  typename DstType::uniform_runtime_nomemspace_type,
668  typename SrcType::uniform_runtime_const_nomemspace_type,
669  Kokkos::LayoutLeft, dst_execution_space, DstType::rank, int64_t>(
670  dst, src);
671  } else {
672  if (iterate == Kokkos::Iterate::Right)
673  Kokkos::Impl::ViewCopy<
674  typename DstType::uniform_runtime_nomemspace_type,
675  typename SrcType::uniform_runtime_const_nomemspace_type,
676  Kokkos::LayoutRight, src_execution_space, DstType::rank, int64_t>(
677  dst, src);
678  else
679  Kokkos::Impl::ViewCopy<
680  typename DstType::uniform_runtime_nomemspace_type,
681  typename SrcType::uniform_runtime_const_nomemspace_type,
682  Kokkos::LayoutLeft, src_execution_space, DstType::rank, int64_t>(
683  dst, src);
684  }
685  } else {
686  if (DstExecCanAccessSrc) {
687  if (iterate == Kokkos::Iterate::Right)
688  Kokkos::Impl::ViewCopy<
689  typename DstType::uniform_runtime_nomemspace_type,
690  typename SrcType::uniform_runtime_const_nomemspace_type,
691  Kokkos::LayoutRight, dst_execution_space, DstType::rank, int>(dst,
692  src);
693  else
694  Kokkos::Impl::ViewCopy<
695  typename DstType::uniform_runtime_nomemspace_type,
696  typename SrcType::uniform_runtime_const_nomemspace_type,
697  Kokkos::LayoutLeft, dst_execution_space, DstType::rank, int>(dst,
698  src);
699  } else {
700  if (iterate == Kokkos::Iterate::Right)
701  Kokkos::Impl::ViewCopy<
702  typename DstType::uniform_runtime_nomemspace_type,
703  typename SrcType::uniform_runtime_const_nomemspace_type,
704  Kokkos::LayoutRight, src_execution_space, DstType::rank, int>(dst,
705  src);
706  else
707  Kokkos::Impl::ViewCopy<
708  typename DstType::uniform_runtime_nomemspace_type,
709  typename SrcType::uniform_runtime_const_nomemspace_type,
710  Kokkos::LayoutLeft, src_execution_space, DstType::rank, int>(dst,
711  src);
712  }
713  }
714 }
715 
716 template <class DstType, class SrcType, int Rank, class... Args>
717 struct CommonSubview;
718 
719 template <class DstType, class SrcType, class Arg0, class... Args>
720 struct CommonSubview<DstType, SrcType, 1, Arg0, Args...> {
721  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0>;
722  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0>;
723  dst_subview_type dst_sub;
724  src_subview_type src_sub;
725  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
726  Args...)
727  : dst_sub(dst, arg0), src_sub(src, arg0) {}
728 };
729 
730 template <class DstType, class SrcType, class Arg0, class Arg1, class... Args>
731 struct CommonSubview<DstType, SrcType, 2, Arg0, Arg1, Args...> {
732  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1>;
733  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1>;
734  dst_subview_type dst_sub;
735  src_subview_type src_sub;
736  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
737  const Arg1& arg1, Args...)
738  : dst_sub(dst, arg0, arg1), src_sub(src, arg0, arg1) {}
739 };
740 
741 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
742  class... Args>
743 struct CommonSubview<DstType, SrcType, 3, Arg0, Arg1, Arg2, Args...> {
744  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2>;
745  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2>;
746  dst_subview_type dst_sub;
747  src_subview_type src_sub;
748  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
749  const Arg1& arg1, const Arg2& arg2, Args...)
750  : dst_sub(dst, arg0, arg1, arg2), src_sub(src, arg0, arg1, arg2) {}
751 };
752 
753 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
754  class Arg3, class... Args>
755 struct CommonSubview<DstType, SrcType, 4, Arg0, Arg1, Arg2, Arg3, Args...> {
756  using dst_subview_type =
757  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3>;
758  using src_subview_type =
759  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3>;
760  dst_subview_type dst_sub;
761  src_subview_type src_sub;
762  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
763  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
764  const Args...)
765  : dst_sub(dst, arg0, arg1, arg2, arg3),
766  src_sub(src, arg0, arg1, arg2, arg3) {}
767 };
768 
769 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
770  class Arg3, class Arg4, class... Args>
771 struct CommonSubview<DstType, SrcType, 5, Arg0, Arg1, Arg2, Arg3, Arg4,
772  Args...> {
773  using dst_subview_type =
774  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4>;
775  using src_subview_type =
776  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4>;
777  dst_subview_type dst_sub;
778  src_subview_type src_sub;
779  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
780  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
781  const Arg4& arg4, const Args...)
782  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4),
783  src_sub(src, arg0, arg1, arg2, arg3, arg4) {}
784 };
785 
786 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
787  class Arg3, class Arg4, class Arg5, class... Args>
788 struct CommonSubview<DstType, SrcType, 6, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
789  Args...> {
790  using dst_subview_type =
791  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>;
792  using src_subview_type =
793  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>;
794  dst_subview_type dst_sub;
795  src_subview_type src_sub;
796  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
797  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
798  const Arg4& arg4, const Arg5& arg5, const Args...)
799  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5),
800  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5) {}
801 };
802 
803 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
804  class Arg3, class Arg4, class Arg5, class Arg6, class... Args>
805 struct CommonSubview<DstType, SrcType, 7, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
806  Arg6, Args...> {
807  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2,
808  Arg3, Arg4, Arg5, Arg6>;
809  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2,
810  Arg3, Arg4, Arg5, Arg6>;
811  dst_subview_type dst_sub;
812  src_subview_type src_sub;
813  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
814  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
815  const Arg4& arg4, const Arg5& arg5, const Arg6& arg6, Args...)
816  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5, arg6),
817  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {}
818 };
819 
820 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
821  class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
822 struct CommonSubview<DstType, SrcType, 8, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
823  Arg6, Arg7> {
824  using dst_subview_type =
825  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
826  Arg6, Arg7>;
827  using src_subview_type =
828  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
829  Arg6, Arg7>;
830  dst_subview_type dst_sub;
831  src_subview_type src_sub;
832  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
833  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
834  const Arg4& arg4, const Arg5& arg5, const Arg6& arg6,
835  const Arg7& arg7)
836  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7),
837  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {}
838 };
839 
840 template <class DstType, class SrcType,
841  class ExecSpace = typename DstType::execution_space,
842  int Rank = DstType::rank>
843 struct ViewRemap;
844 
845 template <class DstType, class SrcType, class ExecSpace>
846 struct ViewRemap<DstType, SrcType, ExecSpace, 1> {
847  using p_type = Kokkos::pair<int64_t, int64_t>;
848 
849  template <typename... OptExecSpace>
850  ViewRemap(const DstType& dst, const SrcType& src,
851  const OptExecSpace&... exec_space) {
852  static_assert(
853  sizeof...(OptExecSpace) <= 1,
854  "OptExecSpace must be either empty or be an execution space!");
855 
856  if (dst.extent(0) == src.extent(0)) {
857  view_copy(exec_space..., dst, src);
858  } else {
859  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
860  using sv_adapter_type = CommonSubview<DstType, SrcType, 1, p_type>;
861  sv_adapter_type common_subview(dst, src, ext0);
862  view_copy(exec_space..., common_subview.dst_sub, common_subview.src_sub);
863  }
864  }
865 };
866 
867 template <class DstType, class SrcType, class ExecSpace>
868 struct ViewRemap<DstType, SrcType, ExecSpace, 2> {
869  using p_type = Kokkos::pair<int64_t, int64_t>;
870 
871  template <typename... OptExecSpace>
872  ViewRemap(const DstType& dst, const SrcType& src,
873  const OptExecSpace&... exec_space) {
874  static_assert(
875  sizeof...(OptExecSpace) <= 1,
876  "OptExecSpace must be either empty or be an execution space!");
877 
878  if (dst.extent(0) == src.extent(0)) {
879  if (dst.extent(1) == src.extent(1)) {
880  view_copy(exec_space..., dst, src);
881  } else {
882  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
883  using sv_adapter_type =
884  CommonSubview<DstType, SrcType, 2, Kokkos::ALL_t, p_type>;
885  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1);
886  view_copy(exec_space..., common_subview.dst_sub,
887  common_subview.src_sub);
888  }
889  } else {
890  if (dst.extent(1) == src.extent(1)) {
891  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
892  using sv_adapter_type =
893  CommonSubview<DstType, SrcType, 2, p_type, Kokkos::ALL_t>;
894  sv_adapter_type common_subview(dst, src, ext0, Kokkos::ALL);
895  view_copy(exec_space..., common_subview.dst_sub,
896  common_subview.src_sub);
897  } else {
898  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
899  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
900  using sv_adapter_type =
901  CommonSubview<DstType, SrcType, 2, p_type, p_type>;
902  sv_adapter_type common_subview(dst, src, ext0, ext1);
903  view_copy(exec_space..., common_subview.dst_sub,
904  common_subview.src_sub);
905  }
906  }
907  }
908 };
909 
910 template <class DstType, class SrcType, class ExecSpace>
911 struct ViewRemap<DstType, SrcType, ExecSpace, 3> {
912  using p_type = Kokkos::pair<int64_t, int64_t>;
913 
914  template <typename... OptExecSpace>
915  ViewRemap(const DstType& dst, const SrcType& src,
916  const OptExecSpace&... exec_space) {
917  static_assert(
918  sizeof...(OptExecSpace) <= 1,
919  "OptExecSpace must be either empty or be an execution space!");
920 
921  if (dst.extent(0) == src.extent(0)) {
922  if (dst.extent(2) == src.extent(2)) {
923  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
924  using sv_adapter_type =
925  CommonSubview<DstType, SrcType, 3, Kokkos::ALL_t, p_type,
926  Kokkos::ALL_t>;
927  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1,
928  Kokkos::ALL);
929  view_copy(exec_space..., common_subview.dst_sub,
930  common_subview.src_sub);
931  } else {
932  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
933  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
934  using sv_adapter_type =
935  CommonSubview<DstType, SrcType, 3, Kokkos::ALL_t, p_type, p_type>;
936  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2);
937  view_copy(exec_space..., common_subview.dst_sub,
938  common_subview.src_sub);
939  }
940  } else {
941  if (dst.extent(2) == src.extent(2)) {
942  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
943  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
944  using sv_adapter_type =
945  CommonSubview<DstType, SrcType, 3, p_type, p_type, Kokkos::ALL_t>;
946  sv_adapter_type common_subview(dst, src, ext0, ext1, Kokkos::ALL);
947  view_copy(exec_space..., common_subview.dst_sub,
948  common_subview.src_sub);
949  } else {
950  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
951  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
952  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
953  using sv_adapter_type =
954  CommonSubview<DstType, SrcType, 3, p_type, p_type, p_type>;
955  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2);
956  view_copy(exec_space..., common_subview.dst_sub,
957  common_subview.src_sub);
958  }
959  }
960  }
961 };
962 
963 template <class DstType, class SrcType, class ExecSpace>
964 struct ViewRemap<DstType, SrcType, ExecSpace, 4> {
965  using p_type = Kokkos::pair<int64_t, int64_t>;
966 
967  template <typename... OptExecSpace>
968  ViewRemap(const DstType& dst, const SrcType& src,
969  const OptExecSpace&... exec_space) {
970  static_assert(
971  sizeof...(OptExecSpace) <= 1,
972  "OptExecSpace must be either empty or be an execution space!");
973 
974  if (dst.extent(0) == src.extent(0)) {
975  if (dst.extent(3) == src.extent(3)) {
976  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
977  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
978  using sv_adapter_type =
979  CommonSubview<DstType, SrcType, 4, Kokkos::ALL_t, p_type, p_type,
980  Kokkos::ALL_t>;
981  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2,
982  Kokkos::ALL);
983  view_copy(exec_space..., common_subview.dst_sub,
984  common_subview.src_sub);
985  } else {
986  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
987  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
988  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
989  using sv_adapter_type =
990  CommonSubview<DstType, SrcType, 4, Kokkos::ALL_t, p_type, p_type,
991  p_type>;
992  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3);
993  view_copy(exec_space..., common_subview.dst_sub,
994  common_subview.src_sub);
995  }
996  } else {
997  if (dst.extent(7) == src.extent(7)) {
998  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
999  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1000  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1001  using sv_adapter_type = CommonSubview<DstType, SrcType, 4, p_type,
1002  p_type, p_type, Kokkos::ALL_t>;
1003  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, Kokkos::ALL);
1004  view_copy(exec_space..., common_subview.dst_sub,
1005  common_subview.src_sub);
1006  } else {
1007  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1008  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1009  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1010  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1011  using sv_adapter_type =
1012  CommonSubview<DstType, SrcType, 4, p_type, p_type, p_type, p_type>;
1013  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3);
1014  view_copy(exec_space..., common_subview.dst_sub,
1015  common_subview.src_sub);
1016  }
1017  }
1018  }
1019 };
1020 
1021 template <class DstType, class SrcType, class ExecSpace>
1022 struct ViewRemap<DstType, SrcType, ExecSpace, 5> {
1023  using p_type = Kokkos::pair<int64_t, int64_t>;
1024 
1025  template <typename... OptExecSpace>
1026  ViewRemap(const DstType& dst, const SrcType& src,
1027  const OptExecSpace&... exec_space) {
1028  static_assert(
1029  sizeof...(OptExecSpace) <= 1,
1030  "OptExecSpace must be either empty or be an execution space!");
1031 
1032  if (dst.extent(0) == src.extent(0)) {
1033  if (dst.extent(4) == src.extent(4)) {
1034  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1035  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1036  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1037  using sv_adapter_type =
1038  CommonSubview<DstType, SrcType, 5, Kokkos::ALL_t, p_type, p_type,
1039  p_type, Kokkos::ALL_t>;
1040  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1041  Kokkos::ALL);
1042  view_copy(exec_space..., common_subview.dst_sub,
1043  common_subview.src_sub);
1044  } else {
1045  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1046  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1047  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1048  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1049  using sv_adapter_type =
1050  CommonSubview<DstType, SrcType, 5, Kokkos::ALL_t, p_type, p_type,
1051  p_type, p_type>;
1052  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1053  ext4);
1054  view_copy(exec_space..., common_subview.dst_sub,
1055  common_subview.src_sub);
1056  }
1057  } else {
1058  if (dst.extent(4) == src.extent(4)) {
1059  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1060  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1061  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1062  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1063  using sv_adapter_type =
1064  CommonSubview<DstType, SrcType, 5, p_type, p_type, p_type, p_type,
1065  Kokkos::ALL_t>;
1066  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3,
1067  Kokkos::ALL);
1068  view_copy(exec_space..., common_subview.dst_sub,
1069  common_subview.src_sub);
1070  } else {
1071  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1072  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1073  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1074  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1075  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1076  using sv_adapter_type = CommonSubview<DstType, SrcType, 5, p_type,
1077  p_type, p_type, p_type, p_type>;
1078  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4);
1079  view_copy(exec_space..., common_subview.dst_sub,
1080  common_subview.src_sub);
1081  }
1082  }
1083  }
1084 };
1085 template <class DstType, class SrcType, class ExecSpace>
1086 struct ViewRemap<DstType, SrcType, ExecSpace, 6> {
1087  using p_type = Kokkos::pair<int64_t, int64_t>;
1088 
1089  template <typename... OptExecSpace>
1090  ViewRemap(const DstType& dst, const SrcType& src,
1091  const OptExecSpace&... exec_space) {
1092  static_assert(
1093  sizeof...(OptExecSpace) <= 1,
1094  "OptExecSpace must be either empty or be an execution space!");
1095 
1096  if (dst.extent(0) == src.extent(0)) {
1097  if (dst.extent(5) == src.extent(5)) {
1098  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1099  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1100  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1101  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1102  using sv_adapter_type =
1103  CommonSubview<DstType, SrcType, 6, Kokkos::ALL_t, p_type, p_type,
1104  p_type, p_type, Kokkos::ALL_t>;
1105  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1106  ext4, Kokkos::ALL);
1107  view_copy(exec_space..., common_subview.dst_sub,
1108  common_subview.src_sub);
1109  } else {
1110  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1111  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1112  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1113  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1114  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1115  using sv_adapter_type =
1116  CommonSubview<DstType, SrcType, 6, Kokkos::ALL_t, p_type, p_type,
1117  p_type, p_type, p_type>;
1118  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1119  ext4, ext5);
1120  view_copy(exec_space..., common_subview.dst_sub,
1121  common_subview.src_sub);
1122  }
1123  } else {
1124  if (dst.extent(5) == src.extent(5)) {
1125  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1126  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1127  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1128  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1129  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1130 
1131  using sv_adapter_type =
1132  CommonSubview<DstType, SrcType, 6, p_type, p_type, p_type, p_type,
1133  p_type, Kokkos::ALL_t>;
1134  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1135  Kokkos::ALL);
1136  view_copy(exec_space..., common_subview.dst_sub,
1137  common_subview.src_sub);
1138  } else {
1139  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1140  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1141  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1142  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1143  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1144  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1145 
1146  using sv_adapter_type =
1147  CommonSubview<DstType, SrcType, 6, p_type, p_type, p_type, p_type,
1148  p_type, p_type>;
1149  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1150  ext5);
1151  view_copy(exec_space..., common_subview.dst_sub,
1152  common_subview.src_sub);
1153  }
1154  }
1155  }
1156 };
1157 
1158 template <class DstType, class SrcType, class ExecSpace>
1159 struct ViewRemap<DstType, SrcType, ExecSpace, 7> {
1160  using p_type = Kokkos::pair<int64_t, int64_t>;
1161 
1162  template <typename... OptExecSpace>
1163  ViewRemap(const DstType& dst, const SrcType& src,
1164  const OptExecSpace&... exec_space) {
1165  static_assert(
1166  sizeof...(OptExecSpace) <= 1,
1167  "OptExecSpace must be either empty or be an execution space!");
1168 
1169  if (dst.extent(0) == src.extent(0)) {
1170  if (dst.extent(6) == src.extent(6)) {
1171  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1172  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1173  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1174  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1175  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1176  using sv_adapter_type =
1177  CommonSubview<DstType, SrcType, 7, Kokkos::ALL_t, p_type, p_type,
1178  p_type, p_type, p_type, Kokkos::ALL_t>;
1179  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1180  ext4, ext5, Kokkos::ALL);
1181  view_copy(exec_space..., common_subview.dst_sub,
1182  common_subview.src_sub);
1183  } else {
1184  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1185  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1186  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1187  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1188  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1189  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1190  using sv_adapter_type =
1191  CommonSubview<DstType, SrcType, 7, Kokkos::ALL_t, p_type, p_type,
1192  p_type, p_type, p_type, p_type>;
1193  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1194  ext4, ext5, ext6);
1195  view_copy(exec_space..., common_subview.dst_sub,
1196  common_subview.src_sub);
1197  }
1198  } else {
1199  if (dst.extent(6) == src.extent(6)) {
1200  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1201  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1202  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1203  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1204  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1205  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1206  using sv_adapter_type =
1207  CommonSubview<DstType, SrcType, 7, p_type, p_type, p_type, p_type,
1208  p_type, p_type, Kokkos::ALL_t>;
1209  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1210  ext5, Kokkos::ALL);
1211  view_copy(exec_space..., common_subview.dst_sub,
1212  common_subview.src_sub);
1213  } else {
1214  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1215  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1216  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1217  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1218  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1219  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1220  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1221  using sv_adapter_type =
1222  CommonSubview<DstType, SrcType, 7, p_type, p_type, p_type, p_type,
1223  p_type, p_type, p_type>;
1224  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1225  ext5, ext6);
1226  view_copy(exec_space..., common_subview.dst_sub,
1227  common_subview.src_sub);
1228  }
1229  }
1230  }
1231 };
1232 
1233 template <class DstType, class SrcType, class ExecSpace>
1234 struct ViewRemap<DstType, SrcType, ExecSpace, 8> {
1235  using p_type = Kokkos::pair<int64_t, int64_t>;
1236 
1237  template <typename... OptExecSpace>
1238  ViewRemap(const DstType& dst, const SrcType& src,
1239  const OptExecSpace&... exec_space) {
1240  static_assert(
1241  sizeof...(OptExecSpace) <= 1,
1242  "OptExecSpace must be either empty or be an execution space!");
1243 
1244  if (dst.extent(0) == src.extent(0)) {
1245  if (dst.extent(7) == src.extent(7)) {
1246  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1247  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1248  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1249  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1250  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1251  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1252  using sv_adapter_type =
1253  CommonSubview<DstType, SrcType, 8, Kokkos::ALL_t, p_type, p_type,
1254  p_type, p_type, p_type, p_type, Kokkos::ALL_t>;
1255  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1256  ext4, ext5, ext6, Kokkos::ALL);
1257  view_copy(exec_space..., common_subview.dst_sub,
1258  common_subview.src_sub);
1259  } else {
1260  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1261  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1262  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1263  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1264  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1265  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1266  p_type ext7(0, std::min(dst.extent(7), src.extent(7)));
1267  using sv_adapter_type =
1268  CommonSubview<DstType, SrcType, 8, Kokkos::ALL_t, p_type, p_type,
1269  p_type, p_type, p_type, p_type, p_type>;
1270  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1271  ext4, ext5, ext6, ext7);
1272  view_copy(exec_space..., common_subview.dst_sub,
1273  common_subview.src_sub);
1274  }
1275  } else {
1276  if (dst.extent(7) == src.extent(7)) {
1277  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1278  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1279  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1280  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1281  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1282  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1283  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1284  using sv_adapter_type =
1285  CommonSubview<DstType, SrcType, 8, p_type, p_type, p_type, p_type,
1286  p_type, p_type, p_type, Kokkos::ALL_t>;
1287  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1288  ext5, ext6, Kokkos::ALL);
1289  view_copy(exec_space..., common_subview.dst_sub,
1290  common_subview.src_sub);
1291  } else {
1292  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1293  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1294  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1295  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1296  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1297  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1298  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1299  p_type ext7(0, std::min(dst.extent(7), src.extent(7)));
1300  using sv_adapter_type =
1301  CommonSubview<DstType, SrcType, 8, p_type, p_type, p_type, p_type,
1302  p_type, p_type, p_type, p_type>;
1303  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1304  ext5, ext6, ext7);
1305  view_copy(exec_space..., common_subview.dst_sub,
1306  common_subview.src_sub);
1307  }
1308  }
1309  }
1310 };
1311 
1312 template <typename ExecutionSpace, class DT, class... DP>
1313 inline void contiguous_fill(
1314  const ExecutionSpace& exec_space, const View<DT, DP...>& dst,
1315  typename ViewTraits<DT, DP...>::const_value_type& value) {
1316  using ViewType = View<DT, DP...>;
1317  using ViewTypeFlat = Kokkos::View<
1318  typename ViewType::value_type*, Kokkos::LayoutRight,
1319  Kokkos::Device<typename ViewType::execution_space,
1320  std::conditional_t<ViewType::rank == 0,
1321  typename ViewType::memory_space,
1322  Kokkos::AnonymousSpace>>,
1323  Kokkos::MemoryTraits<0>>;
1324 
1325  ViewTypeFlat dst_flat(dst.data(), dst.size());
1326  if (dst.span() < static_cast<size_t>(std::numeric_limits<int>::max())) {
1327  Kokkos::Impl::ViewFill<ViewTypeFlat, Kokkos::LayoutRight, ExecutionSpace,
1328  ViewTypeFlat::rank, int>(dst_flat, value,
1329  exec_space);
1330  } else
1331  Kokkos::Impl::ViewFill<ViewTypeFlat, Kokkos::LayoutRight, ExecutionSpace,
1332  ViewTypeFlat::rank, int64_t>(dst_flat, value,
1333  exec_space);
1334 }
1335 
1336 // Default implementation for execution spaces that don't provide a definition
1337 template <typename ExecutionSpace, class ViewType>
1338 struct ZeroMemset {
1339  ZeroMemset(const ExecutionSpace& exec_space, const ViewType& dst) {
1340  using ValueType = typename ViewType::value_type;
1341  alignas(alignof(ValueType)) unsigned char
1342  zero_initialized_storage[sizeof(ValueType)] = {};
1343  contiguous_fill(exec_space, dst,
1344  *reinterpret_cast<ValueType*>(zero_initialized_storage));
1345  }
1346 };
1347 
1348 template <typename ExecutionSpace, class DT, class... DP>
1349 inline std::enable_if_t<
1350  std::is_trivial<typename ViewTraits<DT, DP...>::value_type>::value &&
1351  std::is_trivially_copy_assignable<
1352  typename ViewTraits<DT, DP...>::value_type>::value>
1353 contiguous_fill_or_memset(
1354  const ExecutionSpace& exec_space, const View<DT, DP...>& dst,
1355  typename ViewTraits<DT, DP...>::const_value_type& value) {
1356  // With OpenMP, using memset has significant performance issues.
1357  if (Impl::is_zero_byte(value)
1358 #ifdef KOKKOS_ENABLE_OPENMP
1359  && !std::is_same_v<ExecutionSpace, Kokkos::OpenMP>
1360 #endif
1361  )
1362  // FIXME intel/19 icpc fails to deduce template parameters here,
1363  // resulting in compilation errors; explicitly passing the template
1364  // parameters to ZeroMemset helps workaround the issue
1365  // See https://github.com/kokkos/kokkos/issues/6775
1366  ZeroMemset<ExecutionSpace, View<DT, DP...>>(exec_space, dst);
1367  else
1368  contiguous_fill(exec_space, dst, value);
1369 }
1370 
1371 template <typename ExecutionSpace, class DT, class... DP>
1372 inline std::enable_if_t<
1373  !(std::is_trivial<typename ViewTraits<DT, DP...>::value_type>::value &&
1374  std::is_trivially_copy_assignable<
1375  typename ViewTraits<DT, DP...>::value_type>::value)>
1376 contiguous_fill_or_memset(
1377  const ExecutionSpace& exec_space, const View<DT, DP...>& dst,
1378  typename ViewTraits<DT, DP...>::const_value_type& value) {
1379  contiguous_fill(exec_space, dst, value);
1380 }
1381 
1382 template <class DT, class... DP>
1383 inline std::enable_if_t<
1384  std::is_trivial<typename ViewTraits<DT, DP...>::value_type>::value &&
1385  std::is_trivially_copy_assignable<
1386  typename ViewTraits<DT, DP...>::value_type>::value>
1387 contiguous_fill_or_memset(
1388  const View<DT, DP...>& dst,
1389  typename ViewTraits<DT, DP...>::const_value_type& value) {
1390  using ViewType = View<DT, DP...>;
1391  using exec_space_type = typename ViewType::execution_space;
1392  exec_space_type exec;
1393 
1394 // On A64FX memset seems to do the wrong thing with regards to first touch
1395 // leading to the significant performance issues
1396 #ifndef KOKKOS_ARCH_A64FX
1397  if (Impl::is_zero_byte(value))
1398  // FIXME intel/19 icpc fails to deduce template parameters here,
1399  // resulting in compilation errors; explicitly passing the template
1400  // parameters to ZeroMemset helps workaround the issue
1401  // See https://github.com/kokkos/kokkos/issues/6775
1402  ZeroMemset<exec_space_type, ViewType>(exec, dst);
1403  else
1404 #endif
1405  contiguous_fill(exec, dst, value);
1406 }
1407 
1408 template <class DT, class... DP>
1409 inline std::enable_if_t<
1410  !(std::is_trivial<typename ViewTraits<DT, DP...>::value_type>::value &&
1411  std::is_trivially_copy_assignable<
1412  typename ViewTraits<DT, DP...>::value_type>::value)>
1413 contiguous_fill_or_memset(
1414  const View<DT, DP...>& dst,
1415  typename ViewTraits<DT, DP...>::const_value_type& value) {
1416  using ViewType = View<DT, DP...>;
1417  using exec_space_type = typename ViewType::execution_space;
1418 
1419  contiguous_fill(exec_space_type(), dst, value);
1420 }
1421 } // namespace Impl
1422 
1424 template <class DT, class... DP>
1425 inline void deep_copy(
1426  const View<DT, DP...>& dst,
1427  typename ViewTraits<DT, DP...>::const_value_type& value,
1428  std::enable_if_t<std::is_same<typename ViewTraits<DT, DP...>::specialize,
1429  void>::value>* = nullptr) {
1430  using ViewType = View<DT, DP...>;
1431  using exec_space_type = typename ViewType::execution_space;
1432 
1433  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1434  Kokkos::Profiling::beginDeepCopy(
1435  Kokkos::Profiling::make_space_handle(ViewType::memory_space::name()),
1436  dst.label(), dst.data(),
1437  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
1438  "Scalar", &value, dst.span() * sizeof(typename ViewType::value_type));
1439  }
1440 
1441  if (dst.data() == nullptr) {
1442  Kokkos::fence(
1443  "Kokkos::deep_copy: scalar copy, fence because destination is null");
1444  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1445  Kokkos::Profiling::endDeepCopy();
1446  }
1447  return;
1448  }
1449 
1450  Kokkos::fence("Kokkos::deep_copy: scalar copy, pre copy fence");
1451  static_assert(std::is_same<typename ViewType::non_const_value_type,
1452  typename ViewType::value_type>::value,
1453  "deep_copy requires non-const type");
1454 
1455  // If contiguous we can simply do a 1D flat loop or use memset
1456  if (dst.span_is_contiguous()) {
1457  Impl::contiguous_fill_or_memset(dst, value);
1458  Kokkos::fence("Kokkos::deep_copy: scalar copy, post copy fence");
1459  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1460  Kokkos::Profiling::endDeepCopy();
1461  }
1462  return;
1463  }
1464 
1465  // Figure out iteration order to do the ViewFill
1466  int64_t strides[ViewType::rank + 1];
1467  dst.stride(strides);
1468  Kokkos::Iterate iterate;
1469  if (std::is_same<typename ViewType::array_layout,
1470  Kokkos::LayoutRight>::value) {
1471  iterate = Kokkos::Iterate::Right;
1472  } else if (std::is_same<typename ViewType::array_layout,
1473  Kokkos::LayoutLeft>::value) {
1474  iterate = Kokkos::Iterate::Left;
1475  } else if (std::is_same<typename ViewType::array_layout,
1476  Kokkos::LayoutStride>::value) {
1477  if (strides[0] > strides[ViewType::rank > 0 ? ViewType::rank - 1 : 0])
1478  iterate = Kokkos::Iterate::Right;
1479  else
1480  iterate = Kokkos::Iterate::Left;
1481  } else {
1482  if (std::is_same<typename ViewType::execution_space::array_layout,
1483  Kokkos::LayoutRight>::value)
1484  iterate = Kokkos::Iterate::Right;
1485  else
1486  iterate = Kokkos::Iterate::Left;
1487  }
1488 
1489  // Lets call the right ViewFill functor based on integer space needed and
1490  // iteration type
1491  using ViewTypeUniform =
1492  std::conditional_t<ViewType::rank == 0,
1493  typename ViewType::uniform_runtime_type,
1494  typename ViewType::uniform_runtime_nomemspace_type>;
1495  if (dst.span() > static_cast<size_t>(std::numeric_limits<int>::max())) {
1496  if (iterate == Kokkos::Iterate::Right)
1497  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight,
1498  exec_space_type, ViewType::rank, int64_t>(
1499  dst, value, exec_space_type());
1500  else
1501  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft,
1502  exec_space_type, ViewType::rank, int64_t>(
1503  dst, value, exec_space_type());
1504  } else {
1505  if (iterate == Kokkos::Iterate::Right)
1506  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight,
1507  exec_space_type, ViewType::rank, int>(
1508  dst, value, exec_space_type());
1509  else
1510  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft,
1511  exec_space_type, ViewType::rank, int>(
1512  dst, value, exec_space_type());
1513  }
1514  Kokkos::fence("Kokkos::deep_copy: scalar copy, post copy fence");
1515 
1516  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1517  Kokkos::Profiling::endDeepCopy();
1518  }
1519 }
1520 
1522 template <class ST, class... SP>
1523 inline void deep_copy(
1524  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1525  const View<ST, SP...>& src,
1526  std::enable_if_t<std::is_same<typename ViewTraits<ST, SP...>::specialize,
1527  void>::value>* = nullptr) {
1528  using src_traits = ViewTraits<ST, SP...>;
1529  using src_memory_space = typename src_traits::memory_space;
1530 
1531  static_assert(src_traits::rank == 0,
1532  "ERROR: Non-rank-zero view in deep_copy( value , View )");
1533 
1534  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1535  Kokkos::Profiling::beginDeepCopy(
1536  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
1537  "Scalar", &dst,
1538  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1539  src.label(), src.data(),
1540  src.span() * sizeof(typename src_traits::value_type));
1541  }
1542 
1543  if (src.data() == nullptr) {
1544  Kokkos::fence("Kokkos::deep_copy: copy into scalar, src is null");
1545  } else {
1546  Kokkos::fence("Kokkos::deep_copy: copy into scalar, pre copy fence");
1547  Kokkos::Impl::DeepCopy<HostSpace, src_memory_space>(&dst, src.data(),
1548  sizeof(ST));
1549  Kokkos::fence("Kokkos::deep_copy: copy into scalar, post copy fence");
1550  }
1551 
1552  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1553  Kokkos::Profiling::endDeepCopy();
1554  }
1555 }
1556 
1557 //----------------------------------------------------------------------------
1559 template <class DT, class... DP, class ST, class... SP>
1560 inline void deep_copy(
1561  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1562  std::enable_if_t<
1563  (std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
1564  std::is_void<typename ViewTraits<ST, SP...>::specialize>::value &&
1565  (unsigned(ViewTraits<DT, DP...>::rank) == unsigned(0) &&
1566  unsigned(ViewTraits<ST, SP...>::rank) == unsigned(0)))>* = nullptr) {
1567  using dst_type = View<DT, DP...>;
1568  using src_type = View<ST, SP...>;
1569 
1570  using value_type = typename dst_type::value_type;
1571  using dst_memory_space = typename dst_type::memory_space;
1572  using src_memory_space = typename src_type::memory_space;
1573 
1574  static_assert(std::is_same<typename dst_type::value_type,
1575  typename src_type::non_const_value_type>::value,
1576  "deep_copy requires matching non-const destination type");
1577 
1578  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1579  Kokkos::Profiling::beginDeepCopy(
1580  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
1581  dst.label(), dst.data(),
1582  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1583  src.label(), src.data(),
1584  src.span() * sizeof(typename dst_type::value_type));
1585  }
1586 
1587  if (dst.data() == nullptr && src.data() == nullptr) {
1588  Kokkos::fence(
1589  "Kokkos::deep_copy: scalar to scalar copy, both pointers null");
1590  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1591  Kokkos::Profiling::endDeepCopy();
1592  }
1593  return;
1594  }
1595 
1596  Kokkos::fence("Kokkos::deep_copy: scalar to scalar copy, pre copy fence");
1597  if (dst.data() != src.data()) {
1598  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1599  dst.data(), src.data(), sizeof(value_type));
1600  Kokkos::fence("Kokkos::deep_copy: scalar to scalar copy, post copy fence");
1601  }
1602  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1603  Kokkos::Profiling::endDeepCopy();
1604  }
1605 }
1606 
1607 //----------------------------------------------------------------------------
1611 template <class DT, class... DP, class ST, class... SP>
1612 inline void deep_copy(
1613  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1614  std::enable_if_t<
1615  (std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
1616  std::is_void<typename ViewTraits<ST, SP...>::specialize>::value &&
1617  (unsigned(ViewTraits<DT, DP...>::rank) != 0 ||
1618  unsigned(ViewTraits<ST, SP...>::rank) != 0))>* = nullptr) {
1619  using dst_type = View<DT, DP...>;
1620  using src_type = View<ST, SP...>;
1621  using dst_execution_space = typename dst_type::execution_space;
1622  using src_execution_space = typename src_type::execution_space;
1623  using dst_memory_space = typename dst_type::memory_space;
1624  using src_memory_space = typename src_type::memory_space;
1625  using dst_value_type = typename dst_type::value_type;
1626  using src_value_type = typename src_type::value_type;
1627 
1628  static_assert(std::is_same<typename dst_type::value_type,
1629  typename dst_type::non_const_value_type>::value,
1630  "deep_copy requires non-const destination type");
1631 
1632  static_assert((unsigned(dst_type::rank) == unsigned(src_type::rank)),
1633  "deep_copy requires Views of equal rank");
1634 
1635  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1636  Kokkos::Profiling::beginDeepCopy(
1637  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
1638  dst.label(), dst.data(),
1639  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1640  src.label(), src.data(),
1641  src.span() * sizeof(typename dst_type::value_type));
1642  }
1643 
1644  if (dst.data() == nullptr || src.data() == nullptr) {
1645  // throw if dimension mismatch
1646  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
1647  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
1648  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
1649  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
1650  std::string message(
1651  "Deprecation Error: Kokkos::deep_copy extents of views don't "
1652  "match: ");
1653  message += dst.label();
1654  message += "(";
1655  message += std::to_string(dst.extent(0));
1656  for (size_t r = 1; r < dst_type::rank; r++) {
1657  message += ",";
1658  message += std::to_string(dst.extent(r));
1659  }
1660  message += ") ";
1661  message += src.label();
1662  message += "(";
1663  message += std::to_string(src.extent(0));
1664  for (size_t r = 1; r < src_type::rank; r++) {
1665  message += ",";
1666  message += std::to_string(src.extent(r));
1667  }
1668  message += ") ";
1669 
1670  Kokkos::Impl::throw_runtime_exception(message);
1671  }
1672  Kokkos::fence(
1673  "Kokkos::deep_copy: copy between contiguous views, fence due to null "
1674  "argument");
1675  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1676  Kokkos::Profiling::endDeepCopy();
1677  }
1678  return;
1679  }
1680 
1681  enum {
1682  DstExecCanAccessSrc =
1683  Kokkos::SpaceAccessibility<dst_execution_space,
1684  src_memory_space>::accessible
1685  };
1686 
1687  enum {
1688  SrcExecCanAccessDst =
1689  Kokkos::SpaceAccessibility<src_execution_space,
1690  dst_memory_space>::accessible
1691  };
1692 
1693  // Checking for Overlapping Views.
1694  dst_value_type* dst_start = dst.data();
1695  dst_value_type* dst_end = dst.data() + dst.span();
1696  src_value_type* src_start = src.data();
1697  src_value_type* src_end = src.data() + src.span();
1698  if (((std::ptrdiff_t)dst_start == (std::ptrdiff_t)src_start) &&
1699  ((std::ptrdiff_t)dst_end == (std::ptrdiff_t)src_end) &&
1700  (dst.span_is_contiguous() && src.span_is_contiguous())) {
1701  Kokkos::fence(
1702  "Kokkos::deep_copy: copy between contiguous views, fence due to same "
1703  "spans");
1704  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1705  Kokkos::Profiling::endDeepCopy();
1706  }
1707  return;
1708  }
1709 
1710  if ((((std::ptrdiff_t)dst_start < (std::ptrdiff_t)src_end) &&
1711  ((std::ptrdiff_t)dst_end > (std::ptrdiff_t)src_start)) &&
1712  ((dst.span_is_contiguous() && src.span_is_contiguous()))) {
1713  std::string message("Error: Kokkos::deep_copy of overlapping views: ");
1714  message += dst.label();
1715  message += "(";
1716  message += std::to_string((std::ptrdiff_t)dst_start);
1717  message += ",";
1718  message += std::to_string((std::ptrdiff_t)dst_end);
1719  message += ") ";
1720  message += src.label();
1721  message += "(";
1722  message += std::to_string((std::ptrdiff_t)src_start);
1723  message += ",";
1724  message += std::to_string((std::ptrdiff_t)src_end);
1725  message += ") ";
1726  Kokkos::Impl::throw_runtime_exception(message);
1727  }
1728 
1729  // Check for same extents
1730  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
1731  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
1732  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
1733  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
1734  std::string message(
1735  "Deprecation Error: Kokkos::deep_copy extents of views don't match: ");
1736  message += dst.label();
1737  message += "(";
1738  message += std::to_string(dst.extent(0));
1739  for (size_t r = 1; r < dst_type::rank; r++) {
1740  message += ",";
1741  message += std::to_string(dst.extent(r));
1742  }
1743  message += ") ";
1744  message += src.label();
1745  message += "(";
1746  message += std::to_string(src.extent(0));
1747  for (size_t r = 1; r < src_type::rank; r++) {
1748  message += ",";
1749  message += std::to_string(src.extent(r));
1750  }
1751  message += ") ";
1752 
1753  Kokkos::Impl::throw_runtime_exception(message);
1754  }
1755 
1756  // If same type, equal layout, equal dimensions, equal span, and contiguous
1757  // memory then can byte-wise copy
1758 
1759  if (std::is_same<typename dst_type::value_type,
1760  typename src_type::non_const_value_type>::value &&
1761  (std::is_same<typename dst_type::array_layout,
1762  typename src_type::array_layout>::value ||
1763  (dst_type::rank == 1 && src_type::rank == 1)) &&
1764  dst.span_is_contiguous() && src.span_is_contiguous() &&
1765  ((dst_type::rank < 1) || (dst.stride_0() == src.stride_0())) &&
1766  ((dst_type::rank < 2) || (dst.stride_1() == src.stride_1())) &&
1767  ((dst_type::rank < 3) || (dst.stride_2() == src.stride_2())) &&
1768  ((dst_type::rank < 4) || (dst.stride_3() == src.stride_3())) &&
1769  ((dst_type::rank < 5) || (dst.stride_4() == src.stride_4())) &&
1770  ((dst_type::rank < 6) || (dst.stride_5() == src.stride_5())) &&
1771  ((dst_type::rank < 7) || (dst.stride_6() == src.stride_6())) &&
1772  ((dst_type::rank < 8) || (dst.stride_7() == src.stride_7()))) {
1773  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1774  Kokkos::fence(
1775  "Kokkos::deep_copy: copy between contiguous views, pre view equality "
1776  "check");
1777  if ((void*)dst.data() != (void*)src.data() && 0 < nbytes) {
1778  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1779  dst.data(), src.data(), nbytes);
1780  Kokkos::fence(
1781  "Kokkos::deep_copy: copy between contiguous views, post deep copy "
1782  "fence");
1783  }
1784  } else {
1785  Kokkos::fence(
1786  "Kokkos::deep_copy: copy between contiguous views, pre copy fence");
1787  Impl::view_copy(dst, src);
1788  Kokkos::fence(
1789  "Kokkos::deep_copy: copy between contiguous views, post copy fence");
1790  }
1791  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1792  Kokkos::Profiling::endDeepCopy();
1793  }
1794 }
1795 
1796 //----------------------------------------------------------------------------
1797 //----------------------------------------------------------------------------
1798 namespace Experimental {
1802 template <class TeamType, class DT, class... DP, class ST, class... SP>
1803 void KOKKOS_INLINE_FUNCTION
1804 local_deep_copy_contiguous(const TeamType& team, const View<DT, DP...>& dst,
1805  const View<ST, SP...>& src) {
1806  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, src.span()),
1807  [&](const int& i) { dst.data()[i] = src.data()[i]; });
1808 }
1809 //----------------------------------------------------------------------------
1810 template <class DT, class... DP, class ST, class... SP>
1811 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
1812  const View<DT, DP...>& dst, const View<ST, SP...>& src) {
1813  for (size_t i = 0; i < src.span(); ++i) {
1814  dst.data()[i] = src.data()[i];
1815  }
1816 }
1817 //----------------------------------------------------------------------------
1818 template <class TeamType, class DT, class... DP, class ST, class... SP>
1819 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1820  const TeamType& team, const View<DT, DP...>& dst,
1821  const View<ST, SP...>& src,
1822  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 1 &&
1823  unsigned(ViewTraits<ST, SP...>::rank) == 1)>* = nullptr) {
1824  if (dst.data() == nullptr) {
1825  return;
1826  }
1827 
1828  const size_t N = dst.extent(0);
1829 
1830  team.team_barrier();
1831  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N),
1832  [&](const int& i) { dst(i) = src(i); });
1833  team.team_barrier();
1834 }
1835 //----------------------------------------------------------------------------
1836 template <class TeamType, class DT, class... DP, class ST, class... SP>
1837 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1838  const TeamType& team, const View<DT, DP...>& dst,
1839  const View<ST, SP...>& src,
1840  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 2 &&
1841  unsigned(ViewTraits<ST, SP...>::rank) == 2)>* = nullptr) {
1842  if (dst.data() == nullptr) {
1843  return;
1844  }
1845 
1846  const size_t N = dst.extent(0) * dst.extent(1);
1847 
1848  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1849  team.team_barrier();
1850  local_deep_copy_contiguous(team, dst, src);
1851  team.team_barrier();
1852  } else {
1853  team.team_barrier();
1854  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
1855  int i0 = i % dst.extent(0);
1856  int i1 = i / dst.extent(0);
1857  dst(i0, i1) = src(i0, i1);
1858  });
1859  team.team_barrier();
1860  }
1861 }
1862 //----------------------------------------------------------------------------
1863 template <class TeamType, class DT, class... DP, class ST, class... SP>
1864 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1865  const TeamType& team, const View<DT, DP...>& dst,
1866  const View<ST, SP...>& src,
1867  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 3 &&
1868  unsigned(ViewTraits<ST, SP...>::rank) == 3)>* = nullptr) {
1869  if (dst.data() == nullptr) {
1870  return;
1871  }
1872 
1873  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2);
1874 
1875  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1876  team.team_barrier();
1877  local_deep_copy_contiguous(team, dst, src);
1878  team.team_barrier();
1879  } else {
1880  team.team_barrier();
1881  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
1882  int i0 = i % dst.extent(0);
1883  int itmp = i / dst.extent(0);
1884  int i1 = itmp % dst.extent(1);
1885  int i2 = itmp / dst.extent(1);
1886  dst(i0, i1, i2) = src(i0, i1, i2);
1887  });
1888  team.team_barrier();
1889  }
1890 }
1891 //----------------------------------------------------------------------------
1892 template <class TeamType, class DT, class... DP, class ST, class... SP>
1893 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1894  const TeamType& team, const View<DT, DP...>& dst,
1895  const View<ST, SP...>& src,
1896  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 4 &&
1897  unsigned(ViewTraits<ST, SP...>::rank) == 4)>* = nullptr) {
1898  if (dst.data() == nullptr) {
1899  return;
1900  }
1901 
1902  const size_t N =
1903  dst.extent(0) * dst.extent(1) * dst.extent(2) * dst.extent(3);
1904 
1905  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1906  team.team_barrier();
1907  local_deep_copy_contiguous(team, dst, src);
1908  team.team_barrier();
1909  } else {
1910  team.team_barrier();
1911  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
1912  int i0 = i % dst.extent(0);
1913  int itmp = i / dst.extent(0);
1914  int i1 = itmp % dst.extent(1);
1915  itmp = itmp / dst.extent(1);
1916  int i2 = itmp % dst.extent(2);
1917  int i3 = itmp / dst.extent(2);
1918  dst(i0, i1, i2, i3) = src(i0, i1, i2, i3);
1919  });
1920  team.team_barrier();
1921  }
1922 }
1923 //----------------------------------------------------------------------------
1924 template <class TeamType, class DT, class... DP, class ST, class... SP>
1925 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1926  const TeamType& team, const View<DT, DP...>& dst,
1927  const View<ST, SP...>& src,
1928  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 5 &&
1929  unsigned(ViewTraits<ST, SP...>::rank) == 5)>* = nullptr) {
1930  if (dst.data() == nullptr) {
1931  return;
1932  }
1933 
1934  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1935  dst.extent(3) * dst.extent(4);
1936 
1937  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1938  team.team_barrier();
1939  local_deep_copy_contiguous(team, dst, src);
1940  team.team_barrier();
1941  } else {
1942  team.team_barrier();
1943  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
1944  int i0 = i % dst.extent(0);
1945  int itmp = i / dst.extent(0);
1946  int i1 = itmp % dst.extent(1);
1947  itmp = itmp / dst.extent(1);
1948  int i2 = itmp % dst.extent(2);
1949  itmp = itmp / dst.extent(2);
1950  int i3 = itmp % dst.extent(3);
1951  int i4 = itmp / dst.extent(3);
1952  dst(i0, i1, i2, i3, i4) = src(i0, i1, i2, i3, i4);
1953  });
1954  team.team_barrier();
1955  }
1956 }
1957 //----------------------------------------------------------------------------
1958 template <class TeamType, class DT, class... DP, class ST, class... SP>
1959 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1960  const TeamType& team, const View<DT, DP...>& dst,
1961  const View<ST, SP...>& src,
1962  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 6 &&
1963  unsigned(ViewTraits<ST, SP...>::rank) == 6)>* = nullptr) {
1964  if (dst.data() == nullptr) {
1965  return;
1966  }
1967 
1968  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1969  dst.extent(3) * dst.extent(4) * dst.extent(5);
1970 
1971  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1972  team.team_barrier();
1973  local_deep_copy_contiguous(team, dst, src);
1974  team.team_barrier();
1975  } else {
1976  team.team_barrier();
1977  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
1978  int i0 = i % dst.extent(0);
1979  int itmp = i / dst.extent(0);
1980  int i1 = itmp % dst.extent(1);
1981  itmp = itmp / dst.extent(1);
1982  int i2 = itmp % dst.extent(2);
1983  itmp = itmp / dst.extent(2);
1984  int i3 = itmp % dst.extent(3);
1985  itmp = itmp / dst.extent(3);
1986  int i4 = itmp % dst.extent(4);
1987  int i5 = itmp / dst.extent(4);
1988  dst(i0, i1, i2, i3, i4, i5) = src(i0, i1, i2, i3, i4, i5);
1989  });
1990  team.team_barrier();
1991  }
1992 }
1993 //----------------------------------------------------------------------------
1994 template <class TeamType, class DT, class... DP, class ST, class... SP>
1995 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1996  const TeamType& team, const View<DT, DP...>& dst,
1997  const View<ST, SP...>& src,
1998  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 7 &&
1999  unsigned(ViewTraits<ST, SP...>::rank) == 7)>* = nullptr) {
2000  if (dst.data() == nullptr) {
2001  return;
2002  }
2003 
2004  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2005  dst.extent(3) * dst.extent(4) * dst.extent(5) *
2006  dst.extent(6);
2007 
2008  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2009  team.team_barrier();
2010  local_deep_copy_contiguous(team, dst, src);
2011  team.team_barrier();
2012  } else {
2013  team.team_barrier();
2014  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2015  int i0 = i % dst.extent(0);
2016  int itmp = i / dst.extent(0);
2017  int i1 = itmp % dst.extent(1);
2018  itmp = itmp / dst.extent(1);
2019  int i2 = itmp % dst.extent(2);
2020  itmp = itmp / dst.extent(2);
2021  int i3 = itmp % dst.extent(3);
2022  itmp = itmp / dst.extent(3);
2023  int i4 = itmp % dst.extent(4);
2024  itmp = itmp / dst.extent(4);
2025  int i5 = itmp % dst.extent(5);
2026  int i6 = itmp / dst.extent(5);
2027  dst(i0, i1, i2, i3, i4, i5, i6) = src(i0, i1, i2, i3, i4, i5, i6);
2028  });
2029  team.team_barrier();
2030  }
2031 }
2032 //----------------------------------------------------------------------------
2033 template <class DT, class... DP, class ST, class... SP>
2034 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2035  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2036  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 1 &&
2037  unsigned(ViewTraits<ST, SP...>::rank) == 1)>* = nullptr) {
2038  if (dst.data() == nullptr) {
2039  return;
2040  }
2041 
2042  const size_t N = dst.extent(0);
2043 
2044  for (size_t i = 0; i < N; ++i) {
2045  dst(i) = src(i);
2046  }
2047 }
2048 //----------------------------------------------------------------------------
2049 template <class DT, class... DP, class ST, class... SP>
2050 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2051  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2052  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 2 &&
2053  unsigned(ViewTraits<ST, SP...>::rank) == 2)>* = nullptr) {
2054  if (dst.data() == nullptr) {
2055  return;
2056  }
2057 
2058  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2059  local_deep_copy_contiguous(dst, src);
2060  } else {
2061  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2062  for (size_t i1 = 0; i1 < dst.extent(1); ++i1) dst(i0, i1) = src(i0, i1);
2063  }
2064 }
2065 //----------------------------------------------------------------------------
2066 template <class DT, class... DP, class ST, class... SP>
2067 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2068  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2069  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 3 &&
2070  unsigned(ViewTraits<ST, SP...>::rank) == 3)>* = nullptr) {
2071  if (dst.data() == nullptr) {
2072  return;
2073  }
2074 
2075  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2076  local_deep_copy_contiguous(dst, src);
2077  } else {
2078  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2079  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2080  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2081  dst(i0, i1, i2) = src(i0, i1, i2);
2082  }
2083 }
2084 //----------------------------------------------------------------------------
2085 template <class DT, class... DP, class ST, class... SP>
2086 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2087  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2088  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 4 &&
2089  unsigned(ViewTraits<ST, SP...>::rank) == 4)>* = nullptr) {
2090  if (dst.data() == nullptr) {
2091  return;
2092  }
2093 
2094  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2095  local_deep_copy_contiguous(dst, src);
2096  } else {
2097  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2098  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2099  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2100  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2101  dst(i0, i1, i2, i3) = src(i0, i1, i2, i3);
2102  }
2103 }
2104 //----------------------------------------------------------------------------
2105 template <class DT, class... DP, class ST, class... SP>
2106 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2107  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2108  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 5 &&
2109  unsigned(ViewTraits<ST, SP...>::rank) == 5)>* = nullptr) {
2110  if (dst.data() == nullptr) {
2111  return;
2112  }
2113 
2114  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2115  local_deep_copy_contiguous(dst, src);
2116  } else {
2117  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2118  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2119  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2120  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2121  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2122  dst(i0, i1, i2, i3, i4) = src(i0, i1, i2, i3, i4);
2123  }
2124 }
2125 //----------------------------------------------------------------------------
2126 template <class DT, class... DP, class ST, class... SP>
2127 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2128  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2129  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 6 &&
2130  unsigned(ViewTraits<ST, SP...>::rank) == 6)>* = nullptr) {
2131  if (dst.data() == nullptr) {
2132  return;
2133  }
2134 
2135  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2136  local_deep_copy_contiguous(dst, src);
2137  } else {
2138  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2139  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2140  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2141  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2142  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2143  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2144  dst(i0, i1, i2, i3, i4, i5) = src(i0, i1, i2, i3, i4, i5);
2145  }
2146 }
2147 //----------------------------------------------------------------------------
2148 template <class DT, class... DP, class ST, class... SP>
2149 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2150  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2151  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 7 &&
2152  unsigned(ViewTraits<ST, SP...>::rank) == 7)>* = nullptr) {
2153  if (dst.data() == nullptr) {
2154  return;
2155  }
2156 
2157  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2158  local_deep_copy_contiguous(dst, src);
2159  } else {
2160  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2161  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2162  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2163  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2164  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2165  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2166  for (size_t i6 = 0; i6 < dst.extent(6); ++i6)
2167  dst(i0, i1, i2, i3, i4, i5, i6) =
2168  src(i0, i1, i2, i3, i4, i5, i6);
2169  }
2170 }
2171 //----------------------------------------------------------------------------
2172 //----------------------------------------------------------------------------
2174 template <class TeamType, class DT, class... DP>
2175 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
2176  const TeamType& team, const View<DT, DP...>& dst,
2177  typename ViewTraits<DT, DP...>::const_value_type& value,
2178  std::enable_if_t<std::is_same<typename ViewTraits<DT, DP...>::specialize,
2179  void>::value>* = nullptr) {
2180  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, dst.span()),
2181  [&](const int& i) { dst.data()[i] = value; });
2182 }
2183 //----------------------------------------------------------------------------
2184 template <class DT, class... DP>
2185 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
2186  const View<DT, DP...>& dst,
2187  typename ViewTraits<DT, DP...>::const_value_type& value,
2188  std::enable_if_t<std::is_same<typename ViewTraits<DT, DP...>::specialize,
2189  void>::value>* = nullptr) {
2190  for (size_t i = 0; i < dst.span(); ++i) {
2191  dst.data()[i] = value;
2192  }
2193 }
2194 //----------------------------------------------------------------------------
2195 template <class TeamType, class DT, class... DP>
2196 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2197  const TeamType& team, const View<DT, DP...>& dst,
2198  typename ViewTraits<DT, DP...>::const_value_type& value,
2199  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 1)>* = nullptr) {
2200  if (dst.data() == nullptr) {
2201  return;
2202  }
2203 
2204  const size_t N = dst.extent(0);
2205 
2206  team.team_barrier();
2207  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N),
2208  [&](const int& i) { dst(i) = value; });
2209  team.team_barrier();
2210 }
2211 //----------------------------------------------------------------------------
2212 template <class TeamType, class DT, class... DP>
2213 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2214  const TeamType& team, const View<DT, DP...>& dst,
2215  typename ViewTraits<DT, DP...>::const_value_type& value,
2216  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 2)>* = nullptr) {
2217  if (dst.data() == nullptr) {
2218  return;
2219  }
2220 
2221  const size_t N = dst.extent(0) * dst.extent(1);
2222 
2223  if (dst.span_is_contiguous()) {
2224  team.team_barrier();
2225  local_deep_copy_contiguous(team, dst, value);
2226  team.team_barrier();
2227  } else {
2228  team.team_barrier();
2229  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2230  int i0 = i % dst.extent(0);
2231  int i1 = i / dst.extent(0);
2232  dst(i0, i1) = value;
2233  });
2234  team.team_barrier();
2235  }
2236 }
2237 //----------------------------------------------------------------------------
2238 template <class TeamType, class DT, class... DP>
2239 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2240  const TeamType& team, const View<DT, DP...>& dst,
2241  typename ViewTraits<DT, DP...>::const_value_type& value,
2242  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 3)>* = nullptr) {
2243  if (dst.data() == nullptr) {
2244  return;
2245  }
2246 
2247  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2);
2248 
2249  if (dst.span_is_contiguous()) {
2250  team.team_barrier();
2251  local_deep_copy_contiguous(team, dst, value);
2252  team.team_barrier();
2253  } else {
2254  team.team_barrier();
2255  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2256  int i0 = i % dst.extent(0);
2257  int itmp = i / dst.extent(0);
2258  int i1 = itmp % dst.extent(1);
2259  int i2 = itmp / dst.extent(1);
2260  dst(i0, i1, i2) = value;
2261  });
2262  team.team_barrier();
2263  }
2264 }
2265 //----------------------------------------------------------------------------
2266 template <class TeamType, class DT, class... DP>
2267 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2268  const TeamType& team, const View<DT, DP...>& dst,
2269  typename ViewTraits<DT, DP...>::const_value_type& value,
2270  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 4)>* = nullptr) {
2271  if (dst.data() == nullptr) {
2272  return;
2273  }
2274 
2275  const size_t N =
2276  dst.extent(0) * dst.extent(1) * dst.extent(2) * dst.extent(3);
2277 
2278  if (dst.span_is_contiguous()) {
2279  team.team_barrier();
2280  local_deep_copy_contiguous(team, dst, value);
2281  team.team_barrier();
2282  } else {
2283  team.team_barrier();
2284  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2285  int i0 = i % dst.extent(0);
2286  int itmp = i / dst.extent(0);
2287  int i1 = itmp % dst.extent(1);
2288  itmp = itmp / dst.extent(1);
2289  int i2 = itmp % dst.extent(2);
2290  int i3 = itmp / dst.extent(2);
2291  dst(i0, i1, i2, i3) = value;
2292  });
2293  team.team_barrier();
2294  }
2295 }
2296 //----------------------------------------------------------------------------
2297 template <class TeamType, class DT, class... DP>
2298 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2299  const TeamType& team, const View<DT, DP...>& dst,
2300  typename ViewTraits<DT, DP...>::const_value_type& value,
2301  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 5)>* = nullptr) {
2302  if (dst.data() == nullptr) {
2303  return;
2304  }
2305 
2306  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2307  dst.extent(3) * dst.extent(4);
2308 
2309  if (dst.span_is_contiguous()) {
2310  team.team_barrier();
2311  local_deep_copy_contiguous(team, dst, value);
2312  team.team_barrier();
2313  } else {
2314  team.team_barrier();
2315  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2316  int i0 = i % dst.extent(0);
2317  int itmp = i / dst.extent(0);
2318  int i1 = itmp % dst.extent(1);
2319  itmp = itmp / dst.extent(1);
2320  int i2 = itmp % dst.extent(2);
2321  itmp = itmp / dst.extent(2);
2322  int i3 = itmp % dst.extent(3);
2323  int i4 = itmp / dst.extent(3);
2324  dst(i0, i1, i2, i3, i4) = value;
2325  });
2326  team.team_barrier();
2327  }
2328 }
2329 //----------------------------------------------------------------------------
2330 template <class TeamType, class DT, class... DP>
2331 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2332  const TeamType& team, const View<DT, DP...>& dst,
2333  typename ViewTraits<DT, DP...>::const_value_type& value,
2334  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 6)>* = nullptr) {
2335  if (dst.data() == nullptr) {
2336  return;
2337  }
2338 
2339  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2340  dst.extent(3) * dst.extent(4) * dst.extent(5);
2341 
2342  if (dst.span_is_contiguous()) {
2343  team.team_barrier();
2344  local_deep_copy_contiguous(team, dst, value);
2345  team.team_barrier();
2346  } else {
2347  team.team_barrier();
2348  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2349  int i0 = i % dst.extent(0);
2350  int itmp = i / dst.extent(0);
2351  int i1 = itmp % dst.extent(1);
2352  itmp = itmp / dst.extent(1);
2353  int i2 = itmp % dst.extent(2);
2354  itmp = itmp / dst.extent(2);
2355  int i3 = itmp % dst.extent(3);
2356  itmp = itmp / dst.extent(3);
2357  int i4 = itmp % dst.extent(4);
2358  int i5 = itmp / dst.extent(4);
2359  dst(i0, i1, i2, i3, i4, i5) = value;
2360  });
2361  team.team_barrier();
2362  }
2363 }
2364 //----------------------------------------------------------------------------
2365 template <class TeamType, class DT, class... DP>
2366 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2367  const TeamType& team, const View<DT, DP...>& dst,
2368  typename ViewTraits<DT, DP...>::const_value_type& value,
2369  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 7)>* = nullptr) {
2370  if (dst.data() == nullptr) {
2371  return;
2372  }
2373 
2374  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2375  dst.extent(3) * dst.extent(4) * dst.extent(5) *
2376  dst.extent(6);
2377 
2378  if (dst.span_is_contiguous()) {
2379  team.team_barrier();
2380  local_deep_copy_contiguous(team, dst, value);
2381  team.team_barrier();
2382  } else {
2383  team.team_barrier();
2384  Kokkos::parallel_for(Kokkos::TeamVectorRange(team, N), [&](const int& i) {
2385  int i0 = i % dst.extent(0);
2386  int itmp = i / dst.extent(0);
2387  int i1 = itmp % dst.extent(1);
2388  itmp = itmp / dst.extent(1);
2389  int i2 = itmp % dst.extent(2);
2390  itmp = itmp / dst.extent(2);
2391  int i3 = itmp % dst.extent(3);
2392  itmp = itmp / dst.extent(3);
2393  int i4 = itmp % dst.extent(4);
2394  itmp = itmp / dst.extent(4);
2395  int i5 = itmp % dst.extent(5);
2396  int i6 = itmp / dst.extent(5);
2397  dst(i0, i1, i2, i3, i4, i5, i6) = value;
2398  });
2399  team.team_barrier();
2400  }
2401 }
2402 //----------------------------------------------------------------------------
2403 template <class DT, class... DP>
2404 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2405  const View<DT, DP...>& dst,
2406  typename ViewTraits<DT, DP...>::const_value_type& value,
2407  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 1)>* = nullptr) {
2408  if (dst.data() == nullptr) {
2409  return;
2410  }
2411 
2412  const size_t N = dst.extent(0);
2413 
2414  for (size_t i = 0; i < N; ++i) {
2415  dst(i) = value;
2416  }
2417 }
2418 //----------------------------------------------------------------------------
2419 template <class DT, class... DP>
2420 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2421  const View<DT, DP...>& dst,
2422  typename ViewTraits<DT, DP...>::const_value_type& value,
2423  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 2)>* = nullptr) {
2424  if (dst.data() == nullptr) {
2425  return;
2426  }
2427 
2428  if (dst.span_is_contiguous()) {
2429  local_deep_copy_contiguous(dst, value);
2430  } else {
2431  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2432  for (size_t i1 = 0; i1 < dst.extent(1); ++i1) dst(i0, i1) = value;
2433  }
2434 }
2435 //----------------------------------------------------------------------------
2436 template <class DT, class... DP>
2437 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2438  const View<DT, DP...>& dst,
2439  typename ViewTraits<DT, DP...>::const_value_type& value,
2440  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 3)>* = nullptr) {
2441  if (dst.data() == nullptr) {
2442  return;
2443  }
2444 
2445  if (dst.span_is_contiguous()) {
2446  local_deep_copy_contiguous(dst, value);
2447  } else {
2448  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2449  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2450  for (size_t i2 = 0; i2 < dst.extent(2); ++i2) dst(i0, i1, i2) = value;
2451  }
2452 }
2453 //----------------------------------------------------------------------------
2454 template <class DT, class... DP>
2455 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2456  const View<DT, DP...>& dst,
2457  typename ViewTraits<DT, DP...>::const_value_type& value,
2458  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 4)>* = nullptr) {
2459  if (dst.data() == nullptr) {
2460  return;
2461  }
2462 
2463  if (dst.span_is_contiguous()) {
2464  local_deep_copy_contiguous(dst, value);
2465  } else {
2466  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2467  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2468  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2469  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2470  dst(i0, i1, i2, i3) = value;
2471  }
2472 }
2473 //----------------------------------------------------------------------------
2474 template <class DT, class... DP>
2475 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2476  const View<DT, DP...>& dst,
2477  typename ViewTraits<DT, DP...>::const_value_type& value,
2478  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 5)>* = nullptr) {
2479  if (dst.data() == nullptr) {
2480  return;
2481  }
2482 
2483  if (dst.span_is_contiguous()) {
2484  local_deep_copy_contiguous(dst, value);
2485  } else {
2486  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2487  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2488  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2489  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2490  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2491  dst(i0, i1, i2, i3, i4) = value;
2492  }
2493 }
2494 //----------------------------------------------------------------------------
2495 template <class DT, class... DP>
2496 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2497  const View<DT, DP...>& dst,
2498  typename ViewTraits<DT, DP...>::const_value_type& value,
2499  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 6)>* = nullptr) {
2500  if (dst.data() == nullptr) {
2501  return;
2502  }
2503 
2504  if (dst.span_is_contiguous()) {
2505  local_deep_copy_contiguous(dst, value);
2506  } else {
2507  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2508  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2509  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2510  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2511  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2512  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2513  dst(i0, i1, i2, i3, i4, i5) = value;
2514  }
2515 }
2516 //----------------------------------------------------------------------------
2517 template <class DT, class... DP>
2518 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2519  const View<DT, DP...>& dst,
2520  typename ViewTraits<DT, DP...>::const_value_type& value,
2521  std::enable_if_t<(unsigned(ViewTraits<DT, DP...>::rank) == 7)>* = nullptr) {
2522  if (dst.data() == nullptr) {
2523  return;
2524  }
2525 
2526  if (dst.span_is_contiguous()) {
2527  local_deep_copy_contiguous(dst, value);
2528  } else {
2529  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2530  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2531  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2532  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2533  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2534  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2535  for (size_t i6 = 0; i6 < dst.extent(6); ++i6)
2536  dst(i0, i1, i2, i3, i4, i5, i6) = value;
2537  }
2538 }
2539 } /* namespace Experimental */
2540 } /* namespace Kokkos */
2541 
2542 //----------------------------------------------------------------------------
2543 //----------------------------------------------------------------------------
2544 
2545 namespace Kokkos {
2546 
2549 template <class ExecSpace, class DT, class... DP>
2550 inline void deep_copy(
2551  const ExecSpace& space, const View<DT, DP...>& dst,
2552  typename ViewTraits<DT, DP...>::const_value_type& value,
2553  std::enable_if_t<
2554  Kokkos::is_execution_space<ExecSpace>::value &&
2555  std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
2556  Kokkos::SpaceAccessibility<ExecSpace, typename ViewTraits<DT, DP...>::
2557  memory_space>::accessible>* =
2558  nullptr) {
2559  using dst_traits = ViewTraits<DT, DP...>;
2560  static_assert(std::is_same<typename dst_traits::non_const_value_type,
2561  typename dst_traits::value_type>::value,
2562  "deep_copy requires non-const type");
2563  using dst_memory_space = typename dst_traits::memory_space;
2564  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2565  Kokkos::Profiling::beginDeepCopy(
2566  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2567  dst.label(), dst.data(),
2568  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2569  "(none)", &value, dst.span() * sizeof(typename dst_traits::value_type));
2570  }
2571  if (dst.data() == nullptr) {
2572  space.fence("Kokkos::deep_copy: scalar copy on space, dst data is null");
2573  } else if (dst.span_is_contiguous()) {
2574  Impl::contiguous_fill_or_memset(space, dst, value);
2575  } else {
2576  using ViewType = View<DT, DP...>;
2577  // Figure out iteration order to do the ViewFill
2578  int64_t strides[ViewType::rank + 1];
2579  dst.stride(strides);
2580  Kokkos::Iterate iterate;
2581  if (std::is_same<typename ViewType::array_layout,
2582  Kokkos::LayoutRight>::value) {
2583  iterate = Kokkos::Iterate::Right;
2584  } else if (std::is_same<typename ViewType::array_layout,
2585  Kokkos::LayoutLeft>::value) {
2586  iterate = Kokkos::Iterate::Left;
2587  } else if (std::is_same<typename ViewType::array_layout,
2588  Kokkos::LayoutStride>::value) {
2589  if (strides[0] > strides[ViewType::rank > 0 ? ViewType::rank - 1 : 0])
2590  iterate = Kokkos::Iterate::Right;
2591  else
2592  iterate = Kokkos::Iterate::Left;
2593  } else {
2594  if (std::is_same<typename ViewType::execution_space::array_layout,
2595  Kokkos::LayoutRight>::value)
2596  iterate = Kokkos::Iterate::Right;
2597  else
2598  iterate = Kokkos::Iterate::Left;
2599  }
2600 
2601  // Lets call the right ViewFill functor based on integer space needed and
2602  // iteration type
2603  using ViewTypeUniform =
2604  std::conditional_t<ViewType::rank == 0,
2605  typename ViewType::uniform_runtime_type,
2606  typename ViewType::uniform_runtime_nomemspace_type>;
2607  if (dst.span() > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
2608  if (iterate == Kokkos::Iterate::Right)
2609  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight, ExecSpace,
2610  ViewType::rank, int64_t>(dst, value, space);
2611  else
2612  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft, ExecSpace,
2613  ViewType::rank, int64_t>(dst, value, space);
2614  } else {
2615  if (iterate == Kokkos::Iterate::Right)
2616  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight, ExecSpace,
2617  ViewType::rank, int32_t>(dst, value, space);
2618  else
2619  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft, ExecSpace,
2620  ViewType::rank, int32_t>(dst, value, space);
2621  }
2622  }
2623  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2624  Kokkos::Profiling::endDeepCopy();
2625  }
2626 }
2627 
2630 template <class ExecSpace, class DT, class... DP>
2631 inline void deep_copy(
2632  const ExecSpace& space, const View<DT, DP...>& dst,
2633  typename ViewTraits<DT, DP...>::const_value_type& value,
2634  std::enable_if_t<
2635  Kokkos::is_execution_space<ExecSpace>::value &&
2636  std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
2637  !Kokkos::SpaceAccessibility<ExecSpace, typename ViewTraits<DT, DP...>::
2638  memory_space>::accessible>* =
2639  nullptr) {
2640  using dst_traits = ViewTraits<DT, DP...>;
2641  static_assert(std::is_same<typename dst_traits::non_const_value_type,
2642  typename dst_traits::value_type>::value,
2643  "deep_copy requires non-const type");
2644  using dst_memory_space = typename dst_traits::memory_space;
2645  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2646  Kokkos::Profiling::beginDeepCopy(
2647  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2648  dst.label(), dst.data(),
2649  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2650  "(none)", &value, dst.span() * sizeof(typename dst_traits::value_type));
2651  }
2652  if (dst.data() == nullptr) {
2653  space.fence(
2654  "Kokkos::deep_copy: scalar-to-view copy on space, dst data is null");
2655  } else {
2656  space.fence("Kokkos::deep_copy: scalar-to-view copy on space, pre copy");
2657  using fill_exec_space = typename dst_traits::memory_space::execution_space;
2658  if (dst.span_is_contiguous()) {
2659  Impl::contiguous_fill_or_memset(fill_exec_space(), dst, value);
2660  } else {
2661  using ViewTypeUniform = std::conditional_t<
2662  View<DT, DP...>::rank == 0,
2663  typename View<DT, DP...>::uniform_runtime_type,
2664  typename View<DT, DP...>::uniform_runtime_nomemspace_type>;
2665  Kokkos::Impl::ViewFill<ViewTypeUniform, typename dst_traits::array_layout,
2666  fill_exec_space>(dst, value, fill_exec_space());
2667  }
2668  fill_exec_space().fence(
2669  "Kokkos::deep_copy: scalar-to-view copy on space, fence after fill");
2670  }
2671  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2672  Kokkos::Profiling::endDeepCopy();
2673  }
2674 }
2675 
2677 template <class ExecSpace, class ST, class... SP>
2678 inline void deep_copy(
2679  const ExecSpace& exec_space,
2680  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
2681  const View<ST, SP...>& src,
2682  std::enable_if_t<Kokkos::is_execution_space<ExecSpace>::value &&
2683  std::is_same<typename ViewTraits<ST, SP...>::specialize,
2684  void>::value>* = nullptr) {
2685  using src_traits = ViewTraits<ST, SP...>;
2686  using src_memory_space = typename src_traits::memory_space;
2687  static_assert(src_traits::rank == 0,
2688  "ERROR: Non-rank-zero view in deep_copy( value , View )");
2689  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2690  Kokkos::Profiling::beginDeepCopy(
2691  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2692  "(none)", &dst,
2693  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2694  src.label(), src.data(), sizeof(ST));
2695  }
2696 
2697  if (src.data() == nullptr) {
2698  exec_space.fence(
2699  "Kokkos::deep_copy: view-to-scalar copy on space, src data is null");
2700  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2701  Kokkos::Profiling::endDeepCopy();
2702  }
2703  return;
2704  }
2705 
2706  Kokkos::Impl::DeepCopy<HostSpace, src_memory_space, ExecSpace>(
2707  exec_space, &dst, src.data(), sizeof(ST));
2708  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2709  Kokkos::Profiling::endDeepCopy();
2710  }
2711 }
2712 
2713 //----------------------------------------------------------------------------
2715 template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2716 inline void deep_copy(
2717  const ExecSpace& exec_space, const View<DT, DP...>& dst,
2718  const View<ST, SP...>& src,
2719  std::enable_if_t<
2720  (Kokkos::is_execution_space<ExecSpace>::value &&
2721  std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
2722  std::is_void<typename ViewTraits<ST, SP...>::specialize>::value &&
2723  (unsigned(ViewTraits<DT, DP...>::rank) == unsigned(0) &&
2724  unsigned(ViewTraits<ST, SP...>::rank) == unsigned(0)))>* = nullptr) {
2725  using src_traits = ViewTraits<ST, SP...>;
2726  using dst_traits = ViewTraits<DT, DP...>;
2727 
2728  using src_memory_space = typename src_traits::memory_space;
2729  using dst_memory_space = typename dst_traits::memory_space;
2730  static_assert(std::is_same<typename dst_traits::value_type,
2731  typename src_traits::non_const_value_type>::value,
2732  "deep_copy requires matching non-const destination type");
2733 
2734  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2735  Kokkos::Profiling::beginDeepCopy(
2736  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2737  dst.label(), dst.data(),
2738  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2739  src.label(), src.data(), sizeof(DT));
2740  }
2741 
2742  if (dst.data() == nullptr && src.data() == nullptr) {
2743  exec_space.fence(
2744  "Kokkos::deep_copy: view-to-view copy on space, data is null");
2745  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2746  Kokkos::Profiling::endDeepCopy();
2747  }
2748  return;
2749  }
2750 
2751  if (dst.data() != src.data()) {
2752  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space, ExecSpace>(
2753  exec_space, dst.data(), src.data(),
2754  sizeof(typename dst_traits::value_type));
2755  }
2756  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2757  Kokkos::Profiling::endDeepCopy();
2758  }
2759 }
2760 
2761 //----------------------------------------------------------------------------
2765 template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2766 inline void deep_copy(
2767  const ExecSpace& exec_space, const View<DT, DP...>& dst,
2768  const View<ST, SP...>& src,
2769  std::enable_if_t<
2770  (Kokkos::is_execution_space<ExecSpace>::value &&
2771  std::is_void<typename ViewTraits<DT, DP...>::specialize>::value &&
2772  std::is_void<typename ViewTraits<ST, SP...>::specialize>::value &&
2773  (unsigned(ViewTraits<DT, DP...>::rank) != 0 ||
2774  unsigned(ViewTraits<ST, SP...>::rank) != 0))>* = nullptr) {
2775  using dst_type = View<DT, DP...>;
2776  using src_type = View<ST, SP...>;
2777 
2778  static_assert(std::is_same<typename dst_type::value_type,
2779  typename dst_type::non_const_value_type>::value,
2780  "deep_copy requires non-const destination type");
2781 
2782  static_assert((unsigned(dst_type::rank) == unsigned(src_type::rank)),
2783  "deep_copy requires Views of equal rank");
2784 
2785  using dst_execution_space = typename dst_type::execution_space;
2786  using src_execution_space = typename src_type::execution_space;
2787  using dst_memory_space = typename dst_type::memory_space;
2788  using src_memory_space = typename src_type::memory_space;
2789  using dst_value_type = typename dst_type::value_type;
2790  using src_value_type = typename src_type::value_type;
2791 
2792  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2793  Kokkos::Profiling::beginDeepCopy(
2794  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2795  dst.label(), dst.data(),
2796  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2797  src.label(), src.data(), dst.span() * sizeof(dst_value_type));
2798  }
2799 
2800  dst_value_type* dst_start = dst.data();
2801  dst_value_type* dst_end = dst.data() + dst.span();
2802  src_value_type* src_start = src.data();
2803  src_value_type* src_end = src.data() + src.span();
2804 
2805  // Early dropout if identical range
2806  if ((dst_start == nullptr || src_start == nullptr) ||
2807  ((std::ptrdiff_t(dst_start) == std::ptrdiff_t(src_start)) &&
2808  (std::ptrdiff_t(dst_end) == std::ptrdiff_t(src_end)))) {
2809  // throw if dimension mismatch
2810  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
2811  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
2812  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
2813  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
2814  std::string message(
2815  "Deprecation Error: Kokkos::deep_copy extents of views don't "
2816  "match: ");
2817  message += dst.label();
2818  message += "(";
2819  message += std::to_string(dst.extent(0));
2820  for (size_t r = 1; r < dst_type::rank; r++) {
2821  message += ",";
2822  message += std::to_string(dst.extent(r));
2823  }
2824  message += ") ";
2825  message += src.label();
2826  message += "(";
2827  message += std::to_string(src.extent(0));
2828  for (size_t r = 1; r < src_type::rank; r++) {
2829  message += ",";
2830  message += std::to_string(src.extent(r));
2831  }
2832  message += ") ";
2833 
2834  Kokkos::Impl::throw_runtime_exception(message);
2835  }
2836  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2837  Kokkos::Profiling::endDeepCopy();
2838  }
2839  return;
2840  }
2841 
2842  enum {
2843  ExecCanAccessSrcDst =
2846  };
2847  enum {
2848  DstExecCanAccessSrc =
2849  Kokkos::SpaceAccessibility<dst_execution_space,
2850  src_memory_space>::accessible
2851  };
2852 
2853  enum {
2854  SrcExecCanAccessDst =
2855  Kokkos::SpaceAccessibility<src_execution_space,
2856  dst_memory_space>::accessible
2857  };
2858 
2859  // Error out for non-identical overlapping views.
2860  if ((((std::ptrdiff_t)dst_start < (std::ptrdiff_t)src_end) &&
2861  ((std::ptrdiff_t)dst_end > (std::ptrdiff_t)src_start)) &&
2862  ((dst.span_is_contiguous() && src.span_is_contiguous()))) {
2863  std::string message("Error: Kokkos::deep_copy of overlapping views: ");
2864  message += dst.label();
2865  message += "(";
2866  message += std::to_string((std::ptrdiff_t)dst_start);
2867  message += ",";
2868  message += std::to_string((std::ptrdiff_t)dst_end);
2869  message += ") ";
2870  message += src.label();
2871  message += "(";
2872  message += std::to_string((std::ptrdiff_t)src_start);
2873  message += ",";
2874  message += std::to_string((std::ptrdiff_t)src_end);
2875  message += ") ";
2876  Kokkos::Impl::throw_runtime_exception(message);
2877  }
2878 
2879  // Check for same extents
2880  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
2881  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
2882  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
2883  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
2884  std::string message(
2885  "Deprecation Error: Kokkos::deep_copy extents of views don't match: ");
2886  message += dst.label();
2887  message += "(";
2888  message += std::to_string(dst.extent(0));
2889  for (size_t r = 1; r < dst_type::rank; r++) {
2890  message += ",";
2891  message += std::to_string(dst.extent(r));
2892  }
2893  message += ") ";
2894  message += src.label();
2895  message += "(";
2896  message += std::to_string(src.extent(0));
2897  for (size_t r = 1; r < src_type::rank; r++) {
2898  message += ",";
2899  message += std::to_string(src.extent(r));
2900  }
2901  message += ") ";
2902 
2903  Kokkos::Impl::throw_runtime_exception(message);
2904  }
2905 
2906  // If same type, equal layout, equal dimensions, equal span, and contiguous
2907  // memory then can byte-wise copy
2908 
2909  if (std::is_same<typename dst_type::value_type,
2910  typename src_type::non_const_value_type>::value &&
2911  (std::is_same<typename dst_type::array_layout,
2912  typename src_type::array_layout>::value ||
2913  (dst_type::rank == 1 && src_type::rank == 1)) &&
2914  dst.span_is_contiguous() && src.span_is_contiguous() &&
2915  ((dst_type::rank < 1) || (dst.stride_0() == src.stride_0())) &&
2916  ((dst_type::rank < 2) || (dst.stride_1() == src.stride_1())) &&
2917  ((dst_type::rank < 3) || (dst.stride_2() == src.stride_2())) &&
2918  ((dst_type::rank < 4) || (dst.stride_3() == src.stride_3())) &&
2919  ((dst_type::rank < 5) || (dst.stride_4() == src.stride_4())) &&
2920  ((dst_type::rank < 6) || (dst.stride_5() == src.stride_5())) &&
2921  ((dst_type::rank < 7) || (dst.stride_6() == src.stride_6())) &&
2922  ((dst_type::rank < 8) || (dst.stride_7() == src.stride_7()))) {
2923  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
2924  if ((void*)dst.data() != (void*)src.data() && 0 < nbytes) {
2925  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space, ExecSpace>(
2926  exec_space, dst.data(), src.data(), nbytes);
2927  }
2928  } else {
2929  // Copying data between views in accessible memory spaces and either
2930  // non-contiguous or incompatible shape.
2931  if (ExecCanAccessSrcDst) {
2932  Impl::view_copy(exec_space, dst, src);
2933  } else if (DstExecCanAccessSrc || SrcExecCanAccessDst) {
2934  using cpy_exec_space =
2935  std::conditional_t<DstExecCanAccessSrc, dst_execution_space,
2936  src_execution_space>;
2937  exec_space.fence(
2938  "Kokkos::deep_copy: view-to-view noncontiguous copy on space, pre "
2939  "copy");
2940  Impl::view_copy(cpy_exec_space(), dst, src);
2941  cpy_exec_space().fence(
2942  "Kokkos::deep_copy: view-to-view noncontiguous copy on space, post "
2943  "copy");
2944  } else {
2945  Kokkos::Impl::throw_runtime_exception(
2946  "deep_copy given views that would require a temporary allocation");
2947  }
2948  }
2949  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2950  Kokkos::Profiling::endDeepCopy();
2951  }
2952 }
2953 
2954 } /* namespace Kokkos */
2955 
2956 //----------------------------------------------------------------------------
2957 //----------------------------------------------------------------------------
2958 
2959 namespace Kokkos {
2960 
2961 namespace Impl {
2962 template <typename ViewType>
2963 bool size_mismatch(const ViewType& view, unsigned int max_extent,
2964  const size_t new_extents[8]) {
2965  for (unsigned int dim = 0; dim < max_extent; ++dim)
2966  if (new_extents[dim] != view.extent(dim)) {
2967  return true;
2968  }
2969  for (unsigned int dim = max_extent; dim < 8; ++dim)
2970  if (new_extents[dim] != KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
2971  return true;
2972  }
2973  return false;
2974 }
2975 
2976 } // namespace Impl
2977 
2980 template <class T, class... P, class... ViewCtorArgs>
2981 inline typename std::enable_if<
2982  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2983  Kokkos::LayoutLeft>::value ||
2984  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2985  Kokkos::LayoutRight>::value>::type
2986 impl_resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
2987  Kokkos::View<T, P...>& v, const size_t n0, const size_t n1,
2988  const size_t n2, const size_t n3, const size_t n4, const size_t n5,
2989  const size_t n6, const size_t n7) {
2990  using view_type = Kokkos::View<T, P...>;
2991  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
2992 
2994  "Can only resize managed views");
2995  static_assert(!alloc_prop_input::has_label,
2996  "The view constructor arguments passed to Kokkos::resize "
2997  "must not include a label!");
2998  static_assert(!alloc_prop_input::has_pointer,
2999  "The view constructor arguments passed to Kokkos::resize must "
3000  "not include a pointer!");
3001  static_assert(!alloc_prop_input::has_memory_space,
3002  "The view constructor arguments passed to Kokkos::resize must "
3003  "not include a memory space instance!");
3004 
3005  // TODO (mfh 27 Jun 2017) If the old View has enough space but just
3006  // different dimensions (e.g., if the product of the dimensions,
3007  // including extra space for alignment, will not change), then
3008  // consider just reusing storage. For now, Kokkos always
3009  // reallocates if any of the dimensions change, even if the old View
3010  // has enough space.
3011 
3012  const size_t new_extents[8] = {n0, n1, n2, n3, n4, n5, n6, n7};
3013  const bool sizeMismatch = Impl::size_mismatch(v, v.rank_dynamic, new_extents);
3014 
3015  if (sizeMismatch) {
3016  auto prop_copy = Impl::with_properties_if_unset(
3017  arg_prop, typename view_type::execution_space{}, v.label());
3018 
3019  view_type v_resized(prop_copy, n0, n1, n2, n3, n4, n5, n6, n7);
3020 
3021  if constexpr (alloc_prop_input::has_execution_space)
3022  Kokkos::Impl::ViewRemap<view_type, view_type>(
3023  v_resized, v, Impl::get_property<Impl::ExecutionSpaceTag>(prop_copy));
3024  else {
3025  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
3026  Kokkos::fence("Kokkos::resize(View)");
3027  }
3028 
3029  v = v_resized;
3030  }
3031 }
3032 
3033 template <class T, class... P, class... ViewCtorArgs>
3034 inline std::enable_if_t<
3035  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3036  Kokkos::LayoutLeft>::value ||
3037  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3038  Kokkos::LayoutRight>::value>
3039 resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3040  Kokkos::View<T, P...>& v, const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3041  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3042  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3043  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3044  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3045  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3046  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3047  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3048  impl_resize(arg_prop, v, n0, n1, n2, n3, n4, n5, n6, n7);
3049 }
3050 
3051 template <class T, class... P>
3052 inline std::enable_if_t<
3053  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3054  Kokkos::LayoutLeft>::value ||
3055  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3056  Kokkos::LayoutRight>::value>
3057 resize(Kokkos::View<T, P...>& v, const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3058  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3059  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3060  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3061  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3062  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3063  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3064  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3065  impl_resize(Impl::ViewCtorProp<>{}, v, n0, n1, n2, n3, n4, n5, n6, n7);
3066 }
3067 
3068 template <class I, class T, class... P>
3069 inline std::enable_if_t<
3070  (Impl::is_view_ctor_property<I>::value ||
3071  Kokkos::is_execution_space<I>::value) &&
3072  (std::is_same<typename Kokkos::View<T, P...>::array_layout,
3073  Kokkos::LayoutLeft>::value ||
3074  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3075  Kokkos::LayoutRight>::value)>
3076 resize(const I& arg_prop, Kokkos::View<T, P...>& v,
3077  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3078  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3079  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3080  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3081  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3082  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3083  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3084  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3085  impl_resize(Kokkos::view_alloc(arg_prop), v, n0, n1, n2, n3, n4, n5, n6, n7);
3086 }
3087 
3088 template <class T, class... P, class... ViewCtorArgs>
3089 inline std::enable_if_t<
3090  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3091  Kokkos::LayoutLeft>::value ||
3092  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3093  Kokkos::LayoutRight>::value ||
3094  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3095  Kokkos::LayoutStride>::value ||
3096  is_layouttiled<typename Kokkos::View<T, P...>::array_layout>::value>
3097 impl_resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3099  const typename Kokkos::View<T, P...>::array_layout& layout) {
3100  using view_type = Kokkos::View<T, P...>;
3101  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3102 
3104  "Can only resize managed views");
3105  static_assert(!alloc_prop_input::has_label,
3106  "The view constructor arguments passed to Kokkos::resize "
3107  "must not include a label!");
3108  static_assert(!alloc_prop_input::has_pointer,
3109  "The view constructor arguments passed to Kokkos::resize must "
3110  "not include a pointer!");
3111  static_assert(!alloc_prop_input::has_memory_space,
3112  "The view constructor arguments passed to Kokkos::resize must "
3113  "not include a memory space instance!");
3114 
3115  if (v.layout() != layout) {
3116  auto prop_copy = Impl::with_properties_if_unset(arg_prop, v.label());
3117 
3118  view_type v_resized(prop_copy, layout);
3119 
3120  if constexpr (alloc_prop_input::has_execution_space)
3121  Kokkos::Impl::ViewRemap<view_type, view_type>(
3122  v_resized, v, Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop));
3123  else {
3124  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
3125  Kokkos::fence("Kokkos::resize(View)");
3126  }
3127 
3128  v = v_resized;
3129  }
3130 }
3131 
3132 // FIXME User-provided (custom) layouts are not required to have a comparison
3133 // operator. Hence, there is no way to check if the requested layout is actually
3134 // the same as the existing one.
3135 template <class T, class... P, class... ViewCtorArgs>
3136 inline std::enable_if_t<
3137  !(std::is_same<typename Kokkos::View<T, P...>::array_layout,
3138  Kokkos::LayoutLeft>::value ||
3139  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3140  Kokkos::LayoutRight>::value ||
3141  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3142  Kokkos::LayoutStride>::value ||
3143  is_layouttiled<typename Kokkos::View<T, P...>::array_layout>::value)>
3144 impl_resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3146  const typename Kokkos::View<T, P...>::array_layout& layout) {
3147  using view_type = Kokkos::View<T, P...>;
3148  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3149 
3151  "Can only resize managed views");
3152  static_assert(!alloc_prop_input::has_label,
3153  "The view constructor arguments passed to Kokkos::resize "
3154  "must not include a label!");
3155  static_assert(!alloc_prop_input::has_pointer,
3156  "The view constructor arguments passed to Kokkos::resize must "
3157  "not include a pointer!");
3158  static_assert(!alloc_prop_input::has_memory_space,
3159  "The view constructor arguments passed to Kokkos::resize must "
3160  "not include a memory space instance!");
3161 
3162  auto prop_copy = Impl::with_properties_if_unset(arg_prop, v.label());
3163 
3164  view_type v_resized(prop_copy, layout);
3165 
3166  if constexpr (alloc_prop_input::has_execution_space)
3167  Kokkos::Impl::ViewRemap<view_type, view_type>(
3168  v_resized, v, Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop));
3169  else {
3170  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
3171  Kokkos::fence("Kokkos::resize(View)");
3172  }
3173 
3174  v = v_resized;
3175 }
3176 
3177 template <class T, class... P, class... ViewCtorArgs>
3178 inline void resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3180  const typename Kokkos::View<T, P...>::array_layout& layout) {
3181  impl_resize(arg_prop, v, layout);
3182 }
3183 
3184 template <class I, class T, class... P>
3185 inline std::enable_if_t<Impl::is_view_ctor_property<I>::value ||
3186  Kokkos::is_execution_space<I>::value>
3187 resize(const I& arg_prop, Kokkos::View<T, P...>& v,
3188  const typename Kokkos::View<T, P...>::array_layout& layout) {
3189  impl_resize(arg_prop, v, layout);
3190 }
3191 
3192 template <class ExecutionSpace, class T, class... P>
3193 inline void resize(const ExecutionSpace& exec_space, Kokkos::View<T, P...>& v,
3194  const typename Kokkos::View<T, P...>::array_layout& layout) {
3195  impl_resize(Impl::ViewCtorProp<>(), exec_space, v, layout);
3196 }
3197 
3198 template <class T, class... P>
3199 inline void resize(Kokkos::View<T, P...>& v,
3200  const typename Kokkos::View<T, P...>::array_layout& layout) {
3201  impl_resize(Impl::ViewCtorProp<>{}, v, layout);
3202 }
3203 
3205 template <class T, class... P, class... ViewCtorArgs>
3206 inline std::enable_if_t<
3207  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3208  Kokkos::LayoutLeft>::value ||
3209  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3210  Kokkos::LayoutRight>::value>
3211 impl_realloc(Kokkos::View<T, P...>& v, const size_t n0, const size_t n1,
3212  const size_t n2, const size_t n3, const size_t n4, const size_t n5,
3213  const size_t n6, const size_t n7,
3214  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3215  using view_type = Kokkos::View<T, P...>;
3216  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3217 
3219  "Can only realloc managed views");
3220  static_assert(!alloc_prop_input::has_label,
3221  "The view constructor arguments passed to Kokkos::realloc must "
3222  "not include a label!");
3223  static_assert(!alloc_prop_input::has_pointer,
3224  "The view constructor arguments passed to Kokkos::realloc must "
3225  "not include a pointer!");
3226  static_assert(!alloc_prop_input::has_memory_space,
3227  "The view constructor arguments passed to Kokkos::realloc must "
3228  "not include a memory space instance!");
3229 
3230  const size_t new_extents[8] = {n0, n1, n2, n3, n4, n5, n6, n7};
3231  const bool sizeMismatch = Impl::size_mismatch(v, v.rank_dynamic, new_extents);
3232 
3233  if (sizeMismatch) {
3234  auto arg_prop_copy = Impl::with_properties_if_unset(arg_prop, v.label());
3235  v = view_type(); // Best effort to deallocate in case no other view refers
3236  // to the shared allocation
3237  v = view_type(arg_prop_copy, n0, n1, n2, n3, n4, n5, n6, n7);
3238  } else if (alloc_prop_input::initialize) {
3239  if constexpr (alloc_prop_input::has_execution_space) {
3240  const auto& exec_space =
3241  Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop);
3242  Kokkos::deep_copy(exec_space, v, typename view_type::value_type{});
3243  } else
3244  Kokkos::deep_copy(v, typename view_type::value_type{});
3245  }
3246 }
3247 
3248 template <class T, class... P, class... ViewCtorArgs>
3249 inline std::enable_if_t<
3250  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3251  Kokkos::LayoutLeft>::value ||
3252  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3253  Kokkos::LayoutRight>::value>
3254 realloc(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3256  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3257  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3258  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3259  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3260  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3261  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3262  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3263  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3264  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, arg_prop);
3265 }
3266 
3267 template <class T, class... P>
3268 inline std::enable_if_t<
3269  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3270  Kokkos::LayoutLeft>::value ||
3271  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3272  Kokkos::LayoutRight>::value>
3273 realloc(Kokkos::View<T, P...>& v,
3274  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3275  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3276  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3277  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3278  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3279  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3280  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3281  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3282  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, Impl::ViewCtorProp<>{});
3283 }
3284 
3285 template <class I, class T, class... P>
3286 inline std::enable_if_t<
3287  Impl::is_view_ctor_property<I>::value &&
3288  (std::is_same<typename Kokkos::View<T, P...>::array_layout,
3289  Kokkos::LayoutLeft>::value ||
3290  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3291  Kokkos::LayoutRight>::value)>
3292 realloc(const I& arg_prop, Kokkos::View<T, P...>& v,
3293  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3294  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3295  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3296  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3297  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3298  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3299  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3300  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3301  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, Kokkos::view_alloc(arg_prop));
3302 }
3303 
3304 template <class T, class... P, class... ViewCtorArgs>
3305 inline std::enable_if_t<
3306  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3307  Kokkos::LayoutLeft>::value ||
3308  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3309  Kokkos::LayoutRight>::value ||
3310  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3311  Kokkos::LayoutStride>::value ||
3312  is_layouttiled<typename Kokkos::View<T, P...>::array_layout>::value>
3313 impl_realloc(Kokkos::View<T, P...>& v,
3314  const typename Kokkos::View<T, P...>::array_layout& layout,
3315  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3316  using view_type = Kokkos::View<T, P...>;
3317  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3318 
3320  "Can only realloc managed views");
3321  static_assert(!alloc_prop_input::has_label,
3322  "The view constructor arguments passed to Kokkos::realloc must "
3323  "not include a label!");
3324  static_assert(!alloc_prop_input::has_pointer,
3325  "The view constructor arguments passed to Kokkos::realloc must "
3326  "not include a pointer!");
3327  static_assert(!alloc_prop_input::has_memory_space,
3328  "The view constructor arguments passed to Kokkos::realloc must "
3329  "not include a memory space instance!");
3330 
3331  if (v.layout() != layout) {
3332  v = view_type(); // Deallocate first, if the only view to allocation
3333  v = view_type(arg_prop, layout);
3334  } else if (alloc_prop_input::initialize) {
3335  if constexpr (alloc_prop_input::has_execution_space) {
3336  const auto& exec_space =
3337  Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop);
3338  Kokkos::deep_copy(exec_space, v, typename view_type::value_type{});
3339  } else
3340  Kokkos::deep_copy(v, typename view_type::value_type{});
3341  }
3342 }
3343 
3344 // FIXME User-provided (custom) layouts are not required to have a comparison
3345 // operator. Hence, there is no way to check if the requested layout is actually
3346 // the same as the existing one.
3347 template <class T, class... P, class... ViewCtorArgs>
3348 inline std::enable_if_t<
3349  !(std::is_same<typename Kokkos::View<T, P...>::array_layout,
3350  Kokkos::LayoutLeft>::value ||
3351  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3352  Kokkos::LayoutRight>::value ||
3353  std::is_same<typename Kokkos::View<T, P...>::array_layout,
3354  Kokkos::LayoutStride>::value ||
3355  is_layouttiled<typename Kokkos::View<T, P...>::array_layout>::value)>
3356 impl_realloc(Kokkos::View<T, P...>& v,
3357  const typename Kokkos::View<T, P...>::array_layout& layout,
3358  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3359  using view_type = Kokkos::View<T, P...>;
3360  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3361 
3363  "Can only realloc managed views");
3364  static_assert(!alloc_prop_input::has_label,
3365  "The view constructor arguments passed to Kokkos::realloc must "
3366  "not include a label!");
3367  static_assert(!alloc_prop_input::has_pointer,
3368  "The view constructor arguments passed to Kokkos::realloc must "
3369  "not include a pointer!");
3370  static_assert(!alloc_prop_input::has_memory_space,
3371  "The view constructor arguments passed to Kokkos::realloc must "
3372  "not include a memory space instance!");
3373 
3374  auto arg_prop_copy = Impl::with_properties_if_unset(arg_prop, v.label());
3375 
3376  v = view_type(); // Deallocate first, if the only view to allocation
3377  v = view_type(arg_prop_copy, layout);
3378 }
3379 
3380 template <class T, class... P, class... ViewCtorArgs>
3381 inline void realloc(
3382  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3384  const typename Kokkos::View<T, P...>::array_layout& layout) {
3385  impl_realloc(v, layout, arg_prop);
3386 }
3387 
3388 template <class I, class T, class... P>
3389 inline std::enable_if_t<Impl::is_view_ctor_property<I>::value> realloc(
3390  const I& arg_prop, Kokkos::View<T, P...>& v,
3391  const typename Kokkos::View<T, P...>::array_layout& layout) {
3392  impl_realloc(v, layout, Kokkos::view_alloc(arg_prop));
3393 }
3394 
3395 template <class T, class... P>
3396 inline void realloc(
3398  const typename Kokkos::View<T, P...>::array_layout& layout) {
3399  impl_realloc(v, layout, Impl::ViewCtorProp<>{});
3400 }
3401 
3402 } /* namespace Kokkos */
3403 
3404 //----------------------------------------------------------------------------
3405 //----------------------------------------------------------------------------
3406 
3407 namespace Kokkos {
3408 namespace Impl {
3409 
3410 // Deduce Mirror Types
3411 template <class Space, class T, class... P>
3412 struct MirrorViewType {
3413  // The incoming view_type
3414  using src_view_type = typename Kokkos::View<T, P...>;
3415  // The memory space for the mirror view
3416  using memory_space = typename Space::memory_space;
3417  // Check whether it is the same memory space
3418  enum {
3419  is_same_memspace =
3420  std::is_same<memory_space, typename src_view_type::memory_space>::value
3421  };
3422  // The array_layout
3423  using array_layout = typename src_view_type::array_layout;
3424  // The data type (we probably want it non-const since otherwise we can't even
3425  // deep_copy to it.
3426  using data_type = typename src_view_type::non_const_data_type;
3427  // The destination view type if it is not the same memory space
3428  using dest_view_type = Kokkos::View<data_type, array_layout, Space>;
3429  // If it is the same memory_space return the existsing view_type
3430  // This will also keep the unmanaged trait if necessary
3431  using view_type =
3432  std::conditional_t<is_same_memspace, src_view_type, dest_view_type>;
3433 };
3434 
3435 template <class Space, class T, class... P>
3436 struct MirrorType {
3437  // The incoming view_type
3438  using src_view_type = typename Kokkos::View<T, P...>;
3439  // The memory space for the mirror view
3440  using memory_space = typename Space::memory_space;
3441  // Check whether it is the same memory space
3442  enum {
3443  is_same_memspace =
3444  std::is_same<memory_space, typename src_view_type::memory_space>::value
3445  };
3446  // The array_layout
3447  using array_layout = typename src_view_type::array_layout;
3448  // The data type (we probably want it non-const since otherwise we can't even
3449  // deep_copy to it.
3450  using data_type = typename src_view_type::non_const_data_type;
3451  // The destination view type if it is not the same memory space
3453 };
3454 
3455 template <class... ViewCtorArgs>
3456 void check_view_ctor_args_create_mirror() {
3457  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3458 
3459  static_assert(
3460  !alloc_prop_input::has_label,
3461  "The view constructor arguments passed to Kokkos::create_mirror[_view] "
3462  "must not include a label!");
3463  static_assert(!alloc_prop_input::has_pointer,
3464  "The view constructor arguments passed to "
3465  "Kokkos::create_mirror[_view] must "
3466  "not include a pointer!");
3467  static_assert(!alloc_prop_input::allow_padding,
3468  "The view constructor arguments passed to "
3469  "Kokkos::create_mirror[_view] must "
3470  "not explicitly allow padding!");
3471 }
3472 
3473 template <class T, class... P, class... ViewCtorArgs>
3474 inline std::enable_if_t<!Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space,
3475  typename Kokkos::View<T, P...>::HostMirror>
3476 create_mirror(const Kokkos::View<T, P...>& src,
3477  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3478  using src_type = View<T, P...>;
3479  using dst_type = typename src_type::HostMirror;
3480 
3481  check_view_ctor_args_create_mirror<ViewCtorArgs...>();
3482 
3483  auto prop_copy = Impl::with_properties_if_unset(
3484  arg_prop, std::string(src.label()).append("_mirror"));
3485 
3486  return dst_type(prop_copy, src.layout());
3487 }
3488 
3489 // Create a mirror in a new space (specialization for different space)
3490 template <class T, class... P, class... ViewCtorArgs,
3491  class Enable = std::enable_if_t<
3492  Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
3493 auto create_mirror(const Kokkos::View<T, P...>& src,
3494  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3495  check_view_ctor_args_create_mirror<ViewCtorArgs...>();
3496 
3497  auto prop_copy = Impl::with_properties_if_unset(
3498  arg_prop, std::string(src.label()).append("_mirror"));
3499  using alloc_prop = decltype(prop_copy);
3500 
3501  return typename Impl::MirrorType<typename alloc_prop::memory_space, T,
3502  P...>::view_type(prop_copy, src.layout());
3503 }
3504 } // namespace Impl
3505 
3506 template <class T, class... P>
3507 std::enable_if_t<std::is_void<typename ViewTraits<T, P...>::specialize>::value,
3508  typename Kokkos::View<T, P...>::HostMirror>
3509 create_mirror(Kokkos::View<T, P...> const& v) {
3510  return Impl::create_mirror(v, Impl::ViewCtorProp<>{});
3511 }
3512 
3513 template <class T, class... P>
3514 std::enable_if_t<std::is_void<typename ViewTraits<T, P...>::specialize>::value,
3515  typename Kokkos::View<T, P...>::HostMirror>
3516 create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
3517  Kokkos::View<T, P...> const& v) {
3518  return Impl::create_mirror(v, view_alloc(wi));
3519 }
3520 
3521 template <class Space, class T, class... P,
3522  typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3523 std::enable_if_t<std::is_void<typename ViewTraits<T, P...>::specialize>::value,
3524  typename Impl::MirrorType<Space, T, P...>::view_type>
3525 create_mirror(Space const&, Kokkos::View<T, P...> const& v) {
3526  return Impl::create_mirror(v, view_alloc(typename Space::memory_space{}));
3527 }
3528 
3529 template <class T, class... P, class... ViewCtorArgs,
3530  typename Enable = std::enable_if_t<
3531  std::is_void<typename ViewTraits<T, P...>::specialize>::value &&
3532  Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
3533 auto create_mirror(Impl::ViewCtorProp<ViewCtorArgs...> const& arg_prop,
3534  Kokkos::View<T, P...> const& v) {
3535  return Impl::create_mirror(v, arg_prop);
3536 }
3537 
3538 template <class T, class... P, class... ViewCtorArgs>
3539 std::enable_if_t<
3540  std::is_void<typename ViewTraits<T, P...>::specialize>::value &&
3541  !Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space,
3542  typename Kokkos::View<T, P...>::HostMirror>
3543 create_mirror(Impl::ViewCtorProp<ViewCtorArgs...> const& arg_prop,
3544  Kokkos::View<T, P...> const& v) {
3545  return Impl::create_mirror(v, arg_prop);
3546 }
3547 
3548 template <class Space, class T, class... P,
3549  typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3550 std::enable_if_t<std::is_void<typename ViewTraits<T, P...>::specialize>::value,
3551  typename Impl::MirrorType<Space, T, P...>::view_type>
3552 create_mirror(Kokkos::Impl::WithoutInitializing_t wi, Space const&,
3553  Kokkos::View<T, P...> const& v) {
3554  return Impl::create_mirror(v, view_alloc(typename Space::memory_space{}, wi));
3555 }
3556 
3557 namespace Impl {
3558 
3559 template <class T, class... P, class... ViewCtorArgs>
3560 inline std::enable_if_t<
3561  !Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space &&
3562  (std::is_same<
3563  typename Kokkos::View<T, P...>::memory_space,
3564  typename Kokkos::View<T, P...>::HostMirror::memory_space>::value &&
3565  std::is_same<
3566  typename Kokkos::View<T, P...>::data_type,
3567  typename Kokkos::View<T, P...>::HostMirror::data_type>::value),
3569 create_mirror_view(const Kokkos::View<T, P...>& src,
3570  const Impl::ViewCtorProp<ViewCtorArgs...>&) {
3571  check_view_ctor_args_create_mirror<ViewCtorArgs...>();
3572  return src;
3573 }
3574 
3575 template <class T, class... P, class... ViewCtorArgs>
3576 inline std::enable_if_t<
3577  !Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space &&
3578  !(std::is_same<typename Kokkos::View<T, P...>::memory_space,
3579  typename Kokkos::View<
3580  T, P...>::HostMirror::memory_space>::value &&
3581  std::is_same<
3582  typename Kokkos::View<T, P...>::data_type,
3583  typename Kokkos::View<T, P...>::HostMirror::data_type>::value),
3585 create_mirror_view(const Kokkos::View<T, P...>& src,
3586  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3587  return Kokkos::Impl::create_mirror(src, arg_prop);
3588 }
3589 
3590 // Create a mirror view in a new space (specialization for same space)
3591 template <class T, class... P, class... ViewCtorArgs,
3592  class = std::enable_if_t<
3593  Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
3594 std::enable_if_t<Impl::MirrorViewType<
3595  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
3596  T, P...>::is_same_memspace,
3597  typename Impl::MirrorViewType<
3598  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
3599  T, P...>::view_type>
3600 create_mirror_view(const Kokkos::View<T, P...>& src,
3601  const Impl::ViewCtorProp<ViewCtorArgs...>&) {
3602  check_view_ctor_args_create_mirror<ViewCtorArgs...>();
3603  return src;
3604 }
3605 
3606 // Create a mirror view in a new space (specialization for different space)
3607 template <class T, class... P, class... ViewCtorArgs,
3608  class = std::enable_if_t<
3609  Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
3610 std::enable_if_t<!Impl::MirrorViewType<
3611  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
3612  T, P...>::is_same_memspace,
3613  typename Impl::MirrorViewType<
3614  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
3615  T, P...>::view_type>
3616 create_mirror_view(const Kokkos::View<T, P...>& src,
3617  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
3618  return Kokkos::Impl::create_mirror(src, arg_prop);
3619 }
3620 } // namespace Impl
3621 
3622 template <class T, class... P>
3623 std::enable_if_t<
3624  std::is_same<
3625  typename Kokkos::View<T, P...>::memory_space,
3626  typename Kokkos::View<T, P...>::HostMirror::memory_space>::value &&
3627  std::is_same<
3628  typename Kokkos::View<T, P...>::data_type,
3629  typename Kokkos::View<T, P...>::HostMirror::data_type>::value,
3630  typename Kokkos::View<T, P...>::HostMirror>
3631 create_mirror_view(const Kokkos::View<T, P...>& src) {
3632  return src;
3633 }
3634 
3635 template <class T, class... P>
3636 std::enable_if_t<
3637  !(std::is_same<
3638  typename Kokkos::View<T, P...>::memory_space,
3639  typename Kokkos::View<T, P...>::HostMirror::memory_space>::value &&
3640  std::is_same<
3641  typename Kokkos::View<T, P...>::data_type,
3642  typename Kokkos::View<T, P...>::HostMirror::data_type>::value),
3644 create_mirror_view(const Kokkos::View<T, P...>& src) {
3645  return Kokkos::create_mirror(src);
3646 }
3647 
3648 template <class T, class... P>
3649 typename Kokkos::View<T, P...>::HostMirror create_mirror_view(
3650  Kokkos::Impl::WithoutInitializing_t wi, Kokkos::View<T, P...> const& v) {
3651  return Impl::create_mirror_view(v, view_alloc(wi));
3652 }
3653 
3654 // FIXME_C++17 Improve SFINAE here.
3655 template <class Space, class T, class... P,
3656  class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3657 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3658  const Space&, const Kokkos::View<T, P...>& src,
3659  std::enable_if_t<Impl::MirrorViewType<Space, T, P...>::is_same_memspace>* =
3660  nullptr) {
3661  return src;
3662 }
3663 
3664 // FIXME_C++17 Improve SFINAE here.
3665 template <class Space, class T, class... P,
3666  class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3667 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3668  const Space& space, const Kokkos::View<T, P...>& src,
3669  std::enable_if_t<!Impl::MirrorViewType<Space, T, P...>::is_same_memspace>* =
3670  nullptr) {
3671  return Kokkos::create_mirror(space, src);
3672 }
3673 
3674 template <class Space, class T, class... P,
3675  typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3676 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3677  Kokkos::Impl::WithoutInitializing_t wi, Space const&,
3678  Kokkos::View<T, P...> const& v) {
3679  return Impl::create_mirror_view(
3680  v, view_alloc(typename Space::memory_space{}, wi));
3681 }
3682 
3683 template <class T, class... P, class... ViewCtorArgs>
3684 auto create_mirror_view(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3685  const Kokkos::View<T, P...>& v) {
3686  return Impl::create_mirror_view(v, arg_prop);
3687 }
3688 
3689 template <class... ViewCtorArgs, class T, class... P>
3690 auto create_mirror_view_and_copy(
3691  const Impl::ViewCtorProp<ViewCtorArgs...>&,
3692  const Kokkos::View<T, P...>& src,
3693  std::enable_if_t<
3694  std::is_void<typename ViewTraits<T, P...>::specialize>::value &&
3695  Impl::MirrorViewType<
3696  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
3697  P...>::is_same_memspace>* = nullptr) {
3698  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3699  static_assert(
3700  alloc_prop_input::has_memory_space,
3701  "The view constructor arguments passed to "
3702  "Kokkos::create_mirror_view_and_copy must include a memory space!");
3703  static_assert(!alloc_prop_input::has_pointer,
3704  "The view constructor arguments passed to "
3705  "Kokkos::create_mirror_view_and_copy must "
3706  "not include a pointer!");
3707  static_assert(!alloc_prop_input::allow_padding,
3708  "The view constructor arguments passed to "
3709  "Kokkos::create_mirror_view_and_copy must "
3710  "not explicitly allow padding!");
3711 
3712  // same behavior as deep_copy(src, src)
3713  if (!alloc_prop_input::has_execution_space)
3714  fence(
3715  "Kokkos::create_mirror_view_and_copy: fence before returning src view");
3716  return src;
3717 }
3718 
3719 template <class... ViewCtorArgs, class T, class... P>
3720 auto create_mirror_view_and_copy(
3721  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
3722  const Kokkos::View<T, P...>& src,
3723  std::enable_if_t<
3724  std::is_void<typename ViewTraits<T, P...>::specialize>::value &&
3725  !Impl::MirrorViewType<
3726  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
3727  P...>::is_same_memspace>* = nullptr) {
3728  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
3729  static_assert(
3730  alloc_prop_input::has_memory_space,
3731  "The view constructor arguments passed to "
3732  "Kokkos::create_mirror_view_and_copy must include a memory space!");
3733  static_assert(!alloc_prop_input::has_pointer,
3734  "The view constructor arguments passed to "
3735  "Kokkos::create_mirror_view_and_copy must "
3736  "not include a pointer!");
3737  static_assert(!alloc_prop_input::allow_padding,
3738  "The view constructor arguments passed to "
3739  "Kokkos::create_mirror_view_and_copy must "
3740  "not explicitly allow padding!");
3741  using Space = typename alloc_prop_input::memory_space;
3742  using Mirror = typename Impl::MirrorViewType<Space, T, P...>::view_type;
3743 
3744  auto arg_prop_copy = Impl::with_properties_if_unset(
3745  arg_prop, std::string{}, WithoutInitializing,
3746  typename Space::execution_space{});
3747 
3748  std::string& label = Impl::get_property<Impl::LabelTag>(arg_prop_copy);
3749  if (label.empty()) label = src.label();
3750  auto mirror = typename Mirror::non_const_type{arg_prop_copy, src.layout()};
3751  if constexpr (alloc_prop_input::has_execution_space) {
3752  deep_copy(Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop_copy),
3753  mirror, src);
3754  } else
3755  deep_copy(mirror, src);
3756  return mirror;
3757 }
3758 
3759 // Previously when using auto here, the intel compiler 19.3 would
3760 // sometimes not create a symbol, guessing that it somehow is a combination
3761 // of auto and just forwarding arguments (see issue #5196)
3762 template <class Space, class T, class... P,
3763  typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
3764 typename Impl::MirrorViewType<Space, T, P...>::view_type
3765 create_mirror_view_and_copy(
3766  const Space&, const Kokkos::View<T, P...>& src,
3767  std::string const& name = "",
3768  std::enable_if_t<
3769  std::is_void<typename ViewTraits<T, P...>::specialize>::value>* =
3770  nullptr) {
3771  return create_mirror_view_and_copy(
3772  Kokkos::view_alloc(typename Space::memory_space{}, name), src);
3773 }
3774 
3775 } /* namespace Kokkos */
3776 
3777 //----------------------------------------------------------------------------
3778 //----------------------------------------------------------------------------
3779 
3780 #endif
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Can AccessSpace access MemorySpace ?
Replacement for std::pair that works on CUDA devices.
Definition: Kokkos_Pair.hpp:44
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
View to an array of data.
Memory management for host memory.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...
static constexpr const char * name()
Return Name of the MemorySpace.
Declaration of various MemoryLayout options.
Declaration of parallel operators.
Execution policy for work over a range of an integral type.
Traits class for accessing attributes of a View.