Line data Source code
1 : //
2 : // Class NDIndex
3 : // This is a simple wrapper around Index that just keeps track of
4 : // N of them and passes along requests for intersect, etc.
5 : //
6 : #include <iostream>
7 :
8 : namespace ippl {
9 : template <unsigned Dim>
10 : template <class... Args>
11 944 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Args&... args)
12 944 : : NDIndex({args...}) {
13 : static_assert(Dim == sizeof...(args), "Wrong number of arguments.");
14 944 : }
15 :
16 : template <unsigned Dim>
17 4216 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(std::initializer_list<Index> indices) {
18 944 : unsigned int i = 0;
19 4216 : for (auto& index : indices) {
20 3272 : indices_m[i] = index;
21 3272 : ++i;
22 : }
23 944 : }
24 :
25 : template <unsigned Dim>
26 2520 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Vector<unsigned, Dim>& sizes) {
27 2520 : for (unsigned int d = 0; d < Dim; ++d) {
28 1704 : indices_m[d] = Index(sizes[d]);
29 : }
30 816 : }
31 :
32 : template <unsigned Dim>
33 10917756 : KOKKOS_INLINE_FUNCTION const Index& NDIndex<Dim>::operator[](unsigned d) const noexcept {
34 10917756 : return indices_m[d];
35 : }
36 :
37 : template <unsigned Dim>
38 1891516 : KOKKOS_INLINE_FUNCTION Index& NDIndex<Dim>::operator[](unsigned d) noexcept {
39 1891516 : return indices_m[d];
40 : }
41 :
42 : template <unsigned Dim>
43 492 : KOKKOS_INLINE_FUNCTION unsigned NDIndex<Dim>::size() const noexcept {
44 492 : unsigned s = indices_m[0].length();
45 1116 : for (unsigned int d = 1; d < Dim; ++d) {
46 624 : s *= indices_m[d].length();
47 : }
48 492 : return s;
49 : }
50 :
51 : template <unsigned Dim>
52 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::empty() const noexcept {
53 : bool r = false;
54 : for (unsigned d = 0; d < Dim; ++d) {
55 : r = r || indices_m[d].empty();
56 : }
57 : return r;
58 : }
59 :
60 : template <unsigned Dim>
61 24 : inline std::ostream& operator<<(std::ostream& out, const NDIndex<Dim>& idx) {
62 24 : out << '{';
63 108 : for (unsigned d = 0; d < Dim; ++d) {
64 84 : out << idx[d] << ((d == Dim - 1) ? '}' : ',');
65 : }
66 24 : return out;
67 : }
68 :
69 : template <unsigned Dim>
70 38868 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::intersect(const NDIndex<Dim>& ndi) const {
71 38868 : NDIndex<Dim> r;
72 243180 : for (unsigned d = 0; d < Dim; ++d) {
73 204312 : r[d] = indices_m[d].intersect(ndi[d]);
74 : }
75 38868 : return r;
76 : }
77 :
78 : template <unsigned Dim>
79 27220 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells) const {
80 27220 : NDIndex<Dim> r;
81 167372 : for (unsigned d = 0; d < Dim; ++d) {
82 140152 : r[d] = indices_m[d].grow(ncells);
83 : }
84 27220 : return r;
85 : }
86 :
87 : template <unsigned Dim>
88 576 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells, unsigned int dim) const {
89 576 : NDIndex<Dim> r = *this;
90 576 : r[dim] = indices_m[dim].grow(ncells);
91 576 : return r;
92 : }
93 :
94 : template <unsigned Dim>
95 13404 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::touches(const NDIndex<Dim>& a) const {
96 13404 : bool touch = true;
97 82476 : for (unsigned int d = 0; (d < Dim) && touch; ++d) {
98 69072 : touch = touch && indices_m[d].touches(a.indices_m[d]);
99 : }
100 13404 : return touch;
101 : }
102 :
103 : template <unsigned Dim>
104 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::contains(const NDIndex<Dim>& a) const {
105 : bool cont = true;
106 : for (unsigned int d = 0; (d < Dim) && cont; ++d) {
107 : cont = cont && indices_m[d].contains(a.indices_m[d]);
108 : }
109 : return cont;
110 : }
111 :
112 : template <unsigned Dim>
113 48 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
114 : int i) const {
115 48 : if (&l != this) {
116 48 : l = *this;
117 : }
118 48 : if (&r != this) {
119 48 : r = *this;
120 : }
121 48 : return indices_m[d].split(l[d], r[d], i);
122 : }
123 :
124 : template <unsigned Dim>
125 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
126 : double a) const {
127 0 : if (&l != this) {
128 0 : l = *this;
129 : }
130 0 : if (&r != this) {
131 0 : r = *this;
132 : }
133 0 : return indices_m[d].split(l[d], r[d], a);
134 : }
135 :
136 : template <unsigned Dim>
137 1324 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r,
138 : unsigned d) const {
139 1324 : if (&l != this) {
140 1324 : l = *this;
141 : }
142 1324 : if (&r != this) {
143 1324 : r = *this;
144 : }
145 1324 : return indices_m[d].split(l[d], r[d]);
146 : }
147 :
148 : template <unsigned Dim>
149 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r) const {
150 : unsigned int max_dim = 0;
151 : unsigned int max_length = 0;
152 : for (unsigned int d = 0; d < Dim; ++d) {
153 : if (indices_m[d].length() > max_length) {
154 : max_dim = d;
155 : max_length = indices_m[d].length();
156 : }
157 : }
158 : return split(l, r, max_dim);
159 : }
160 :
161 : template <unsigned Dim>
162 2543744 : KOKKOS_INLINE_FUNCTION Vector<size_t, Dim> NDIndex<Dim>::length() const {
163 5087488 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
164 2543744 : return Vector<size_t, Dim>{indices_m[Idx].length()...};
165 : };
166 2543744 : return construct(std::make_index_sequence<Dim>{});
167 : }
168 :
169 : template <unsigned Dim>
170 3539004 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::first() const {
171 7078008 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
172 3539004 : return Vector<int, Dim>{indices_m[Idx].first()...};
173 : };
174 3539004 : return construct(std::make_index_sequence<Dim>{});
175 : }
176 :
177 : template <unsigned Dim>
178 396 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::last() const {
179 792 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
180 396 : return Vector<int, Dim>{indices_m[Idx].last()...};
181 : };
182 396 : return construct(std::make_index_sequence<Dim>{});
183 : }
184 :
185 : template <unsigned Dim>
186 536 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::begin() {
187 536 : return indices_m;
188 : }
189 :
190 : template <unsigned Dim>
191 488 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::end() {
192 488 : return indices_m + Dim;
193 : }
194 :
195 : template <unsigned Dim>
196 96 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::begin()
197 : const {
198 96 : return indices_m;
199 : }
200 :
201 : template <unsigned Dim>
202 96 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::end()
203 : const {
204 96 : return indices_m + Dim;
205 : }
206 :
207 : template <unsigned Dim>
208 : bool operator==(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
209 : for (unsigned d = 0; d < Dim; d++) {
210 : if (nd1[d] != nd2[d]) {
211 : return false;
212 : }
213 : }
214 : return true;
215 : }
216 :
217 : template <unsigned Dim>
218 : bool operator!=(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
219 : return !(nd1 == nd2);
220 : }
221 : } // namespace ippl
|