Branch data 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 : 472 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Args&... args)
12 : 472 : : NDIndex({args...}) {
13 : : static_assert(Dim == sizeof...(args), "Wrong number of arguments.");
14 : 472 : }
15 : :
16 : : template <unsigned Dim>
17 [ + + ]: 2108 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(std::initializer_list<Index> indices) {
18 : 472 : unsigned int i = 0;
19 [ + + ]: 2108 : for (auto& index : indices) {
20 : 1636 : indices_m[i] = index;
21 : 1636 : ++i;
22 : : }
23 : 472 : }
24 : :
25 : : template <unsigned Dim>
26 [ + + ]: 1232 : KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Vector<unsigned, Dim>& sizes) {
27 [ + + ]: 1232 : for (unsigned int d = 0; d < Dim; ++d) {
28 : 832 : indices_m[d] = Index(sizes[d]);
29 : : }
30 : 400 : }
31 : :
32 : : template <unsigned Dim>
33 : 8910192 : KOKKOS_INLINE_FUNCTION const Index& NDIndex<Dim>::operator[](unsigned d) const noexcept {
34 : 8910192 : return indices_m[d];
35 : : }
36 : :
37 : : template <unsigned Dim>
38 : 116548 : KOKKOS_INLINE_FUNCTION Index& NDIndex<Dim>::operator[](unsigned d) noexcept {
39 : 116548 : return indices_m[d];
40 : : }
41 : :
42 : : template <unsigned Dim>
43 : 246 : KOKKOS_INLINE_FUNCTION unsigned NDIndex<Dim>::size() const noexcept {
44 : 246 : unsigned s = indices_m[0].length();
45 [ + + ]: 558 : for (unsigned int d = 1; d < Dim; ++d) {
46 : 312 : s *= indices_m[d].length();
47 : : }
48 : 246 : 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 : 24 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells) const {
80 : 24 : NDIndex<Dim> r;
81 [ + + ]: 108 : for (unsigned d = 0; d < Dim; ++d) {
82 : 84 : r[d] = indices_m[d].grow(ncells);
83 : : }
84 : 24 : 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 : 3355774 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::first() const {
171 : 6711548 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
172 : 3355774 : return Vector<int, Dim>{indices_m[Idx].first()...};
173 : : };
174 [ + - ]: 3355774 : 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 : 24 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::begin()
197 : : const {
198 : 24 : return indices_m;
199 : : }
200 : :
201 : : template <unsigned Dim>
202 : 24 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::end()
203 : : const {
204 : 24 : 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
|