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