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 : 8909418 : KOKKOS_INLINE_FUNCTION const Index& NDIndex<Dim>::operator[](unsigned d) const noexcept {
27 : 8909418 : return indices_m[d];
28 : : }
29 : :
30 : : template <unsigned Dim>
31 : 116362 : KOKKOS_INLINE_FUNCTION Index& NDIndex<Dim>::operator[](unsigned d) noexcept {
32 : 116362 : return indices_m[d];
33 : : }
34 : :
35 : : template <unsigned Dim>
36 : 48 : KOKKOS_INLINE_FUNCTION unsigned NDIndex<Dim>::size() const noexcept {
37 : 48 : unsigned s = indices_m[0].length();
38 [ + + ]: 144 : for (unsigned int d = 1; d < Dim; ++d) {
39 : 96 : s *= indices_m[d].length();
40 : : }
41 : 48 : return s;
42 : : }
43 : :
44 : : template <unsigned Dim>
45 : : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::empty() const noexcept {
46 : : bool r = false;
47 : : for (unsigned d = 0; d < Dim; ++d) {
48 : : r = r || indices_m[d].empty();
49 : : }
50 : : return r;
51 : : }
52 : :
53 : : template <unsigned Dim>
54 : 12 : inline std::ostream& operator<<(std::ostream& out, const NDIndex<Dim>& idx) {
55 : 12 : out << '{';
56 [ + + ]: 54 : for (unsigned d = 0; d < Dim; ++d) {
57 [ + + ]: 42 : out << idx[d] << ((d == Dim - 1) ? '}' : ',');
58 : : }
59 : 12 : return out;
60 : : }
61 : :
62 : : template <unsigned Dim>
63 : 0 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::intersect(const NDIndex<Dim>& ndi) const {
64 : 0 : NDIndex<Dim> r;
65 [ # # ]: 0 : for (unsigned d = 0; d < Dim; ++d) {
66 [ # # ]: 0 : r[d] = indices_m[d].intersect(ndi[d]);
67 : : }
68 : 0 : return r;
69 : : }
70 : :
71 : : template <unsigned Dim>
72 : 24 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells) const {
73 : 24 : NDIndex<Dim> r;
74 [ + + ]: 108 : for (unsigned d = 0; d < Dim; ++d) {
75 : 84 : r[d] = indices_m[d].grow(ncells);
76 : : }
77 : 24 : return r;
78 : : }
79 : :
80 : : template <unsigned Dim>
81 : 0 : KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells, unsigned int dim) const {
82 : 0 : NDIndex<Dim> r = *this;
83 : 0 : r[dim] = indices_m[dim].grow(ncells);
84 : 0 : return r;
85 : : }
86 : :
87 : : template <unsigned Dim>
88 : 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::touches(const NDIndex<Dim>& a) const {
89 : 0 : bool touch = true;
90 [ # # # # ]: 0 : for (unsigned int d = 0; (d < Dim) && touch; ++d) {
91 [ # # # # ]: 0 : touch = touch && indices_m[d].touches(a.indices_m[d]);
92 : : }
93 : 0 : return touch;
94 : : }
95 : :
96 : : template <unsigned Dim>
97 : : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::contains(const NDIndex<Dim>& a) const {
98 : : bool cont = true;
99 : : for (unsigned int d = 0; (d < Dim) && cont; ++d) {
100 : : cont = cont && indices_m[d].contains(a.indices_m[d]);
101 : : }
102 : : return cont;
103 : : }
104 : :
105 : : template <unsigned Dim>
106 : 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
107 : : int i) const {
108 [ # # ]: 0 : if (&l != this) {
109 : 0 : l = *this;
110 : : }
111 [ # # ]: 0 : if (&r != this) {
112 : 0 : r = *this;
113 : : }
114 : 0 : return indices_m[d].split(l[d], r[d], i);
115 : : }
116 : :
117 : : template <unsigned Dim>
118 : 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
119 : : double a) const {
120 [ # # ]: 0 : if (&l != this) {
121 : 0 : l = *this;
122 : : }
123 [ # # ]: 0 : if (&r != this) {
124 : 0 : r = *this;
125 : : }
126 : 0 : return indices_m[d].split(l[d], r[d], a);
127 : : }
128 : :
129 : : template <unsigned Dim>
130 : 0 : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r,
131 : : unsigned d) const {
132 [ # # ]: 0 : if (&l != this) {
133 : 0 : l = *this;
134 : : }
135 [ # # ]: 0 : if (&r != this) {
136 : 0 : r = *this;
137 : : }
138 : 0 : return indices_m[d].split(l[d], r[d]);
139 : : }
140 : :
141 : : template <unsigned Dim>
142 : : KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r) const {
143 : : unsigned int max_dim = 0;
144 : : unsigned int max_length = 0;
145 : : for (unsigned int d = 0; d < Dim; ++d) {
146 : : if (indices_m[d].length() > max_length) {
147 : : max_dim = d;
148 : : max_length = indices_m[d].length();
149 : : }
150 : : }
151 : : return split(l, r, max_dim);
152 : : }
153 : :
154 : : template <unsigned Dim>
155 : 2543744 : KOKKOS_INLINE_FUNCTION Vector<size_t, Dim> NDIndex<Dim>::length() const {
156 : 5087488 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
157 : 2543744 : return Vector<size_t, Dim>{indices_m[Idx].length()...};
158 : : };
159 [ + - ]: 2543744 : return construct(std::make_index_sequence<Dim>{});
160 : : }
161 : :
162 : : template <unsigned Dim>
163 : 3355576 : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::first() const {
164 : 6711152 : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
165 : 3355576 : return Vector<int, Dim>{indices_m[Idx].first()...};
166 : : };
167 [ + - ]: 3355576 : return construct(std::make_index_sequence<Dim>{});
168 : : }
169 : :
170 : : template <unsigned Dim>
171 : : KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::last() const {
172 : : auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
173 : : return Vector<int, Dim>{indices_m[Idx].last()...};
174 : : };
175 : : return construct(std::make_index_sequence<Dim>{});
176 : : }
177 : :
178 : : template <unsigned Dim>
179 : 0 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::begin() {
180 : 0 : return indices_m;
181 : : }
182 : :
183 : : template <unsigned Dim>
184 : 0 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::end() {
185 : 0 : return indices_m + Dim;
186 : : }
187 : :
188 : : template <unsigned Dim>
189 : 24 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::begin()
190 : : const {
191 : 24 : return indices_m;
192 : : }
193 : :
194 : : template <unsigned Dim>
195 : 24 : KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::end()
196 : : const {
197 : 24 : return indices_m + Dim;
198 : : }
199 : :
200 : : template <unsigned Dim>
201 : : bool operator==(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
202 : : for (unsigned d = 0; d < Dim; d++) {
203 : : if (nd1[d] != nd2[d]) {
204 : : return false;
205 : : }
206 : : }
207 : : return true;
208 : : }
209 : :
210 : : template <unsigned Dim>
211 : : bool operator!=(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
212 : : return !(nd1 == nd2);
213 : : }
214 : : } // namespace ippl
|