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 [ + - ]: 4132 : 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 : 4888 : ~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 : 1894 : int getNghost() const { return nghost_m; }
126 : :
127 : : void fillHalo();
128 : : void accumulateHalo();
129 : : void accumulateHalo_noghost(int nghost = 1);
130 : :
131 : 1858 : auto& getCommunicator() const { return getLayout().comm; }
132 : :
133 : : // Access to the layout.
134 : 3344 : Layout_t& getLayout() const {
135 [ - + ]: 3344 : PAssert(layout_m != 0);
136 : 3344 : 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 : 0 : 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 : 51073228 : KOKKOS_INLINE_FUNCTION T operator()(Args... args) const {
166 : 102146456 : return dview_m(args...);
167 : : }
168 : :
169 : 1176 : view_type& getView() { return dview_m; }
170 : :
171 : 50 : const view_type& getView() const { return dview_m; }
172 : :
173 : 152 : 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 : 134 : policy_type<execution_space, PolicyArgs...> getFieldRangePolicy(
184 : : const int nghost = 0) const {
185 [ - + ]: 134 : PAssert_LE(nghost, nghost_m);
186 : 134 : const size_t shift = nghost_m - nghost;
187 [ + - + - ]: 134 : 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
|