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