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
54namespace Kokkos {
55
56namespace Impl {
57
58template <class Layout>
59struct ViewFillLayoutSelector {};
60
61template <>
62struct ViewFillLayoutSelector<Kokkos::LayoutLeft> {
63 static const Kokkos::Iterate iterate = Kokkos::Iterate::Left;
64};
65
66template <>
67struct ViewFillLayoutSelector<Kokkos::LayoutRight> {
68 static const Kokkos::Iterate iterate = Kokkos::Iterate::Right;
69};
70
71} // namespace Impl
72} // namespace Kokkos
73
74namespace Kokkos {
75namespace Impl {
76
77template <class ViewType, class Layout, class ExecSpace, typename iType>
78struct 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
86template <class ViewType, class Layout, class ExecSpace, typename iType>
87struct 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
103template <class ViewType, class Layout, class ExecSpace, typename iType>
104struct 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
125template <class ViewType, class Layout, class ExecSpace, typename iType>
126struct 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_) {
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
150template <class ViewType, class Layout, class ExecSpace, typename iType>
151struct 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_) {
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
177template <class ViewType, class Layout, class ExecSpace, typename iType>
178struct 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
204template <class ViewType, class Layout, class ExecSpace, typename iType>
205struct 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
231template <class ViewType, class Layout, class ExecSpace, typename iType>
232struct 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
259template <class ViewType, class Layout, class ExecSpace, typename iType>
260struct 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
288template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
289 typename iType>
290struct 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
310template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
311 typename iType>
312struct 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
339template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
340 typename iType>
341struct 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_) {
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
370template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
371 typename iType>
372struct 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_) {
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
402template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
403 typename iType>
404struct 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
434template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
435 typename iType>
436struct 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
466template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
467 typename iType>
468struct 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
499template <class ViewTypeA, class ViewTypeB, class Layout, class ExecSpace,
500 typename iType>
501struct 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
536namespace Kokkos {
537namespace Impl {
538
539template <class ExecutionSpace, class DstType, class SrcType>
540void 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 =
548 src_memory_space>::accessible
549 };
550 enum {
551 ExecCanAccessDst =
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
618template <class DstType, class SrcType>
619void 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
733template <class DstType, class SrcType, int Rank, class... Args>
734struct CommonSubview;
735
736template <class DstType, class SrcType, class Arg0, class... Args>
737struct 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
747template <class DstType, class SrcType, class Arg0, class Arg1, class... Args>
748struct 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
758template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
759 class... Args>
760struct 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
770template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
771 class Arg3, class... Args>
772struct 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
786template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
787 class Arg3, class Arg4, class... Args>
788struct 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
803template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
804 class Arg3, class Arg4, class Arg5, class... Args>
805struct 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
820template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
821 class Arg3, class Arg4, class Arg5, class Arg6, class... Args>
822struct 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
837template <class DstType, class SrcType, class Arg0, class Arg1, class Arg2,
838 class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
839struct 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
857template <class DstType, class SrcType,
858 class ExecSpace = typename DstType::execution_space,
859 int Rank = DstType::Rank>
860struct ViewRemap;
861
862template <class DstType, class SrcType, class ExecSpace>
863struct 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
878template <class DstType, class SrcType, class ExecSpace>
879struct 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
912template <class DstType, class SrcType, class ExecSpace>
913struct 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
956template <class DstType, class SrcType, class ExecSpace>
957struct 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
1005template <class DstType, class SrcType, class ExecSpace>
1006struct 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};
1059template <class DstType, class SrcType, class ExecSpace>
1060struct 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
1122template <class DstType, class SrcType, class ExecSpace>
1123struct 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
1187template <class DstType, class SrcType, class ExecSpace>
1188struct 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
1260template <class DT, class... DP>
1261inline 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
1373template <class ST, class... SP>
1374inline 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//----------------------------------------------------------------------------
1412template <class DT, class... DP, class ST, class... SP>
1413inline 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//----------------------------------------------------------------------------
1464template <class DT, class... DP, class ST, class... SP>
1465inline 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//----------------------------------------------------------------------------
1641namespace Experimental {
1645template <class TeamType, class DT, class... DP, class ST, class... SP>
1646void KOKKOS_INLINE_FUNCTION
1647local_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//----------------------------------------------------------------------------
1653template <class DT, class... DP, class ST, class... SP>
1654void 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//----------------------------------------------------------------------------
1661template <class TeamType, class DT, class... DP, class ST, class... SP>
1662void 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//----------------------------------------------------------------------------
1680template <class TeamType, class DT, class... DP, class ST, class... SP>
1681void 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//----------------------------------------------------------------------------
1708template <class TeamType, class DT, class... DP, class ST, class... SP>
1709void 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//----------------------------------------------------------------------------
1738template <class TeamType, class DT, class... DP, class ST, class... SP>
1739void 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//----------------------------------------------------------------------------
1771template <class TeamType, class DT, class... DP, class ST, class... SP>
1772void 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//----------------------------------------------------------------------------
1806template <class TeamType, class DT, class... DP, class ST, class... SP>
1807void 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//----------------------------------------------------------------------------
1843template <class TeamType, class DT, class... DP, class ST, class... SP>
1844void 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//----------------------------------------------------------------------------
1883template <class DT, class... DP, class ST, class... SP>
1884void 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//----------------------------------------------------------------------------
1900template <class DT, class... DP, class ST, class... SP>
1901void 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//----------------------------------------------------------------------------
1918template <class DT, class... DP, class ST, class... SP>
1919void 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//----------------------------------------------------------------------------
1938template <class DT, class... DP, class ST, class... SP>
1939void 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//----------------------------------------------------------------------------
1959template <class DT, class... DP, class ST, class... SP>
1960void 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//----------------------------------------------------------------------------
1981template <class DT, class... DP, class ST, class... SP>
1982void 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//----------------------------------------------------------------------------
2004template <class DT, class... DP, class ST, class... SP>
2005void 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//----------------------------------------------------------------------------
2031template <class TeamType, class DT, class... DP>
2032void 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//----------------------------------------------------------------------------
2039template <class DT, class... DP>
2040void 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//----------------------------------------------------------------------------
2048template <class TeamType, class DT, class... DP>
2049void 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//----------------------------------------------------------------------------
2066template <class TeamType, class DT, class... DP>
2067void 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//----------------------------------------------------------------------------
2093template <class TeamType, class DT, class... DP>
2094void 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//----------------------------------------------------------------------------
2122template <class TeamType, class DT, class... DP>
2123void 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//----------------------------------------------------------------------------
2154template <class TeamType, class DT, class... DP>
2155void 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//----------------------------------------------------------------------------
2188template <class TeamType, class DT, class... DP>
2189void 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//----------------------------------------------------------------------------
2224template <class TeamType, class DT, class... DP>
2225void 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//----------------------------------------------------------------------------
2263template <class DT, class... DP>
2264void 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//----------------------------------------------------------------------------
2280template <class DT, class... DP>
2281void 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//----------------------------------------------------------------------------
2298template <class DT, class... DP>
2299void 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//----------------------------------------------------------------------------
2317template <class DT, class... DP>
2318void 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//----------------------------------------------------------------------------
2338template <class DT, class... DP>
2339void 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//----------------------------------------------------------------------------
2360template <class DT, class... DP>
2361void 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//----------------------------------------------------------------------------
2383template <class DT, class... DP>
2384void 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
2412namespace Kokkos {
2413
2416template <class ExecSpace, class DT, class... DP>
2417inline 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
2456template <class ExecSpace, class DT, class... DP>
2457inline 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
2498template <class ExecSpace, class ST, class... SP>
2499inline 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//----------------------------------------------------------------------------
2536template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2537inline 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//----------------------------------------------------------------------------
2586template <class ExecSpace, class DT, class... DP, class ST, class... SP>
2587inline 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
2778namespace Kokkos {
2779
2782template <class T, class... P>
2783inline 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
2788resize(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
2798 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
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
2878template <class I, class T, class... P>
2879inline 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
2884resize(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
2895 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
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
2976template <class T, class... P>
2977inline 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
2981 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
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
2992template <class T, class... P>
2993inline 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
2998realloc(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
3009 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
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
3019template <class T, class... P>
3020inline void realloc(
3022 const typename Kokkos::View<T, P...>::array_layout& layout) {
3023 using view_type = Kokkos::View<T, P...>;
3024
3025 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
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
3038namespace Kokkos {
3039namespace Impl {
3040
3041// Deduce Mirror Types
3042template <class Space, class T, class... P>
3043struct 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
3066template <class Space, class T, class... P>
3067struct 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
3088template <class T, class... P>
3089inline 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
3110template <class T, class... P>
3111inline 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)
3144template <class Space, class T, class... P>
3145typename 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
3154template <class T, class... P>
3155inline 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
3167template <class T, class... P>
3168inline 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)
3181template <class Space, class T, class... P>
3182typename 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)
3191template <class Space, class T, class... P>
3192typename 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)
3203template <class Space, class T, class... P>
3204typename Impl::MirrorViewType<Space, T, P...>::view_type
3205create_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)
3218template <class Space, class T, class... P>
3219typename Impl::MirrorViewType<Space, T, P...>::view_type
3220create_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)
3236template <class Space, class T, class... P>
3237typename 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)
3248template <class Space, class T, class... P>
3249typename 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
Declaration of parallel operators.
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename std::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=nullptr)
Execute functor in parallel according to the execution policy.
Memory management for host memory.
static constexpr const char * name()
Return Name of the MemorySpace.
Execution policy for work over a range of an integral type.
View to an array of data.
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
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory.
Can AccessSpace access MemorySpace ?
Traits class for accessing attributes of a View.
Replacement for std::pair that works on CUDA devices.
Definition: Kokkos_Pair.hpp:65