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 422 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Args&... args)
12 422 : : NDIndex({args...}) {
13 : static_assert(Dim == sizeof...(args), "Wrong number of arguments.");
14 422 : }
15 :
16 : template <unsigned Dim>
17 1888 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(std::initializer_list<Index> indices) {
18 422 : unsigned int i = 0;
19 1888 : for (auto& index : indices) {
20 1466 : indices_m[i] = index;
21 1466 : ++i;
22 : }
23 422 : }
24 :
25 : template <unsigned Dim>
26 1260 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Vector<unsigned, Dim>& sizes) {
27 1260 : for (unsigned int d = 0; d < Dim; ++d) {
28 852 : indices_m[d] = Index(sizes[d]);
29 : }
30 408 : }
31 :
32 : template <unsigned Dim>
33 10239660 : KOKKOS_INLINE_FUNCTION const Index& NDIndex<Dim>::operator[](unsigned d) const noexcept {
34 10239660 : return indices_m[d];
35 : }
36 :
37 : template <unsigned Dim>
38 120178 : KOKKOS_INLINE_FUNCTION Index& NDIndex<Dim>::operator[](unsigned d) noexcept {
39 120178 : return indices_m[d];
40 : }
41 :
42 : template <unsigned Dim>
43 228 : KOKKOS_INLINE_FUNCTION unsigned NDIndex<Dim>::size() const noexcept {
44 228 : unsigned s = indices_m[0].length();
45 494 : for (unsigned int d = 1; d < Dim; ++d) {
46 266 : s *= indices_m[d].length();
47 : }
48 228 : 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 12 : inline std::ostream& operator<<(std::ostream& out, const NDIndex<Dim>& idx) {
62 12 : out << '{';
63 54 : for (unsigned d = 0; d < Dim; ++d) {
64 42 : out << idx[d] << ((d == Dim - 1) ? '}' : ',');
65 : }
66 12 : return out;
67 : }
68 :
69 : template <unsigned Dim>
70 0 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::intersect(const NDIndex<Dim>& ndi) const {
71 0 : NDIndex<Dim> r;
72 0 : for (unsigned d = 0; d < Dim; ++d) {
73 0 : r[d] = indices_m[d].intersect(ndi[d]);
74 : }
75 0 : return r;
76 : }
77 :
78 : template <unsigned Dim>
79 6 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells) const {
80 6 : NDIndex<Dim> r;
81 26 : for (unsigned d = 0; d < Dim; ++d) {
82 20 : r[d] = indices_m[d].grow(ncells);
83 : }
84 6 : return r;
85 : }
86 :
87 : template <unsigned Dim>
88 0 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells, unsigned int dim) const {
89 0 : NDIndex<Dim> r = *this;
90 0 : r[dim] = indices_m[dim].grow(ncells);
91 0 : return r;
92 : }
93 :
94 : template <unsigned Dim>
95 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::touches(const NDIndex<Dim>& a) const {
96 0 : bool touch = true;
97 0 : for (unsigned int d = 0; (d < Dim) && touch; ++d) {
98 0 : touch = touch && indices_m[d].touches(a.indices_m[d]);
99 : }
100 0 : 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 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
114 : int i) const {
115 0 : if (&l != this) {
116 0 : l = *this;
117 : }
118 0 : if (&r != this) {
119 0 : r = *this;
120 : }
121 0 : 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 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r,
138 : unsigned d) const {
139 0 : if (&l != this) {
140 0 : l = *this;
141 : }
142 0 : if (&r != this) {
143 0 : r = *this;
144 : }
145 0 : 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 3351614 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::first() const {
171 6703228 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
172 3350398 : return Vector<int, Dim>{indices_m[Idx].first()...};
173 : };
174 3351614 : return construct(std::make_index_sequence<Dim>{});
175 : }
176 :
177 : template <unsigned Dim>
178 198 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::last() const {
179 396 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
180 198 : return Vector<int, Dim>{indices_m[Idx].last()...};
181 : };
182 198 : return construct(std::make_index_sequence<Dim>{});
183 : }
184 :
185 : template <unsigned Dim>
186 0 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::begin() {
187 0 : return indices_m;
188 : }
189 :
190 : template <unsigned Dim>
191 0 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::end() {
192 0 : return indices_m + Dim;
193 : }
194 :
195 : template <unsigned Dim>
196 6 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::begin()
197 : const {
198 6 : return indices_m;
199 : }
200 :
201 : template <unsigned Dim>
202 6 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::end()
203 : const {
204 6 : 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
|