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