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