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