IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
ViewUtils.h
1//
2// View Utilities
3// Utility functions relating to Kokkos views
4//
5
6#ifndef IPPL_VIEW_UTILS_H
7#define IPPL_VIEW_UTILS_H
8
9#include <Kokkos_Core.hpp>
10
11#include <iostream>
12
13#include "Types/ViewTypes.h"
14
15namespace ippl {
16 namespace detail {
33 template <unsigned Dim, unsigned Current = 0, class BeginFunctor, class EndFunctor,
34 class Functor, typename Check = std::nullptr_t>
35 constexpr void nestedLoop(BeginFunctor&& begin, EndFunctor&& end, Functor&& body,
36 Check&& check = nullptr) {
37 for (size_t i = begin(Current); i < end(Current); ++i) {
38 if constexpr (Dim - 1 == Current) {
39 body(i);
40 } else {
41 auto inner = [i, &body](auto... args) {
42 body(i, args...);
43 };
44 nestedLoop<Dim, Current + 1>(begin, end, inner, check);
45 }
46 }
47 if constexpr (!std::is_null_pointer_v<std::decay_t<Check>>) {
48 check(Current);
49 }
50 }
51
63 template <typename View, class Functor, typename Check = std::nullptr_t>
64 constexpr void nestedViewLoop(View& view, int shift, Functor&& body,
65 Check&& check = nullptr) {
66 nestedLoop<View::rank>(
67 [&](unsigned) {
68 return shift;
69 },
70 [&](unsigned d) {
71 return view.extent(d) - shift;
72 },
73 body, check);
74 }
75
85 template <typename T, unsigned Dim, class... Properties>
86 void write(const typename ViewType<T, Dim, Properties...>::view_type& view,
87 std::ostream& out = std::cout) {
88 using view_type = typename ViewType<T, Dim, Properties...>::view_type;
89 typename view_type::host_mirror_type hview = Kokkos::create_mirror_view(view);
90 Kokkos::deep_copy(hview, view);
91
92 nestedViewLoop(
93 view, 0,
94 [&]<typename... Args>(Args&&... args) {
95 out << hview(args...) << " ";
96 },
97 [&](unsigned axis) {
98 if (axis + 1 >= 2 || axis == 0) {
99 out << std::endl;
100 }
101 });
102 }
103
111 template <unsigned Dim, typename View>
112 void write_as_list_impl(const View& view, std::ostream& out = std::cout) {
113 auto N = view.extent(0);
114 out << "[";
115 for (std::size_t i = 0; i < N; ++i) {
116 if constexpr (Dim == 1) {
117 out << view(i);
118 } else {
119 auto make_subview = [&]<std::size_t... Is>(std::index_sequence<Is...>) {
120 return Kokkos::subview(view, i, (static_cast<void>(Is), Kokkos::ALL)...);
121 };
122
123 auto subview = make_subview(std::make_index_sequence<Dim - 1>());
124 write_as_list_impl<Dim - 1>(subview, out);
125 }
126 if (i != N - 1)
127 out << ", ";
128 }
129 out << "]";
130 };
131
141 template <typename T, unsigned Dim, class... Properties>
142 void write_as_list(const typename ViewType<T, Dim, Properties...>::view_type& view,
143 std::ostream& out = std::cout) {
144 auto hview =
145 Kokkos::create_mirror_view_and_copy(Kokkos::DefaultHostExecutionSpace(), view);
146
147 write_as_list_impl<Dim>(hview, out);
148 }
149
153 template <typename View, size_t... Idx>
154 decltype(auto) shrinkView_impl(std::string label, const View& view, int nghost,
155 const std::index_sequence<Idx...>&) {
156 using view_type = typename Kokkos::View<typename View::data_type, Kokkos::LayoutLeft,
157 typename View::memory_space>::uniform_type;
158 return view_type(label, (view.extent(Idx) - 2 * nghost)...);
159 }
160
169 template <typename View>
170 decltype(auto) shrinkView(std::string label, const View& view, int nghost) {
171 return shrinkView_impl(label, view, nghost, std::make_index_sequence<View::rank>{});
172 }
173 } // namespace detail
174} // namespace ippl
175
176#endif
Definition Archive.h:20