Kokkos Core Kernels Package Version of the Day
Kokkos_DynRankView.hpp
Go to the documentation of this file.
1/*
2//@HEADER
3// ************************************************************************
4//
5// Kokkos v. 3.0
6// Copyright (2020) National Technology & Engineering
7// Solutions of Sandia, LLC (NTESS).
8//
9// Under the terms of Contract DE-NA0003525 with NTESS,
10// the U.S. Government retains certain rights in this software.
11//
12// Redistribution and use in source and binary forms, with or without
13// modification, are permitted provided that the following conditions are
14// met:
15//
16// 1. Redistributions of source code must retain the above copyright
17// notice, this list of conditions and the following disclaimer.
18//
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22//
23// 3. Neither the name of the Corporation nor the names of the
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38//
39// Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40//
41// ************************************************************************
42//@HEADER
43*/
44
50
51#ifndef KOKKOS_DYNRANKVIEW_HPP
52#define KOKKOS_DYNRANKVIEW_HPP
53
54#include <Kokkos_Core.hpp>
55#include <impl/Kokkos_Error.hpp>
56#include <type_traits>
57
58namespace Kokkos {
59
60template <typename DataType, class... Properties>
61class DynRankView; // forward declare
62
63namespace Impl {
64
65template <typename Specialize>
66struct DynRankDimTraits {
67 enum : size_t { unspecified = KOKKOS_INVALID_INDEX };
68
69 // Compute the rank of the view from the nonzero dimension arguments.
70 KOKKOS_INLINE_FUNCTION
71 static size_t computeRank(const size_t N0, const size_t N1, const size_t N2,
72 const size_t N3, const size_t N4, const size_t N5,
73 const size_t N6, const size_t /* N7 */) {
74 return (
75 (N6 == unspecified && N5 == unspecified && N4 == unspecified &&
76 N3 == unspecified && N2 == unspecified && N1 == unspecified &&
77 N0 == unspecified)
78 ? 0
79 : ((N6 == unspecified && N5 == unspecified && N4 == unspecified &&
80 N3 == unspecified && N2 == unspecified && N1 == unspecified)
81 ? 1
82 : ((N6 == unspecified && N5 == unspecified &&
83 N4 == unspecified && N3 == unspecified &&
84 N2 == unspecified)
85 ? 2
86 : ((N6 == unspecified && N5 == unspecified &&
87 N4 == unspecified && N3 == unspecified)
88 ? 3
89 : ((N6 == unspecified && N5 == unspecified &&
90 N4 == unspecified)
91 ? 4
92 : ((N6 == unspecified &&
93 N5 == unspecified)
94 ? 5
95 : ((N6 == unspecified)
96 ? 6
97 : 7)))))));
98 }
99
100 // Compute the rank of the view from the nonzero layout arguments.
101 template <typename Layout>
102 KOKKOS_INLINE_FUNCTION static size_t computeRank(const Layout& layout) {
103 return computeRank(layout.dimension[0], layout.dimension[1],
104 layout.dimension[2], layout.dimension[3],
105 layout.dimension[4], layout.dimension[5],
106 layout.dimension[6], layout.dimension[7]);
107 }
108
109 // Extra overload to match that for specialize types v2
110 template <typename Layout, typename... P>
111 KOKKOS_INLINE_FUNCTION static size_t computeRank(
112 const Kokkos::Impl::ViewCtorProp<P...>& /* prop */,
113 const Layout& layout) {
114 return computeRank(layout);
115 }
116
117 // Create the layout for the rank-7 view.
118 // Non-strided Layout
119 template <typename Layout>
120 KOKKOS_INLINE_FUNCTION static typename std::enable_if<
121 (std::is_same<Layout, Kokkos::LayoutRight>::value ||
122 std::is_same<Layout, Kokkos::LayoutLeft>::value),
123 Layout>::type
124 createLayout(const Layout& layout) {
125 return Layout(layout.dimension[0] != unspecified ? layout.dimension[0] : 1,
126 layout.dimension[1] != unspecified ? layout.dimension[1] : 1,
127 layout.dimension[2] != unspecified ? layout.dimension[2] : 1,
128 layout.dimension[3] != unspecified ? layout.dimension[3] : 1,
129 layout.dimension[4] != unspecified ? layout.dimension[4] : 1,
130 layout.dimension[5] != unspecified ? layout.dimension[5] : 1,
131 layout.dimension[6] != unspecified ? layout.dimension[6] : 1,
132 layout.dimension[7] != unspecified ? layout.dimension[7] : 1);
133 }
134
135 // LayoutStride
136 template <typename Layout>
137 KOKKOS_INLINE_FUNCTION static typename std::enable_if<
138 (std::is_same<Layout, Kokkos::LayoutStride>::value), Layout>::type
139 createLayout(const Layout& layout) {
140 return Layout(layout.dimension[0] != unspecified ? layout.dimension[0] : 1,
141 layout.stride[0],
142 layout.dimension[1] != unspecified ? layout.dimension[1] : 1,
143 layout.stride[1],
144 layout.dimension[2] != unspecified ? layout.dimension[2] : 1,
145 layout.stride[2],
146 layout.dimension[3] != unspecified ? layout.dimension[3] : 1,
147 layout.stride[3],
148 layout.dimension[4] != unspecified ? layout.dimension[4] : 1,
149 layout.stride[4],
150 layout.dimension[5] != unspecified ? layout.dimension[5] : 1,
151 layout.stride[5],
152 layout.dimension[6] != unspecified ? layout.dimension[6] : 1,
153 layout.stride[6],
154 layout.dimension[7] != unspecified ? layout.dimension[7] : 1,
155 layout.stride[7]);
156 }
157
158 // Extra overload to match that for specialize types
159 template <typename Traits, typename... P>
160 KOKKOS_INLINE_FUNCTION static typename std::enable_if<
161 (std::is_same<typename Traits::array_layout,
162 Kokkos::LayoutRight>::value ||
163 std::is_same<typename Traits::array_layout, Kokkos::LayoutLeft>::value ||
164 std::is_same<typename Traits::array_layout,
165 Kokkos::LayoutStride>::value),
166 typename Traits::array_layout>::type
167 createLayout(const Kokkos::Impl::ViewCtorProp<P...>& /* prop */,
168 const typename Traits::array_layout& layout) {
169 return createLayout(layout);
170 }
171
172 // Create a view from the given dimension arguments.
173 // This is only necessary because the shmem constructor doesn't take a layout.
174 // NDE shmem View's are not compatible with the added view_alloc value_type
175 // / fad_dim deduction functionality
176 template <typename ViewType, typename ViewArg>
177 static ViewType createView(const ViewArg& arg, const size_t N0,
178 const size_t N1, const size_t N2, const size_t N3,
179 const size_t N4, const size_t N5, const size_t N6,
180 const size_t N7) {
181 return ViewType(arg, N0 != unspecified ? N0 : 1, N1 != unspecified ? N1 : 1,
182 N2 != unspecified ? N2 : 1, N3 != unspecified ? N3 : 1,
183 N4 != unspecified ? N4 : 1, N5 != unspecified ? N5 : 1,
184 N6 != unspecified ? N6 : 1, N7 != unspecified ? N7 : 1);
185 }
186};
187
188// Non-strided Layout
189template <typename Layout, typename iType>
190KOKKOS_INLINE_FUNCTION static
191 typename std::enable_if<(std::is_same<Layout, Kokkos::LayoutRight>::value ||
192 std::is_same<Layout, Kokkos::LayoutLeft>::value) &&
193 std::is_integral<iType>::value,
194 Layout>::type
195 reconstructLayout(const Layout& layout, iType dynrank) {
196 return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
197 dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
198 dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
199 dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
200 dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
201 dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
202 dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
203 dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX);
204}
205
206// LayoutStride
207template <typename Layout, typename iType>
208KOKKOS_INLINE_FUNCTION static typename std::enable_if<
209 (std::is_same<Layout, Kokkos::LayoutStride>::value) &&
210 std::is_integral<iType>::value,
211 Layout>::type
212reconstructLayout(const Layout& layout, iType dynrank) {
213 return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
214 dynrank > 0 ? layout.stride[0] : (0),
215 dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
216 dynrank > 1 ? layout.stride[1] : (0),
217 dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
218 dynrank > 2 ? layout.stride[2] : (0),
219 dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
220 dynrank > 3 ? layout.stride[3] : (0),
221 dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
222 dynrank > 4 ? layout.stride[4] : (0),
223 dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
224 dynrank > 5 ? layout.stride[5] : (0),
225 dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
226 dynrank > 6 ? layout.stride[6] : (0),
227 dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX,
228 dynrank > 7 ? layout.stride[7] : (0));
229}
230
232// Enhanced debug checking - most infrastructure matches that of functions in
233// Kokkos_ViewMapping; additional checks for extra arguments beyond rank are 0
234template <unsigned, typename iType0, class MapType>
235KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
236 const iType0&, const MapType&) {
237 return true;
238}
239
240template <unsigned R, typename iType0, class MapType, typename iType1,
241 class... Args>
242KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
243 const iType0& rank, const MapType& map, const iType1& i, Args... args) {
244 if (static_cast<iType0>(R) < rank) {
245 return (size_t(i) < map.extent(R)) &&
246 dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
247 } else if (i != 0) {
248 KOKKOS_IMPL_DO_NOT_USE_PRINTF(
249 "DynRankView Debug Bounds Checking Error: at rank %u\n Extra "
250 "arguments beyond the rank must be zero \n",
251 R);
252 return (false) &&
253 dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
254 } else {
255 return (true) &&
256 dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
257 }
258}
259
260template <unsigned, class MapType>
261inline void dyn_rank_view_error_operator_bounds(char*, int, const MapType&) {}
262
263template <unsigned R, class MapType, class iType, class... Args>
264inline void dyn_rank_view_error_operator_bounds(char* buf, int len,
265 const MapType& map,
266 const iType& i, Args... args) {
267 const int n = snprintf(
268 buf, len, " %ld < %ld %c", static_cast<unsigned long>(i),
269 static_cast<unsigned long>(map.extent(R)), (sizeof...(Args) ? ',' : ')'));
270 dyn_rank_view_error_operator_bounds<R + 1>(buf + n, len - n, map, args...);
271}
272
273// op_rank = rank of the operator version that was called
274template <typename MemorySpace, typename iType0, typename iType1, class MapType,
275 class... Args>
276KOKKOS_INLINE_FUNCTION void dyn_rank_view_verify_operator_bounds(
277 const iType0& op_rank, const iType1& rank,
278 const Kokkos::Impl::SharedAllocationTracker& tracker, const MapType& map,
279 Args... args) {
280 if (static_cast<iType0>(rank) > op_rank) {
281 Kokkos::abort(
282 "DynRankView Bounds Checking Error: Need at least rank arguments to "
283 "the operator()");
284 }
285
286 if (!dyn_rank_view_verify_operator_bounds<0>(rank, map, args...)) {
287#if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
288 enum { LEN = 1024 };
289 char buffer[LEN];
290 const std::string label = tracker.template get_label<MemorySpace>();
291 int n = snprintf(buffer, LEN, "DynRankView bounds error of view %s (",
292 label.c_str());
293 dyn_rank_view_error_operator_bounds<0>(buffer + n, LEN - n, map, args...);
294 Kokkos::Impl::throw_runtime_exception(std::string(buffer));
295#else
296 (void)tracker;
297 Kokkos::abort("DynRankView bounds error");
298#endif
299 }
300}
301
304
305} // namespace Impl
306
307namespace Impl {
308
309template <class DstTraits, class SrcTraits>
310class ViewMapping<
311 DstTraits, SrcTraits,
312 typename std::enable_if<
313 (std::is_same<typename DstTraits::memory_space,
314 typename SrcTraits::memory_space>::value &&
315 std::is_same<typename DstTraits::specialize, void>::value &&
316 std::is_same<typename SrcTraits::specialize, void>::value &&
317 (std::is_same<typename DstTraits::array_layout,
318 typename SrcTraits::array_layout>::value ||
319 ((std::is_same<typename DstTraits::array_layout,
320 Kokkos::LayoutLeft>::value ||
321 std::is_same<typename DstTraits::array_layout,
322 Kokkos::LayoutRight>::value ||
323 std::is_same<typename DstTraits::array_layout,
324 Kokkos::LayoutStride>::value) &&
325 (std::is_same<typename SrcTraits::array_layout,
326 Kokkos::LayoutLeft>::value ||
327 std::is_same<typename SrcTraits::array_layout,
328 Kokkos::LayoutRight>::value ||
329 std::is_same<typename SrcTraits::array_layout,
330 Kokkos::LayoutStride>::value)))),
331 Kokkos::Impl::ViewToDynRankViewTag>::type> {
332 private:
333 enum {
334 is_assignable_value_type =
335 std::is_same<typename DstTraits::value_type,
336 typename SrcTraits::value_type>::value ||
337 std::is_same<typename DstTraits::value_type,
338 typename SrcTraits::const_value_type>::value
339 };
340
341 enum {
342 is_assignable_layout =
343 std::is_same<typename DstTraits::array_layout,
344 typename SrcTraits::array_layout>::value ||
345 std::is_same<typename DstTraits::array_layout,
347 };
348
349 public:
350 enum { is_assignable = is_assignable_value_type && is_assignable_layout };
351
352 using DstType = ViewMapping<DstTraits, typename DstTraits::specialize>;
353 using SrcType = ViewMapping<SrcTraits, typename SrcTraits::specialize>;
354
355 template <typename DT, typename... DP, typename ST, typename... SP>
356 KOKKOS_INLINE_FUNCTION static void assign(
357 Kokkos::DynRankView<DT, DP...>& dst, const Kokkos::View<ST, SP...>& src) {
358 static_assert(
359 is_assignable_value_type,
360 "View assignment must have same value type or const = non-const");
361
362 static_assert(
363 is_assignable_layout,
364 "View assignment must have compatible layout or have rank <= 1");
365
366 // Removed dimension checks...
367
368 using dst_offset_type = typename DstType::offset_type;
369 dst.m_map.m_impl_offset = dst_offset_type(
370 std::integral_constant<unsigned, 0>(),
371 src.layout()); // Check this for integer input1 for padding, etc
372 dst.m_map.m_impl_handle = Kokkos::Impl::ViewDataHandle<DstTraits>::assign(
373 src.m_map.m_impl_handle, src.m_track.m_tracker);
374 dst.m_track.assign(src.m_track.m_tracker, DstTraits::is_managed);
375 dst.m_rank = src.Rank;
376 }
377};
378
379} // namespace Impl
380
381/* \class DynRankView
382 * \brief Container that creates a Kokkos view with rank determined at runtime.
383 * Essentially this is a rank 7 view
384 *
385 * Changes from View
386 * 1. The rank of the DynRankView is returned by the method rank()
387 * 2. Max rank of a DynRankView is 7
388 * 3. subview called with 'subview(...)' or 'subdynrankview(...)' (backward
389 * compatibility)
390 * 4. Every subview is returned with LayoutStride
391 * 5. Copy and Copy-Assign View to DynRankView
392 * 6. deep_copy between Views and DynRankViews
393 * 7. rank( view ); returns the rank of View or DynRankView
394 *
395 */
396
397template <class>
398struct is_dyn_rank_view : public std::false_type {};
399
400template <class D, class... P>
401struct is_dyn_rank_view<Kokkos::DynRankView<D, P...> > : public std::true_type {
402};
403
404template <typename DataType, class... Properties>
405class DynRankView : public ViewTraits<DataType, Properties...> {
406 static_assert(!std::is_array<DataType>::value &&
407 !std::is_pointer<DataType>::value,
408 "Cannot template DynRankView with array or pointer datatype - "
409 "must be pod");
410
411 private:
412 template <class, class...>
413 friend class DynRankView;
414 template <class, class...>
415 friend class Kokkos::Impl::ViewMapping;
416
417 public:
418 using drvtraits = ViewTraits<DataType, Properties...>;
419
420 using view_type = View<DataType*******, Properties...>;
421
422 using traits = ViewTraits<DataType*******, Properties...>;
423
424 private:
425 using map_type =
426 Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
427 using track_type = Kokkos::Impl::SharedAllocationTracker;
428
429 track_type m_track;
430 map_type m_map;
431 unsigned m_rank;
432
433 public:
434 KOKKOS_INLINE_FUNCTION
435 view_type& DownCast() const { return (view_type&)(*this); }
436 KOKKOS_INLINE_FUNCTION
437 const view_type& ConstDownCast() const { return (const view_type&)(*this); }
438
439 // Types below - at least the HostMirror requires the value_type, NOT the rank
440 // 7 data_type of the traits
441
443 using array_type = DynRankView<
444 typename drvtraits::scalar_array_type, typename drvtraits::array_layout,
445 typename drvtraits::device_type, typename drvtraits::memory_traits>;
446
448 using const_type = DynRankView<
449 typename drvtraits::const_data_type, typename drvtraits::array_layout,
450 typename drvtraits::device_type, typename drvtraits::memory_traits>;
451
453 using non_const_type = DynRankView<
454 typename drvtraits::non_const_data_type, typename drvtraits::array_layout,
455 typename drvtraits::device_type, typename drvtraits::memory_traits>;
456
458 using HostMirror = DynRankView<typename drvtraits::non_const_data_type,
459 typename drvtraits::array_layout,
460 typename drvtraits::host_mirror_space>;
461
462 //----------------------------------------
463 // Domain rank and extents
464
465 // enum { Rank = map_type::Rank }; //Will be dyn rank of 7 always, keep the
466 // enum?
467
468 template <typename iType>
469 KOKKOS_INLINE_FUNCTION constexpr
470 typename std::enable_if<std::is_integral<iType>::value, size_t>::type
471 extent(const iType& r) const {
472 return m_map.extent(r);
473 }
474
475 template <typename iType>
476 KOKKOS_INLINE_FUNCTION constexpr
477 typename std::enable_if<std::is_integral<iType>::value, int>::type
478 extent_int(const iType& r) const {
479 return static_cast<int>(m_map.extent(r));
480 }
481
482 KOKKOS_INLINE_FUNCTION constexpr typename traits::array_layout layout()
483 const {
484 return m_map.layout();
485 }
486
487 //----------------------------------------
488 /* Deprecate all 'dimension' functions in favor of
489 * ISO/C++ vocabulary 'extent'.
490 */
491
492 KOKKOS_INLINE_FUNCTION constexpr size_t size() const {
493 return m_map.extent(0) * m_map.extent(1) * m_map.extent(2) *
494 m_map.extent(3) * m_map.extent(4) * m_map.extent(5) *
495 m_map.extent(6) * m_map.extent(7);
496 }
497
498 KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const {
499 return m_map.stride_0();
500 }
501 KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const {
502 return m_map.stride_1();
503 }
504 KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const {
505 return m_map.stride_2();
506 }
507 KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const {
508 return m_map.stride_3();
509 }
510 KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const {
511 return m_map.stride_4();
512 }
513 KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const {
514 return m_map.stride_5();
515 }
516 KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const {
517 return m_map.stride_6();
518 }
519 KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const {
520 return m_map.stride_7();
521 }
522
523 template <typename iType>
524 KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
525 m_map.stride(s);
526 }
527
528 //----------------------------------------
529 // Range span is the span which contains all members.
530
531 using reference_type = typename map_type::reference_type;
532 using pointer_type = typename map_type::pointer_type;
533
534 enum {
535 reference_type_is_lvalue_reference =
536 std::is_lvalue_reference<reference_type>::value
537 };
538
539 KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
540 KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const {
541 return m_map.span_is_contiguous();
542 }
543 KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
544 return m_map.data();
545 }
546 KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
547 return (m_map.data() != nullptr);
548 }
549
550 //----------------------------------------
551 // Allow specializations to query their specialized map
552 KOKKOS_INLINE_FUNCTION
553 const Kokkos::Impl::ViewMapping<traits, typename traits::specialize>&
554 impl_map() const {
555 return m_map;
556 }
557
558 //----------------------------------------
559
560 private:
561 enum {
562 is_layout_left =
563 std::is_same<typename traits::array_layout, Kokkos::LayoutLeft>::value,
564
565 is_layout_right =
566 std::is_same<typename traits::array_layout, Kokkos::LayoutRight>::value,
567
568 is_layout_stride = std::is_same<typename traits::array_layout,
569 Kokkos::LayoutStride>::value,
570
571 is_default_map = std::is_same<typename traits::specialize, void>::value &&
572 (is_layout_left || is_layout_right || is_layout_stride)
573 };
574
575// Bounds checking macros
576#if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
577
578// rank of the calling operator - included as first argument in ARG
579#define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
580 Kokkos::Impl::verify_space<Kokkos::Impl::ActiveExecutionMemorySpace, \
581 typename traits::memory_space>::check(); \
582 Kokkos::Impl::dyn_rank_view_verify_operator_bounds< \
583 typename traits::memory_space> \
584 ARG;
585
586#else
587
588#define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
589 Kokkos::Impl::verify_space<Kokkos::Impl::ActiveExecutionMemorySpace, \
590 typename traits::memory_space>::check();
591
592#endif
593
594 public:
595 KOKKOS_INLINE_FUNCTION
596 constexpr unsigned rank() const { return m_rank; }
597
598 // operators ()
599 // Rank 0
600 KOKKOS_INLINE_FUNCTION
601 reference_type operator()() const {
602 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((0, this->rank(), m_track, m_map))
603 return impl_map().reference();
604 // return m_map.reference(0,0,0,0,0,0,0);
605 }
606
607 // Rank 1
608 // This assumes a contiguous underlying memory (i.e. no padding, no
609 // striding...)
610 template <typename iType>
611 KOKKOS_INLINE_FUNCTION typename std::enable_if<
612 std::is_same<typename drvtraits::value_type,
613 typename drvtraits::scalar_array_type>::value &&
614 std::is_integral<iType>::value,
615 reference_type>::type
616 operator[](const iType& i0) const {
617 // Phalanx is violating this, since they use the operator to access ALL
618 // elements in the allocation KOKKOS_IMPL_VIEW_OPERATOR_VERIFY( (1 ,
619 // this->rank(), m_track, m_map) )
620 return data()[i0];
621 }
622
623 // This assumes a contiguous underlying memory (i.e. no padding, no
624 // striding... AND a Trilinos/Sacado scalar type )
625 template <typename iType>
626 KOKKOS_INLINE_FUNCTION typename std::enable_if<
627 !std::is_same<typename drvtraits::value_type,
628 typename drvtraits::scalar_array_type>::value &&
629 std::is_integral<iType>::value,
630 reference_type>::type
631 operator[](const iType& i0) const {
632 // auto map = impl_map();
633 const size_t dim_scalar = m_map.dimension_scalar();
634 const size_t bytes = this->span() / dim_scalar;
635
636 using tmp_view_type = Kokkos::View<
637 DataType*, typename traits::array_layout, typename traits::device_type,
638 Kokkos::MemoryTraits<traits::memory_traits::is_unmanaged |
639 traits::memory_traits::is_random_access |
640 traits::memory_traits::is_atomic> >;
641 tmp_view_type rankone_view(this->data(), bytes, dim_scalar);
642 return rankone_view(i0);
643 }
644
645 // Rank 1 parenthesis
646 template <typename iType>
647 KOKKOS_INLINE_FUNCTION typename std::enable_if<
648 (std::is_same<typename traits::specialize, void>::value &&
649 std::is_integral<iType>::value),
650 reference_type>::type
651 operator()(const iType& i0) const {
652 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
653 return m_map.reference(i0);
654 }
655
656 template <typename iType>
657 KOKKOS_INLINE_FUNCTION typename std::enable_if<
658 !(std::is_same<typename traits::specialize, void>::value &&
659 std::is_integral<iType>::value),
660 reference_type>::type
661 operator()(const iType& i0) const {
662 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
663 return m_map.reference(i0, 0, 0, 0, 0, 0, 0);
664 }
665
666 // Rank 2
667 template <typename iType0, typename iType1>
668 KOKKOS_INLINE_FUNCTION typename std::enable_if<
669 (std::is_same<typename traits::specialize, void>::value &&
670 std::is_integral<iType0>::value && std::is_integral<iType1>::value),
671 reference_type>::type
672 operator()(const iType0& i0, const iType1& i1) const {
673 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
674 return m_map.reference(i0, i1);
675 }
676
677 template <typename iType0, typename iType1>
678 KOKKOS_INLINE_FUNCTION typename std::enable_if<
679 !(std::is_same<typename drvtraits::specialize, void>::value &&
680 std::is_integral<iType0>::value),
681 reference_type>::type
682 operator()(const iType0& i0, const iType1& i1) const {
683 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
684 return m_map.reference(i0, i1, 0, 0, 0, 0, 0);
685 }
686
687 // Rank 3
688 template <typename iType0, typename iType1, typename iType2>
689 KOKKOS_INLINE_FUNCTION typename std::enable_if<
690 (std::is_same<typename traits::specialize, void>::value &&
691 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
692 std::is_integral<iType2>::value),
693 reference_type>::type
694 operator()(const iType0& i0, const iType1& i1, const iType2& i2) const {
695 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
696 (3, this->rank(), m_track, m_map, i0, i1, i2))
697 return m_map.reference(i0, i1, i2);
698 }
699
700 template <typename iType0, typename iType1, typename iType2>
701 KOKKOS_INLINE_FUNCTION typename std::enable_if<
702 !(std::is_same<typename drvtraits::specialize, void>::value &&
703 std::is_integral<iType0>::value),
704 reference_type>::type
705 operator()(const iType0& i0, const iType1& i1, const iType2& i2) const {
706 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
707 (3, this->rank(), m_track, m_map, i0, i1, i2))
708 return m_map.reference(i0, i1, i2, 0, 0, 0, 0);
709 }
710
711 // Rank 4
712 template <typename iType0, typename iType1, typename iType2, typename iType3>
713 KOKKOS_INLINE_FUNCTION typename std::enable_if<
714 (std::is_same<typename traits::specialize, void>::value &&
715 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
716 std::is_integral<iType2>::value && std::is_integral<iType3>::value),
717 reference_type>::type
718 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
719 const iType3& i3) const {
720 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
721 (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
722 return m_map.reference(i0, i1, i2, i3);
723 }
724
725 template <typename iType0, typename iType1, typename iType2, typename iType3>
726 KOKKOS_INLINE_FUNCTION typename std::enable_if<
727 !(std::is_same<typename drvtraits::specialize, void>::value &&
728 std::is_integral<iType0>::value),
729 reference_type>::type
730 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
731 const iType3& i3) const {
732 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
733 (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
734 return m_map.reference(i0, i1, i2, i3, 0, 0, 0);
735 }
736
737 // Rank 5
738 template <typename iType0, typename iType1, typename iType2, typename iType3,
739 typename iType4>
740 KOKKOS_INLINE_FUNCTION typename std::enable_if<
741 (std::is_same<typename traits::specialize, void>::value &&
742 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
743 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
744 std::is_integral<iType4>::value),
745 reference_type>::type
746 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
747 const iType3& i3, const iType4& i4) const {
748 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
749 (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
750 return m_map.reference(i0, i1, i2, i3, i4);
751 }
752
753 template <typename iType0, typename iType1, typename iType2, typename iType3,
754 typename iType4>
755 KOKKOS_INLINE_FUNCTION typename std::enable_if<
756 !(std::is_same<typename drvtraits::specialize, void>::value &&
757 std::is_integral<iType0>::value),
758 reference_type>::type
759 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
760 const iType3& i3, const iType4& i4) const {
761 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
762 (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
763 return m_map.reference(i0, i1, i2, i3, i4, 0, 0);
764 }
765
766 // Rank 6
767 template <typename iType0, typename iType1, typename iType2, typename iType3,
768 typename iType4, typename iType5>
769 KOKKOS_INLINE_FUNCTION typename std::enable_if<
770 (std::is_same<typename traits::specialize, void>::value &&
771 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
772 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
773 std::is_integral<iType4>::value && std::is_integral<iType5>::value),
774 reference_type>::type
775 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
776 const iType3& i3, const iType4& i4, const iType5& i5) const {
777 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
778 (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
779 return m_map.reference(i0, i1, i2, i3, i4, i5);
780 }
781
782 template <typename iType0, typename iType1, typename iType2, typename iType3,
783 typename iType4, typename iType5>
784 KOKKOS_INLINE_FUNCTION typename std::enable_if<
785 !(std::is_same<typename drvtraits::specialize, void>::value &&
786 std::is_integral<iType0>::value),
787 reference_type>::type
788 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
789 const iType3& i3, const iType4& i4, const iType5& i5) const {
790 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
791 (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
792 return m_map.reference(i0, i1, i2, i3, i4, i5, 0);
793 }
794
795 // Rank 7
796 template <typename iType0, typename iType1, typename iType2, typename iType3,
797 typename iType4, typename iType5, typename iType6>
798 KOKKOS_INLINE_FUNCTION typename std::enable_if<
799 (std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
800 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
801 std::is_integral<iType4>::value && std::is_integral<iType5>::value &&
802 std::is_integral<iType6>::value),
803 reference_type>::type
804 operator()(const iType0& i0, const iType1& i1, const iType2& i2,
805 const iType3& i3, const iType4& i4, const iType5& i5,
806 const iType6& i6) const {
807 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
808 (7, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5, i6))
809 return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
810 }
811
812 // Rank 0
813 KOKKOS_INLINE_FUNCTION
814 reference_type access() const {
815 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((0, this->rank(), m_track, m_map))
816 return impl_map().reference();
817 // return m_map.reference(0,0,0,0,0,0,0);
818 }
819
820 // Rank 1
821 // Rank 1 parenthesis
822 template <typename iType>
823 KOKKOS_INLINE_FUNCTION typename std::enable_if<
824 (std::is_same<typename traits::specialize, void>::value &&
825 std::is_integral<iType>::value),
826 reference_type>::type
827 access(const iType& i0) const {
828 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
829 return m_map.reference(i0);
830 }
831
832 template <typename iType>
833 KOKKOS_INLINE_FUNCTION typename std::enable_if<
834 !(std::is_same<typename traits::specialize, void>::value &&
835 std::is_integral<iType>::value),
836 reference_type>::type
837 access(const iType& i0) const {
838 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((1, this->rank(), m_track, m_map, i0))
839 return m_map.reference(i0, 0, 0, 0, 0, 0, 0);
840 }
841
842 // Rank 2
843 template <typename iType0, typename iType1>
844 KOKKOS_INLINE_FUNCTION typename std::enable_if<
845 (std::is_same<typename traits::specialize, void>::value &&
846 std::is_integral<iType0>::value && std::is_integral<iType1>::value),
847 reference_type>::type
848 access(const iType0& i0, const iType1& i1) const {
849 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
850 return m_map.reference(i0, i1);
851 }
852
853 template <typename iType0, typename iType1>
854 KOKKOS_INLINE_FUNCTION typename std::enable_if<
855 !(std::is_same<typename drvtraits::specialize, void>::value &&
856 std::is_integral<iType0>::value),
857 reference_type>::type
858 access(const iType0& i0, const iType1& i1) const {
859 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY((2, this->rank(), m_track, m_map, i0, i1))
860 return m_map.reference(i0, i1, 0, 0, 0, 0, 0);
861 }
862
863 // Rank 3
864 template <typename iType0, typename iType1, typename iType2>
865 KOKKOS_INLINE_FUNCTION typename std::enable_if<
866 (std::is_same<typename traits::specialize, void>::value &&
867 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
868 std::is_integral<iType2>::value),
869 reference_type>::type
870 access(const iType0& i0, const iType1& i1, const iType2& i2) const {
871 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
872 (3, this->rank(), m_track, m_map, i0, i1, i2))
873 return m_map.reference(i0, i1, i2);
874 }
875
876 template <typename iType0, typename iType1, typename iType2>
877 KOKKOS_INLINE_FUNCTION typename std::enable_if<
878 !(std::is_same<typename drvtraits::specialize, void>::value &&
879 std::is_integral<iType0>::value),
880 reference_type>::type
881 access(const iType0& i0, const iType1& i1, const iType2& i2) const {
882 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
883 (3, this->rank(), m_track, m_map, i0, i1, i2))
884 return m_map.reference(i0, i1, i2, 0, 0, 0, 0);
885 }
886
887 // Rank 4
888 template <typename iType0, typename iType1, typename iType2, typename iType3>
889 KOKKOS_INLINE_FUNCTION typename std::enable_if<
890 (std::is_same<typename traits::specialize, void>::value &&
891 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
892 std::is_integral<iType2>::value && std::is_integral<iType3>::value),
893 reference_type>::type
894 access(const iType0& i0, const iType1& i1, const iType2& i2,
895 const iType3& i3) const {
896 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
897 (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
898 return m_map.reference(i0, i1, i2, i3);
899 }
900
901 template <typename iType0, typename iType1, typename iType2, typename iType3>
902 KOKKOS_INLINE_FUNCTION typename std::enable_if<
903 !(std::is_same<typename drvtraits::specialize, void>::value &&
904 std::is_integral<iType0>::value),
905 reference_type>::type
906 access(const iType0& i0, const iType1& i1, const iType2& i2,
907 const iType3& i3) const {
908 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
909 (4, this->rank(), m_track, m_map, i0, i1, i2, i3))
910 return m_map.reference(i0, i1, i2, i3, 0, 0, 0);
911 }
912
913 // Rank 5
914 template <typename iType0, typename iType1, typename iType2, typename iType3,
915 typename iType4>
916 KOKKOS_INLINE_FUNCTION typename std::enable_if<
917 (std::is_same<typename traits::specialize, void>::value &&
918 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
919 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
920 std::is_integral<iType4>::value),
921 reference_type>::type
922 access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
923 const iType4& i4) const {
924 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
925 (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
926 return m_map.reference(i0, i1, i2, i3, i4);
927 }
928
929 template <typename iType0, typename iType1, typename iType2, typename iType3,
930 typename iType4>
931 KOKKOS_INLINE_FUNCTION typename std::enable_if<
932 !(std::is_same<typename drvtraits::specialize, void>::value &&
933 std::is_integral<iType0>::value),
934 reference_type>::type
935 access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
936 const iType4& i4) const {
937 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
938 (5, this->rank(), m_track, m_map, i0, i1, i2, i3, i4))
939 return m_map.reference(i0, i1, i2, i3, i4, 0, 0);
940 }
941
942 // Rank 6
943 template <typename iType0, typename iType1, typename iType2, typename iType3,
944 typename iType4, typename iType5>
945 KOKKOS_INLINE_FUNCTION typename std::enable_if<
946 (std::is_same<typename traits::specialize, void>::value &&
947 std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
948 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
949 std::is_integral<iType4>::value && std::is_integral<iType5>::value),
950 reference_type>::type
951 access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
952 const iType4& i4, const iType5& i5) const {
953 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
954 (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
955 return m_map.reference(i0, i1, i2, i3, i4, i5);
956 }
957
958 template <typename iType0, typename iType1, typename iType2, typename iType3,
959 typename iType4, typename iType5>
960 KOKKOS_INLINE_FUNCTION typename std::enable_if<
961 !(std::is_same<typename drvtraits::specialize, void>::value &&
962 std::is_integral<iType0>::value),
963 reference_type>::type
964 access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
965 const iType4& i4, const iType5& i5) const {
966 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
967 (6, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5))
968 return m_map.reference(i0, i1, i2, i3, i4, i5, 0);
969 }
970
971 // Rank 7
972 template <typename iType0, typename iType1, typename iType2, typename iType3,
973 typename iType4, typename iType5, typename iType6>
974 KOKKOS_INLINE_FUNCTION typename std::enable_if<
975 (std::is_integral<iType0>::value && std::is_integral<iType1>::value &&
976 std::is_integral<iType2>::value && std::is_integral<iType3>::value &&
977 std::is_integral<iType4>::value && std::is_integral<iType5>::value &&
978 std::is_integral<iType6>::value),
979 reference_type>::type
980 access(const iType0& i0, const iType1& i1, const iType2& i2, const iType3& i3,
981 const iType4& i4, const iType5& i5, const iType6& i6) const {
982 KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(
983 (7, this->rank(), m_track, m_map, i0, i1, i2, i3, i4, i5, i6))
984 return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
985 }
986
987#undef KOKKOS_IMPL_VIEW_OPERATOR_VERIFY
988
989 //----------------------------------------
990 // Standard constructor, destructor, and assignment operators...
991
992 KOKKOS_DEFAULTED_FUNCTION
993 ~DynRankView() = default;
994
995 KOKKOS_INLINE_FUNCTION
996 DynRankView() : m_track(), m_map(), m_rank() {} // Default ctor
997
998 KOKKOS_INLINE_FUNCTION
999 DynRankView(const DynRankView& rhs)
1000 : m_track(rhs.m_track), m_map(rhs.m_map), m_rank(rhs.m_rank) {}
1001
1002 KOKKOS_INLINE_FUNCTION
1003 DynRankView(DynRankView&& rhs)
1004 : m_track(rhs.m_track), m_map(rhs.m_map), m_rank(rhs.m_rank) {}
1005
1006 KOKKOS_INLINE_FUNCTION
1007 DynRankView& operator=(const DynRankView& rhs) {
1008 m_track = rhs.m_track;
1009 m_map = rhs.m_map;
1010 m_rank = rhs.m_rank;
1011 return *this;
1012 }
1013
1014 KOKKOS_INLINE_FUNCTION
1015 DynRankView& operator=(DynRankView&& rhs) {
1016 m_track = rhs.m_track;
1017 m_map = rhs.m_map;
1018 m_rank = rhs.m_rank;
1019 return *this;
1020 }
1021
1022 //----------------------------------------
1023 // Compatible view copy constructor and assignment
1024 // may assign unmanaged from managed.
1025 template <class RT, class... RP>
1026 KOKKOS_INLINE_FUNCTION DynRankView(const DynRankView<RT, RP...>& rhs)
1027 : m_track(rhs.m_track, traits::is_managed), m_map(), m_rank(rhs.m_rank) {
1028 using SrcTraits = typename DynRankView<RT, RP...>::traits;
1029 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1030 typename traits::specialize>;
1031 static_assert(Mapping::is_assignable,
1032 "Incompatible DynRankView copy construction");
1033 Mapping::assign(m_map, rhs.m_map, rhs.m_track);
1034 }
1035
1036 template <class RT, class... RP>
1037 KOKKOS_INLINE_FUNCTION DynRankView& operator=(
1038 const DynRankView<RT, RP...>& rhs) {
1039 using SrcTraits = typename DynRankView<RT, RP...>::traits;
1040 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1041 typename traits::specialize>;
1042 static_assert(Mapping::is_assignable,
1043 "Incompatible DynRankView copy construction");
1044 Mapping::assign(m_map, rhs.m_map, rhs.m_track);
1045 m_track.assign(rhs.m_track, traits::is_managed);
1046 m_rank = rhs.rank();
1047 return *this;
1048 }
1049
1050 // Copy/Assign View to DynRankView
1051 template <class RT, class... RP>
1052 KOKKOS_INLINE_FUNCTION DynRankView(const View<RT, RP...>& rhs)
1053 : m_track(), m_map(), m_rank(rhs.Rank) {
1054 using SrcTraits = typename View<RT, RP...>::traits;
1055 using Mapping =
1056 Kokkos::Impl::ViewMapping<traits, SrcTraits,
1058 static_assert(Mapping::is_assignable,
1059 "Incompatible View to DynRankView copy construction");
1060 Mapping::assign(*this, rhs);
1061 }
1062
1063 template <class RT, class... RP>
1064 KOKKOS_INLINE_FUNCTION DynRankView& operator=(const View<RT, RP...>& rhs) {
1065 using SrcTraits = typename View<RT, RP...>::traits;
1066 using Mapping =
1067 Kokkos::Impl::ViewMapping<traits, SrcTraits,
1069 static_assert(Mapping::is_assignable,
1070 "Incompatible View to DynRankView copy assignment");
1071 Mapping::assign(*this, rhs);
1072 return *this;
1073 }
1074
1075 //----------------------------------------
1076 // Allocation tracking properties
1077
1078 KOKKOS_INLINE_FUNCTION
1079 int use_count() const { return m_track.use_count(); }
1080
1081 inline const std::string label() const {
1082 return m_track.template get_label<typename traits::memory_space>();
1083 }
1084
1085 //----------------------------------------
1086 // Allocation according to allocation properties and array layout
1087 // unused arg_layout dimensions must be set to KOKKOS_INVALID_INDEX so that
1088 // rank deduction can properly take place
1089 template <class... P>
1090 explicit inline DynRankView(
1091 const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1092 typename std::enable_if<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1093 typename traits::array_layout>::type const&
1094 arg_layout)
1095 : m_track(),
1096 m_map(),
1097 m_rank(Impl::DynRankDimTraits<typename traits::specialize>::
1098 template computeRank<typename traits::array_layout, P...>(
1099 arg_prop, arg_layout)) {
1100 // Append layout and spaces if not input
1101 using alloc_prop_input = Kokkos::Impl::ViewCtorProp<P...>;
1102
1103 // use 'std::integral_constant<unsigned,I>' for non-types
1104 // to avoid duplicate class error.
1105 using alloc_prop = Kokkos::Impl::ViewCtorProp<
1106 P...,
1107 typename std::conditional<alloc_prop_input::has_label,
1108 std::integral_constant<unsigned, 0>,
1109 typename std::string>::type,
1110 typename std::conditional<
1111 alloc_prop_input::has_memory_space,
1112 std::integral_constant<unsigned, 1>,
1113 typename traits::device_type::memory_space>::type,
1114 typename std::conditional<
1115 alloc_prop_input::has_execution_space,
1116 std::integral_constant<unsigned, 2>,
1117 typename traits::device_type::execution_space>::type>;
1118
1119 static_assert(traits::is_managed,
1120 "View allocation constructor requires managed memory");
1121
1122 if (alloc_prop::initialize &&
1123 !alloc_prop::execution_space::impl_is_initialized()) {
1124 // If initializing view data then
1125 // the execution space must be initialized.
1126 Kokkos::Impl::throw_runtime_exception(
1127 "Constructing DynRankView and initializing data with uninitialized "
1128 "execution space");
1129 }
1130
1131 // Copy the input allocation properties with possibly defaulted properties
1132 alloc_prop prop_copy(arg_prop);
1133
1134//------------------------------------------------------------
1135#if defined(KOKKOS_ENABLE_CUDA)
1136 // If allocating in CudaUVMSpace must fence before and after
1137 // the allocation to protect against possible concurrent access
1138 // on the CPU and the GPU.
1139 // Fence using the trait's executon space (which will be Kokkos::Cuda)
1140 // to avoid incomplete type errors from usng Kokkos::Cuda directly.
1141 if (std::is_same<Kokkos::CudaUVMSpace,
1142 typename traits::device_type::memory_space>::value) {
1143 typename traits::device_type::memory_space::execution_space().fence();
1144 }
1145#endif
1146 //------------------------------------------------------------
1147
1148 Kokkos::Impl::SharedAllocationRecord<>* record = m_map.allocate_shared(
1149 prop_copy,
1150 Impl::DynRankDimTraits<typename traits::specialize>::
1151 template createLayout<traits, P...>(arg_prop, arg_layout));
1152
1153//------------------------------------------------------------
1154#if defined(KOKKOS_ENABLE_CUDA)
1155 if (std::is_same<Kokkos::CudaUVMSpace,
1156 typename traits::device_type::memory_space>::value) {
1157 typename traits::device_type::memory_space::execution_space().fence();
1158 }
1159#endif
1160 //------------------------------------------------------------
1161
1162 // Setup and initialization complete, start tracking
1163 m_track.assign_allocated_record_to_uninitialized(record);
1164 }
1165
1166 // Wrappers
1167 template <class... P>
1168 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1169 const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1170 typename std::enable_if<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1171 typename traits::array_layout>::type const&
1172 arg_layout)
1173 : m_track() // No memory tracking
1174 ,
1175 m_map(arg_prop,
1176 Impl::DynRankDimTraits<typename traits::specialize>::
1177 template createLayout<traits, P...>(arg_prop, arg_layout)),
1178 m_rank(Impl::DynRankDimTraits<typename traits::specialize>::
1179 template computeRank<typename traits::array_layout, P...>(
1180 arg_prop, arg_layout)) {
1181 static_assert(
1182 std::is_same<pointer_type,
1183 typename Impl::ViewCtorProp<P...>::pointer_type>::value,
1184 "Constructing DynRankView to wrap user memory must supply matching "
1185 "pointer type");
1186 }
1187
1188 //----------------------------------------
1189 // Constructor(s)
1190
1191 // Simple dimension-only layout
1192 template <class... P>
1193 explicit inline DynRankView(
1194 const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1195 typename std::enable_if<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1196 size_t>::type const arg_N0 = KOKKOS_INVALID_INDEX,
1197 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1198 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1199 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1200 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1201 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1202 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1203 const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1204 : DynRankView(arg_prop, typename traits::array_layout(
1205 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1206 arg_N5, arg_N6, arg_N7)) {}
1207
1208 template <class... P>
1209 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1210 const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1211 typename std::enable_if<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1212 size_t>::type const arg_N0 = KOKKOS_INVALID_INDEX,
1213 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1214 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1215 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1216 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1217 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1218 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1219 const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1220 : DynRankView(arg_prop, typename traits::array_layout(
1221 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1222 arg_N5, arg_N6, arg_N7)) {}
1223
1224 // Allocate with label and layout
1225 template <typename Label>
1226 explicit inline DynRankView(
1227 const Label& arg_label,
1228 typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value,
1229 typename traits::array_layout>::type const&
1230 arg_layout)
1231 : DynRankView(Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1232 arg_layout) {}
1233
1234 // Allocate label and layout, must disambiguate from subview constructor
1235 template <typename Label>
1236 explicit inline DynRankView(
1237 const Label& arg_label,
1238 typename std::enable_if<Kokkos::Impl::is_view_label<Label>::value,
1239 const size_t>::type arg_N0 = KOKKOS_INVALID_INDEX,
1240 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1241 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1242 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1243 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1244 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1245 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1246 const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1247 : DynRankView(
1248 Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1249 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1250 arg_N4, arg_N5, arg_N6, arg_N7)) {}
1251
1252 //----------------------------------------
1253 // Memory span required to wrap these dimensions.
1254 static constexpr size_t required_allocation_size(
1255 const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
1256 const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
1257 const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
1258 return map_type::memory_span(typename traits::array_layout(
1259 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1260 }
1261
1262 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1263 pointer_type arg_ptr, const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1264 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1265 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1266 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1267 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1268 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1269 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1270 const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1271 : DynRankView(Kokkos::Impl::ViewCtorProp<pointer_type>(arg_ptr), arg_N0,
1272 arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7) {}
1273
1274 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1275 pointer_type arg_ptr, typename traits::array_layout& arg_layout)
1276 : DynRankView(Kokkos::Impl::ViewCtorProp<pointer_type>(arg_ptr),
1277 arg_layout) {}
1278
1279 //----------------------------------------
1280 // Shared scratch memory constructor
1281
1282 static inline size_t shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1283 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1284 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1285 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1286 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1287 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1288 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1289 const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1290 const size_t num_passed_args =
1291 (arg_N0 != KOKKOS_INVALID_INDEX) + (arg_N1 != KOKKOS_INVALID_INDEX) +
1292 (arg_N2 != KOKKOS_INVALID_INDEX) + (arg_N3 != KOKKOS_INVALID_INDEX) +
1293 (arg_N4 != KOKKOS_INVALID_INDEX) + (arg_N5 != KOKKOS_INVALID_INDEX) +
1294 (arg_N6 != KOKKOS_INVALID_INDEX) + (arg_N7 != KOKKOS_INVALID_INDEX);
1295
1296 if (std::is_same<typename traits::specialize, void>::value &&
1297 num_passed_args != traits::rank_dynamic) {
1298 Kokkos::abort(
1299 "Kokkos::View::shmem_size() rank_dynamic != number of arguments.\n");
1300 }
1301 {}
1302
1303 return map_type::memory_span(typename traits::array_layout(
1304 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1305 }
1306
1307 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1308 const typename traits::execution_space::scratch_memory_space& arg_space,
1309 const typename traits::array_layout& arg_layout)
1310 : DynRankView(
1311 Kokkos::Impl::ViewCtorProp<pointer_type>(
1312 reinterpret_cast<pointer_type>(
1313 arg_space.get_shmem(map_type::memory_span(
1314 Impl::DynRankDimTraits<typename traits::specialize>::
1315 createLayout(arg_layout) // is this correct?
1316 )))),
1317 arg_layout) {}
1318
1319 explicit KOKKOS_INLINE_FUNCTION DynRankView(
1320 const typename traits::execution_space::scratch_memory_space& arg_space,
1321 const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1322 const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1323 const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1324 const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1325 const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1326 const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1327 const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1328 const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1329
1330 : DynRankView(
1331 Kokkos::Impl::ViewCtorProp<pointer_type>(
1332 reinterpret_cast<pointer_type>(
1333 arg_space.get_shmem(map_type::memory_span(
1334 Impl::DynRankDimTraits<typename traits::specialize>::
1335 createLayout(typename traits::array_layout(
1336 arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
1337 arg_N6, arg_N7)))))),
1338 typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1339 arg_N4, arg_N5, arg_N6, arg_N7)) {}
1340};
1341
1342template <typename D, class... P>
1343KOKKOS_INLINE_FUNCTION constexpr unsigned rank(
1344 const DynRankView<D, P...>& DRV) {
1345 return DRV.rank();
1346} // needed for transition to common constexpr method in view and dynrankview
1347 // to return rank
1348
1349//----------------------------------------------------------------------------
1350// Subview mapping.
1351// Deduce destination view type from source view traits and subview arguments
1352
1353namespace Impl {
1354
1355struct DynRankSubviewTag {};
1356
1357} // namespace Impl
1358
1359namespace Impl {
1360
1361template <class SrcTraits, class... Args>
1362class ViewMapping<
1363 typename std::enable_if<
1364 (std::is_same<typename SrcTraits::specialize, void>::value &&
1365 (std::is_same<typename SrcTraits::array_layout,
1366 Kokkos::LayoutLeft>::value ||
1367 std::is_same<typename SrcTraits::array_layout,
1368 Kokkos::LayoutRight>::value ||
1369 std::is_same<typename SrcTraits::array_layout,
1370 Kokkos::LayoutStride>::value)),
1371 Kokkos::Impl::DynRankSubviewTag>::type,
1372 SrcTraits, Args...> {
1373 private:
1374 enum {
1375 RZ = false,
1376 R0 = bool(is_integral_extent<0, Args...>::value),
1377 R1 = bool(is_integral_extent<1, Args...>::value),
1378 R2 = bool(is_integral_extent<2, Args...>::value),
1379 R3 = bool(is_integral_extent<3, Args...>::value),
1380 R4 = bool(is_integral_extent<4, Args...>::value),
1381 R5 = bool(is_integral_extent<5, Args...>::value),
1382 R6 = bool(is_integral_extent<6, Args...>::value)
1383 };
1384
1385 enum {
1386 rank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3) +
1387 unsigned(R4) + unsigned(R5) + unsigned(R6)
1388 };
1389
1390 using array_layout = Kokkos::LayoutStride;
1391
1392 using value_type = typename SrcTraits::value_type;
1393
1394 using data_type = value_type*******;
1395
1396 public:
1397 using traits_type = Kokkos::ViewTraits<data_type, array_layout,
1398 typename SrcTraits::device_type,
1399 typename SrcTraits::memory_traits>;
1400
1401 using type =
1402 Kokkos::View<data_type, array_layout, typename SrcTraits::device_type,
1403 typename SrcTraits::memory_traits>;
1404
1405 template <class MemoryTraits>
1406 struct apply {
1407 static_assert(Kokkos::Impl::is_memory_traits<MemoryTraits>::value, "");
1408
1409 using traits_type =
1410 Kokkos::ViewTraits<data_type, array_layout,
1411 typename SrcTraits::device_type, MemoryTraits>;
1412
1413 using type = Kokkos::View<data_type, array_layout,
1414 typename SrcTraits::device_type, MemoryTraits>;
1415 };
1416
1417 using dimension = typename SrcTraits::dimension;
1418
1419 template <class Arg0 = int, class Arg1 = int, class Arg2 = int,
1420 class Arg3 = int, class Arg4 = int, class Arg5 = int,
1421 class Arg6 = int>
1422 struct ExtentGenerator {
1423 KOKKOS_INLINE_FUNCTION
1424 static SubviewExtents<7, rank> generator(
1425 const dimension& dim, Arg0 arg0 = Arg0(), Arg1 arg1 = Arg1(),
1426 Arg2 arg2 = Arg2(), Arg3 arg3 = Arg3(), Arg4 arg4 = Arg4(),
1427 Arg5 arg5 = Arg5(), Arg6 arg6 = Arg6()) {
1428 return SubviewExtents<7, rank>(dim, arg0, arg1, arg2, arg3, arg4, arg5,
1429 arg6);
1430 }
1431 };
1432
1433 using ret_type = Kokkos::DynRankView<value_type, array_layout,
1434 typename SrcTraits::device_type,
1435 typename SrcTraits::memory_traits>;
1436
1437 template <typename T, class... P>
1438 KOKKOS_INLINE_FUNCTION static ret_type subview(
1439 const unsigned src_rank, Kokkos::DynRankView<T, P...> const& src,
1440 Args... args) {
1441 using DstType = ViewMapping<traits_type, typename traits_type::specialize>;
1442
1443 using DstDimType = typename std::conditional<
1444 (rank == 0), ViewDimension<>,
1445 typename std::conditional<
1446 (rank == 1), ViewDimension<0>,
1447 typename std::conditional<
1448 (rank == 2), ViewDimension<0, 0>,
1449 typename std::conditional<
1450 (rank == 3), ViewDimension<0, 0, 0>,
1451 typename std::conditional<
1452 (rank == 4), ViewDimension<0, 0, 0, 0>,
1453 typename std::conditional<
1454 (rank == 5), ViewDimension<0, 0, 0, 0, 0>,
1455 typename std::conditional<
1456 (rank == 6), ViewDimension<0, 0, 0, 0, 0, 0>,
1457 ViewDimension<0, 0, 0, 0, 0, 0, 0> >::type>::
1458 type>::type>::type>::type>::type>::type;
1459
1460 using dst_offset_type = ViewOffset<DstDimType, Kokkos::LayoutStride>;
1461 using dst_handle_type = typename DstType::handle_type;
1462
1463 ret_type dst;
1464
1465 const SubviewExtents<7, rank> extents = ExtentGenerator<Args...>::generator(
1466 src.m_map.m_impl_offset.m_dim, args...);
1467
1468 dst_offset_type tempdst(src.m_map.m_impl_offset, extents);
1469
1470 dst.m_track = src.m_track;
1471
1472 dst.m_map.m_impl_offset.m_dim.N0 = tempdst.m_dim.N0;
1473 dst.m_map.m_impl_offset.m_dim.N1 = tempdst.m_dim.N1;
1474 dst.m_map.m_impl_offset.m_dim.N2 = tempdst.m_dim.N2;
1475 dst.m_map.m_impl_offset.m_dim.N3 = tempdst.m_dim.N3;
1476 dst.m_map.m_impl_offset.m_dim.N4 = tempdst.m_dim.N4;
1477 dst.m_map.m_impl_offset.m_dim.N5 = tempdst.m_dim.N5;
1478 dst.m_map.m_impl_offset.m_dim.N6 = tempdst.m_dim.N6;
1479
1480 dst.m_map.m_impl_offset.m_stride.S0 = tempdst.m_stride.S0;
1481 dst.m_map.m_impl_offset.m_stride.S1 = tempdst.m_stride.S1;
1482 dst.m_map.m_impl_offset.m_stride.S2 = tempdst.m_stride.S2;
1483 dst.m_map.m_impl_offset.m_stride.S3 = tempdst.m_stride.S3;
1484 dst.m_map.m_impl_offset.m_stride.S4 = tempdst.m_stride.S4;
1485 dst.m_map.m_impl_offset.m_stride.S5 = tempdst.m_stride.S5;
1486 dst.m_map.m_impl_offset.m_stride.S6 = tempdst.m_stride.S6;
1487
1488 dst.m_map.m_impl_handle =
1489 dst_handle_type(src.m_map.m_impl_handle +
1490 src.m_map.m_impl_offset(
1491 extents.domain_offset(0), extents.domain_offset(1),
1492 extents.domain_offset(2), extents.domain_offset(3),
1493 extents.domain_offset(4), extents.domain_offset(5),
1494 extents.domain_offset(6)));
1495
1496 dst.m_rank =
1497 (src_rank > 0 ? unsigned(R0) : 0) + (src_rank > 1 ? unsigned(R1) : 0) +
1498 (src_rank > 2 ? unsigned(R2) : 0) + (src_rank > 3 ? unsigned(R3) : 0) +
1499 (src_rank > 4 ? unsigned(R4) : 0) + (src_rank > 5 ? unsigned(R5) : 0) +
1500 (src_rank > 6 ? unsigned(R6) : 0);
1501
1502 return dst;
1503 }
1504};
1505
1506} // namespace Impl
1507
1508template <class V, class... Args>
1509using Subdynrankview =
1510 typename Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag, V,
1511 Args...>::ret_type;
1512
1513template <class D, class... P, class... Args>
1514KOKKOS_INLINE_FUNCTION Subdynrankview<ViewTraits<D*******, P...>, Args...>
1515subdynrankview(const Kokkos::DynRankView<D, P...>& src, Args... args) {
1516 if (src.rank() > sizeof...(Args)) // allow sizeof...(Args) >= src.rank(),
1517 // ignore the remaining args
1518 {
1519 Kokkos::abort(
1520 "subdynrankview: num of args must be >= rank of the source "
1521 "DynRankView");
1522 }
1523
1524 using metafcn =
1525 Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag,
1526 Kokkos::ViewTraits<D*******, P...>, Args...>;
1527
1528 return metafcn::subview(src.rank(), src, args...);
1529}
1530
1531// Wrapper to allow subview function name
1532template <class D, class... P, class... Args>
1533KOKKOS_INLINE_FUNCTION Subdynrankview<ViewTraits<D*******, P...>, Args...>
1534subview(const Kokkos::DynRankView<D, P...>& src, Args... args) {
1535 return subdynrankview(src, args...);
1536}
1537
1538} // namespace Kokkos
1539
1540namespace Kokkos {
1541
1542// overload == and !=
1543template <class LT, class... LP, class RT, class... RP>
1544KOKKOS_INLINE_FUNCTION bool operator==(const DynRankView<LT, LP...>& lhs,
1545 const DynRankView<RT, RP...>& rhs) {
1546 // Same data, layout, dimensions
1547 using lhs_traits = ViewTraits<LT, LP...>;
1548 using rhs_traits = ViewTraits<RT, RP...>;
1549
1550 return std::is_same<typename lhs_traits::const_value_type,
1551 typename rhs_traits::const_value_type>::value &&
1552 std::is_same<typename lhs_traits::array_layout,
1553 typename rhs_traits::array_layout>::value &&
1554 std::is_same<typename lhs_traits::memory_space,
1555 typename rhs_traits::memory_space>::value &&
1556 lhs.rank() == rhs.rank() && lhs.data() == rhs.data() &&
1557 lhs.span() == rhs.span() && lhs.extent(0) == rhs.extent(0) &&
1558 lhs.extent(1) == rhs.extent(1) && lhs.extent(2) == rhs.extent(2) &&
1559 lhs.extent(3) == rhs.extent(3) && lhs.extent(4) == rhs.extent(4) &&
1560 lhs.extent(5) == rhs.extent(5) && lhs.extent(6) == rhs.extent(6) &&
1561 lhs.extent(7) == rhs.extent(7);
1562}
1563
1564template <class LT, class... LP, class RT, class... RP>
1565KOKKOS_INLINE_FUNCTION bool operator!=(const DynRankView<LT, LP...>& lhs,
1566 const DynRankView<RT, RP...>& rhs) {
1567 return !(operator==(lhs, rhs));
1568}
1569
1570} // namespace Kokkos
1571
1572//----------------------------------------------------------------------------
1573//----------------------------------------------------------------------------
1574namespace Kokkos {
1575namespace Impl {
1576
1577template <class OutputView, typename Enable = void>
1578struct DynRankViewFill {
1579 using const_value_type = typename OutputView::traits::const_value_type;
1580
1581 const OutputView output;
1582 const_value_type input;
1583
1584 KOKKOS_INLINE_FUNCTION
1585 void operator()(const size_t i0) const {
1586 const size_t n1 = output.extent(1);
1587 const size_t n2 = output.extent(2);
1588 const size_t n3 = output.extent(3);
1589 const size_t n4 = output.extent(4);
1590 const size_t n5 = output.extent(5);
1591 const size_t n6 = output.extent(6);
1592
1593 for (size_t i1 = 0; i1 < n1; ++i1) {
1594 for (size_t i2 = 0; i2 < n2; ++i2) {
1595 for (size_t i3 = 0; i3 < n3; ++i3) {
1596 for (size_t i4 = 0; i4 < n4; ++i4) {
1597 for (size_t i5 = 0; i5 < n5; ++i5) {
1598 for (size_t i6 = 0; i6 < n6; ++i6) {
1599 output.access(i0, i1, i2, i3, i4, i5, i6) = input;
1600 }
1601 }
1602 }
1603 }
1604 }
1605 }
1606 }
1607
1608 DynRankViewFill(const OutputView& arg_out, const_value_type& arg_in)
1609 : output(arg_out), input(arg_in) {
1610 using execution_space = typename OutputView::execution_space;
1612
1613 Kokkos::parallel_for("Kokkos::DynRankViewFill", Policy(0, output.extent(0)),
1614 *this);
1615 }
1616};
1617
1618template <class OutputView>
1619struct DynRankViewFill<OutputView,
1620 typename std::enable_if<OutputView::Rank == 0>::type> {
1621 DynRankViewFill(const OutputView& dst,
1622 const typename OutputView::const_value_type& src) {
1623 Kokkos::Impl::DeepCopy<typename OutputView::memory_space,
1625 dst.data(), &src, sizeof(typename OutputView::const_value_type));
1626 }
1627};
1628
1629template <class OutputView, class InputView,
1630 class ExecSpace = typename OutputView::execution_space>
1631struct DynRankViewRemap {
1632 const OutputView output;
1633 const InputView input;
1634 const size_t n0;
1635 const size_t n1;
1636 const size_t n2;
1637 const size_t n3;
1638 const size_t n4;
1639 const size_t n5;
1640 const size_t n6;
1641 const size_t n7;
1642
1643 DynRankViewRemap(const OutputView& arg_out, const InputView& arg_in)
1644 : output(arg_out),
1645 input(arg_in),
1646 n0(std::min((size_t)arg_out.extent(0), (size_t)arg_in.extent(0))),
1647 n1(std::min((size_t)arg_out.extent(1), (size_t)arg_in.extent(1))),
1648 n2(std::min((size_t)arg_out.extent(2), (size_t)arg_in.extent(2))),
1649 n3(std::min((size_t)arg_out.extent(3), (size_t)arg_in.extent(3))),
1650 n4(std::min((size_t)arg_out.extent(4), (size_t)arg_in.extent(4))),
1651 n5(std::min((size_t)arg_out.extent(5), (size_t)arg_in.extent(5))),
1652 n6(std::min((size_t)arg_out.extent(6), (size_t)arg_in.extent(6))),
1653 n7(std::min((size_t)arg_out.extent(7), (size_t)arg_in.extent(7))) {
1654 using Policy = Kokkos::RangePolicy<ExecSpace>;
1655
1656 Kokkos::parallel_for("Kokkos::DynRankViewRemap", Policy(0, n0), *this);
1657 }
1658
1659 KOKKOS_INLINE_FUNCTION
1660 void operator()(const size_t i0) const {
1661 for (size_t i1 = 0; i1 < n1; ++i1) {
1662 for (size_t i2 = 0; i2 < n2; ++i2) {
1663 for (size_t i3 = 0; i3 < n3; ++i3) {
1664 for (size_t i4 = 0; i4 < n4; ++i4) {
1665 for (size_t i5 = 0; i5 < n5; ++i5) {
1666 for (size_t i6 = 0; i6 < n6; ++i6) {
1667 output.access(i0, i1, i2, i3, i4, i5, i6) =
1668 input.access(i0, i1, i2, i3, i4, i5, i6);
1669 }
1670 }
1671 }
1672 }
1673 }
1674 }
1675 }
1676};
1677
1678} /* namespace Impl */
1679} /* namespace Kokkos */
1680
1681namespace Kokkos {
1682
1684template <class DT, class... DP>
1685inline void deep_copy(
1686 const DynRankView<DT, DP...>& dst,
1687 typename ViewTraits<DT, DP...>::const_value_type& value,
1688 typename std::enable_if<std::is_same<
1689 typename ViewTraits<DT, DP...>::specialize, void>::value>::type* =
1690 nullptr) {
1691 static_assert(
1692 std::is_same<typename ViewTraits<DT, DP...>::non_const_value_type,
1693 typename ViewTraits<DT, DP...>::value_type>::value,
1694 "deep_copy requires non-const type");
1695
1696 Kokkos::fence();
1697 Kokkos::Impl::DynRankViewFill<DynRankView<DT, DP...> >(dst, value);
1698 Kokkos::fence();
1699}
1700
1702template <class ST, class... SP>
1703inline void deep_copy(
1704 typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1705 const DynRankView<ST, SP...>& src,
1706 typename std::enable_if<std::is_same<
1707 typename ViewTraits<ST, SP...>::specialize, void>::value>::type* = 0) {
1708 if (src.rank() != 0) {
1709 Kokkos::abort("");
1710 }
1711
1712 using src_traits = ViewTraits<ST, SP...>;
1713 using src_memory_space = typename src_traits::memory_space;
1714 Kokkos::fence();
1715 Kokkos::Impl::DeepCopy<HostSpace, src_memory_space>(&dst, src.data(),
1716 sizeof(ST));
1717 Kokkos::fence();
1718}
1719
1720//----------------------------------------------------------------------------
1724template <class DstType, class SrcType>
1725inline void deep_copy(
1726 const DstType& dst, const SrcType& src,
1727 typename std::enable_if<
1728 (std::is_same<typename DstType::traits::specialize, void>::value &&
1729 std::is_same<typename SrcType::traits::specialize, void>::value &&
1730 (Kokkos::is_dyn_rank_view<DstType>::value ||
1731 Kokkos::is_dyn_rank_view<SrcType>::value))>::type* = nullptr) {
1732 static_assert(
1733 std::is_same<typename DstType::traits::value_type,
1734 typename DstType::traits::non_const_value_type>::value,
1735 "deep_copy requires non-const destination type");
1736
1737 using dst_type = DstType;
1738 using src_type = SrcType;
1739
1740 using dst_execution_space = typename dst_type::execution_space;
1741 using src_execution_space = typename src_type::execution_space;
1742 using dst_memory_space = typename dst_type::memory_space;
1743 using src_memory_space = typename src_type::memory_space;
1744
1745 enum {
1746 DstExecCanAccessSrc =
1747 Kokkos::Impl::SpaceAccessibility<dst_execution_space,
1748 src_memory_space>::accessible
1749 };
1750
1751 enum {
1752 SrcExecCanAccessDst =
1753 Kokkos::Impl::SpaceAccessibility<src_execution_space,
1754 dst_memory_space>::accessible
1755 };
1756
1757 if ((void*)dst.data() != (void*)src.data()) {
1758 // Concern: If overlapping views then a parallel copy will be erroneous.
1759 // ...
1760
1761 // If same type, equal layout, equal dimensions, equal span, and contiguous
1762 // memory then can byte-wise copy
1763 if (rank(src) == 0 && rank(dst) == 0) {
1764 using value_type = typename dst_type::value_type;
1765 Kokkos::fence();
1766 Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1767 dst.data(), src.data(), sizeof(value_type));
1768 Kokkos::fence();
1769 } else if (std::is_same<
1770 typename DstType::traits::value_type,
1771 typename SrcType::traits::non_const_value_type>::value &&
1772 ((std::is_same<typename DstType::traits::array_layout,
1773 typename SrcType::traits::array_layout>::value &&
1774 (std::is_same<typename DstType::traits::array_layout,
1775 typename Kokkos::LayoutLeft>::value ||
1776 std::is_same<typename DstType::traits::array_layout,
1777 typename Kokkos::LayoutRight>::value)) ||
1778 (rank(dst) == 1 && rank(src) == 1)) &&
1779 dst.span_is_contiguous() && src.span_is_contiguous() &&
1780 dst.span() == src.span() && dst.extent(0) == src.extent(0) &&
1781
1782 dst.extent(1) == src.extent(1) &&
1783 dst.extent(2) == src.extent(2) &&
1784 dst.extent(3) == src.extent(3) &&
1785 dst.extent(4) == src.extent(4) &&
1786 dst.extent(5) == src.extent(5) &&
1787 dst.extent(6) == src.extent(6) &&
1788 dst.extent(7) == src.extent(7)) {
1789 const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1790 Kokkos::fence();
1791 Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1792 dst.data(), src.data(), nbytes);
1793 Kokkos::fence();
1794 } else if (std::is_same<
1795 typename DstType::traits::value_type,
1796 typename SrcType::traits::non_const_value_type>::value &&
1797 ((std::is_same<typename DstType::traits::array_layout,
1798 typename SrcType::traits::array_layout>::value &&
1799 std::is_same<typename DstType::traits::array_layout,
1800 typename Kokkos::LayoutStride>::value) ||
1801 (rank(dst) == 1 && rank(src) == 1)) &&
1802 dst.span_is_contiguous() && src.span_is_contiguous() &&
1803 dst.span() == src.span() && dst.extent(0) == src.extent(0) &&
1804 dst.extent(1) == src.extent(1) &&
1805 dst.extent(2) == src.extent(2) &&
1806 dst.extent(3) == src.extent(3) &&
1807 dst.extent(4) == src.extent(4) &&
1808 dst.extent(5) == src.extent(5) &&
1809 dst.extent(6) == src.extent(6) &&
1810 dst.extent(7) == src.extent(7) &&
1811 dst.stride_0() == src.stride_0() &&
1812 dst.stride_1() == src.stride_1() &&
1813 dst.stride_2() == src.stride_2() &&
1814 dst.stride_3() == src.stride_3() &&
1815 dst.stride_4() == src.stride_4() &&
1816 dst.stride_5() == src.stride_5() &&
1817 dst.stride_6() == src.stride_6() &&
1818 dst.stride_7() == src.stride_7()) {
1819 const size_t nbytes = sizeof(typename dst_type::value_type) * dst.span();
1820 Kokkos::fence();
1821 Kokkos::Impl::DeepCopy<dst_memory_space, src_memory_space>(
1822 dst.data(), src.data(), nbytes);
1823 Kokkos::fence();
1824 } else if (DstExecCanAccessSrc) {
1825 // Copying data between views in accessible memory spaces and either
1826 // non-contiguous or incompatible shape.
1827 Kokkos::fence();
1828 Kokkos::Impl::DynRankViewRemap<dst_type, src_type>(dst, src);
1829 Kokkos::fence();
1830 } else if (SrcExecCanAccessDst) {
1831 // Copying data between views in accessible memory spaces and either
1832 // non-contiguous or incompatible shape.
1833 Kokkos::fence();
1834 Kokkos::Impl::DynRankViewRemap<dst_type, src_type, src_execution_space>(
1835 dst, src);
1836 Kokkos::fence();
1837 } else {
1838 Kokkos::Impl::throw_runtime_exception(
1839 "deep_copy given views that would require a temporary allocation");
1840 }
1841 } else {
1842 Kokkos::fence();
1843 }
1844}
1845
1846} // namespace Kokkos
1847
1848//----------------------------------------------------------------------------
1849//----------------------------------------------------------------------------
1850
1851namespace Kokkos {
1852namespace Impl {
1853
1854// Deduce Mirror Types
1855template <class Space, class T, class... P>
1856struct MirrorDRViewType {
1857 // The incoming view_type
1858 using src_view_type = typename Kokkos::DynRankView<T, P...>;
1859 // The memory space for the mirror view
1860 using memory_space = typename Space::memory_space;
1861 // Check whether it is the same memory space
1862 enum {
1863 is_same_memspace =
1864 std::is_same<memory_space, typename src_view_type::memory_space>::value
1865 };
1866 // The array_layout
1867 using array_layout = typename src_view_type::array_layout;
1868 // The data type (we probably want it non-const since otherwise we can't even
1869 // deep_copy to it.
1870 using data_type = typename src_view_type::non_const_data_type;
1871 // The destination view type if it is not the same memory space
1872 using dest_view_type = Kokkos::DynRankView<data_type, array_layout, Space>;
1873 // If it is the same memory_space return the existsing view_type
1874 // This will also keep the unmanaged trait if necessary
1875 using view_type = typename std::conditional<is_same_memspace, src_view_type,
1876 dest_view_type>::type;
1877};
1878
1879template <class Space, class T, class... P>
1880struct MirrorDRVType {
1881 // The incoming view_type
1882 using src_view_type = typename Kokkos::DynRankView<T, P...>;
1883 // The memory space for the mirror view
1884 using memory_space = typename Space::memory_space;
1885 // Check whether it is the same memory space
1886 enum {
1887 is_same_memspace =
1888 std::is_same<memory_space, typename src_view_type::memory_space>::value
1889 };
1890 // The array_layout
1891 using array_layout = typename src_view_type::array_layout;
1892 // The data type (we probably want it non-const since otherwise we can't even
1893 // deep_copy to it.
1894 using data_type = typename src_view_type::non_const_data_type;
1895 // The destination view type if it is not the same memory space
1896 using view_type = Kokkos::DynRankView<data_type, array_layout, Space>;
1897};
1898
1899} // namespace Impl
1900
1901template <class T, class... P>
1902inline typename DynRankView<T, P...>::HostMirror create_mirror(
1903 const DynRankView<T, P...>& src,
1904 typename std::enable_if<
1905 std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
1906 !std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
1907 Kokkos::LayoutStride>::value>::type* = nullptr) {
1908 using src_type = DynRankView<T, P...>;
1909 using dst_type = typename src_type::HostMirror;
1910
1911 return dst_type(std::string(src.label()).append("_mirror"),
1912 Impl::reconstructLayout(src.layout(), src.rank()));
1913}
1914
1915template <class T, class... P>
1916inline typename DynRankView<T, P...>::HostMirror create_mirror(
1917 const DynRankView<T, P...>& src,
1918 typename std::enable_if<
1919 std::is_same<typename ViewTraits<T, P...>::specialize, void>::value &&
1920 std::is_same<typename Kokkos::ViewTraits<T, P...>::array_layout,
1921 Kokkos::LayoutStride>::value>::type* = 0) {
1922 using src_type = DynRankView<T, P...>;
1923 using dst_type = typename src_type::HostMirror;
1924
1925 return dst_type(std::string(src.label()).append("_mirror"),
1926 Impl::reconstructLayout(src.layout(), src.rank()));
1927}
1928
1929// Create a mirror in a new space (specialization for different space)
1930template <class Space, class T, class... P>
1931typename Impl::MirrorDRVType<Space, T, P...>::view_type create_mirror(
1932 const Space&, const Kokkos::DynRankView<T, P...>& src,
1933 typename std::enable_if<std::is_same<
1934 typename ViewTraits<T, P...>::specialize, void>::value>::type* =
1935 nullptr) {
1936 return typename Impl::MirrorDRVType<Space, T, P...>::view_type(
1937 src.label(), Impl::reconstructLayout(src.layout(), src.rank()));
1938}
1939
1940template <class T, class... P>
1941inline typename DynRankView<T, P...>::HostMirror create_mirror_view(
1942 const DynRankView<T, P...>& src,
1943 typename std::enable_if<
1944 (std::is_same<
1945 typename DynRankView<T, P...>::memory_space,
1946 typename DynRankView<T, P...>::HostMirror::memory_space>::value &&
1947 std::is_same<typename DynRankView<T, P...>::data_type,
1948 typename DynRankView<T, P...>::HostMirror::data_type>::
1949 value)>::type* = nullptr) {
1950 return src;
1951}
1952
1953template <class T, class... P>
1954inline typename DynRankView<T, P...>::HostMirror create_mirror_view(
1955 const DynRankView<T, P...>& src,
1956 typename std::enable_if<
1957 !(std::is_same<
1958 typename DynRankView<T, P...>::memory_space,
1959 typename DynRankView<T, P...>::HostMirror::memory_space>::value &&
1960 std::is_same<typename DynRankView<T, P...>::data_type,
1961 typename DynRankView<T, P...>::HostMirror::data_type>::
1962 value)>::type* = nullptr) {
1963 return Kokkos::create_mirror(src);
1964}
1965
1966// Create a mirror view in a new space (specialization for same space)
1967template <class Space, class T, class... P>
1968typename Impl::MirrorDRViewType<Space, T, P...>::view_type create_mirror_view(
1969 const Space&, const Kokkos::DynRankView<T, P...>& src,
1970 typename std::enable_if<
1971 Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1972 nullptr) {
1973 return src;
1974}
1975
1976// Create a mirror view in a new space (specialization for different space)
1977template <class Space, class T, class... P>
1978typename Impl::MirrorDRViewType<Space, T, P...>::view_type create_mirror_view(
1979 const Space&, const Kokkos::DynRankView<T, P...>& src,
1980 typename std::enable_if<
1981 !Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1982 nullptr) {
1983 return typename Impl::MirrorDRViewType<Space, T, P...>::view_type(
1984 src.label(), Impl::reconstructLayout(src.layout(), src.rank()));
1985}
1986
1987// Create a mirror view and deep_copy in a new space (specialization for same
1988// space)
1989template <class Space, class T, class... P>
1990typename Impl::MirrorDRViewType<Space, T, P...>::view_type
1991create_mirror_view_and_copy(
1992 const Space&, const Kokkos::DynRankView<T, P...>& src,
1993 std::string const& name = "",
1994 typename std::enable_if<
1995 Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
1996 nullptr) {
1997 (void)name;
1998 return src;
1999}
2000
2001// Create a mirror view and deep_copy in a new space (specialization for
2002// different space)
2003template <class Space, class T, class... P>
2004typename Impl::MirrorDRViewType<Space, T, P...>::view_type
2005create_mirror_view_and_copy(
2006 const Space&, const Kokkos::DynRankView<T, P...>& src,
2007 std::string const& name = "",
2008 typename std::enable_if<
2009 !Impl::MirrorDRViewType<Space, T, P...>::is_same_memspace>::type* =
2010 nullptr) {
2011 using Mirror = typename Impl::MirrorDRViewType<Space, T, P...>::view_type;
2012 std::string label = name.empty() ? src.label() : name;
2013 auto mirror = Mirror(view_alloc(WithoutInitializing, label),
2014 Impl::reconstructLayout(src.layout(), src.rank()));
2015 deep_copy(mirror, src);
2016 return mirror;
2017}
2018
2019} // namespace Kokkos
2020
2021//----------------------------------------------------------------------------
2022//----------------------------------------------------------------------------
2023
2024namespace Kokkos {
2027template <class T, class... P>
2028inline void resize(DynRankView<T, P...>& v,
2029 const size_t n0 = KOKKOS_INVALID_INDEX,
2030 const size_t n1 = KOKKOS_INVALID_INDEX,
2031 const size_t n2 = KOKKOS_INVALID_INDEX,
2032 const size_t n3 = KOKKOS_INVALID_INDEX,
2033 const size_t n4 = KOKKOS_INVALID_INDEX,
2034 const size_t n5 = KOKKOS_INVALID_INDEX,
2035 const size_t n6 = KOKKOS_INVALID_INDEX,
2036 const size_t n7 = KOKKOS_INVALID_INDEX) {
2037 using drview_type = DynRankView<T, P...>;
2038
2039 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
2040 "Can only resize managed views");
2041
2042 drview_type v_resized(v.label(), n0, n1, n2, n3, n4, n5, n6, n7);
2043
2044 Kokkos::Impl::DynRankViewRemap<drview_type, drview_type>(v_resized, v);
2045
2046 v = v_resized;
2047}
2048
2051template <class T, class... P>
2052inline void realloc(DynRankView<T, P...>& v,
2053 const size_t n0 = KOKKOS_INVALID_INDEX,
2054 const size_t n1 = KOKKOS_INVALID_INDEX,
2055 const size_t n2 = KOKKOS_INVALID_INDEX,
2056 const size_t n3 = KOKKOS_INVALID_INDEX,
2057 const size_t n4 = KOKKOS_INVALID_INDEX,
2058 const size_t n5 = KOKKOS_INVALID_INDEX,
2059 const size_t n6 = KOKKOS_INVALID_INDEX,
2060 const size_t n7 = KOKKOS_INVALID_INDEX) {
2061 using drview_type = DynRankView<T, P...>;
2062
2063 static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
2064 "Can only realloc managed views");
2065
2066 const std::string label = v.label();
2067
2068 v = drview_type(); // Deallocate first, if the only view to allocation
2069 v = drview_type(label, n0, n1, n2, n3, n4, n5, n6, n7);
2070}
2071
2072} // namespace Kokkos
2073
2074#endif
View
KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(const iType0 &, const MapType &)
Debug bounds-checking routines.
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename std::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=nullptr)
Execute functor in parallel according to the execution policy.
Memory management for host memory.
Execution policy for work over a range of an integral type.
View to an array of data.
Assign compatible default mappings.
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory.
Can AccessSpace access MemorySpace ?
Traits class for accessing attributes of a View.