Gyselalib++
 
Loading...
Searching...
No Matches
derivative_field.hpp
1// SPDX-License-Identifier: MIT
2
3#pragma once
4#include <ddc/ddc.hpp>
5
6#include "ddc_aliases.hpp"
7#include "derivative_field_common.hpp"
8
9template <class, class, int, class>
11
15template <
16 class ElementType,
17 class SupportType,
18 class MemorySpace = Kokkos::HostSpace,
19 class LayoutStridedPolicy = Kokkos::layout_right>
21
22template <class ElementType, class SupportType, class MemorySpace, class LayoutStridedPolicy>
23inline constexpr bool enable_deriv_field<
25
26template <class ElementType, class SupportType, class MemorySpace, class LayoutStridedPolicy>
27inline constexpr bool enable_borrowed_deriv_field<
29
30template <class ElementType, class SupportType, class MemorySpace, class LayoutStridedPolicy>
31inline constexpr bool enable_data_access_methods<
33
34namespace ddcHelper {
35
42template <
43 class FieldDst,
44 class FieldSrc,
45 std::enable_if_t<
46 is_borrowed_deriv_field_v<FieldDst> && is_borrowed_deriv_field_v<FieldSrc>,
47 bool> = true>
48auto deepcopy(FieldDst&& dst, FieldSrc&& src)
49{
50 assert(dst.get_values_field().domain().extents() == src.get_values_field().domain().extents());
51
52 DerivField dst_field = get_field(dst);
53 DerivField src_field = get_field(src);
54
55 dst_field.deepcopy(src_field);
56
57 return dst_field;
58}
59
67template <class ExecSpace, class FieldDst, class FieldSrc>
68auto deepcopy(ExecSpace const& execution_space, FieldDst&& dst, FieldSrc&& src)
69{
70 static_assert(is_borrowed_deriv_field_v<FieldDst>);
71 static_assert(is_borrowed_deriv_field_v<FieldSrc>);
72
73 assert(dst.get_values_field().idx_range().extents()
74 == src.get_values_field().idx_range().extents());
75
76 DerivField dst_field = get_field(dst);
77 DerivField src_field = get_field(src);
78
79 dst_field.deepcopy(execution_space, src_field);
80
81 return dst_field;
82}
83
84} // namespace ddcHelper
85
102template <class ElementType, class... DDims, class MemorySpace, class LayoutStridedPolicy>
103class DerivField<ElementType, IdxRange<DDims...>, MemorySpace, LayoutStridedPolicy>
104 : public DerivFieldCommon<
105 Field<ElementType, IdxRange<DDims...>, MemorySpace, LayoutStridedPolicy>,
106 IdxRange<DDims...>>
107{
108private:
111 Field<ElementType, IdxRange<DDims...>, MemorySpace, LayoutStridedPolicy>,
112 IdxRange<DDims...>>;
113
114public:
116 using element_type = typename base_type::element_type;
117
124 using discrete_domain_type = typename base_type::discrete_domain_type;
126 using index_range_type = typename base_type::index_range_type;
127
134 using discrete_element_type = typename base_type::discrete_element_type;
135
137 using deriv_tags = typename base_type::deriv_tags;
138
140 using physical_deriv_grids = typename detail::strip_deriv_t<deriv_tags>;
141
143 using physical_grids = typename base_type::physical_grids;
144
146 using physical_idx_range_type = typename base_type::physical_idx_range_type;
147
155 using chunk_type = typename base_type::chunk_type;
156
158 using span_type = DerivField<ElementType, IdxRange<DDims...>, MemorySpace, LayoutStridedPolicy>;
159
162 = DerivField<ElementType const, IdxRange<DDims...>, MemorySpace, LayoutStridedPolicy>;
163
164private:
166 using discrete_deriv_idx_range_type = typename base_type::discrete_deriv_idx_range_type;
167
171 using discrete_deriv_index_type = typename base_type::discrete_deriv_index_type;
172
174 using reference = typename chunk_type::reference;
175
177 using base_type::n_fields;
178
179private:
183 template <std::size_t ArrayIndex, class Tag>
184 KOKKOS_FUNCTION constexpr Idx<Tag> get_chunk_subidx_range_1d_idx()
185 {
186 // The Tag describes a dimension for which a derivative is defined
187 if constexpr (ddc::in_tags_v<Tag, deriv_tags>) {
188 // If the Field at this index contains the derivatives of this dimension
189 if constexpr (ArrayIndex & (1 << ddc::type_seq_rank_v<Tag, deriv_tags>)) {
190 return Idx<Tag>(1);
191 }
192 // If the Field at this index doesn't contain derivatives of this dimension
193 else {
194 return Idx<Tag>(0);
195 }
196 } else {
197 // Empty IdxRange to be discarded
198 return Idx<Tag>();
199 }
200 }
201
203 template <std::size_t ArrayIndex>
204 KOKKOS_FUNCTION constexpr discrete_deriv_index_type get_chunk_subidx_range_idx()
205 {
206 return discrete_deriv_index_type(get_chunk_subidx_range_1d_idx<ArrayIndex, DDims>()...);
207 }
208
210 template <class Field, std::size_t... ArrayIndex>
211 KOKKOS_FUNCTION constexpr void initialise_fields(
212 Field const& chunks,
213 std::index_sequence<ArrayIndex...>)
214 {
215 ((base_type::internal_fields[ArrayIndex] = chunks.internal_fields[chunks.get_array_index(
216 get_chunk_subidx_range_idx<ArrayIndex>())]),
217 ...);
218 }
219
220 auto get_kokkos_view_from_internal_chunk(int index)
221 {
222 typename base_type::internal_mdspan_type field = base_type::internal_fields[index];
223 auto kokkos_layout = ddc::detail::build_kokkos_layout(
224 field.extents(),
225 field.mapping(),
226 std::make_index_sequence<sizeof...(DDims)> {});
227 return Kokkos::View<
228 ddc::detail::mdspan_to_kokkos_element_t<ElementType, sizeof...(DDims)>,
229 decltype(kokkos_layout),
230 MemorySpace>(field.data_handle(), kokkos_layout);
231 }
232
233public:
239 KOKKOS_DEFAULTED_FUNCTION constexpr DerivField(DerivField const& other) = default;
240
246 KOKKOS_DEFAULTED_FUNCTION constexpr DerivField(DerivField&& other) = default;
247
253 template <
254 class OElementType,
255 int NDerivs,
256 class Allocator,
257 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
258 explicit constexpr DerivField(
260 : base_type(
261 field.m_physical_idx_range,
262 field.m_deriv_idx_range,
263 field.m_cross_derivative_idx_range)
264 {
265 initialise_fields(field, std::make_integer_sequence<std::size_t, n_fields> {});
266 }
267
273 // Disabled by SFINAE if `ElementType` is not `const` to avoid write access
274 template <
275 class OElementType,
276 class SFINAEElementType = ElementType,
277 class = std::enable_if_t<std::is_const_v<SFINAEElementType>>,
278 int NDerivs,
279 class Allocator,
280 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
281 explicit constexpr DerivField(
283 : base_type(
284 field.m_physical_idx_range,
285 field.m_deriv_idx_range,
286 field.m_cross_derivative_idx_range)
287 {
288 initialise_fields(field, std::make_integer_sequence<std::size_t, n_fields> {});
289 }
290
297 template <class OElementType>
298 KOKKOS_FUNCTION constexpr DerivField(
300 field)
301 : base_type(
302 field.m_physical_idx_range,
303 field.m_deriv_idx_range,
304 field.m_cross_derivative_idx_range)
305 {
306 initialise_fields(field, std::make_integer_sequence<std::size_t, n_fields> {});
307 }
308
309 KOKKOS_DEFAULTED_FUNCTION ~DerivField() = default;
310
315 KOKKOS_DEFAULTED_FUNCTION constexpr DerivField& operator=(DerivField const& other) = default;
316
321 KOKKOS_DEFAULTED_FUNCTION constexpr DerivField& operator=(DerivField&& other) = default;
322
328 template <class OElementType, class OLayoutStridedPolicy, class OMemorySpace>
331 {
332 for (int i(0); i < n_fields; ++i) {
333 auto kokkos_span = get_kokkos_view_from_internal_chunk(i);
334 auto src_kokkos_span = src.get_kokkos_view_from_internal_chunk(i);
335 Kokkos::deep_copy(kokkos_span, src_kokkos_span);
336 }
337 }
338
345 template <class ExecSpace, class OElementType, class OMemorySpace, class OLayoutStridedPolicy>
347 ExecSpace const& execution_space,
349 {
350 for (int i(0); i < n_fields; ++i) {
351 auto kokkos_span = get_kokkos_view_from_internal_chunk(i);
352 auto src_kokkos_span = src.get_kokkos_view_from_internal_chunk(i);
353 Kokkos::deep_copy(execution_space, kokkos_span, src_kokkos_span);
354 }
355 }
356
366 template <class... DElem>
367 KOKKOS_FUNCTION constexpr reference operator()(DElem... elems) const noexcept
368 {
369 static_assert((ddc::is_discrete_element_v<DElem> && ...));
370 using full_index_type = detail::combine_t<DElem...>;
371 full_index_type elem(elems...);
372 return base_type::get_internal_field(elem)();
373 }
374
383 KOKKOS_FUNCTION constexpr view_type span_cview() const
384 {
385 return view_type(*this);
386 }
387
396 KOKKOS_FUNCTION constexpr span_type span_view() const
397 {
398 return *this;
399 }
400};
401
402template <
403 class ElementType,
404 class SupportType,
405 class MemorySpace = Kokkos::HostSpace,
406 class LayoutStridedPolicy = Kokkos::layout_right>
407using DerivConstField
409
410namespace detail {
411template <
412 class NewMemorySpace,
413 class ElementType,
414 class SupportType,
415 class MemorySpace,
416 class Layout>
417struct OnMemorySpace<NewMemorySpace, DerivField<ElementType, SupportType, MemorySpace, Layout>>
418{
420};
421}; // namespace detail
Definition derivative_field_common.hpp:31
See DerivFieldMemImplementation.
Definition derivative_field.hpp:10
A class which holds references to chunks of memory describing a field and its derivatives.
Definition derivative_field.hpp:107
KOKKOS_DEFAULTED_FUNCTION constexpr DerivField(DerivField const &other)=default
Copy-construct a DerivField.
typename base_type::element_type element_type
The type of the elements in the chunks.
Definition derivative_field.hpp:116
KOKKOS_FUNCTION constexpr reference operator()(DElem... elems) const noexcept
Get an element from a constant field.
Definition derivative_field.hpp:367
KOKKOS_DEFAULTED_FUNCTION constexpr DerivField & operator=(DerivField &&other)=default
Move-assigns a new value to this DerivField.
typename detail::strip_deriv_t< deriv_tags > physical_deriv_grids
A type sequence containing all grid types for which derivatives are present in this object.
Definition derivative_field.hpp:140
KOKKOS_FUNCTION constexpr view_type span_cview() const
Get a constant DerivField of this field.
Definition derivative_field.hpp:383
typename base_type::deriv_tags deriv_tags
A type sequence containing all derivatives present in this object.
Definition derivative_field.hpp:137
KOKKOS_DEFAULTED_FUNCTION constexpr DerivField & operator=(DerivField const &other)=default
Copy-assigns a new value to this DerivField, yields a new view to the same data.
KOKKOS_FUNCTION constexpr span_type span_view() const
Get a modifiable DerivField of this field.
Definition derivative_field.hpp:396
void deepcopy(ExecSpace const &execution_space, DerivField< OElementType, index_range_type, OMemorySpace, OLayoutStridedPolicy > src)
Copy the source DerivField into this DerivField using Kokkos::deep_copy.
Definition derivative_field.hpp:346
void deepcopy(DerivField< OElementType, index_range_type, OMemorySpace, OLayoutStridedPolicy > src)
Copy the source DerivField into this DerivField using Kokkos::deep_copy.
Definition derivative_field.hpp:329
typename base_type::chunk_type chunk_type
The type of the field stored in the array.
Definition derivative_field.hpp:155
typename base_type::index_range_type index_range_type
The IdxRange on which the fields in this object are defined.
Definition derivative_field.hpp:126
typename base_type::discrete_domain_type discrete_domain_type
The IdxRange on which the chunks in this object are defined.
Definition derivative_field.hpp:124
KOKKOS_FUNCTION constexpr DerivField(DerivField< OElementType, index_range_type, MemorySpace, LayoutStridedPolicy > const &field)
Copy construct a DerivField.
Definition derivative_field.hpp:298
typename base_type::physical_idx_range_type physical_idx_range_type
The physical index range on which the field is defined.
Definition derivative_field.hpp:146
typename base_type::discrete_element_type discrete_element_type
The Idx which can be used to index this object.
Definition derivative_field.hpp:134
constexpr DerivField(DerivFieldMem< OElementType, index_range_type, NDerivs, Allocator > &field)
Constructs a new DerivField containing a modifiable view on the data in a DerivFieldMem.
Definition derivative_field.hpp:258
typename base_type::physical_grids physical_grids
A type sequence containing all the grids on which the fields are defined.
Definition derivative_field.hpp:143
constexpr DerivField(DerivFieldMem< OElementType, index_range_type, NDerivs, Allocator > const &field)
Constructs a new DerivField containing a constant view on the data in a DerivFieldMem.
Definition derivative_field.hpp:281
KOKKOS_DEFAULTED_FUNCTION constexpr DerivField(DerivField &&other)=default
Move-construct a DerivField.
See DerivFieldImplementation.
Definition derivative_field.hpp:20