Branch data 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 [ + - ]: 4112 : 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 : 4848 : ~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 : 24 : 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 : 1878 : int getNghost() const { return nghost_m; }
126 : :
127 : : void fillHalo();
128 : : void accumulateHalo();
129 : :
130 : 1850 : auto& getCommunicator() const { return getLayout().comm; }
131 : :
132 : : // Access to the layout.
133 : 3242 : Layout_t& getLayout() const {
134 [ - + ]: 3242 : PAssert(layout_m != 0);
135 : 3242 : return *layout_m;
136 : : }
137 : :
138 : : const Index& getIndex(unsigned d) const { return getLayout().getDomain()[d]; }
139 : 0 : const NDIndex<Dim>& getDomain() const { return getLayout().getDomain(); }
140 : :
141 : 0 : halo_type& getHalo() { return halo_m; }
142 : :
143 : : // Assignment from a constant.
144 : : BareField& operator=(T x);
145 : :
146 : : /*!
147 : : * Assign an arbitrary BareField expression
148 : : * @tparam E expression type
149 : : * @tparam N size of the expression, this is necessary for running on the
150 : : * device since otherwise it does not allocate enough memory
151 : : * @param expr is the expression
152 : : */
153 : : template <typename E, size_t N>
154 : : BareField& operator=(const detail::Expression<E, N>& expr);
155 : :
156 : : /*!
157 : : * Assign another field.
158 : : * @tparam Args... variadic template to specify an access index for
159 : : * a view element.
160 : : * @param args view indices
161 : : * @returns a view element
162 : : */
163 : : template <typename... Args>
164 : 51073088 : KOKKOS_INLINE_FUNCTION T operator()(Args... args) const {
165 : 102146176 : return dview_m(args...);
166 : : }
167 : :
168 : 1140 : view_type& getView() { return dview_m; }
169 : :
170 : 48 : const view_type& getView() const { return dview_m; }
171 : :
172 : 152 : HostMirror getHostMirror() const { return Kokkos::create_mirror(dview_m); }
173 : :
174 : : /*!
175 : : * Generate the range policy for iterating over the field,
176 : : * excluding ghost layers
177 : : * @tparam PolicyArgs... additional template parameters for the range policy
178 : : * @param nghost Number of ghost layers to include in the range policy (default 0)
179 : : * @return Range policy for iterating over the field and nghost of the ghost layers
180 : : */
181 : : template <class... PolicyArgs>
182 : 132 : policy_type<execution_space, PolicyArgs...> getFieldRangePolicy(
183 : : const int nghost = 0) const {
184 [ - + ]: 132 : PAssert_LE(nghost, nghost_m);
185 : 132 : const size_t shift = nghost_m - nghost;
186 [ + - + - ]: 132 : return getRangePolicy(dview_m, shift);
187 : : }
188 : :
189 : : /*!
190 : : * Print the BareField.
191 : : * @param out stream
192 : : */
193 : : void write(std::ostream& out = std::cout) const;
194 : :
195 : : /*!
196 : : * Print the BareField
197 : : * @param inf Inform object
198 : : */
199 : : void write(Inform& inf) const;
200 : :
201 : : T sum(int nghost = 0) const;
202 : : T max(int nghost = 0) const;
203 : : T min(int nghost = 0) const;
204 : : T prod(int nghost = 0) const;
205 : :
206 : : private:
207 : : //! Number of ghost layers on each field boundary
208 : : int nghost_m;
209 : :
210 : : //! Actual field data
211 : : view_type dview_m;
212 : :
213 : : //! Domain of the data
214 : : Domain_t owned_m;
215 : :
216 : : halo_type halo_m;
217 : :
218 : : /*!
219 : : * Allocate field.
220 : : */
221 : : void setup();
222 : :
223 : : //! How the arrays are laid out.
224 : : Layout_t* layout_m = nullptr;
225 : : };
226 : :
227 : : } // namespace ippl
228 : :
229 : : #include "Field/BareField.hpp"
230 : : #include "Field/BareFieldOperations.hpp"
231 : :
232 : : #endif
|