Kokkos Core Kernels Package  Version of the Day
Kokkos_CopyViews.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
45 #ifndef KOKKOS_COPYVIEWS_HPP_
46 #define KOKKOS_COPYVIEWS_HPP_
47 #include <string>
48 #include <Kokkos_Parallel.hpp>
49 #include <KokkosExp_MDRangePolicy.hpp>
50 
51 //----------------------------------------------------------------------------
52 //----------------------------------------------------------------------------
53 
54 namespace Kokkos {
55 
56 namespace Impl {
57 
58 template <class Layout>
59 struct ViewFillLayoutSelector {};
60 
61 template <>
62 struct ViewFillLayoutSelector<Kokkos::LayoutLeft> {
63  static const Kokkos::Iterate iterate = Kokkos::Iterate::Left;
64 };
65 
66 template <>
67 struct ViewFillLayoutSelector<Kokkos::LayoutRight> {
68  static const Kokkos::Iterate iterate = Kokkos::Iterate::Right;
69 };
70 
71 } // namespace Impl
72 } // namespace Kokkos
73 
74 namespace Kokkos {
75 namespace Impl {
76 
77 template <class ViewType, class Layout, class ExecSpace, typename iType>
78 struct ViewFill<ViewType, Layout, ExecSpace, 0, iType> {
79  using ST = typename ViewType::non_const_value_type;
80  ViewFill(const ViewType& a, const ST& val, const ExecSpace& space) {
81  Kokkos::Impl::DeepCopy<typename ViewType::memory_space, Kokkos::HostSpace,
82  ExecSpace>(space, a.data(), &val, sizeof(ST));
83  }
84 };
85 
86 template <class ViewType, class Layout, class ExecSpace, typename iType>
87 struct ViewFill<ViewType, Layout, ExecSpace, 1, iType> {
88  ViewType a;
89  typename ViewType::const_value_type val;
91 
92  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
93  const ExecSpace& space)
94  : a(a_), val(val_) {
95  Kokkos::parallel_for("Kokkos::ViewFill-1D",
96  policy_type(space, 0, a.extent(0)), *this);
97  }
98 
99  KOKKOS_INLINE_FUNCTION
100  void operator()(const iType& i) const { a(i) = val; };
101 };
102 
103 template <class ViewType, class Layout, class ExecSpace, typename iType>
104 struct ViewFill<ViewType, Layout, ExecSpace, 2, iType> {
105  ViewType a;
106  typename ViewType::const_value_type val;
107 
108  using iterate_type = Kokkos::Rank<2, 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("Kokkos::ViewFill-2D",
117  policy_type(space, {0, 0}, {a.extent(0), a.extent(1)}),
118  *this);
119  }
120 
121  KOKKOS_INLINE_FUNCTION
122  void operator()(const iType& i0, const iType& i1) const { a(i0, i1) = val; };
123 };
124 
125 template <class ViewType, class Layout, class ExecSpace, typename iType>
126 struct ViewFill<ViewType, Layout, ExecSpace, 3, iType> {
127  ViewType a;
128  typename ViewType::const_value_type val;
129 
130  using iterate_type = Kokkos::Rank<3, ViewFillLayoutSelector<Layout>::iterate,
131  ViewFillLayoutSelector<Layout>::iterate>;
132  using policy_type =
133  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
134 
135  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
136  const ExecSpace& space)
137  : a(a_), val(val_) {
138  Kokkos::parallel_for(
139  "Kokkos::ViewFill-3D",
140  policy_type(space, {0, 0, 0}, {a.extent(0), a.extent(1), a.extent(2)}),
141  *this);
142  }
143 
144  KOKKOS_INLINE_FUNCTION
145  void operator()(const iType& i0, const iType& i1, const iType& i2) const {
146  a(i0, i1, i2) = val;
147  };
148 };
149 
150 template <class ViewType, class Layout, class ExecSpace, typename iType>
151 struct ViewFill<ViewType, Layout, ExecSpace, 4, iType> {
152  ViewType a;
153  typename ViewType::const_value_type val;
154 
155  using iterate_type = Kokkos::Rank<4, ViewFillLayoutSelector<Layout>::iterate,
156  ViewFillLayoutSelector<Layout>::iterate>;
157  using policy_type =
158  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
159 
160  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
161  const ExecSpace& space)
162  : a(a_), val(val_) {
163  Kokkos::parallel_for(
164  "Kokkos::ViewFill-4D",
165  policy_type(space, {0, 0, 0, 0},
166  {a.extent(0), a.extent(1), a.extent(2), a.extent(3)}),
167  *this);
168  }
169 
170  KOKKOS_INLINE_FUNCTION
171  void operator()(const iType& i0, const iType& i1, const iType& i2,
172  const iType& i3) const {
173  a(i0, i1, i2, i3) = val;
174  };
175 };
176 
177 template <class ViewType, class Layout, class ExecSpace, typename iType>
178 struct ViewFill<ViewType, Layout, ExecSpace, 5, iType> {
179  ViewType a;
180  typename ViewType::const_value_type val;
181 
182  using iterate_type = Kokkos::Rank<5, ViewFillLayoutSelector<Layout>::iterate,
183  ViewFillLayoutSelector<Layout>::iterate>;
184  using policy_type =
185  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
186 
187  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
188  const ExecSpace& space)
189  : a(a_), val(val_) {
190  Kokkos::parallel_for("Kokkos::ViewFill-5D",
191  policy_type(space, {0, 0, 0, 0, 0},
192  {a.extent(0), a.extent(1), a.extent(2),
193  a.extent(3), a.extent(4)}),
194  *this);
195  }
196 
197  KOKKOS_INLINE_FUNCTION
198  void operator()(const iType& i0, const iType& i1, const iType& i2,
199  const iType& i3, const iType& i4) const {
200  a(i0, i1, i2, i3, i4) = val;
201  };
202 };
203 
204 template <class ViewType, class Layout, class ExecSpace, typename iType>
205 struct ViewFill<ViewType, Layout, ExecSpace, 6, iType> {
206  ViewType a;
207  typename ViewType::const_value_type val;
208 
209  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
210  ViewFillLayoutSelector<Layout>::iterate>;
211  using policy_type =
212  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
213 
214  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
215  const ExecSpace& space)
216  : a(a_), val(val_) {
217  Kokkos::parallel_for("Kokkos::ViewFill-6D",
218  policy_type(space, {0, 0, 0, 0, 0, 0},
219  {a.extent(0), a.extent(1), a.extent(2),
220  a.extent(3), a.extent(4), a.extent(5)}),
221  *this);
222  }
223 
224  KOKKOS_INLINE_FUNCTION
225  void operator()(const iType& i0, const iType& i1, const iType& i2,
226  const iType& i3, const iType& i4, const iType& i5) const {
227  a(i0, i1, i2, i3, i4, i5) = val;
228  };
229 };
230 
231 template <class ViewType, class Layout, class ExecSpace, typename iType>
232 struct ViewFill<ViewType, Layout, ExecSpace, 7, iType> {
233  ViewType a;
234  typename ViewType::const_value_type val;
235 
236  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
237  ViewFillLayoutSelector<Layout>::iterate>;
238  using policy_type =
239  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
240 
241  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
242  const ExecSpace& space)
243  : a(a_), val(val_) {
244  Kokkos::parallel_for("Kokkos::ViewFill-7D",
245  policy_type(space, {0, 0, 0, 0, 0, 0},
246  {a.extent(0), a.extent(1), a.extent(2),
247  a.extent(3), a.extent(5), a.extent(6)}),
248  *this);
249  }
250 
251  KOKKOS_INLINE_FUNCTION
252  void operator()(const iType& i0, const iType& i1, const iType& i3,
253  const iType& i4, const iType& i5, const iType& i6) const {
254  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
255  a(i0, i1, i2, i3, i4, i5, i6) = val;
256  };
257 };
258 
259 template <class ViewType, class Layout, class ExecSpace, typename iType>
260 struct ViewFill<ViewType, Layout, ExecSpace, 8, iType> {
261  ViewType a;
262  typename ViewType::const_value_type val;
263 
264  using iterate_type = Kokkos::Rank<6, ViewFillLayoutSelector<Layout>::iterate,
265  ViewFillLayoutSelector<Layout>::iterate>;
266  using policy_type =
267  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
268 
269  ViewFill(const ViewType& a_, typename ViewType::const_value_type& val_,
270  const ExecSpace& space)
271  : a(a_), val(val_) {
272  Kokkos::parallel_for("Kokkos::ViewFill-8D",
273  policy_type(space, {0, 0, 0, 0, 0, 0},
274  {a.extent(0), a.extent(1), a.extent(3),
275  a.extent(5), a.extent(6), a.extent(7)}),
276  *this);
277  }
278 
279  KOKKOS_INLINE_FUNCTION
280  void operator()(const iType& i0, const iType& i1, const iType& i3,
281  const iType& i5, const iType& i6, const iType& i7) const {
282  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
283  for (iType i4 = 0; i4 < iType(a.extent(4)); i4++)
284  a(i0, i1, i2, i3, i4, i5, i6, i7) = val;
285  };
286 };
287 
288 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
289  typename iType>
290 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 1, iType> {
291  ViewTypeA a;
292  ViewTypeB b;
293 
295  using value_type = typename ViewTypeA::value_type;
296 
297  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
298  const ExecSpace space = ExecSpace())
299  : a(a_), b(b_) {
300  Kokkos::parallel_for("Kokkos::ViewCopy-1D",
301  policy_type(space, 0, a.extent(0)), *this);
302  }
303 
304  KOKKOS_INLINE_FUNCTION
305  void operator()(const iType& i0) const {
306  a(i0) = static_cast<value_type>(b(i0));
307  };
308 };
309 
310 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
311  typename iType>
312 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 2, iType> {
313  ViewTypeA a;
314  ViewTypeB b;
315  static const Kokkos::Iterate outer_iteration_pattern =
316  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
317  static const Kokkos::Iterate inner_iteration_pattern =
318  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
319  using iterate_type =
320  Kokkos::Rank<2, outer_iteration_pattern, inner_iteration_pattern>;
321  using policy_type =
322  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
323  using value_type = typename ViewTypeA::value_type;
324 
325  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
326  const ExecSpace space = ExecSpace())
327  : a(a_), b(b_) {
328  Kokkos::parallel_for("Kokkos::ViewCopy-2D",
329  policy_type(space, {0, 0}, {a.extent(0), a.extent(1)}),
330  *this);
331  }
332 
333  KOKKOS_INLINE_FUNCTION
334  void operator()(const iType& i0, const iType& i1) const {
335  a(i0, i1) = static_cast<value_type>(b(i0, i1));
336  };
337 };
338 
339 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
340  typename iType>
341 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 3, iType> {
342  ViewTypeA a;
343  ViewTypeB b;
344 
345  static const Kokkos::Iterate outer_iteration_pattern =
346  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
347  static const Kokkos::Iterate inner_iteration_pattern =
348  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
349  using iterate_type =
350  Kokkos::Rank<3, outer_iteration_pattern, inner_iteration_pattern>;
351  using policy_type =
352  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
353  using value_type = typename ViewTypeA::value_type;
354 
355  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
356  const ExecSpace space = ExecSpace())
357  : a(a_), b(b_) {
358  Kokkos::parallel_for(
359  "Kokkos::ViewCopy-3D",
360  policy_type(space, {0, 0, 0}, {a.extent(0), a.extent(1), a.extent(2)}),
361  *this);
362  }
363 
364  KOKKOS_INLINE_FUNCTION
365  void operator()(const iType& i0, const iType& i1, const iType& i2) const {
366  a(i0, i1, i2) = static_cast<value_type>(b(i0, i1, i2));
367  };
368 };
369 
370 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
371  typename iType>
372 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 4, iType> {
373  ViewTypeA a;
374  ViewTypeB b;
375 
376  static const Kokkos::Iterate outer_iteration_pattern =
377  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
378  static const Kokkos::Iterate inner_iteration_pattern =
379  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
380  using iterate_type =
381  Kokkos::Rank<4, outer_iteration_pattern, inner_iteration_pattern>;
382  using policy_type =
383  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
384 
385  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
386  const ExecSpace space = ExecSpace())
387  : a(a_), b(b_) {
388  Kokkos::parallel_for(
389  "Kokkos::ViewCopy-4D",
390  policy_type(space, {0, 0, 0, 0},
391  {a.extent(0), a.extent(1), a.extent(2), a.extent(3)}),
392  *this);
393  }
394 
395  KOKKOS_INLINE_FUNCTION
396  void operator()(const iType& i0, const iType& i1, const iType& i2,
397  const iType& i3) const {
398  a(i0, i1, i2, i3) = b(i0, i1, i2, i3);
399  };
400 };
401 
402 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
403  typename iType>
404 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 5, iType> {
405  ViewTypeA a;
406  ViewTypeB b;
407 
408  static const Kokkos::Iterate outer_iteration_pattern =
409  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
410  static const Kokkos::Iterate inner_iteration_pattern =
411  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
412  using iterate_type =
413  Kokkos::Rank<5, outer_iteration_pattern, inner_iteration_pattern>;
414  using policy_type =
415  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
416 
417  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
418  const ExecSpace space = ExecSpace())
419  : a(a_), b(b_) {
420  Kokkos::parallel_for("Kokkos::ViewCopy-5D",
421  policy_type(space, {0, 0, 0, 0, 0},
422  {a.extent(0), a.extent(1), a.extent(2),
423  a.extent(3), a.extent(4)}),
424  *this);
425  }
426 
427  KOKKOS_INLINE_FUNCTION
428  void operator()(const iType& i0, const iType& i1, const iType& i2,
429  const iType& i3, const iType& i4) const {
430  a(i0, i1, i2, i3, i4) = b(i0, i1, i2, i3, i4);
431  };
432 };
433 
434 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
435  typename iType>
436 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 6, iType> {
437  ViewTypeA a;
438  ViewTypeB b;
439 
440  static const Kokkos::Iterate outer_iteration_pattern =
441  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
442  static const Kokkos::Iterate inner_iteration_pattern =
443  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
444  using iterate_type =
445  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
446  using policy_type =
447  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
448 
449  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
450  const ExecSpace space = ExecSpace())
451  : a(a_), b(b_) {
452  Kokkos::parallel_for("Kokkos::ViewCopy-6D",
453  policy_type(space, {0, 0, 0, 0, 0, 0},
454  {a.extent(0), a.extent(1), a.extent(2),
455  a.extent(3), a.extent(4), a.extent(5)}),
456  *this);
457  }
458 
459  KOKKOS_INLINE_FUNCTION
460  void operator()(const iType& i0, const iType& i1, const iType& i2,
461  const iType& i3, const iType& i4, const iType& i5) const {
462  a(i0, i1, i2, i3, i4, i5) = b(i0, i1, i2, i3, i4, i5);
463  };
464 };
465 
466 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
467  typename iType>
468 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 7, iType> {
469  ViewTypeA a;
470  ViewTypeB b;
471 
472  static const Kokkos::Iterate outer_iteration_pattern =
473  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
474  static const Kokkos::Iterate inner_iteration_pattern =
475  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
476  using iterate_type =
477  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
478  using policy_type =
479  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
480 
481  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
482  const ExecSpace space = ExecSpace())
483  : a(a_), b(b_) {
484  Kokkos::parallel_for("Kokkos::ViewCopy-7D",
485  policy_type(space, {0, 0, 0, 0, 0, 0},
486  {a.extent(0), a.extent(1), a.extent(3),
487  a.extent(4), a.extent(5), a.extent(6)}),
488  *this);
489  }
490 
491  KOKKOS_INLINE_FUNCTION
492  void operator()(const iType& i0, const iType& i1, const iType& i3,
493  const iType& i4, const iType& i5, const iType& i6) const {
494  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
495  a(i0, i1, i2, i3, i4, i5, i6) = b(i0, i1, i2, i3, i4, i5, i6);
496  };
497 };
498 
499 template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
500  typename iType>
501 struct ViewCopy<ViewTypeA, ViewTypeB, Layout, ExecSpace, 8, iType> {
502  ViewTypeA a;
503  ViewTypeB b;
504 
505  static const Kokkos::Iterate outer_iteration_pattern =
506  Kokkos::layout_iterate_type_selector<Layout>::outer_iteration_pattern;
507  static const Kokkos::Iterate inner_iteration_pattern =
508  Kokkos::layout_iterate_type_selector<Layout>::inner_iteration_pattern;
509  using iterate_type =
510  Kokkos::Rank<6, outer_iteration_pattern, inner_iteration_pattern>;
511  using policy_type =
512  Kokkos::MDRangePolicy<ExecSpace, iterate_type, Kokkos::IndexType<iType>>;
513 
514  ViewCopy(const ViewTypeA& a_, const ViewTypeB& b_,
515  const ExecSpace space = ExecSpace())
516  : a(a_), b(b_) {
517  Kokkos::parallel_for("Kokkos::ViewCopy-8D",
518  policy_type(space, {0, 0, 0, 0, 0, 0},
519  {a.extent(0), a.extent(1), a.extent(3),
520  a.extent(5), a.extent(6), a.extent(7)}),
521  *this);
522  }
523 
524  KOKKOS_INLINE_FUNCTION
525  void operator()(const iType& i0, const iType& i1, const iType& i3,
526  const iType& i5, const iType& i6, const iType& i7) const {
527  for (iType i2 = 0; i2 < iType(a.extent(2)); i2++)
528  for (iType i4 = 0; i4 < iType(a.extent(4)); i4++)
529  a(i0, i1, i2, i3, i4, i5, i6, i7) = b(i0, i1, i2, i3, i4, i5, i6, i7);
530  };
531 };
532 
533 } // namespace Impl
534 } // namespace Kokkos
535 
536 namespace Kokkos {
537 namespace Impl {
538 
539 template <class ExecutionSpace, class DstType, class SrcType>
540 void view_copy(const ExecutionSpace& space, const DstType& dst,
541  const SrcType& src) {
542  using dst_memory_space = typename DstType::memory_space;
543  using src_memory_space = typename SrcType::memory_space;
544 
545  enum {
546  ExecCanAccessSrc =
547  Kokkos::Impl::SpaceAccessibility<ExecutionSpace,
548  src_memory_space>::accessible
549  };
550  enum {
551  ExecCanAccessDst =
552  Kokkos::Impl::SpaceAccessibility<ExecutionSpace,
553  dst_memory_space>::accessible
554  };
555 
556  if (!(ExecCanAccessSrc && ExecCanAccessDst)) {
557  Kokkos::Impl::throw_runtime_exception(
558  "Kokkos::Impl::view_copy called with invalid execution space");
559  } else {
560  // Figure out iteration order in case we need it
561  int64_t strides[DstType::Rank + 1];
562  dst.stride(strides);
563  Kokkos::Iterate iterate;
564  if (Kokkos::is_layouttiled<typename DstType::array_layout>::value) {
565  iterate = Kokkos::layout_iterate_type_selector<
566  typename DstType::array_layout>::outer_iteration_pattern;
567  } else if (std::is_same<typename DstType::array_layout,
568  Kokkos::LayoutRight>::value) {
569  iterate = Kokkos::Iterate::Right;
570  } else if (std::is_same<typename DstType::array_layout,
571  Kokkos::LayoutLeft>::value) {
572  iterate = Kokkos::Iterate::Left;
573  } else if (std::is_same<typename DstType::array_layout,
574  Kokkos::LayoutStride>::value) {
575  if (strides[0] > strides[DstType::Rank - 1])
576  iterate = Kokkos::Iterate::Right;
577  else
578  iterate = Kokkos::Iterate::Left;
579  } else {
580  if (std::is_same<typename DstType::execution_space::array_layout,
581  Kokkos::LayoutRight>::value)
582  iterate = Kokkos::Iterate::Right;
583  else
584  iterate = Kokkos::Iterate::Left;
585  }
586 
587  if ((dst.span() >= size_t(std::numeric_limits<int>::max())) ||
588  (src.span() >= size_t(std::numeric_limits<int>::max()))) {
589  if (iterate == Kokkos::Iterate::Right)
590  Kokkos::Impl::ViewCopy<
591  typename DstType::uniform_runtime_nomemspace_type,
592  typename SrcType::uniform_runtime_const_nomemspace_type,
593  Kokkos::LayoutRight, ExecutionSpace, DstType::Rank, int64_t>(
594  dst, src, space);
595  else
596  Kokkos::Impl::ViewCopy<
597  typename DstType::uniform_runtime_nomemspace_type,
598  typename SrcType::uniform_runtime_const_nomemspace_type,
599  Kokkos::LayoutLeft, ExecutionSpace, DstType::Rank, int64_t>(
600  dst, src, space);
601  } else {
602  if (iterate == Kokkos::Iterate::Right)
603  Kokkos::Impl::ViewCopy<
604  typename DstType::uniform_runtime_nomemspace_type,
605  typename SrcType::uniform_runtime_const_nomemspace_type,
606  Kokkos::LayoutRight, ExecutionSpace, DstType::Rank, int>(dst, src,
607  space);
608  else
609  Kokkos::Impl::ViewCopy<
610  typename DstType::uniform_runtime_nomemspace_type,
611  typename SrcType::uniform_runtime_const_nomemspace_type,
612  Kokkos::LayoutLeft, ExecutionSpace, DstType::Rank, int>(dst, src,
613  space);
614  }
615  }
616 }
617 
618 template <class DstType, class SrcType>
619 void view_copy(const DstType& dst, const SrcType& src) {
620  using dst_execution_space = typename DstType::execution_space;
621  using src_execution_space = typename SrcType::execution_space;
622  using dst_memory_space = typename DstType::memory_space;
623  using src_memory_space = typename SrcType::memory_space;
624 
625  enum {
626  DstExecCanAccessSrc =
627  Kokkos::Impl::SpaceAccessibility<dst_execution_space,
628  src_memory_space>::accessible
629  };
630 
631  enum {
632  SrcExecCanAccessDst =
633  Kokkos::Impl::SpaceAccessibility<src_execution_space,
634  dst_memory_space>::accessible
635  };
636 
637  if (!DstExecCanAccessSrc && !SrcExecCanAccessDst) {
638  std::string message(
639  "Error: Kokkos::deep_copy with no available copy mechanism: ");
640  message += src.label();
641  message += " to ";
642  message += dst.label();
643  Kokkos::Impl::throw_runtime_exception(message);
644  }
645 
646  // Figure out iteration order in case we need it
647  int64_t strides[DstType::Rank + 1];
648  dst.stride(strides);
649  Kokkos::Iterate iterate;
650  if (Kokkos::is_layouttiled<typename DstType::array_layout>::value) {
651  iterate = Kokkos::layout_iterate_type_selector<
652  typename DstType::array_layout>::outer_iteration_pattern;
653  } else if (std::is_same<typename DstType::array_layout,
654  Kokkos::LayoutRight>::value) {
655  iterate = Kokkos::Iterate::Right;
656  } else if (std::is_same<typename DstType::array_layout,
657  Kokkos::LayoutLeft>::value) {
658  iterate = Kokkos::Iterate::Left;
659  } else if (std::is_same<typename DstType::array_layout,
660  Kokkos::LayoutStride>::value) {
661  if (strides[0] > strides[DstType::Rank - 1])
662  iterate = Kokkos::Iterate::Right;
663  else
664  iterate = Kokkos::Iterate::Left;
665  } else {
666  if (std::is_same<typename DstType::execution_space::array_layout,
667  Kokkos::LayoutRight>::value)
668  iterate = Kokkos::Iterate::Right;
669  else
670  iterate = Kokkos::Iterate::Left;
671  }
672 
673  if ((dst.span() >= size_t(std::numeric_limits<int>::max())) ||
674  (src.span() >= size_t(std::numeric_limits<int>::max()))) {
675  if (DstExecCanAccessSrc) {
676  if (iterate == Kokkos::Iterate::Right)
677  Kokkos::Impl::ViewCopy<
678  typename DstType::uniform_runtime_nomemspace_type,
679  typename SrcType::uniform_runtime_const_nomemspace_type,
680  Kokkos::LayoutRight, dst_execution_space, DstType::Rank, int64_t>(
681  dst, src);
682  else
683  Kokkos::Impl::ViewCopy<
684  typename DstType::uniform_runtime_nomemspace_type,
685  typename SrcType::uniform_runtime_const_nomemspace_type,
686  Kokkos::LayoutLeft, dst_execution_space, DstType::Rank, int64_t>(
687  dst, src);
688  } else {
689  if (iterate == Kokkos::Iterate::Right)
690  Kokkos::Impl::ViewCopy<
691  typename DstType::uniform_runtime_nomemspace_type,
692  typename SrcType::uniform_runtime_const_nomemspace_type,
693  Kokkos::LayoutRight, src_execution_space, DstType::Rank, int64_t>(
694  dst, src);
695  else
696  Kokkos::Impl::ViewCopy<
697  typename DstType::uniform_runtime_nomemspace_type,
698  typename SrcType::uniform_runtime_const_nomemspace_type,
699  Kokkos::LayoutLeft, src_execution_space, DstType::Rank, int64_t>(
700  dst, src);
701  }
702  } else {
703  if (DstExecCanAccessSrc) {
704  if (iterate == Kokkos::Iterate::Right)
705  Kokkos::Impl::ViewCopy<
706  typename DstType::uniform_runtime_nomemspace_type,
707  typename SrcType::uniform_runtime_const_nomemspace_type,
708  Kokkos::LayoutRight, dst_execution_space, DstType::Rank, int>(dst,
709  src);
710  else
711  Kokkos::Impl::ViewCopy<
712  typename DstType::uniform_runtime_nomemspace_type,
713  typename SrcType::uniform_runtime_const_nomemspace_type,
714  Kokkos::LayoutLeft, dst_execution_space, DstType::Rank, int>(dst,
715  src);
716  } else {
717  if (iterate == Kokkos::Iterate::Right)
718  Kokkos::Impl::ViewCopy<
719  typename DstType::uniform_runtime_nomemspace_type,
720  typename SrcType::uniform_runtime_const_nomemspace_type,
721  Kokkos::LayoutRight, src_execution_space, DstType::Rank, int>(dst,
722  src);
723  else
724  Kokkos::Impl::ViewCopy<
725  typename DstType::uniform_runtime_nomemspace_type,
726  typename SrcType::uniform_runtime_const_nomemspace_type,
727  Kokkos::LayoutLeft, src_execution_space, DstType::Rank, int>(dst,
728  src);
729  }
730  }
731 }
732 
733 template <class DstType, class SrcType, int Rank, class... Args>
734 struct CommonSubview;
735 
736 template <class DstType, class SrcType, class Arg0, class... Args>
737 struct CommonSubview<DstType, SrcType, 1, Arg0, Args...> {
738  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0>;
739  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0>;
740  dst_subview_type dst_sub;
741  src_subview_type src_sub;
742  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
743  Args...)
744  : dst_sub(dst, arg0), src_sub(src, arg0) {}
745 };
746 
747 template <class DstType, class SrcType, class Arg0, class Arg1, class... Args>
748 struct CommonSubview<DstType, SrcType, 2, Arg0, Arg1, Args...> {
749  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1>;
750  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1>;
751  dst_subview_type dst_sub;
752  src_subview_type src_sub;
753  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
754  const Arg1& arg1, Args...)
755  : dst_sub(dst, arg0, arg1), src_sub(src, arg0, arg1) {}
756 };
757 
758 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
759  class... Args>
760 struct CommonSubview<DstType, SrcType, 3, Arg0, Arg1, Arg2, Args...> {
761  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2>;
762  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2>;
763  dst_subview_type dst_sub;
764  src_subview_type src_sub;
765  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
766  const Arg1& arg1, const Arg2& arg2, Args...)
767  : dst_sub(dst, arg0, arg1, arg2), src_sub(src, arg0, arg1, arg2) {}
768 };
769 
770 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
771  class Arg3, class... Args>
772 struct CommonSubview<DstType, SrcType, 4, Arg0, Arg1, Arg2, Arg3, Args...> {
773  using dst_subview_type =
774  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3>;
775  using src_subview_type =
776  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3>;
777  dst_subview_type dst_sub;
778  src_subview_type src_sub;
779  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
780  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
781  const Args...)
782  : dst_sub(dst, arg0, arg1, arg2, arg3),
783  src_sub(src, arg0, arg1, arg2, arg3) {}
784 };
785 
786 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
787  class Arg3, class Arg4, class... Args>
788 struct CommonSubview<DstType, SrcType, 5, Arg0, Arg1, Arg2, Arg3, Arg4,
789  Args...> {
790  using dst_subview_type =
791  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4>;
792  using src_subview_type =
793  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4>;
794  dst_subview_type dst_sub;
795  src_subview_type src_sub;
796  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
797  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
798  const Arg4& arg4, const Args...)
799  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4),
800  src_sub(src, arg0, arg1, arg2, arg3, arg4) {}
801 };
802 
803 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
804  class Arg3, class Arg4, class Arg5, class... Args>
805 struct CommonSubview<DstType, SrcType, 6, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
806  Args...> {
807  using dst_subview_type =
808  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>;
809  using src_subview_type =
810  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5>;
811  dst_subview_type dst_sub;
812  src_subview_type src_sub;
813  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
814  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
815  const Arg4& arg4, const Arg5& arg5, const Args...)
816  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5),
817  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5) {}
818 };
819 
820 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
821  class Arg3, class Arg4, class Arg5, class Arg6, class... Args>
822 struct CommonSubview<DstType, SrcType, 7, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
823  Arg6, Args...> {
824  using dst_subview_type = typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2,
825  Arg3, Arg4, Arg5, Arg6>;
826  using src_subview_type = typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2,
827  Arg3, Arg4, Arg5, Arg6>;
828  dst_subview_type dst_sub;
829  src_subview_type src_sub;
830  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
831  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
832  const Arg4& arg4, const Arg5& arg5, const Arg6& arg6, Args...)
833  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5, arg6),
834  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5, arg6) {}
835 };
836 
837 template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
838  class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
839 struct CommonSubview<DstType, SrcType, 8, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
840  Arg6, Arg7> {
841  using dst_subview_type =
842  typename Kokkos::Subview<DstType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
843  Arg6, Arg7>;
844  using src_subview_type =
845  typename Kokkos::Subview<SrcType, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
846  Arg6, Arg7>;
847  dst_subview_type dst_sub;
848  src_subview_type src_sub;
849  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0,
850  const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,
851  const Arg4& arg4, const Arg5& arg5, const Arg6& arg6,
852  const Arg7& arg7)
853  : dst_sub(dst, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7),
854  src_sub(src, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {}
855 };
856 
857 template <class DstType, class SrcType,
858  class ExecSpace = typename DstType::execution_space,
859  int Rank = DstType::Rank>
860 struct ViewRemap;
861 
862 template <class DstType, class SrcType, class ExecSpace>
863 struct ViewRemap<DstType, SrcType, ExecSpace, 1> {
864  using p_type = Kokkos::pair<int64_t, int64_t>;
865 
866  ViewRemap(const DstType& dst, const SrcType& src) {
867  if (dst.extent(0) == src.extent(0)) {
868  view_copy(dst, src);
869  } else {
870  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
871  using sv_adapter_type = CommonSubview<DstType, SrcType, 1, p_type>;
872  sv_adapter_type common_subview(dst, src, ext0);
873  view_copy(common_subview.dst_sub, common_subview.src_sub);
874  }
875  }
876 };
877 
878 template <class DstType, class SrcType, class ExecSpace>
879 struct ViewRemap<DstType, SrcType, ExecSpace, 2> {
880  using p_type = Kokkos::pair<int64_t, int64_t>;
881 
882  ViewRemap(const DstType& dst, const SrcType& src) {
883  if (dst.extent(0) == src.extent(0)) {
884  if (dst.extent(1) == src.extent(1)) {
885  view_copy(dst, src);
886  } else {
887  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
888  using sv_adapter_type =
889  CommonSubview<DstType, SrcType, 2, Kokkos::Impl::ALL_t, p_type>;
890  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1);
891  view_copy(common_subview.dst_sub, common_subview.src_sub);
892  }
893  } else {
894  if (dst.extent(1) == src.extent(1)) {
895  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
896  using sv_adapter_type =
897  CommonSubview<DstType, SrcType, 2, p_type, Kokkos::Impl::ALL_t>;
898  sv_adapter_type common_subview(dst, src, ext0, Kokkos::ALL);
899  view_copy(common_subview.dst_sub, common_subview.src_sub);
900  } else {
901  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
902  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
903  using sv_adapter_type =
904  CommonSubview<DstType, SrcType, 2, p_type, p_type>;
905  sv_adapter_type common_subview(dst, src, ext0, ext1);
906  view_copy(common_subview.dst_sub, common_subview.src_sub);
907  }
908  }
909  }
910 };
911 
912 template <class DstType, class SrcType, class ExecSpace>
913 struct ViewRemap<DstType, SrcType, ExecSpace, 3> {
914  using p_type = Kokkos::pair<int64_t, int64_t>;
915 
916  ViewRemap(const DstType& dst, const SrcType& src) {
917  if (dst.extent(0) == src.extent(0)) {
918  if (dst.extent(2) == src.extent(2)) {
919  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
920  using sv_adapter_type =
921  CommonSubview<DstType, SrcType, 3, Kokkos::Impl::ALL_t, p_type,
922  Kokkos::Impl::ALL_t>;
923  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1,
924  Kokkos::ALL);
925  view_copy(common_subview.dst_sub, common_subview.src_sub);
926  } else {
927  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
928  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
929  using sv_adapter_type =
930  CommonSubview<DstType, SrcType, 3, Kokkos::Impl::ALL_t, p_type,
931  p_type>;
932  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2);
933  view_copy(common_subview.dst_sub, common_subview.src_sub);
934  }
935  } else {
936  if (dst.extent(2) == src.extent(2)) {
937  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
938  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
939  using sv_adapter_type = CommonSubview<DstType, SrcType, 3, p_type,
940  p_type, Kokkos::Impl::ALL_t>;
941  sv_adapter_type common_subview(dst, src, ext0, ext1, Kokkos::ALL);
942  view_copy(common_subview.dst_sub, 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(common_subview.dst_sub, common_subview.src_sub);
951  }
952  }
953  }
954 };
955 
956 template <class DstType, class SrcType, class ExecSpace>
957 struct ViewRemap<DstType, SrcType, ExecSpace, 4> {
958  using p_type = Kokkos::pair<int64_t, int64_t>;
959 
960  ViewRemap(const DstType& dst, const SrcType& src) {
961  if (dst.extent(0) == src.extent(0)) {
962  if (dst.extent(3) == src.extent(3)) {
963  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
964  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
965  using sv_adapter_type =
966  CommonSubview<DstType, SrcType, 4, Kokkos::Impl::ALL_t, p_type,
967  p_type, Kokkos::Impl::ALL_t>;
968  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2,
969  Kokkos::ALL);
970  view_copy(common_subview.dst_sub, common_subview.src_sub);
971  } else {
972  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
973  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
974  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
975  using sv_adapter_type =
976  CommonSubview<DstType, SrcType, 4, Kokkos::Impl::ALL_t, p_type,
977  p_type, p_type>;
978  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3);
979  view_copy(common_subview.dst_sub, common_subview.src_sub);
980  }
981  } else {
982  if (dst.extent(7) == src.extent(7)) {
983  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
984  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
985  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
986  using sv_adapter_type =
987  CommonSubview<DstType, SrcType, 4, p_type, p_type, p_type,
988  Kokkos::Impl::ALL_t>;
989  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, Kokkos::ALL);
990  view_copy(common_subview.dst_sub, common_subview.src_sub);
991  } else {
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  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
996  using sv_adapter_type =
997  CommonSubview<DstType, SrcType, 4, p_type, p_type, p_type, p_type>;
998  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3);
999  view_copy(common_subview.dst_sub, common_subview.src_sub);
1000  }
1001  }
1002  }
1003 };
1004 
1005 template <class DstType, class SrcType, class ExecSpace>
1006 struct ViewRemap<DstType, SrcType, ExecSpace, 5> {
1007  using p_type = Kokkos::pair<int64_t, int64_t>;
1008 
1009  ViewRemap(const DstType& dst, const SrcType& src) {
1010  if (dst.extent(0) == src.extent(0)) {
1011  if (dst.extent(4) == src.extent(4)) {
1012  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1013  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1014  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1015  using sv_adapter_type =
1016  CommonSubview<DstType, SrcType, 5, Kokkos::Impl::ALL_t, p_type,
1017  p_type, p_type, Kokkos::Impl::ALL_t>;
1018  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1019  Kokkos::ALL);
1020  view_copy(common_subview.dst_sub, common_subview.src_sub);
1021  } else {
1022  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1023  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1024  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1025  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1026  using sv_adapter_type =
1027  CommonSubview<DstType, SrcType, 5, Kokkos::Impl::ALL_t, p_type,
1028  p_type, p_type, p_type>;
1029  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1030  ext4);
1031  view_copy(common_subview.dst_sub, common_subview.src_sub);
1032  }
1033  } else {
1034  if (dst.extent(4) == src.extent(4)) {
1035  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1036  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1037  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1038  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1039  using sv_adapter_type =
1040  CommonSubview<DstType, SrcType, 5, p_type, p_type, p_type, p_type,
1041  Kokkos::Impl::ALL_t>;
1042  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3,
1043  Kokkos::ALL);
1044  view_copy(common_subview.dst_sub, common_subview.src_sub);
1045  } else {
1046  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1047  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1048  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1049  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1050  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1051  using sv_adapter_type = CommonSubview<DstType, SrcType, 5, p_type,
1052  p_type, p_type, p_type, p_type>;
1053  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4);
1054  view_copy(common_subview.dst_sub, common_subview.src_sub);
1055  }
1056  }
1057  }
1058 };
1059 template <class DstType, class SrcType, class ExecSpace>
1060 struct ViewRemap<DstType, SrcType, ExecSpace, 6> {
1061  using p_type = Kokkos::pair<int64_t, int64_t>;
1062 
1063  ViewRemap(const DstType& dst, const SrcType& src) {
1064  if (dst.extent(0) == src.extent(0)) {
1065  if (dst.extent(5) == src.extent(5)) {
1066  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1067  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1068  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1069  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1070  using sv_adapter_type =
1071  CommonSubview<DstType, SrcType, 6, Kokkos::Impl::ALL_t, p_type,
1072  p_type, p_type, p_type, Kokkos::Impl::ALL_t>;
1073  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1074  ext4, Kokkos::ALL);
1075  view_copy(common_subview.dst_sub, common_subview.src_sub);
1076  } else {
1077  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1078  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1079  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1080  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1081  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1082  using sv_adapter_type =
1083  CommonSubview<DstType, SrcType, 6, Kokkos::Impl::ALL_t, p_type,
1084  p_type, p_type, p_type, p_type>;
1085  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1086  ext4, ext5);
1087  view_copy(common_subview.dst_sub, common_subview.src_sub);
1088  }
1089  } else {
1090  if (dst.extent(5) == src.extent(5)) {
1091  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1092  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1093  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1094  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1095  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1096 
1097  using sv_adapter_type =
1098  CommonSubview<DstType, SrcType, 6, p_type, p_type, p_type, p_type,
1099  p_type, Kokkos::Impl::ALL_t>;
1100  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1101  Kokkos::ALL);
1102  view_copy(common_subview.dst_sub, common_subview.src_sub);
1103  } else {
1104  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
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 
1111  using sv_adapter_type =
1112  CommonSubview<DstType, SrcType, 6, p_type, p_type, p_type, p_type,
1113  p_type, p_type>;
1114  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1115  ext5);
1116  view_copy(common_subview.dst_sub, common_subview.src_sub);
1117  }
1118  }
1119  }
1120 };
1121 
1122 template <class DstType, class SrcType, class ExecSpace>
1123 struct ViewRemap<DstType, SrcType, ExecSpace, 7> {
1124  using p_type = Kokkos::pair<int64_t, int64_t>;
1125 
1126  ViewRemap(const DstType& dst, const SrcType& src) {
1127  if (dst.extent(0) == src.extent(0)) {
1128  if (dst.extent(6) == src.extent(6)) {
1129  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1130  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1131  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1132  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1133  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1134  using sv_adapter_type =
1135  CommonSubview<DstType, SrcType, 7, Kokkos::Impl::ALL_t, p_type,
1136  p_type, p_type, p_type, p_type, Kokkos::Impl::ALL_t>;
1137  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1138  ext4, ext5, Kokkos::ALL);
1139  view_copy(common_subview.dst_sub, common_subview.src_sub);
1140  } else {
1141  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1142  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1143  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1144  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1145  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1146  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1147  using sv_adapter_type =
1148  CommonSubview<DstType, SrcType, 7, Kokkos::Impl::ALL_t, p_type,
1149  p_type, p_type, p_type, p_type, p_type>;
1150  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1151  ext4, ext5, ext6);
1152  view_copy(common_subview.dst_sub, common_subview.src_sub);
1153  }
1154  } else {
1155  if (dst.extent(6) == src.extent(6)) {
1156  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1157  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1158  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1159  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1160  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1161  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1162  using sv_adapter_type =
1163  CommonSubview<DstType, SrcType, 7, p_type, p_type, p_type, p_type,
1164  p_type, p_type, Kokkos::Impl::ALL_t>;
1165  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1166  ext5, Kokkos::ALL);
1167  view_copy(common_subview.dst_sub, common_subview.src_sub);
1168  } else {
1169  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1170  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1171  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1172  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1173  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1174  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1175  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1176  using sv_adapter_type =
1177  CommonSubview<DstType, SrcType, 7, p_type, p_type, p_type, p_type,
1178  p_type, p_type, p_type>;
1179  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1180  ext5, ext6);
1181  view_copy(common_subview.dst_sub, common_subview.src_sub);
1182  }
1183  }
1184  }
1185 };
1186 
1187 template <class DstType, class SrcType, class ExecSpace>
1188 struct ViewRemap<DstType, SrcType, ExecSpace, 8> {
1189  using p_type = Kokkos::pair<int64_t, int64_t>;
1190 
1191  ViewRemap(const DstType& dst, const SrcType& src) {
1192  if (dst.extent(0) == src.extent(0)) {
1193  if (dst.extent(7) == src.extent(7)) {
1194  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1195  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1196  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1197  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1198  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1199  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1200  using sv_adapter_type =
1201  CommonSubview<DstType, SrcType, 8, Kokkos::Impl::ALL_t, p_type,
1202  p_type, p_type, p_type, p_type, p_type,
1203  Kokkos::Impl::ALL_t>;
1204  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1205  ext4, ext5, ext6, Kokkos::ALL);
1206  view_copy(common_subview.dst_sub, common_subview.src_sub);
1207  } else {
1208  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1209  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1210  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1211  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1212  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1213  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1214  p_type ext7(0, std::min(dst.extent(7), src.extent(7)));
1215  using sv_adapter_type =
1216  CommonSubview<DstType, SrcType, 8, Kokkos::Impl::ALL_t, p_type,
1217  p_type, p_type, p_type, p_type, p_type, p_type>;
1218  sv_adapter_type common_subview(dst, src, Kokkos::ALL, ext1, ext2, ext3,
1219  ext4, ext5, ext6, ext7);
1220  view_copy(common_subview.dst_sub, common_subview.src_sub);
1221  }
1222  } else {
1223  if (dst.extent(7) == src.extent(7)) {
1224  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1225  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1226  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1227  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1228  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1229  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1230  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1231  using sv_adapter_type =
1232  CommonSubview<DstType, SrcType, 8, p_type, p_type, p_type, p_type,
1233  p_type, p_type, p_type, Kokkos::Impl::ALL_t>;
1234  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1235  ext5, ext6, Kokkos::ALL);
1236  view_copy(common_subview.dst_sub, common_subview.src_sub);
1237  } else {
1238  p_type ext0(0, std::min(dst.extent(0), src.extent(0)));
1239  p_type ext1(0, std::min(dst.extent(1), src.extent(1)));
1240  p_type ext2(0, std::min(dst.extent(2), src.extent(2)));
1241  p_type ext3(0, std::min(dst.extent(3), src.extent(3)));
1242  p_type ext4(0, std::min(dst.extent(4), src.extent(4)));
1243  p_type ext5(0, std::min(dst.extent(5), src.extent(5)));
1244  p_type ext6(0, std::min(dst.extent(6), src.extent(6)));
1245  p_type ext7(0, std::min(dst.extent(7), src.extent(7)));
1246  using sv_adapter_type =
1247  CommonSubview<DstType, SrcType, 8, p_type, p_type, p_type, p_type,
1248  p_type, p_type, p_type, p_type>;
1249  sv_adapter_type common_subview(dst, src, ext0, ext1, ext2, ext3, ext4,
1250  ext5, ext6, ext7);
1251  view_copy(common_subview.dst_sub, common_subview.src_sub);
1252  }
1253  }
1254  }
1255 };
1256 
1257 } // namespace Impl
1258 
1260 template <class DT, class... DP>
1261 inline void deep_copy(
1262  const View<DT, DP...>& dst,
1263  typename ViewTraits<DT, DP...>::const_value_type& value,
1264  typename std::enable_if<std::is_same<
1265  typename ViewTraits<DT, DP...>::specialize, void>::value>::type* =
1266  nullptr) {
1267  using ViewType = View<DT, DP...>;
1268  using exec_space_type = typename ViewType::execution_space;
1269 
1270  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1271  Kokkos::Profiling::beginDeepCopy(
1272  Kokkos::Profiling::make_space_handle(ViewType::memory_space::name()),
1273  dst.label(), dst.data(),
1274  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
1275  "Scalar", &value, dst.span() * sizeof(typename ViewType::value_type));
1276  }
1277 
1278  if (dst.data() == nullptr) {
1279  Kokkos::fence();
1280  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1281  Kokkos::Profiling::endDeepCopy();
1282  }
1283  return;
1284  }
1285 
1286  Kokkos::fence();
1287  static_assert(std::is_same<typename ViewType::non_const_value_type,
1288  typename ViewType::value_type>::value,
1289  "deep_copy requires non-const type");
1290 
1291  // If contiguous we can simply do a 1D flat loop
1292  if (dst.span_is_contiguous()) {
1293  using ViewTypeFlat = Kokkos::View<
1294  typename ViewType::value_type*, Kokkos::LayoutRight,
1295  Kokkos::Device<typename ViewType::execution_space,
1296  typename std::conditional<
1297  ViewType::Rank == 0, typename ViewType::memory_space,
1298  Kokkos::AnonymousSpace>::type>,
1299  Kokkos::MemoryTraits<0>>;
1300 
1301  ViewTypeFlat dst_flat(dst.data(), dst.size());
1302  if (dst.span() < static_cast<size_t>(std::numeric_limits<int>::max())) {
1303  Kokkos::Impl::ViewFill<ViewTypeFlat, Kokkos::LayoutRight, exec_space_type,
1304  ViewTypeFlat::Rank, int>(dst_flat, value,
1305  exec_space_type());
1306  } else
1307  Kokkos::Impl::ViewFill<ViewTypeFlat, Kokkos::LayoutRight, exec_space_type,
1308  ViewTypeFlat::Rank, int64_t>(dst_flat, value,
1309  exec_space_type());
1310  Kokkos::fence();
1311  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1312  Kokkos::Profiling::endDeepCopy();
1313  }
1314  return;
1315  }
1316 
1317  // Figure out iteration order to do the ViewFill
1318  int64_t strides[ViewType::Rank + 1];
1319  dst.stride(strides);
1320  Kokkos::Iterate iterate;
1321  if (std::is_same<typename ViewType::array_layout,
1322  Kokkos::LayoutRight>::value) {
1323  iterate = Kokkos::Iterate::Right;
1324  } else if (std::is_same<typename ViewType::array_layout,
1325  Kokkos::LayoutLeft>::value) {
1326  iterate = Kokkos::Iterate::Left;
1327  } else if (std::is_same<typename ViewType::array_layout,
1328  Kokkos::LayoutStride>::value) {
1329  if (strides[0] > strides[ViewType::Rank > 0 ? ViewType::Rank - 1 : 0])
1330  iterate = Kokkos::Iterate::Right;
1331  else
1332  iterate = Kokkos::Iterate::Left;
1333  } else {
1334  if (std::is_same<typename ViewType::execution_space::array_layout,
1335  Kokkos::LayoutRight>::value)
1336  iterate = Kokkos::Iterate::Right;
1337  else
1338  iterate = Kokkos::Iterate::Left;
1339  }
1340 
1341  // Lets call the right ViewFill functor based on integer space needed and
1342  // iteration type
1343  using ViewTypeUniform = typename std::conditional<
1344  ViewType::Rank == 0, typename ViewType::uniform_runtime_type,
1345  typename ViewType::uniform_runtime_nomemspace_type>::type;
1346  if (dst.span() > static_cast<size_t>(std::numeric_limits<int>::max())) {
1347  if (iterate == Kokkos::Iterate::Right)
1348  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight,
1349  exec_space_type, ViewType::Rank, int64_t>(
1350  dst, value, exec_space_type());
1351  else
1352  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft,
1353  exec_space_type, ViewType::Rank, int64_t>(
1354  dst, value, exec_space_type());
1355  } else {
1356  if (iterate == Kokkos::Iterate::Right)
1357  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutRight,
1358  exec_space_type, ViewType::Rank, int>(
1359  dst, value, exec_space_type());
1360  else
1361  Kokkos::Impl::ViewFill<ViewTypeUniform, Kokkos::LayoutLeft,
1362  exec_space_type, ViewType::Rank, int>(
1363  dst, value, exec_space_type());
1364  }
1365  Kokkos::fence();
1366 
1367  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1368  Kokkos::Profiling::endDeepCopy();
1369  }
1370 }
1371 
1373 template <class ST, class... SP>
1374 inline void deep_copy(
1375  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1376  const View<ST, SP...>& src,
1377  typename std::enable_if<std::is_same<
1378  typename ViewTraits<ST, SP...>::specialize, void>::value>::type* =
1379  nullptr) {
1380  using src_traits = ViewTraits<ST, SP...>;
1381  using src_memory_space = typename src_traits::memory_space;
1382 
1383  static_assert(src_traits::rank == 0,
1384  "ERROR: Non-rank-zero view in deep_copy( value , View )");
1385 
1386  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1387  Kokkos::Profiling::beginDeepCopy(
1388  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
1389  "Scalar", &dst,
1390  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1391  src.label(), src.data(),
1392  src.span() * sizeof(typename src_traits::value_type));
1393  }
1394 
1395  if (src.data() == nullptr) {
1396  Kokkos::fence();
1397  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1398  Kokkos::Profiling::endDeepCopy();
1399  }
1400  return;
1401  }
1402 
1403  Kokkos::Impl::DeepCopy<HostSpace, src_memory_space>(&dst, src.data(),
1404  sizeof(ST));
1405  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1406  Kokkos::Profiling::endDeepCopy();
1407  }
1408 }
1409 
1410 //----------------------------------------------------------------------------
1412 template <class DT, class... DP, class ST, class... SP>
1413 inline void deep_copy(
1414  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1415  typename std::enable_if<(
1416  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
1417  std::is_same<typename ViewTraits<ST, SP...>::specialize, void>::value &&
1418  (unsigned(ViewTraits<DT, DP...>::rank) == unsigned(0) &&
1419  unsigned(ViewTraits<ST, SP...>::rank) == unsigned(0)))>::type* =
1420  nullptr) {
1421  using dst_type = View<DT, DP...>;
1422  using src_type = View<ST, SP...>;
1423 
1424  using value_type = typename dst_type::value_type;
1425  using dst_memory_space = typename dst_type::memory_space;
1426  using src_memory_space = typename src_type::memory_space;
1427 
1428  static_assert(std::is_same<typename dst_type::value_type,
1429  typename src_type::non_const_value_type>::value,
1430  "deep_copy requires matching non-const destination type");
1431 
1432  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1433  Kokkos::Profiling::beginDeepCopy(
1434  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
1435  dst.label(), dst.data(),
1436  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1437  src.label(), src.data(),
1438  src.span() * sizeof(typename dst_type::value_type));
1439  }
1440 
1441  if (dst.data() == nullptr && src.data() == nullptr) {
1442  Kokkos::fence();
1443  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1444  Kokkos::Profiling::endDeepCopy();
1445  }
1446  return;
1447  }
1448 
1449  Kokkos::fence();
1450  if (dst.data() != src.data()) {
1451  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1452  dst.data(), src.data(), sizeof(value_type));
1453  Kokkos::fence();
1454  }
1455  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1456  Kokkos::Profiling::endDeepCopy();
1457  }
1458 }
1459 
1460 //----------------------------------------------------------------------------
1464 template <class DT, class... DP, class ST, class... SP>
1465 inline void deep_copy(
1466  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1467  typename std::enable_if<(
1468  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
1469  std::is_same<typename ViewTraits<ST, SP...>::specialize, void>::value &&
1470  (unsigned(ViewTraits<DT, DP...>::rank) != 0 ||
1471  unsigned(ViewTraits<ST, SP...>::rank) != 0))>::type* = nullptr) {
1472  using dst_type = View<DT, DP...>;
1473  using src_type = View<ST, SP...>;
1474  using dst_execution_space = typename dst_type::execution_space;
1475  using src_execution_space = typename src_type::execution_space;
1476  using dst_memory_space = typename dst_type::memory_space;
1477  using src_memory_space = typename src_type::memory_space;
1478  using dst_value_type = typename dst_type::value_type;
1479  using src_value_type = typename src_type::value_type;
1480 
1481  static_assert(std::is_same<typename dst_type::value_type,
1482  typename dst_type::non_const_value_type>::value,
1483  "deep_copy requires non-const destination type");
1484 
1485  static_assert((unsigned(dst_type::rank) == unsigned(src_type::rank)),
1486  "deep_copy requires Views of equal rank");
1487 
1488  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
1489  Kokkos::Profiling::beginDeepCopy(
1490  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
1491  dst.label(), dst.data(),
1492  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
1493  src.label(), src.data(),
1494  src.span() * sizeof(typename dst_type::value_type));
1495  }
1496 
1497  if (dst.data() == nullptr || src.data() == nullptr) {
1498  // throw if dimension mismatch
1499  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
1500  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
1501  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
1502  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
1503  std::string message(
1504  "Deprecation Error: Kokkos::deep_copy extents of views don't "
1505  "match: ");
1506  message += dst.label();
1507  message += "(";
1508  for (int r = 0; r < dst_type::Rank - 1; r++) {
1509  message += std::to_string(dst.extent(r));
1510  message += ",";
1511  }
1512  message += std::to_string(dst.extent(dst_type::Rank - 1));
1513  message += ") ";
1514  message += src.label();
1515  message += "(";
1516  for (int r = 0; r < src_type::Rank - 1; r++) {
1517  message += std::to_string(src.extent(r));
1518  message += ",";
1519  }
1520  message += std::to_string(src.extent(src_type::Rank - 1));
1521  message += ") ";
1522 
1523  Kokkos::Impl::throw_runtime_exception(message);
1524  }
1525  Kokkos::fence();
1526  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1527  Kokkos::Profiling::endDeepCopy();
1528  }
1529  return;
1530  }
1531 
1532  enum {
1533  DstExecCanAccessSrc =
1534  Kokkos::Impl::SpaceAccessibility<dst_execution_space,
1535  src_memory_space>::accessible
1536  };
1537 
1538  enum {
1539  SrcExecCanAccessDst =
1540  Kokkos::Impl::SpaceAccessibility<src_execution_space,
1541  dst_memory_space>::accessible
1542  };
1543 
1544  // Checking for Overlapping Views.
1545  dst_value_type* dst_start = dst.data();
1546  dst_value_type* dst_end = dst.data() + dst.span();
1547  src_value_type* src_start = src.data();
1548  src_value_type* src_end = src.data() + src.span();
1549  if (((std::ptrdiff_t)dst_start == (std::ptrdiff_t)src_start) &&
1550  ((std::ptrdiff_t)dst_end == (std::ptrdiff_t)src_end) &&
1551  (dst.span_is_contiguous() && src.span_is_contiguous())) {
1552  Kokkos::fence();
1553  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1554  Kokkos::Profiling::endDeepCopy();
1555  }
1556  return;
1557  }
1558 
1559  if ((((std::ptrdiff_t)dst_start < (std::ptrdiff_t)src_end) &&
1560  ((std::ptrdiff_t)dst_end > (std::ptrdiff_t)src_start)) &&
1561  ((dst.span_is_contiguous() && src.span_is_contiguous()))) {
1562  std::string message("Error: Kokkos::deep_copy of overlapping views: ");
1563  message += dst.label();
1564  message += "(";
1565  message += std::to_string((std::ptrdiff_t)dst_start);
1566  message += ",";
1567  message += std::to_string((std::ptrdiff_t)dst_end);
1568  message += ") ";
1569  message += src.label();
1570  message += "(";
1571  message += std::to_string((std::ptrdiff_t)src_start);
1572  message += ",";
1573  message += std::to_string((std::ptrdiff_t)src_end);
1574  message += ") ";
1575  Kokkos::Impl::throw_runtime_exception(message);
1576  }
1577 
1578  // Check for same extents
1579  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
1580  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
1581  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
1582  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
1583  std::string message(
1584  "Deprecation Error: Kokkos::deep_copy extents of views don't match: ");
1585  message += dst.label();
1586  message += "(";
1587  for (int r = 0; r < dst_type::Rank - 1; r++) {
1588  message += std::to_string(dst.extent(r));
1589  message += ",";
1590  }
1591  message += std::to_string(dst.extent(dst_type::Rank - 1));
1592  message += ") ";
1593  message += src.label();
1594  message += "(";
1595  for (int r = 0; r < src_type::Rank - 1; r++) {
1596  message += std::to_string(src.extent(r));
1597  message += ",";
1598  }
1599  message += std::to_string(src.extent(src_type::Rank - 1));
1600  message += ") ";
1601 
1602  Kokkos::Impl::throw_runtime_exception(message);
1603  }
1604 
1605  // If same type, equal layout, equal dimensions, equal span, and contiguous
1606  // memory then can byte-wise copy
1607 
1608  if (std::is_same<typename dst_type::value_type,
1609  typename src_type::non_const_value_type>::value &&
1610  (std::is_same<typename dst_type::array_layout,
1611  typename src_type::array_layout>::value ||
1612  (dst_type::rank == 1 && src_type::rank == 1)) &&
1613  dst.span_is_contiguous() && src.span_is_contiguous() &&
1614  ((dst_type::rank < 1) || (dst.stride_0() == src.stride_0())) &&
1615  ((dst_type::rank < 2) || (dst.stride_1() == src.stride_1())) &&
1616  ((dst_type::rank < 3) || (dst.stride_2() == src.stride_2())) &&
1617  ((dst_type::rank < 4) || (dst.stride_3() == src.stride_3())) &&
1618  ((dst_type::rank < 5) || (dst.stride_4() == src.stride_4())) &&
1619  ((dst_type::rank < 6) || (dst.stride_5() == src.stride_5())) &&
1620  ((dst_type::rank < 7) || (dst.stride_6() == src.stride_6())) &&
1621  ((dst_type::rank < 8) || (dst.stride_7() == src.stride_7()))) {
1622  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1623  Kokkos::fence();
1624  if ((void*)dst.data() != (void*)src.data()) {
1625  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1626  dst.data(), src.data(), nbytes);
1627  Kokkos::fence();
1628  }
1629  } else {
1630  Kokkos::fence();
1631  Impl::view_copy(dst, src);
1632  Kokkos::fence();
1633  }
1634  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
1635  Kokkos::Profiling::endDeepCopy();
1636  }
1637 }
1638 
1639 //----------------------------------------------------------------------------
1640 //----------------------------------------------------------------------------
1641 namespace Experimental {
1645 template <class TeamType, class DT, class... DP, class ST, class... SP>
1646 void KOKKOS_INLINE_FUNCTION
1647 local_deep_copy_contiguous(const TeamType& team, const View<DT, DP...>& dst,
1648  const View<ST, SP...>& src) {
1649  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, src.span()),
1650  [&](const int& i) { dst.data()[i] = src.data()[i]; });
1651 }
1652 //----------------------------------------------------------------------------
1653 template <class DT, class... DP, class ST, class... SP>
1654 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
1655  const View<DT, DP...>& dst, const View<ST, SP...>& src) {
1656  for (size_t i = 0; i < src.span(); ++i) {
1657  dst.data()[i] = src.data()[i];
1658  }
1659 }
1660 //----------------------------------------------------------------------------
1661 template <class TeamType, class DT, class... DP, class ST, class... SP>
1662 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1663  const TeamType& team, const View<DT, DP...>& dst,
1664  const View<ST, SP...>& src,
1665  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 1 &&
1666  unsigned(ViewTraits<ST, SP...>::rank) ==
1667  1)>::type* = nullptr) {
1668  if (dst.data() == nullptr) {
1669  return;
1670  }
1671 
1672  const size_t N = dst.extent(0);
1673 
1674  team.team_barrier();
1675  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N),
1676  [&](const int& i) { dst(i) = src(i); });
1677  team.team_barrier();
1678 }
1679 //----------------------------------------------------------------------------
1680 template <class TeamType, class DT, class... DP, class ST, class... SP>
1681 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1682  const TeamType& team, const View<DT, DP...>& dst,
1683  const View<ST, SP...>& src,
1684  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 2 &&
1685  unsigned(ViewTraits<ST, SP...>::rank) ==
1686  2)>::type* = nullptr) {
1687  if (dst.data() == nullptr) {
1688  return;
1689  }
1690 
1691  const size_t N = dst.extent(0) * dst.extent(1);
1692 
1693  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1694  team.team_barrier();
1695  local_deep_copy_contiguous(team, dst, src);
1696  team.team_barrier();
1697  } else {
1698  team.team_barrier();
1699  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1700  int i0 = i % dst.extent(0);
1701  int i1 = i / dst.extent(0);
1702  dst(i0, i1) = src(i0, i1);
1703  });
1704  team.team_barrier();
1705  }
1706 }
1707 //----------------------------------------------------------------------------
1708 template <class TeamType, class DT, class... DP, class ST, class... SP>
1709 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1710  const TeamType& team, const View<DT, DP...>& dst,
1711  const View<ST, SP...>& src,
1712  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 3 &&
1713  unsigned(ViewTraits<ST, SP...>::rank) ==
1714  3)>::type* = nullptr) {
1715  if (dst.data() == nullptr) {
1716  return;
1717  }
1718 
1719  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2);
1720 
1721  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1722  team.team_barrier();
1723  local_deep_copy_contiguous(team, dst, src);
1724  team.team_barrier();
1725  } else {
1726  team.team_barrier();
1727  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1728  int i0 = i % dst.extent(0);
1729  int itmp = i / dst.extent(0);
1730  int i1 = itmp % dst.extent(1);
1731  int i2 = itmp / dst.extent(1);
1732  dst(i0, i1, i2) = src(i0, i1, i2);
1733  });
1734  team.team_barrier();
1735  }
1736 }
1737 //----------------------------------------------------------------------------
1738 template <class TeamType, class DT, class... DP, class ST, class... SP>
1739 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1740  const TeamType& team, const View<DT, DP...>& dst,
1741  const View<ST, SP...>& src,
1742  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 4 &&
1743  unsigned(ViewTraits<ST, SP...>::rank) ==
1744  4)>::type* = nullptr) {
1745  if (dst.data() == nullptr) {
1746  return;
1747  }
1748 
1749  const size_t N =
1750  dst.extent(0) * dst.extent(1) * dst.extent(2) * dst.extent(3);
1751 
1752  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1753  team.team_barrier();
1754  local_deep_copy_contiguous(team, dst, src);
1755  team.team_barrier();
1756  } else {
1757  team.team_barrier();
1758  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1759  int i0 = i % dst.extent(0);
1760  int itmp = i / dst.extent(0);
1761  int i1 = itmp % dst.extent(1);
1762  itmp = itmp / dst.extent(1);
1763  int i2 = itmp % dst.extent(2);
1764  int i3 = itmp / dst.extent(2);
1765  dst(i0, i1, i2, i3) = src(i0, i1, i2, i3);
1766  });
1767  team.team_barrier();
1768  }
1769 }
1770 //----------------------------------------------------------------------------
1771 template <class TeamType, class DT, class... DP, class ST, class... SP>
1772 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1773  const TeamType& team, const View<DT, DP...>& dst,
1774  const View<ST, SP...>& src,
1775  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 5 &&
1776  unsigned(ViewTraits<ST, SP...>::rank) ==
1777  5)>::type* = nullptr) {
1778  if (dst.data() == nullptr) {
1779  return;
1780  }
1781 
1782  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1783  dst.extent(3) * dst.extent(4);
1784 
1785  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1786  team.team_barrier();
1787  local_deep_copy_contiguous(team, dst, src);
1788  team.team_barrier();
1789  } else {
1790  team.team_barrier();
1791  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1792  int i0 = i % dst.extent(0);
1793  int itmp = i / dst.extent(0);
1794  int i1 = itmp % dst.extent(1);
1795  itmp = itmp / dst.extent(1);
1796  int i2 = itmp % dst.extent(2);
1797  itmp = itmp / dst.extent(2);
1798  int i3 = itmp % dst.extent(3);
1799  int i4 = itmp / dst.extent(3);
1800  dst(i0, i1, i2, i3, i4) = src(i0, i1, i2, i3, i4);
1801  });
1802  team.team_barrier();
1803  }
1804 }
1805 //----------------------------------------------------------------------------
1806 template <class TeamType, class DT, class... DP, class ST, class... SP>
1807 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1808  const TeamType& team, const View<DT, DP...>& dst,
1809  const View<ST, SP...>& src,
1810  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 6 &&
1811  unsigned(ViewTraits<ST, SP...>::rank) ==
1812  6)>::type* = nullptr) {
1813  if (dst.data() == nullptr) {
1814  return;
1815  }
1816 
1817  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1818  dst.extent(3) * dst.extent(4) * dst.extent(5);
1819 
1820  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1821  team.team_barrier();
1822  local_deep_copy_contiguous(team, dst, src);
1823  team.team_barrier();
1824  } else {
1825  team.team_barrier();
1826  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1827  int i0 = i % dst.extent(0);
1828  int itmp = i / dst.extent(0);
1829  int i1 = itmp % dst.extent(1);
1830  itmp = itmp / dst.extent(1);
1831  int i2 = itmp % dst.extent(2);
1832  itmp = itmp / dst.extent(2);
1833  int i3 = itmp % dst.extent(3);
1834  itmp = itmp / dst.extent(3);
1835  int i4 = itmp % dst.extent(4);
1836  int i5 = itmp / dst.extent(4);
1837  dst(i0, i1, i2, i3, i4, i5) = src(i0, i1, i2, i3, i4, i5);
1838  });
1839  team.team_barrier();
1840  }
1841 }
1842 //----------------------------------------------------------------------------
1843 template <class TeamType, class DT, class... DP, class ST, class... SP>
1844 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1845  const TeamType& team, const View<DT, DP...>& dst,
1846  const View<ST, SP...>& src,
1847  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 7 &&
1848  unsigned(ViewTraits<ST, SP...>::rank) ==
1849  7)>::type* = nullptr) {
1850  if (dst.data() == nullptr) {
1851  return;
1852  }
1853 
1854  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
1855  dst.extent(3) * dst.extent(4) * dst.extent(5) *
1856  dst.extent(6);
1857 
1858  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1859  team.team_barrier();
1860  local_deep_copy_contiguous(team, dst, src);
1861  team.team_barrier();
1862  } else {
1863  team.team_barrier();
1864  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
1865  int i0 = i % dst.extent(0);
1866  int itmp = i / dst.extent(0);
1867  int i1 = itmp % dst.extent(1);
1868  itmp = itmp / dst.extent(1);
1869  int i2 = itmp % dst.extent(2);
1870  itmp = itmp / dst.extent(2);
1871  int i3 = itmp % dst.extent(3);
1872  itmp = itmp / dst.extent(3);
1873  int i4 = itmp % dst.extent(4);
1874  itmp = itmp / dst.extent(4);
1875  int i5 = itmp % dst.extent(5);
1876  int i6 = itmp / dst.extent(5);
1877  dst(i0, i1, i2, i3, i4, i5, i6) = src(i0, i1, i2, i3, i4, i5, i6);
1878  });
1879  team.team_barrier();
1880  }
1881 }
1882 //----------------------------------------------------------------------------
1883 template <class DT, class... DP, class ST, class... SP>
1884 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1885  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1886  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 1 &&
1887  unsigned(ViewTraits<ST, SP...>::rank) ==
1888  1)>::type* = nullptr) {
1889  if (dst.data() == nullptr) {
1890  return;
1891  }
1892 
1893  const size_t N = dst.extent(0);
1894 
1895  for (size_t i = 0; i < N; ++i) {
1896  dst(i) = src(i);
1897  }
1898 }
1899 //----------------------------------------------------------------------------
1900 template <class DT, class... DP, class ST, class... SP>
1901 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1902  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1903  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 2 &&
1904  unsigned(ViewTraits<ST, SP...>::rank) ==
1905  2)>::type* = nullptr) {
1906  if (dst.data() == nullptr) {
1907  return;
1908  }
1909 
1910  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1911  local_deep_copy_contiguous(dst, src);
1912  } else {
1913  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
1914  for (size_t i1 = 0; i1 < dst.extent(1); ++i1) dst(i0, i1) = src(i0, i1);
1915  }
1916 }
1917 //----------------------------------------------------------------------------
1918 template <class DT, class... DP, class ST, class... SP>
1919 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1920  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1921  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 3 &&
1922  unsigned(ViewTraits<ST, SP...>::rank) ==
1923  3)>::type* = nullptr) {
1924  if (dst.data() == nullptr) {
1925  return;
1926  }
1927 
1928  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1929  local_deep_copy_contiguous(dst, src);
1930  } else {
1931  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
1932  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
1933  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
1934  dst(i0, i1, i2) = src(i0, i1, i2);
1935  }
1936 }
1937 //----------------------------------------------------------------------------
1938 template <class DT, class... DP, class ST, class... SP>
1939 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1940  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1941  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 4 &&
1942  unsigned(ViewTraits<ST, SP...>::rank) ==
1943  4)>::type* = nullptr) {
1944  if (dst.data() == nullptr) {
1945  return;
1946  }
1947 
1948  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1949  local_deep_copy_contiguous(dst, src);
1950  } else {
1951  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
1952  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
1953  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
1954  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
1955  dst(i0, i1, i2, i3) = src(i0, i1, i2, i3);
1956  }
1957 }
1958 //----------------------------------------------------------------------------
1959 template <class DT, class... DP, class ST, class... SP>
1960 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1961  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1962  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 5 &&
1963  unsigned(ViewTraits<ST, SP...>::rank) ==
1964  5)>::type* = nullptr) {
1965  if (dst.data() == nullptr) {
1966  return;
1967  }
1968 
1969  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1970  local_deep_copy_contiguous(dst, src);
1971  } else {
1972  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
1973  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
1974  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
1975  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
1976  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
1977  dst(i0, i1, i2, i3, i4) = src(i0, i1, i2, i3, i4);
1978  }
1979 }
1980 //----------------------------------------------------------------------------
1981 template <class DT, class... DP, class ST, class... SP>
1982 void KOKKOS_INLINE_FUNCTION local_deep_copy(
1983  const View<DT, DP...>& dst, const View<ST, SP...>& src,
1984  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 6 &&
1985  unsigned(ViewTraits<ST, SP...>::rank) ==
1986  6)>::type* = nullptr) {
1987  if (dst.data() == nullptr) {
1988  return;
1989  }
1990 
1991  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
1992  local_deep_copy_contiguous(dst, src);
1993  } else {
1994  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
1995  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
1996  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
1997  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
1998  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
1999  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2000  dst(i0, i1, i2, i3, i4, i5) = src(i0, i1, i2, i3, i4, i5);
2001  }
2002 }
2003 //----------------------------------------------------------------------------
2004 template <class DT, class... DP, class ST, class... SP>
2005 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2006  const View<DT, DP...>& dst, const View<ST, SP...>& src,
2007  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) == 7 &&
2008  unsigned(ViewTraits<ST, SP...>::rank) ==
2009  7)>::type* = nullptr) {
2010  if (dst.data() == nullptr) {
2011  return;
2012  }
2013 
2014  if (dst.span_is_contiguous() && src.span_is_contiguous()) {
2015  local_deep_copy_contiguous(dst, src);
2016  } else {
2017  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2018  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2019  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2020  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2021  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2022  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2023  for (size_t i6 = 0; i6 < dst.extent(6); ++i6)
2024  dst(i0, i1, i2, i3, i4, i5, i6) =
2025  src(i0, i1, i2, i3, i4, i5, i6);
2026  }
2027 }
2028 //----------------------------------------------------------------------------
2029 //----------------------------------------------------------------------------
2031 template <class TeamType, class DT, class... DP>
2032 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
2033  const TeamType& team, const View<DT, DP...>& dst,
2034  typename ViewTraits<DT, DP...>::const_value_type& value) {
2035  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, dst.span()),
2036  [&](const int& i) { dst.data()[i] = value; });
2037 }
2038 //----------------------------------------------------------------------------
2039 template <class DT, class... DP>
2040 void KOKKOS_INLINE_FUNCTION local_deep_copy_contiguous(
2041  const View<DT, DP...>& dst,
2042  typename ViewTraits<DT, DP...>::const_value_type& value) {
2043  for (size_t i = 0; i < dst.span(); ++i) {
2044  dst.data()[i] = value;
2045  }
2046 }
2047 //----------------------------------------------------------------------------
2048 template <class TeamType, class DT, class... DP>
2049 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2050  const TeamType& team, const View<DT, DP...>& dst,
2051  typename ViewTraits<DT, DP...>::const_value_type& value,
2052  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2053  1)>::type* = nullptr) {
2054  if (dst.data() == nullptr) {
2055  return;
2056  }
2057 
2058  const size_t N = dst.extent(0);
2059 
2060  team.team_barrier();
2061  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N),
2062  [&](const int& i) { dst(i) = value; });
2063  team.team_barrier();
2064 }
2065 //----------------------------------------------------------------------------
2066 template <class TeamType, class DT, class... DP>
2067 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2068  const TeamType& team, const View<DT, DP...>& dst,
2069  typename ViewTraits<DT, DP...>::const_value_type& value,
2070  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2071  2)>::type* = nullptr) {
2072  if (dst.data() == nullptr) {
2073  return;
2074  }
2075 
2076  const size_t N = dst.extent(0) * dst.extent(1);
2077 
2078  if (dst.span_is_contiguous()) {
2079  team.team_barrier();
2080  local_deep_copy_contiguous(team, dst, value);
2081  team.team_barrier();
2082  } else {
2083  team.team_barrier();
2084  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2085  int i0 = i % dst.extent(0);
2086  int i1 = i / dst.extent(0);
2087  dst(i0, i1) = value;
2088  });
2089  team.team_barrier();
2090  }
2091 }
2092 //----------------------------------------------------------------------------
2093 template <class TeamType, class DT, class... DP>
2094 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2095  const TeamType& team, const View<DT, DP...>& dst,
2096  typename ViewTraits<DT, DP...>::const_value_type& value,
2097  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2098  3)>::type* = nullptr) {
2099  if (dst.data() == nullptr) {
2100  return;
2101  }
2102 
2103  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2);
2104 
2105  if (dst.span_is_contiguous()) {
2106  team.team_barrier();
2107  local_deep_copy_contiguous(team, dst, value);
2108  team.team_barrier();
2109  } else {
2110  team.team_barrier();
2111  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2112  int i0 = i % dst.extent(0);
2113  int itmp = i / dst.extent(0);
2114  int i1 = itmp % dst.extent(1);
2115  int i2 = itmp / dst.extent(1);
2116  dst(i0, i1, i2) = value;
2117  });
2118  team.team_barrier();
2119  }
2120 }
2121 //----------------------------------------------------------------------------
2122 template <class TeamType, class DT, class... DP>
2123 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2124  const TeamType& team, const View<DT, DP...>& dst,
2125  typename ViewTraits<DT, DP...>::const_value_type& value,
2126  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2127  4)>::type* = nullptr) {
2128  if (dst.data() == nullptr) {
2129  return;
2130  }
2131 
2132  const size_t N =
2133  dst.extent(0) * dst.extent(1) * dst.extent(2) * dst.extent(3);
2134 
2135  if (dst.span_is_contiguous()) {
2136  team.team_barrier();
2137  local_deep_copy_contiguous(team, dst, value);
2138  team.team_barrier();
2139  } else {
2140  team.team_barrier();
2141  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2142  int i0 = i % dst.extent(0);
2143  int itmp = i / dst.extent(0);
2144  int i1 = itmp % dst.extent(1);
2145  itmp = itmp / dst.extent(1);
2146  int i2 = itmp % dst.extent(2);
2147  int i3 = itmp / dst.extent(2);
2148  dst(i0, i1, i2, i3) = value;
2149  });
2150  team.team_barrier();
2151  }
2152 }
2153 //----------------------------------------------------------------------------
2154 template <class TeamType, class DT, class... DP>
2155 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2156  const TeamType& team, const View<DT, DP...>& dst,
2157  typename ViewTraits<DT, DP...>::const_value_type& value,
2158  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2159  5)>::type* = nullptr) {
2160  if (dst.data() == nullptr) {
2161  return;
2162  }
2163 
2164  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2165  dst.extent(3) * dst.extent(4);
2166 
2167  if (dst.span_is_contiguous()) {
2168  team.team_barrier();
2169  local_deep_copy_contiguous(team, dst, value);
2170  team.team_barrier();
2171  } else {
2172  team.team_barrier();
2173  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2174  int i0 = i % dst.extent(0);
2175  int itmp = i / dst.extent(0);
2176  int i1 = itmp % dst.extent(1);
2177  itmp = itmp / dst.extent(1);
2178  int i2 = itmp % dst.extent(2);
2179  itmp = itmp / dst.extent(2);
2180  int i3 = itmp % dst.extent(3);
2181  int i4 = itmp / dst.extent(3);
2182  dst(i0, i1, i2, i3, i4) = value;
2183  });
2184  team.team_barrier();
2185  }
2186 }
2187 //----------------------------------------------------------------------------
2188 template <class TeamType, class DT, class... DP>
2189 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2190  const TeamType& team, const View<DT, DP...>& dst,
2191  typename ViewTraits<DT, DP...>::const_value_type& value,
2192  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2193  6)>::type* = nullptr) {
2194  if (dst.data() == nullptr) {
2195  return;
2196  }
2197 
2198  const size_t N = dst.extent(0) * dst.extent(1) * dst.extent(2) *
2199  dst.extent(3) * dst.extent(4) * dst.extent(5);
2200 
2201  if (dst.span_is_contiguous()) {
2202  team.team_barrier();
2203  local_deep_copy_contiguous(team, dst, value);
2204  team.team_barrier();
2205  } else {
2206  team.team_barrier();
2207  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2208  int i0 = i % dst.extent(0);
2209  int itmp = i / dst.extent(0);
2210  int i1 = itmp % dst.extent(1);
2211  itmp = itmp / dst.extent(1);
2212  int i2 = itmp % dst.extent(2);
2213  itmp = itmp / dst.extent(2);
2214  int i3 = itmp % dst.extent(3);
2215  itmp = itmp / dst.extent(3);
2216  int i4 = itmp % dst.extent(4);
2217  int i5 = itmp / dst.extent(4);
2218  dst(i0, i1, i2, i3, i4, i5) = value;
2219  });
2220  team.team_barrier();
2221  }
2222 }
2223 //----------------------------------------------------------------------------
2224 template <class TeamType, class DT, class... DP>
2225 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2226  const TeamType& team, const View<DT, DP...>& dst,
2227  typename ViewTraits<DT, DP...>::const_value_type& value,
2228  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2229  7)>::type* = 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  dst.extent(3) * dst.extent(4) * dst.extent(5) *
2236  dst.extent(6);
2237 
2238  if (dst.span_is_contiguous()) {
2239  team.team_barrier();
2240  local_deep_copy_contiguous(team, dst, value);
2241  team.team_barrier();
2242  } else {
2243  team.team_barrier();
2244  Kokkos::parallel_for(Kokkos::TeamThreadRange(team, N), [&](const int& i) {
2245  int i0 = i % dst.extent(0);
2246  int itmp = i / dst.extent(0);
2247  int i1 = itmp % dst.extent(1);
2248  itmp = itmp / dst.extent(1);
2249  int i2 = itmp % dst.extent(2);
2250  itmp = itmp / dst.extent(2);
2251  int i3 = itmp % dst.extent(3);
2252  itmp = itmp / dst.extent(3);
2253  int i4 = itmp % dst.extent(4);
2254  itmp = itmp / dst.extent(4);
2255  int i5 = itmp % dst.extent(5);
2256  int i6 = itmp / dst.extent(5);
2257  dst(i0, i1, i2, i3, i4, i5, i6) = value;
2258  });
2259  team.team_barrier();
2260  }
2261 }
2262 //----------------------------------------------------------------------------
2263 template <class DT, class... DP>
2264 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2265  const View<DT, DP...>& dst,
2266  typename ViewTraits<DT, DP...>::const_value_type& value,
2267  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2268  1)>::type* = nullptr) {
2269  if (dst.data() == nullptr) {
2270  return;
2271  }
2272 
2273  const size_t N = dst.extent(0);
2274 
2275  for (size_t i = 0; i < N; ++i) {
2276  dst(i) = value;
2277  }
2278 }
2279 //----------------------------------------------------------------------------
2280 template <class DT, class... DP>
2281 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2282  const View<DT, DP...>& dst,
2283  typename ViewTraits<DT, DP...>::const_value_type& value,
2284  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2285  2)>::type* = nullptr) {
2286  if (dst.data() == nullptr) {
2287  return;
2288  }
2289 
2290  if (dst.span_is_contiguous()) {
2291  local_deep_copy_contiguous(dst, value);
2292  } else {
2293  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2294  for (size_t i1 = 0; i1 < dst.extent(1); ++i1) dst(i0, i1) = value;
2295  }
2296 }
2297 //----------------------------------------------------------------------------
2298 template <class DT, class... DP>
2299 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2300  const View<DT, DP...>& dst,
2301  typename ViewTraits<DT, DP...>::const_value_type& value,
2302  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2303  3)>::type* = nullptr) {
2304  if (dst.data() == nullptr) {
2305  return;
2306  }
2307 
2308  if (dst.span_is_contiguous()) {
2309  local_deep_copy_contiguous(dst, value);
2310  } else {
2311  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2312  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2313  for (size_t i2 = 0; i2 < dst.extent(2); ++i2) dst(i0, i1, i2) = value;
2314  }
2315 }
2316 //----------------------------------------------------------------------------
2317 template <class DT, class... DP>
2318 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2319  const View<DT, DP...>& dst,
2320  typename ViewTraits<DT, DP...>::const_value_type& value,
2321  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2322  4)>::type* = nullptr) {
2323  if (dst.data() == nullptr) {
2324  return;
2325  }
2326 
2327  if (dst.span_is_contiguous()) {
2328  local_deep_copy_contiguous(dst, value);
2329  } else {
2330  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2331  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2332  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2333  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2334  dst(i0, i1, i2, i3) = value;
2335  }
2336 }
2337 //----------------------------------------------------------------------------
2338 template <class DT, class... DP>
2339 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2340  const View<DT, DP...>& dst,
2341  typename ViewTraits<DT, DP...>::const_value_type& value,
2342  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2343  5)>::type* = nullptr) {
2344  if (dst.data() == nullptr) {
2345  return;
2346  }
2347 
2348  if (dst.span_is_contiguous()) {
2349  local_deep_copy_contiguous(dst, value);
2350  } else {
2351  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2352  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2353  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2354  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2355  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2356  dst(i0, i1, i2, i3, i4) = value;
2357  }
2358 }
2359 //----------------------------------------------------------------------------
2360 template <class DT, class... DP>
2361 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2362  const View<DT, DP...>& dst,
2363  typename ViewTraits<DT, DP...>::const_value_type& value,
2364  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2365  6)>::type* = nullptr) {
2366  if (dst.data() == nullptr) {
2367  return;
2368  }
2369 
2370  if (dst.span_is_contiguous()) {
2371  local_deep_copy_contiguous(dst, value);
2372  } else {
2373  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2374  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2375  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2376  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2377  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2378  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2379  dst(i0, i1, i2, i3, i4, i5) = value;
2380  }
2381 }
2382 //----------------------------------------------------------------------------
2383 template <class DT, class... DP>
2384 void KOKKOS_INLINE_FUNCTION local_deep_copy(
2385  const View<DT, DP...>& dst,
2386  typename ViewTraits<DT, DP...>::const_value_type& value,
2387  typename std::enable_if<(unsigned(ViewTraits<DT, DP...>::rank) ==
2388  7)>::type* = nullptr) {
2389  if (dst.data() == nullptr) {
2390  return;
2391  }
2392 
2393  if (dst.span_is_contiguous()) {
2394  local_deep_copy_contiguous(dst, value);
2395  } else {
2396  for (size_t i0 = 0; i0 < dst.extent(0); ++i0)
2397  for (size_t i1 = 0; i1 < dst.extent(1); ++i1)
2398  for (size_t i2 = 0; i2 < dst.extent(2); ++i2)
2399  for (size_t i3 = 0; i3 < dst.extent(3); ++i3)
2400  for (size_t i4 = 0; i4 < dst.extent(4); ++i4)
2401  for (size_t i5 = 0; i5 < dst.extent(5); ++i5)
2402  for (size_t i6 = 0; i6 < dst.extent(6); ++i6)
2403  dst(i0, i1, i2, i3, i4, i5, i6) = value;
2404  }
2405 }
2406 } /* namespace Experimental */
2407 } /* namespace Kokkos */
2408 
2409 //----------------------------------------------------------------------------
2410 //----------------------------------------------------------------------------
2411 
2412 namespace Kokkos {
2413 
2416 template <class ExecSpace, class DT, class... DP>
2417 inline void deep_copy(
2418  const ExecSpace& space, const View<DT, DP...>& dst,
2419  typename ViewTraits<DT, DP...>::const_value_type& value,
2420  typename std::enable_if<
2421  Kokkos::Impl::is_execution_space<ExecSpace>::value &&
2422  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
2424  ExecSpace,
2425  typename ViewTraits<DT, DP...>::memory_space>::accessible>::type* =
2426  nullptr) {
2427  using dst_traits = ViewTraits<DT, DP...>;
2428  static_assert(std::is_same<typename dst_traits::non_const_value_type,
2429  typename dst_traits::value_type>::value,
2430  "deep_copy requires non-const type");
2431  using dst_memory_space = typename dst_traits::memory_space;
2432  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2433  Kokkos::Profiling::beginDeepCopy(
2434  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2435  dst.label(), dst.data(),
2436  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2437  "(none)", &value, dst.span() * sizeof(typename dst_traits::value_type));
2438  }
2439  if (dst.data() == nullptr) {
2440  space.fence();
2441  } else {
2442  using ViewTypeUniform = typename std::conditional<
2443  View<DT, DP...>::Rank == 0,
2444  typename View<DT, DP...>::uniform_runtime_type,
2445  typename View<DT, DP...>::uniform_runtime_nomemspace_type>::type;
2446  Kokkos::Impl::ViewFill<ViewTypeUniform, typename dst_traits::array_layout,
2447  ExecSpace>(dst, value, space);
2448  }
2449  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2450  Kokkos::Profiling::endDeepCopy();
2451  }
2452 }
2453 
2456 template <class ExecSpace, class DT, class... DP>
2457 inline void deep_copy(
2458  const ExecSpace& space, const View<DT, DP...>& dst,
2459  typename ViewTraits<DT, DP...>::const_value_type& value,
2460  typename std::enable_if<
2461  Kokkos::Impl::is_execution_space<ExecSpace>::value &&
2462  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
2464  ExecSpace,
2465  typename ViewTraits<DT, DP...>::memory_space>::accessible>::type* =
2466  nullptr) {
2467  using dst_traits = ViewTraits<DT, DP...>;
2468  static_assert(std::is_same<typename dst_traits::non_const_value_type,
2469  typename dst_traits::value_type>::value,
2470  "deep_copy requires non-const type");
2471  using dst_memory_space = typename dst_traits::memory_space;
2472  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2473  Kokkos::Profiling::beginDeepCopy(
2474  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2475  dst.label(), dst.data(),
2476  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2477  "(none)", &value, dst.span() * sizeof(typename dst_traits::value_type));
2478  }
2479  if (dst.data() == nullptr) {
2480  space.fence();
2481  } else {
2482  space.fence();
2483  using ViewTypeUniform = typename std::conditional<
2484  View<DT, DP...>::Rank == 0,
2485  typename View<DT, DP...>::uniform_runtime_type,
2486  typename View<DT, DP...>::uniform_runtime_nomemspace_type>::type;
2487  using fill_exec_space = typename dst_traits::memory_space::execution_space;
2488  Kokkos::Impl::ViewFill<ViewTypeUniform, typename dst_traits::array_layout,
2489  fill_exec_space>(dst, value, fill_exec_space());
2490  fill_exec_space().fence();
2491  }
2492  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2493  Kokkos::Profiling::endDeepCopy();
2494  }
2495 }
2496 
2498 template <class ExecSpace, class ST, class... SP>
2499 inline void deep_copy(
2500  const ExecSpace& exec_space,
2501  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
2502  const View<ST, SP...>& src,
2503  typename std::enable_if<
2504  Kokkos::Impl::is_execution_space<ExecSpace>::value &&
2505  std::is_same<typename ViewTraits<ST, SP...>::specialize,
2506  void>::value>::type* = nullptr) {
2507  using src_traits = ViewTraits<ST, SP...>;
2508  using src_memory_space = typename src_traits::memory_space;
2509  static_assert(src_traits::rank == 0,
2510  "ERROR: Non-rank-zero view in deep_copy( value , View )");
2511  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2512  Kokkos::Profiling::beginDeepCopy(
2513  Kokkos::Profiling::make_space_handle(Kokkos::HostSpace::name()),
2514  "(none)", &dst,
2515  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2516  src.label(), src.data(), sizeof(ST));
2517  }
2518 
2519  if (src.data() == nullptr) {
2520  exec_space.fence();
2521  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2522  Kokkos::Profiling::endDeepCopy();
2523  }
2524  return;
2525  }
2526 
2527  Kokkos::Impl::DeepCopy<HostSpace, src_memory_space, ExecSpace>(
2528  exec_space, &dst, src.data(), sizeof(ST));
2529  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2530  Kokkos::Profiling::endDeepCopy();
2531  }
2532 }
2533 
2534 //----------------------------------------------------------------------------
2536 template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2537 inline void deep_copy(
2538  const ExecSpace& exec_space, const View<DT, DP...>& dst,
2539  const View<ST, SP...>& src,
2540  typename std::enable_if<(
2541  Kokkos::Impl::is_execution_space<ExecSpace>::value &&
2542  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
2543  std::is_same<typename ViewTraits<ST, SP...>::specialize, void>::value &&
2544  (unsigned(ViewTraits<DT, DP...>::rank) == unsigned(0) &&
2545  unsigned(ViewTraits<ST, SP...>::rank) == unsigned(0)))>::type* =
2546  nullptr) {
2547  using src_traits = ViewTraits<ST, SP...>;
2548  using dst_traits = ViewTraits<DT, DP...>;
2549 
2550  using src_memory_space = typename src_traits::memory_space;
2551  using dst_memory_space = typename dst_traits::memory_space;
2552  static_assert(std::is_same<typename dst_traits::value_type,
2553  typename src_traits::non_const_value_type>::value,
2554  "deep_copy requires matching non-const destination type");
2555 
2556  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2557  Kokkos::Profiling::beginDeepCopy(
2558  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2559  dst.label(), dst.data(),
2560  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2561  src.label(), src.data(), sizeof(DT));
2562  }
2563 
2564  if (dst.data() == nullptr && src.data() == nullptr) {
2565  exec_space.fence();
2566  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2567  Kokkos::Profiling::endDeepCopy();
2568  }
2569  return;
2570  }
2571 
2572  if (dst.data() != src.data()) {
2573  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space, ExecSpace>(
2574  exec_space, dst.data(), src.data(),
2575  sizeof(typename dst_traits::value_type));
2576  }
2577  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2578  Kokkos::Profiling::endDeepCopy();
2579  }
2580 }
2581 
2582 //----------------------------------------------------------------------------
2586 template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2587 inline void deep_copy(
2588  const ExecSpace& exec_space, const View<DT, DP...>& dst,
2589  const View<ST, SP...>& src,
2590  typename std::enable_if<(
2591  Kokkos::Impl::is_execution_space<ExecSpace>::value &&
2592  std::is_same<typename ViewTraits<DT, DP...>::specialize, void>::value &&
2593  std::is_same<typename ViewTraits<ST, SP...>::specialize, void>::value &&
2594  (unsigned(ViewTraits<DT, DP...>::rank) != 0 ||
2595  unsigned(ViewTraits<ST, SP...>::rank) != 0))>::type* = nullptr) {
2596  using dst_type = View<DT, DP...>;
2597  using src_type = View<ST, SP...>;
2598 
2599  static_assert(std::is_same<typename dst_type::value_type,
2600  typename dst_type::non_const_value_type>::value,
2601  "deep_copy requires non-const destination type");
2602 
2603  static_assert((unsigned(dst_type::rank) == unsigned(src_type::rank)),
2604  "deep_copy requires Views of equal rank");
2605 
2606  using dst_execution_space = typename dst_type::execution_space;
2607  using src_execution_space = typename src_type::execution_space;
2608  using dst_memory_space = typename dst_type::memory_space;
2609  using src_memory_space = typename src_type::memory_space;
2610  using dst_value_type = typename dst_type::value_type;
2611  using src_value_type = typename src_type::value_type;
2612 
2613  if (Kokkos::Tools::Experimental::get_callbacks().begin_deep_copy != nullptr) {
2614  Kokkos::Profiling::beginDeepCopy(
2615  Kokkos::Profiling::make_space_handle(dst_memory_space::name()),
2616  dst.label(), dst.data(),
2617  Kokkos::Profiling::make_space_handle(src_memory_space::name()),
2618  src.label(), src.data(), dst.span() * sizeof(dst_value_type));
2619  }
2620 
2621  dst_value_type* dst_start = dst.data();
2622  dst_value_type* dst_end = dst.data() + dst.span();
2623  src_value_type* src_start = src.data();
2624  src_value_type* src_end = src.data() + src.span();
2625 
2626  // Early dropout if identical range
2627  if ((dst_start == nullptr || src_start == nullptr) ||
2628  ((std::ptrdiff_t(dst_start) == std::ptrdiff_t(src_start)) &&
2629  (std::ptrdiff_t(dst_end) == std::ptrdiff_t(src_end)))) {
2630  // throw if dimension mismatch
2631  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
2632  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
2633  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
2634  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
2635  std::string message(
2636  "Deprecation Error: Kokkos::deep_copy extents of views don't "
2637  "match: ");
2638  message += dst.label();
2639  message += "(";
2640  for (int r = 0; r < dst_type::Rank - 1; r++) {
2641  message += std::to_string(dst.extent(r));
2642  message += ",";
2643  }
2644  message += std::to_string(dst.extent(dst_type::Rank - 1));
2645  message += ") ";
2646  message += src.label();
2647  message += "(";
2648  for (int r = 0; r < src_type::Rank - 1; r++) {
2649  message += std::to_string(src.extent(r));
2650  message += ",";
2651  }
2652  message += std::to_string(src.extent(src_type::Rank - 1));
2653  message += ") ";
2654 
2655  Kokkos::Impl::throw_runtime_exception(message);
2656  }
2657  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2658  Kokkos::Profiling::endDeepCopy();
2659  }
2660  return;
2661  }
2662 
2663  enum {
2664  ExecCanAccessSrcDst =
2666  dst_memory_space>::accessible &&
2668  src_memory_space>::accessible
2669  };
2670  enum {
2671  DstExecCanAccessSrc =
2672  Kokkos::Impl::SpaceAccessibility<dst_execution_space,
2673  src_memory_space>::accessible
2674  };
2675 
2676  enum {
2677  SrcExecCanAccessDst =
2678  Kokkos::Impl::SpaceAccessibility<src_execution_space,
2679  dst_memory_space>::accessible
2680  };
2681 
2682  // Error out for non-identical overlapping views.
2683  if ((((std::ptrdiff_t)dst_start < (std::ptrdiff_t)src_end) &&
2684  ((std::ptrdiff_t)dst_end > (std::ptrdiff_t)src_start)) &&
2685  ((dst.span_is_contiguous() && src.span_is_contiguous()))) {
2686  std::string message("Error: Kokkos::deep_copy of overlapping views: ");
2687  message += dst.label();
2688  message += "(";
2689  message += std::to_string((std::ptrdiff_t)dst_start);
2690  message += ",";
2691  message += std::to_string((std::ptrdiff_t)dst_end);
2692  message += ") ";
2693  message += src.label();
2694  message += "(";
2695  message += std::to_string((std::ptrdiff_t)src_start);
2696  message += ",";
2697  message += std::to_string((std::ptrdiff_t)src_end);
2698  message += ") ";
2699  Kokkos::Impl::throw_runtime_exception(message);
2700  }
2701 
2702  // Check for same extents
2703  if ((src.extent(0) != dst.extent(0)) || (src.extent(1) != dst.extent(1)) ||
2704  (src.extent(2) != dst.extent(2)) || (src.extent(3) != dst.extent(3)) ||
2705  (src.extent(4) != dst.extent(4)) || (src.extent(5) != dst.extent(5)) ||
2706  (src.extent(6) != dst.extent(6)) || (src.extent(7) != dst.extent(7))) {
2707  std::string message(
2708  "Deprecation Error: Kokkos::deep_copy extents of views don't match: ");
2709  message += dst.label();
2710  message += "(";
2711  for (int r = 0; r < dst_type::Rank - 1; r++) {
2712  message += std::to_string(dst.extent(r));
2713  message += ",";
2714  }
2715  message += std::to_string(dst.extent(dst_type::Rank - 1));
2716  message += ") ";
2717  message += src.label();
2718  message += "(";
2719  for (int r = 0; r < src_type::Rank - 1; r++) {
2720  message += std::to_string(src.extent(r));
2721  message += ",";
2722  }
2723  message += std::to_string(src.extent(src_type::Rank - 1));
2724  message += ") ";
2725 
2726  Kokkos::Impl::throw_runtime_exception(message);
2727  }
2728 
2729  // If same type, equal layout, equal dimensions, equal span, and contiguous
2730  // memory then can byte-wise copy
2731 
2732  if (std::is_same<typename dst_type::value_type,
2733  typename src_type::non_const_value_type>::value &&
2734  (std::is_same<typename dst_type::array_layout,
2735  typename src_type::array_layout>::value ||
2736  (dst_type::rank == 1 && src_type::rank == 1)) &&
2737  dst.span_is_contiguous() && src.span_is_contiguous() &&
2738  ((dst_type::rank < 1) || (dst.stride_0() == src.stride_0())) &&
2739  ((dst_type::rank < 2) || (dst.stride_1() == src.stride_1())) &&
2740  ((dst_type::rank < 3) || (dst.stride_2() == src.stride_2())) &&
2741  ((dst_type::rank < 4) || (dst.stride_3() == src.stride_3())) &&
2742  ((dst_type::rank < 5) || (dst.stride_4() == src.stride_4())) &&
2743  ((dst_type::rank < 6) || (dst.stride_5() == src.stride_5())) &&
2744  ((dst_type::rank < 7) || (dst.stride_6() == src.stride_6())) &&
2745  ((dst_type::rank < 8) || (dst.stride_7() == src.stride_7()))) {
2746  const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
2747  if ((void*)dst.data() != (void*)src.data()) {
2748  Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space, ExecSpace>(
2749  exec_space, dst.data(), src.data(), nbytes);
2750  }
2751  } else {
2752  // Copying data between views in accessible memory spaces and either
2753  // non-contiguous or incompatible shape.
2754  if (ExecCanAccessSrcDst) {
2755  Impl::view_copy(exec_space, dst, src);
2756  } else if (DstExecCanAccessSrc || SrcExecCanAccessDst) {
2757  using cpy_exec_space =
2758  typename std::conditional<DstExecCanAccessSrc, dst_execution_space,
2759  src_execution_space>::type;
2760  exec_space.fence();
2761  Impl::view_copy(cpy_exec_space(), dst, src);
2762  cpy_exec_space().fence();
2763  } else {
2764  Kokkos::Impl::throw_runtime_exception(
2765  "deep_copy given views that would require a temporary allocation");
2766  }
2767  }
2768  if (Kokkos::Tools::Experimental::get_callbacks().end_deep_copy != nullptr) {
2769  Kokkos::Profiling::endDeepCopy();
2770  }
2771 }
2772 
2773 } /* namespace Kokkos */
2774 
2775 //----------------------------------------------------------------------------
2776 //----------------------------------------------------------------------------
2777 
2778 namespace Kokkos {
2779 
2782 template <class T, class... P>
2783 inline typename std::enable_if<
2784  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2785  Kokkos::LayoutLeft>::value ||
2786  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2787  Kokkos::LayoutRight>::value>::type
2788 resize(Kokkos::View<T, P...>& v, const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2789  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2790  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2791  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2792  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2793  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2794  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2795  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
2796  using view_type = Kokkos::View<T, P...>;
2797 
2799  "Can only resize managed views");
2800 
2801  // Fix #904 by checking dimensions before actually resizing.
2802  //
2803  // Rank is known at compile time, so hopefully the compiler will
2804  // remove branches that are compile-time false. The upcoming "if
2805  // constexpr" language feature would make this certain.
2806  if (view_type::Rank == 1 && n0 == static_cast<size_t>(v.extent(0))) {
2807  return;
2808  }
2809  if (view_type::Rank == 2 && n0 == static_cast<size_t>(v.extent(0)) &&
2810  n1 == static_cast<size_t>(v.extent(1))) {
2811  return;
2812  }
2813  if (view_type::Rank == 3 && n0 == static_cast<size_t>(v.extent(0)) &&
2814  n1 == static_cast<size_t>(v.extent(1)) &&
2815  n2 == static_cast<size_t>(v.extent(2))) {
2816  return;
2817  }
2818  if (view_type::Rank == 4 && n0 == static_cast<size_t>(v.extent(0)) &&
2819  n1 == static_cast<size_t>(v.extent(1)) &&
2820  n2 == static_cast<size_t>(v.extent(2)) &&
2821  n3 == static_cast<size_t>(v.extent(3))) {
2822  return;
2823  }
2824  if (view_type::Rank == 5 && n0 == static_cast<size_t>(v.extent(0)) &&
2825  n1 == static_cast<size_t>(v.extent(1)) &&
2826  n2 == static_cast<size_t>(v.extent(2)) &&
2827  n3 == static_cast<size_t>(v.extent(3)) &&
2828  n4 == static_cast<size_t>(v.extent(4))) {
2829  return;
2830  }
2831  if (view_type::Rank == 6 && n0 == static_cast<size_t>(v.extent(0)) &&
2832  n1 == static_cast<size_t>(v.extent(1)) &&
2833  n2 == static_cast<size_t>(v.extent(2)) &&
2834  n3 == static_cast<size_t>(v.extent(3)) &&
2835  n4 == static_cast<size_t>(v.extent(4)) &&
2836  n5 == static_cast<size_t>(v.extent(5))) {
2837  return;
2838  }
2839  if (view_type::Rank == 7 && n0 == static_cast<size_t>(v.extent(0)) &&
2840  n1 == static_cast<size_t>(v.extent(1)) &&
2841  n2 == static_cast<size_t>(v.extent(2)) &&
2842  n3 == static_cast<size_t>(v.extent(3)) &&
2843  n4 == static_cast<size_t>(v.extent(4)) &&
2844  n5 == static_cast<size_t>(v.extent(5)) &&
2845  n6 == static_cast<size_t>(v.extent(6))) {
2846  return;
2847  }
2848  if (view_type::Rank == 8 && n0 == static_cast<size_t>(v.extent(0)) &&
2849  n1 == static_cast<size_t>(v.extent(1)) &&
2850  n2 == static_cast<size_t>(v.extent(2)) &&
2851  n3 == static_cast<size_t>(v.extent(3)) &&
2852  n4 == static_cast<size_t>(v.extent(4)) &&
2853  n5 == static_cast<size_t>(v.extent(5)) &&
2854  n6 == static_cast<size_t>(v.extent(6)) &&
2855  n7 == static_cast<size_t>(v.extent(7))) {
2856  return;
2857  }
2858  // If Kokkos ever supports Views of rank > 8, the above code won't
2859  // be incorrect, because avoiding reallocation in resize() is just
2860  // an optimization.
2861 
2862  // TODO (mfh 27 Jun 2017) If the old View has enough space but just
2863  // different dimensions (e.g., if the product of the dimensions,
2864  // including extra space for alignment, will not change), then
2865  // consider just reusing storage. For now, Kokkos always
2866  // reallocates if any of the dimensions change, even if the old View
2867  // has enough space.
2868 
2869  view_type v_resized(v.label(), n0, n1, n2, n3, n4, n5, n6, n7);
2870 
2871  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
2872 
2873  v = v_resized;
2874 }
2875 
2878 template <class I, class T, class... P>
2879 inline typename std::enable_if<
2880  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2881  Kokkos::LayoutLeft>::value ||
2882  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2883  Kokkos::LayoutRight>::value>::type
2884 resize(const I& arg_prop, Kokkos::View<T, P...>& v,
2885  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2886  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2887  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2888  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2889  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2890  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2891  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
2892  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
2893  using view_type = Kokkos::View<T, P...>;
2894 
2896  "Can only resize managed views");
2897 
2898  // Fix #904 by checking dimensions before actually resizing.
2899  //
2900  // Rank is known at compile time, so hopefully the compiler will
2901  // remove branches that are compile-time false. The upcoming "if
2902  // constexpr" language feature would make this certain.
2903  if (view_type::Rank == 1 && n0 == static_cast<size_t>(v.extent(0))) {
2904  return;
2905  }
2906  if (view_type::Rank == 2 && n0 == static_cast<size_t>(v.extent(0)) &&
2907  n1 == static_cast<size_t>(v.extent(1))) {
2908  return;
2909  }
2910  if (view_type::Rank == 3 && n0 == static_cast<size_t>(v.extent(0)) &&
2911  n1 == static_cast<size_t>(v.extent(1)) &&
2912  n2 == static_cast<size_t>(v.extent(2))) {
2913  return;
2914  }
2915  if (view_type::Rank == 4 && n0 == static_cast<size_t>(v.extent(0)) &&
2916  n1 == static_cast<size_t>(v.extent(1)) &&
2917  n2 == static_cast<size_t>(v.extent(2)) &&
2918  n3 == static_cast<size_t>(v.extent(3))) {
2919  return;
2920  }
2921  if (view_type::Rank == 5 && n0 == static_cast<size_t>(v.extent(0)) &&
2922  n1 == static_cast<size_t>(v.extent(1)) &&
2923  n2 == static_cast<size_t>(v.extent(2)) &&
2924  n3 == static_cast<size_t>(v.extent(3)) &&
2925  n4 == static_cast<size_t>(v.extent(4))) {
2926  return;
2927  }
2928  if (view_type::Rank == 6 && n0 == static_cast<size_t>(v.extent(0)) &&
2929  n1 == static_cast<size_t>(v.extent(1)) &&
2930  n2 == static_cast<size_t>(v.extent(2)) &&
2931  n3 == static_cast<size_t>(v.extent(3)) &&
2932  n4 == static_cast<size_t>(v.extent(4)) &&
2933  n5 == static_cast<size_t>(v.extent(5))) {
2934  return;
2935  }
2936  if (view_type::Rank == 7 && n0 == static_cast<size_t>(v.extent(0)) &&
2937  n1 == static_cast<size_t>(v.extent(1)) &&
2938  n2 == static_cast<size_t>(v.extent(2)) &&
2939  n3 == static_cast<size_t>(v.extent(3)) &&
2940  n4 == static_cast<size_t>(v.extent(4)) &&
2941  n5 == static_cast<size_t>(v.extent(5)) &&
2942  n6 == static_cast<size_t>(v.extent(6))) {
2943  return;
2944  }
2945  if (view_type::Rank == 8 && n0 == static_cast<size_t>(v.extent(0)) &&
2946  n1 == static_cast<size_t>(v.extent(1)) &&
2947  n2 == static_cast<size_t>(v.extent(2)) &&
2948  n3 == static_cast<size_t>(v.extent(3)) &&
2949  n4 == static_cast<size_t>(v.extent(4)) &&
2950  n5 == static_cast<size_t>(v.extent(5)) &&
2951  n6 == static_cast<size_t>(v.extent(6)) &&
2952  n7 == static_cast<size_t>(v.extent(7))) {
2953  return;
2954  }
2955  // If Kokkos ever supports Views of rank > 8, the above code won't
2956  // be incorrect, because avoiding reallocation in resize() is just
2957  // an optimization.
2958 
2959  // TODO (mfh 27 Jun 2017) If the old View has enough space but just
2960  // different dimensions (e.g., if the product of the dimensions,
2961  // including extra space for alignment, will not change), then
2962  // consider just reusing storage. For now, Kokkos always
2963  // reallocates if any of the dimensions change, even if the old View
2964  // has enough space.
2965 
2966  view_type v_resized(view_alloc(v.label(), std::forward<const I>(arg_prop)),
2967  n0, n1, n2, n3, n4, n5, n6, n7);
2968 
2969  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
2970 
2971  v = v_resized;
2972 }
2973 
2976 template <class T, class... P>
2977 inline void resize(Kokkos::View<T, P...>& v,
2978  const typename Kokkos::View<T, P...>::array_layout& layout) {
2979  using view_type = Kokkos::View<T, P...>;
2980 
2982  "Can only resize managed views");
2983 
2984  view_type v_resized(v.label(), layout);
2985 
2986  Kokkos::Impl::ViewRemap<view_type, view_type>(v_resized, v);
2987 
2988  v = v_resized;
2989 }
2990 
2992 template <class T, class... P>
2993 inline typename std::enable_if<
2994  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2995  Kokkos::LayoutLeft>::value ||
2996  std::is_same<typename Kokkos::View<T, P...>::array_layout,
2997  Kokkos::LayoutRight>::value>::type
2998 realloc(Kokkos::View<T, P...>& v,
2999  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3000  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3001  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3002  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3003  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3004  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3005  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3006  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
3007  using view_type = Kokkos::View<T, P...>;
3008 
3010  "Can only realloc managed views");
3011 
3012  const std::string label = v.label();
3013 
3014  v = view_type(); // Deallocate first, if the only view to allocation
3015  v = view_type(label, n0, n1, n2, n3, n4, n5, n6, n7);
3016 }
3017 
3019 template <class T, class... P>
3020 inline void realloc(
3022  const typename Kokkos::View<T, P...>::array_layout& layout) {
3023  using view_type = Kokkos::View<T, P...>;
3024 
3026  "Can only realloc managed views");
3027 
3028  const std::string label = v.label();
3029 
3030  v = view_type(); // Deallocate first, if the only view to allocation
3031  v = view_type(label, layout);
3032 }
3033 } /* namespace Kokkos */
3034 
3035 //----------------------------------------------------------------------------
3036 //----------------------------------------------------------------------------
3037 
3038 namespace Kokkos {
3039 namespace Impl {
3040 
3041 // Deduce Mirror Types
3042 template <class Space, class T, class... P>
3043 struct MirrorViewType {
3044  // The incoming view_type
3045  using src_view_type = typename Kokkos::View<T, P...>;
3046  // The memory space for the mirror view
3047  using memory_space = typename Space::memory_space;
3048  // Check whether it is the same memory space
3049  enum {
3050  is_same_memspace =
3051  std::is_same<memory_space, typename src_view_type::memory_space>::value
3052  };
3053  // The array_layout
3054  using array_layout = typename src_view_type::array_layout;
3055  // The data type (we probably want it non-const since otherwise we can't even
3056  // deep_copy to it.
3057  using data_type = typename src_view_type::non_const_data_type;
3058  // The destination view type if it is not the same memory space
3059  using dest_view_type = Kokkos::View<data_type, array_layout, Space>;
3060  // If it is the same memory_space return the existsing view_type
3061  // This will also keep the unmanaged trait if necessary
3062  using view_type = typename std::conditional<is_same_memspace, src_view_type,
3063  dest_view_type>::type;
3064 };
3065 
3066 template <class Space, class T, class... P>
3067 struct MirrorType {
3068  // The incoming view_type
3069  using src_view_type = typename Kokkos::View<T, P...>;
3070  // The memory space for the mirror view
3071  using memory_space = typename Space::memory_space;
3072  // Check whether it is the same memory space
3073  enum {
3074  is_same_memspace =
3075  std::is_same<memory_space, typename src_view_type::memory_space>::value
3076  };
3077  // The array_layout
3078  using array_layout = typename src_view_type::array_layout;
3079  // The data type (we probably want it non-const since otherwise we can't even
3080  // deep_copy to it.
3081  using data_type = typename src_view_type::non_const_data_type;
3082  // The destination view type if it is not the same memory space
3084 };
3085 
3086 } // namespace Impl
3087 
3088 template <class T, class... P>
3089 inline typename Kokkos::View<T, P...>::HostMirror create_mirror(
3090  const Kokkos::View<T, P...>& src,
3091  typename std::enable_if<
3092  std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
3093  !std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
3094  Kokkos::LayoutStride>::value>::type* = nullptr) {
3095  using src_type = View<T, P...>;
3096  using dst_type = typename src_type::HostMirror;
3097 
3098  return dst_type(
3099  std::string(src.label()).append("_mirror"),
3100  src.rank_dynamic > 0 ? src.extent(0) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3101  src.rank_dynamic > 1 ? src.extent(1) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3102  src.rank_dynamic > 2 ? src.extent(2) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3103  src.rank_dynamic > 3 ? src.extent(3) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3104  src.rank_dynamic > 4 ? src.extent(4) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3105  src.rank_dynamic > 5 ? src.extent(5) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3106  src.rank_dynamic > 6 ? src.extent(6) : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
3107  src.rank_dynamic > 7 ? src.extent(7) : KOKKOS_IMPL_CTOR_DEFAULT_ARG);
3108 }
3109 
3110 template <class T, class... P>
3111 inline typename Kokkos::View<T, P...>::HostMirror create_mirror(
3112  const Kokkos::View<T, P...>& src,
3113  typename std::enable_if<
3114  std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
3115  std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
3116  Kokkos::LayoutStride>::value>::type* = nullptr) {
3117  using src_type = View<T, P...>;
3118  using dst_type = typename src_type::HostMirror;
3119 
3120  Kokkos::LayoutStride layout;
3121 
3122  layout.dimension[0] = src.extent(0);
3123  layout.dimension[1] = src.extent(1);
3124  layout.dimension[2] = src.extent(2);
3125  layout.dimension[3] = src.extent(3);
3126  layout.dimension[4] = src.extent(4);
3127  layout.dimension[5] = src.extent(5);
3128  layout.dimension[6] = src.extent(6);
3129  layout.dimension[7] = src.extent(7);
3130 
3131  layout.stride[0] = src.stride_0();
3132  layout.stride[1] = src.stride_1();
3133  layout.stride[2] = src.stride_2();
3134  layout.stride[3] = src.stride_3();
3135  layout.stride[4] = src.stride_4();
3136  layout.stride[5] = src.stride_5();
3137  layout.stride[6] = src.stride_6();
3138  layout.stride[7] = src.stride_7();
3139 
3140  return dst_type(std::string(src.label()).append("_mirror"), layout);
3141 }
3142 
3143 // Create a mirror in a new space (specialization for different space)
3144 template <class Space, class T, class... P>
3145 typename Impl::MirrorType<Space, T, P...>::view_type create_mirror(
3146  const Space&, const Kokkos::View<T, P...>& src,
3147  typename std::enable_if<std::is_same<
3148  typename ViewTraits<T, P...>::specialize, void>::value>::type* =
3149  nullptr) {
3150  return typename Impl::MirrorType<Space, T, P...>::view_type(src.label(),
3151  src.layout());
3152 }
3153 
3154 template <class T, class... P>
3155 inline typename Kokkos::View<T, P...>::HostMirror create_mirror_view(
3156  const Kokkos::View<T, P...>& src,
3157  typename std::enable_if<
3158  (std::is_same<
3159  typename Kokkos::View<T, P...>::memory_space,
3160  typename Kokkos::View<T, P...>::HostMirror::memory_space>::value &&
3161  std::is_same<typename Kokkos::View<T, P...>::data_type,
3162  typename Kokkos::View<T, P...>::HostMirror::data_type>::
3163  value)>::type* = nullptr) {
3164  return src;
3165 }
3166 
3167 template <class T, class... P>
3168 inline typename Kokkos::View<T, P...>::HostMirror create_mirror_view(
3169  const Kokkos::View<T, P...>& src,
3170  typename std::enable_if<!(
3171  std::is_same<
3172  typename Kokkos::View<T, P...>::memory_space,
3173  typename Kokkos::View<T, P...>::HostMirror::memory_space>::value &&
3174  std::is_same<typename Kokkos::View<T, P...>::data_type,
3175  typename Kokkos::View<T, P...>::HostMirror::data_type>::
3176  value)>::type* = nullptr) {
3177  return Kokkos::create_mirror(src);
3178 }
3179 
3180 // Create a mirror view in a new space (specialization for same space)
3181 template <class Space, class T, class... P>
3182 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3183  const Space&, const Kokkos::View<T, P...>& src,
3184  typename std::enable_if<
3185  Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3186  nullptr) {
3187  return src;
3188 }
3189 
3190 // Create a mirror view in a new space (specialization for different space)
3191 template <class Space, class T, class... P>
3192 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3193  const Space&, const Kokkos::View<T, P...>& src,
3194  typename std::enable_if<
3195  !Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3196  nullptr) {
3197  return typename Impl::MirrorViewType<Space, T, P...>::view_type(src.label(),
3198  src.layout());
3199 }
3200 
3201 // Create a mirror view and deep_copy in a new space (specialization for same
3202 // space)
3203 template <class Space, class T, class... P>
3204 typename Impl::MirrorViewType<Space, T, P...>::view_type
3205 create_mirror_view_and_copy(
3206  const Space&, const Kokkos::View<T, P...>& src,
3207  std::string const& name = "",
3208  typename std::enable_if<
3209  Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3210  nullptr) {
3211  (void)name;
3212  fence(); // same behavior as deep_copy(src, src)
3213  return src;
3214 }
3215 
3216 // Create a mirror view and deep_copy in a new space (specialization for
3217 // different space)
3218 template <class Space, class T, class... P>
3219 typename Impl::MirrorViewType<Space, T, P...>::view_type
3220 create_mirror_view_and_copy(
3221  const Space&, const Kokkos::View<T, P...>& src,
3222  std::string const& name = "",
3223  typename std::enable_if<
3224  !Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3225  nullptr) {
3226  using Mirror = typename Impl::MirrorViewType<Space, T, P...>::view_type;
3227  std::string label = name.empty() ? src.label() : name;
3228  auto mirror = typename Mirror::non_const_type{
3229  view_alloc(WithoutInitializing, label), src.layout()};
3230  deep_copy(mirror, src);
3231  return mirror;
3232 }
3233 
3234 // Create a mirror view in a new space without initializing (specialization for
3235 // same space)
3236 template <class Space, class T, class... P>
3237 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3238  const Space&, const Kokkos::View<T, P...>& src,
3239  Kokkos::Impl::WithoutInitializing_t,
3240  typename std::enable_if<
3241  Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3242  nullptr) {
3243  return src;
3244 }
3245 
3246 // Create a mirror view in a new space without initializing (specialization for
3247 // different space)
3248 template <class Space, class T, class... P>
3249 typename Impl::MirrorViewType<Space, T, P...>::view_type create_mirror_view(
3250  const Space&, const Kokkos::View<T, P...>& src,
3251  Kokkos::Impl::WithoutInitializing_t,
3252  typename std::enable_if<
3253  !Impl::MirrorViewType<Space, T, P...>::is_same_memspace>::type* =
3254  nullptr) {
3255  using Mirror = typename Impl::MirrorViewType<Space, T, P...>::view_type;
3256  return Mirror(view_alloc(WithoutInitializing, src.label()), src.layout());
3257 }
3258 
3259 } /* namespace Kokkos */
3260 
3261 //----------------------------------------------------------------------------
3262 //----------------------------------------------------------------------------
3263 
3264 #endif
View
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< std::is_integral< iType >::value, size_t >::type extent(const iType &r) const noexcept
rank() to be implemented
Can AccessSpace access MemorySpace ?
Replacement for std::pair that works on CUDA devices.
Definition: Kokkos_Pair.hpp:65
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 parallel operators.
Execution policy for work over a range of an integral type.
Traits class for accessing attributes of a View.
Definition: dummy.cpp:3