Line data Source code
1 : //
2 : // Class BareField
3 : // A BareField represents a field.
4 : //
5 : #ifndef IPPL_BARE_FIELD_H
6 : #define IPPL_BARE_FIELD_H
7 :
8 : #include <Kokkos_Core.hpp>
9 :
10 : #include <cstdlib>
11 : #include <iostream>
12 :
13 : #include "Types/IpplTypes.h"
14 :
15 : #include "Utility/IpplInfo.h"
16 : #include "Utility/PAssert.h"
17 : #include "Utility/ViewUtils.h"
18 :
19 : #include "Expression/IpplExpressions.h"
20 :
21 : #include "Field/HaloCells.h"
22 : #include "FieldLayout/FieldLayout.h"
23 :
24 : namespace ippl {
25 : class Index;
26 :
27 : /*!
28 : * @file BareField.h
29 : * A BareField represents a real field.
30 : */
31 :
32 : /*!
33 : * @class BareField
34 : * @tparam T data type
35 : * @tparam Dim field dimension
36 : * @warning The implementation currently only supports 3-dimensional fields. The reason are
37 : * runtime issues with "if constrexpr" in the assignment operator when running on GPU.
38 : */
39 : template <typename T, unsigned Dim, class... ViewArgs>
40 : class BareField : public detail::Expression<
41 : BareField<T, Dim, ViewArgs...>,
42 : sizeof(typename detail::ViewType<T, Dim, ViewArgs...>::view_type)> {
43 : public:
44 : using Layout_t = FieldLayout<Dim>;
45 :
46 : //! Domain type specifying the index region
47 : using Domain_t = NDIndex<Dim>;
48 :
49 : //! View type storing the data
50 : using view_type = typename detail::ViewType<T, Dim, ViewArgs...>::view_type;
51 : typedef typename view_type::memory_space memory_space;
52 : typedef typename view_type::execution_space execution_space;
53 : using HostMirror = typename view_type::host_mirror_type;
54 : template <class... PolicyArgs>
55 : using policy_type = typename RangePolicy<Dim, PolicyArgs...>::policy_type;
56 :
57 : using halo_type = detail::HaloCells<T, Dim, ViewArgs...>;
58 :
59 : using value_type = T;
60 : constexpr static unsigned dim = Dim;
61 :
62 : /*! A default constructor, which should be used only if the user calls the
63 : * 'initialize' function before doing anything else. There are no special
64 : * checks in the rest of the BareField methods to check that the field has
65 : * been properly initialized.
66 : */
67 : BareField();
68 :
69 8424 : BareField(const BareField&) = default;
70 :
71 : /*! Constructor for a BareField. The default constructor is deleted.
72 : * @param l of field
73 : * @param nghost number of ghost layers
74 : */
75 : BareField(Layout_t& l, int nghost = 1);
76 :
77 : /*!
78 : * Creates a new BareField with the same properties and contents
79 : * @return A deep copy of the field
80 : */
81 : BareField deepCopy() const;
82 :
83 : // Destroy the BareField.
84 9980 : ~BareField() = default;
85 :
86 : /*!
87 : * Dimension independent view resize function which calls Kokkos.
88 : * @tparam Args... variadic template specifying the individiual
89 : * dimension arguments
90 : */
91 : template <typename... Args>
92 : void resize(Args... args);
93 :
94 : /*!
95 : * Initialize the field, if it was constructed from the default constructor.
96 : * This should NOT be called if the field was constructed by providing
97 : * a FieldLayout.
98 : * @param l of field
99 : * @param nghost number of ghost layers
100 : */
101 : void initialize(Layout_t& l, int nghost = 1);
102 :
103 : // ML
104 : void updateLayout(Layout_t&, int nghost = 1);
105 :
106 : /*!
107 : * Local field size.
108 : * @param d the dimension
109 : * @returns the number of grid points in the given dimension.
110 : */
111 : detail::size_type size(unsigned d) const { return owned_m[d].length(); }
112 :
113 : /*!
114 : * Index domain of the local field.
115 : * @returns the index domain.
116 : */
117 96 : const Domain_t& getOwned() const { return owned_m; }
118 :
119 : /*!
120 : * Index domain of the allocated field.
121 : * @returns the allocated index domain (including ghost cells)
122 : */
123 : const Domain_t getAllocated() const { return owned_m.grow(nghost_m); }
124 :
125 3852 : int getNghost() const { return nghost_m; }
126 :
127 : void fillHalo();
128 : void accumulateHalo();
129 : void accumulateHalo_noghost(int nghost = 1);
130 :
131 4428 : auto& getCommunicator() const { return getLayout().comm; }
132 :
133 : // Access to the layout.
134 7960 : Layout_t& getLayout() const {
135 7960 : PAssert(layout_m != 0);
136 7960 : return *layout_m;
137 : }
138 :
139 : const Index& getIndex(unsigned d) const { return getLayout().getDomain()[d]; }
140 0 : const NDIndex<Dim>& getDomain() const { return getLayout().getDomain(); }
141 :
142 192 : halo_type& getHalo() { return halo_m; }
143 :
144 : // Assignment from a constant.
145 : BareField& operator=(T x);
146 :
147 : /*!
148 : * Assign an arbitrary BareField expression
149 : * @tparam E expression type
150 : * @tparam N size of the expression, this is necessary for running on the
151 : * device since otherwise it does not allocate enough memory
152 : * @param expr is the expression
153 : */
154 : template <typename E, size_t N>
155 : BareField& operator=(const detail::Expression<E, N>& expr);
156 :
157 : /*!
158 : * Assign another field.
159 : * @tparam Args... variadic template to specify an access index for
160 : * a view element.
161 : * @param args view indices
162 : * @returns a view element
163 : */
164 : template <typename... Args>
165 51517028 : KOKKOS_INLINE_FUNCTION T operator()(Args... args) const {
166 103034056 : return dview_m(args...);
167 : }
168 :
169 2408 : view_type& getView() { return dview_m; }
170 :
171 116 : const view_type& getView() const { return dview_m; }
172 :
173 304 : HostMirror getHostMirror() const { return Kokkos::create_mirror(dview_m); }
174 :
175 : /*!
176 : * Generate the range policy for iterating over the field,
177 : * excluding ghost layers
178 : * @tparam PolicyArgs... additional template parameters for the range policy
179 : * @param nghost Number of ghost layers to include in the range policy (default 0)
180 : * @return Range policy for iterating over the field and nghost of the ghost layers
181 : */
182 : template <class... PolicyArgs>
183 284 : policy_type<execution_space, PolicyArgs...> getFieldRangePolicy(
184 : const int nghost = 0) const {
185 284 : PAssert_LE(nghost, nghost_m);
186 284 : const size_t shift = nghost_m - nghost;
187 284 : return getRangePolicy(dview_m, shift);
188 : }
189 :
190 : /*!
191 : * Print the BareField.
192 : * @param out stream
193 : */
194 : void write(std::ostream& out = std::cout) const;
195 :
196 : /*!
197 : * Print the BareField
198 : * @param inf Inform object
199 : */
200 : void write(Inform& inf) const;
201 :
202 : T sum(int nghost = 0) const;
203 : T max(int nghost = 0) const;
204 : T min(int nghost = 0) const;
205 : T prod(int nghost = 0) const;
206 :
207 : private:
208 : //! Number of ghost layers on each field boundary
209 : int nghost_m;
210 :
211 : //! Actual field data
212 : view_type dview_m;
213 :
214 : //! Domain of the data
215 : Domain_t owned_m;
216 :
217 : halo_type halo_m;
218 :
219 : /*!
220 : * Allocate field.
221 : */
222 : void setup();
223 :
224 : //! How the arrays are laid out.
225 : Layout_t* layout_m = nullptr;
226 : };
227 :
228 : } // namespace ippl
229 :
230 : #include "Field/BareField.hpp"
231 : #include "Field/BareFieldOperations.hpp"
232 :
233 : #endif
|