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