DDC 0.0.0

a discrete domain computation library

discrete_element.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <array>
8#include <cstddef>
9#include <ostream>
10#include <type_traits>
11#include <utility>
12
13#include "ddc/detail/macros.hpp"
14#include "ddc/detail/type_seq.hpp"
15#include "ddc/discrete_vector.hpp"
16
17namespace ddc {
18
19template <class...>
20class DiscreteElement;
21
22template <class T>
23struct is_discrete_element : std::false_type
24{
25};
26
27template <class... Tags>
28struct is_discrete_element<DiscreteElement<Tags...>> : std::true_type
29{
30};
31
32template <class T>
34
35
36namespace detail {
37
38template <class... Tags>
39struct ToTypeSeq<DiscreteElement<Tags...>>
40{
41 using type = TypeSeq<Tags...>;
42};
43
44} // namespace detail
45
48using DiscreteElementType = std::size_t;
49
50template <class Tag>
51KOKKOS_FUNCTION constexpr DiscreteElementType const& uid(DiscreteElement<Tag> const& tuple) noexcept
52{
53 return tuple.uid();
54}
55
56template <class Tag>
57KOKKOS_FUNCTION constexpr DiscreteElementType& uid(DiscreteElement<Tag>& tuple) noexcept
58{
59 return tuple.uid();
60}
61
62template <class QueryTag, class... Tags>
63KOKKOS_FUNCTION constexpr DiscreteElementType const& uid(
64 DiscreteElement<Tags...> const& tuple) noexcept
65{
66 return tuple.template uid<QueryTag>();
67}
68
69template <class QueryTag, class... Tags>
70KOKKOS_FUNCTION constexpr DiscreteElementType& uid(DiscreteElement<Tags...>& tuple) noexcept
71{
72 return tuple.template uid<QueryTag>();
73}
74
75template <class QueryTag, class... Tags>
76KOKKOS_FUNCTION constexpr DiscreteElementType const& uid_or(
77 DiscreteElement<Tags...> const& tuple,
78 DiscreteElementType const& default_value) noexcept
79{
80 return tuple.template uid_or<QueryTag>(default_value);
81}
82
83template <class... QueryTags, class... Tags>
84KOKKOS_FUNCTION constexpr DiscreteElement<QueryTags...> select(
85 DiscreteElement<Tags...> const& arr) noexcept
86{
87 return DiscreteElement<QueryTags...>(arr);
88}
89
90template <class... QueryTags, class... Tags>
91KOKKOS_FUNCTION constexpr DiscreteElement<QueryTags...> select(
92 DiscreteElement<Tags...>&& arr) noexcept
93{
94 return DiscreteElement<QueryTags...>(std::move(arr));
95}
96
98template <
99 class QueryTag,
100 class HeadDElem,
101 class... TailDElems,
102 std::enable_if_t<
103 is_discrete_element_v<HeadDElem> && (is_discrete_element_v<TailDElems> && ...),
104 int> = 1>
105KOKKOS_FUNCTION constexpr auto const& take(HeadDElem const& head, TailDElems const&... tail)
106{
107 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
108 if constexpr (type_seq_contains_v<detail::TypeSeq<QueryTag>, to_type_seq_t<HeadDElem>>) {
109 static_assert(
110 (!type_seq_contains_v<detail::TypeSeq<QueryTag>, to_type_seq_t<TailDElems>> && ...),
111 "ERROR: tag redundant");
112 return head;
113 } else {
114 static_assert(sizeof...(TailDElems) > 0, "ERROR: tag not found");
115 return take<QueryTag>(tail...);
116 }
117 DDC_IF_NVCC_THEN_POP
118}
119
120namespace detail {
121
123template <class... Tags>
124KOKKOS_FUNCTION constexpr std::array<DiscreteElementType, sizeof...(Tags)>& array(
125 DiscreteElement<Tags...>& v) noexcept
126{
127 return v.m_values;
128}
129
131template <class... Tags>
132KOKKOS_FUNCTION constexpr std::array<DiscreteElementType, sizeof...(Tags)> const& array(
133 DiscreteElement<Tags...> const& v) noexcept
134{
135 return v.m_values;
136}
137
138} // namespace detail
139
144template <class... Tags>
146{
147 using tags_seq = detail::TypeSeq<Tags...>;
148
149 friend KOKKOS_FUNCTION constexpr std::array<DiscreteElementType, sizeof...(Tags)>& detail::
150 array<Tags...>(DiscreteElement<Tags...>& v) noexcept;
151
152 friend KOKKOS_FUNCTION constexpr std::array<DiscreteElementType, sizeof...(Tags)> const&
153 detail::array<Tags...>(DiscreteElement<Tags...> const& v) noexcept;
154
155private:
156 std::array<DiscreteElementType, sizeof...(Tags)> m_values;
157
158public:
160
161 static KOKKOS_FUNCTION constexpr std::size_t size() noexcept
162 {
163 return sizeof...(Tags);
164 }
165
166public:
167 KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement() = default;
168
169 KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement const&) = default;
170
171 KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement&&) = default;
172
173 template <class... DElems, class = std::enable_if_t<(is_discrete_element_v<DElems> && ...)>>
174 explicit KOKKOS_FUNCTION constexpr DiscreteElement(DElems const&... delems) noexcept
175 : m_values {take<Tags>(delems...).template uid<Tags>()...}
176 {
177 }
178
179 template <
180 class... Params,
181 class = std::enable_if_t<(!is_discrete_element_v<Params> && ...)>,
182 class = std::enable_if_t<(std::is_integral_v<Params> && ...)>,
183 class = std::enable_if_t<sizeof...(Params) == sizeof...(Tags)>>
184 explicit KOKKOS_FUNCTION constexpr DiscreteElement(Params const&... params) noexcept
185 : m_values {static_cast<value_type>(params)...}
186 {
187 }
188
189 KOKKOS_DEFAULTED_FUNCTION ~DiscreteElement() = default;
190
191 KOKKOS_DEFAULTED_FUNCTION DiscreteElement& operator=(DiscreteElement const& other) = default;
192
193 KOKKOS_DEFAULTED_FUNCTION DiscreteElement& operator=(DiscreteElement&& other) = default;
194
195 template <class... OTags>
196 KOKKOS_FUNCTION constexpr DiscreteElement& operator=(
197 DiscreteElement<OTags...> const& other) noexcept
198 {
199 m_values = other.m_values;
200 return *this;
201 }
202
203 template <class... OTags>
204 KOKKOS_FUNCTION constexpr DiscreteElement& operator=(DiscreteElement<OTags...>&& other) noexcept
205 {
206 m_values = std::move(other.m_values);
207 return *this;
208 }
209
210 template <class QueryTag>
211 KOKKOS_FUNCTION constexpr value_type const& uid_or(value_type const& default_value) const&
212 {
213 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
214 if constexpr (in_tags_v<QueryTag, tags_seq>) {
215 return m_values[type_seq_rank_v<QueryTag, tags_seq>];
216 } else {
217 return default_value;
218 }
219 DDC_IF_NVCC_THEN_POP
220 }
221
222 template <class QueryTag>
223 KOKKOS_FUNCTION constexpr value_type& uid() noexcept
224 {
225 using namespace detail;
226 static_assert(in_tags_v<QueryTag, tags_seq>, "requested Tag absent from DiscreteElement");
227 return m_values[type_seq_rank_v<QueryTag, tags_seq>];
228 }
229
230 template <class QueryTag>
231 KOKKOS_FUNCTION constexpr value_type const& uid() const noexcept
232 {
233 using namespace detail;
234 static_assert(in_tags_v<QueryTag, tags_seq>, "requested Tag absent from DiscreteElement");
235 return m_values[type_seq_rank_v<QueryTag, tags_seq>];
236 }
237
238 template <std::size_t N = sizeof...(Tags)>
239 KOKKOS_FUNCTION constexpr std::enable_if_t<N == 1, value_type&> uid() noexcept
240 {
241 return m_values[0];
242 }
243
244 template <std::size_t N = sizeof...(Tags)>
245 KOKKOS_FUNCTION constexpr std::enable_if_t<N == 1, value_type const&> uid() const noexcept
246 {
247 return m_values[0];
248 }
249
250 template <std::size_t N = sizeof...(Tags), class = std::enable_if_t<N == 1>>
251 KOKKOS_FUNCTION constexpr DiscreteElement& operator++()
252 {
253 ++m_values[0];
254 return *this;
255 }
256
257 template <std::size_t N = sizeof...(Tags), class = std::enable_if_t<N == 1>>
258 KOKKOS_FUNCTION constexpr DiscreteElement operator++(int)
259 {
260 DiscreteElement const tmp = *this;
261 ++m_values[0];
262 return tmp;
263 }
264
265 template <std::size_t N = sizeof...(Tags), class = std::enable_if_t<N == 1>>
266 KOKKOS_FUNCTION constexpr DiscreteElement& operator--()
267 {
268 ++m_values[0];
269 return *this;
270 }
271
272 template <std::size_t N = sizeof...(Tags), class = std::enable_if_t<N == 1>>
273 KOKKOS_FUNCTION constexpr DiscreteElement operator--(int)
274 {
275 DiscreteElement const tmp = *this;
276 ++m_values[0];
277 return tmp;
278 }
279
280 template <class... OTags>
281 KOKKOS_FUNCTION constexpr DiscreteElement& operator+=(DiscreteVector<OTags...> const& rhs)
282 {
283 static_assert(((type_seq_contains_v<detail::TypeSeq<OTags>, tags_seq>)&&...));
284 ((m_values[type_seq_rank_v<OTags, tags_seq>] += rhs.template get<OTags>()), ...);
285 return *this;
286 }
287
288 template <
289 class IntegralType,
290 std::size_t N = sizeof...(Tags),
291 class = std::enable_if_t<N == 1>,
292 class = std::enable_if_t<std::is_integral_v<IntegralType>>>
293 KOKKOS_FUNCTION constexpr DiscreteElement& operator+=(IntegralType const& rhs)
294 {
295 m_values[0] += rhs;
296 return *this;
297 }
298
299 template <class... OTags>
300 KOKKOS_FUNCTION constexpr DiscreteElement& operator-=(DiscreteVector<OTags...> const& rhs)
301 {
302 static_assert(((type_seq_contains_v<detail::TypeSeq<OTags>, tags_seq>)&&...));
303 ((m_values[type_seq_rank_v<OTags, tags_seq>] -= rhs.template get<OTags>()), ...);
304 return *this;
305 }
306
307 template <
308 class IntegralType,
309 std::size_t N = sizeof...(Tags),
310 class = std::enable_if_t<N == 1>,
311 class = std::enable_if_t<std::is_integral_v<IntegralType>>>
312 KOKKOS_FUNCTION constexpr DiscreteElement& operator-=(IntegralType const& rhs)
313 {
314 m_values[0] -= rhs;
315 return *this;
316 }
317};
318
319inline std::ostream& operator<<(std::ostream& out, DiscreteElement<> const&)
320{
321 out << "()";
322 return out;
323}
324
325template <class Head, class... Tags>
326std::ostream& operator<<(std::ostream& out, DiscreteElement<Head, Tags...> const& arr)
327{
328 out << "(";
329 out << uid<Head>(arr);
330 ((out << ", " << uid<Tags>(arr)), ...);
331 out << ")";
332 return out;
333}
334
335
336template <class... Tags, class... OTags>
337KOKKOS_FUNCTION constexpr bool operator==(
338 DiscreteElement<Tags...> const& lhs,
339 DiscreteElement<OTags...> const& rhs) noexcept
340{
341 return ((lhs.template uid<Tags>() == rhs.template uid<Tags>()) && ...);
342}
343
344template <class... Tags, class... OTags>
345KOKKOS_FUNCTION constexpr bool operator!=(
346 DiscreteElement<Tags...> const& lhs,
347 DiscreteElement<OTags...> const& rhs) noexcept
348{
349 return !(lhs == rhs);
350}
351
352template <class Tag>
353KOKKOS_FUNCTION constexpr bool operator<(
354 DiscreteElement<Tag> const& lhs,
355 DiscreteElement<Tag> const& rhs)
356{
357 return lhs.uid() < rhs.uid();
358}
359
360template <class Tag>
361KOKKOS_FUNCTION constexpr bool operator<=(
362 DiscreteElement<Tag> const& lhs,
363 DiscreteElement<Tag> const& rhs)
364{
365 return lhs.uid() <= rhs.uid();
366}
367
368template <class Tag>
369KOKKOS_FUNCTION constexpr bool operator>(
370 DiscreteElement<Tag> const& lhs,
371 DiscreteElement<Tag> const& rhs)
372{
373 return lhs.uid() > rhs.uid();
374}
375
376template <class Tag>
377KOKKOS_FUNCTION constexpr bool operator>=(
378 DiscreteElement<Tag> const& lhs,
379 DiscreteElement<Tag> const& rhs)
380{
381 return lhs.uid() >= rhs.uid();
382}
383
385
386template <class... Tags, class... OTags>
387KOKKOS_FUNCTION constexpr DiscreteElement<Tags...> operator+(
388 DiscreteElement<Tags...> const& lhs,
389 DiscreteVector<OTags...> const& rhs)
390{
391 using detail::TypeSeq;
392 static_assert(((type_seq_contains_v<TypeSeq<OTags>, TypeSeq<Tags...>>)&&...));
393 DiscreteElement<Tags...> result(lhs);
394 result += rhs;
395 return result;
396}
397
398template <
399 class Tag,
400 class IntegralType,
401 class = std::enable_if_t<std::is_integral_v<IntegralType>>,
402 class = std::enable_if_t<!is_discrete_vector_v<IntegralType>>>
403KOKKOS_FUNCTION constexpr DiscreteElement<Tag> operator+(
404 DiscreteElement<Tag> const& lhs,
405 IntegralType const& rhs)
406{
407 return DiscreteElement<Tag>(uid<Tag>(lhs) + rhs);
408}
409
410template <class... Tags, class... OTags>
411KOKKOS_FUNCTION constexpr DiscreteElement<Tags...> operator-(
412 DiscreteElement<Tags...> const& lhs,
413 DiscreteVector<OTags...> const& rhs)
414{
415 using detail::TypeSeq;
416 static_assert(((type_seq_contains_v<TypeSeq<OTags>, TypeSeq<Tags...>>)&&...));
417 DiscreteElement<Tags...> result(lhs);
418 result -= rhs;
419 return result;
420}
421
422template <
423 class Tag,
424 class IntegralType,
425 class = std::enable_if_t<std::is_integral_v<IntegralType>>,
426 class = std::enable_if_t<!is_discrete_vector_v<IntegralType>>>
427KOKKOS_FUNCTION constexpr DiscreteElement<Tag> operator-(
428 DiscreteElement<Tag> const& lhs,
429 IntegralType const& rhs)
430{
431 return DiscreteElement<Tag>(uid<Tag>(lhs) - rhs);
432}
433
435
436template <class... Tags, class... OTags>
437KOKKOS_FUNCTION constexpr DiscreteVector<Tags...> operator-(
438 DiscreteElement<Tags...> const& lhs,
439 DiscreteElement<OTags...> const& rhs)
440{
441 static_assert(type_seq_same_v<detail::TypeSeq<Tags...>, detail::TypeSeq<OTags...>>);
442 return DiscreteVector<Tags...>((uid<Tags>(lhs) - uid<Tags>(rhs))...);
443}
444
445} // namespace ddc
A DiscreteElement identifies an element of the discrete dimension.
Definition: discrete_element.hpp:146
KOKKOS_FUNCTION constexpr DiscreteElement & operator+=(DiscreteVector< OTags... > const &rhs)
Definition: discrete_element.hpp:281
KOKKOS_FUNCTION constexpr value_type const & uid() const noexcept
Definition: discrete_element.hpp:231
KOKKOS_FUNCTION constexpr value_type & uid() noexcept
Definition: discrete_element.hpp:223
KOKKOS_DEFAULTED_FUNCTION ~DiscreteElement()=default
KOKKOS_FUNCTION constexpr DiscreteElement & operator=(DiscreteElement< OTags... > const &other) noexcept
Definition: discrete_element.hpp:196
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement const &)=default
KOKKOS_FUNCTION constexpr DiscreteElement(DElems const &... delems) noexcept
Definition: discrete_element.hpp:174
KOKKOS_FUNCTION constexpr value_type const & uid_or(value_type const &default_value) const &
Definition: discrete_element.hpp:211
KOKKOS_FUNCTION constexpr DiscreteElement & operator-=(DiscreteVector< OTags... > const &rhs)
Definition: discrete_element.hpp:300
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement()=default
DiscreteElementType value_type
Definition: discrete_element.hpp:159
KOKKOS_DEFAULTED_FUNCTION DiscreteElement & operator=(DiscreteElement const &other)=default
KOKKOS_FUNCTION constexpr std::enable_if_t< N==1, value_type & > uid() noexcept
Definition: discrete_element.hpp:239
KOKKOS_FUNCTION constexpr DiscreteElement & operator=(DiscreteElement< OTags... > &&other) noexcept
Definition: discrete_element.hpp:204
static KOKKOS_FUNCTION constexpr std::size_t size() noexcept
Definition: discrete_element.hpp:161
KOKKOS_FUNCTION constexpr std::enable_if_t< N==1, value_type const & > uid() const noexcept
Definition: discrete_element.hpp:245
KOKKOS_DEFAULTED_FUNCTION DiscreteElement & operator=(DiscreteElement &&other)=default
KOKKOS_FUNCTION constexpr DiscreteElement(Params const &... params) noexcept
Definition: discrete_element.hpp:184
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement(DiscreteElement &&)=default
A DiscreteVector is a vector in the discrete dimension.
Definition: discrete_vector.hpp:254
The top-level namespace of DDC.
Definition: aligned_allocator.hpp:11
KOKKOS_FUNCTION constexpr bool operator<(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
Definition: discrete_element.hpp:353
KOKKOS_FUNCTION constexpr DiscreteElementType const & uid_or(DiscreteElement< Tags... > const &tuple, DiscreteElementType const &default_value) noexcept
Definition: discrete_element.hpp:76
constexpr bool operator!=(AlignedAllocator< T, NT > const &, AlignedAllocator< U, NU > const &) noexcept
Definition: aligned_allocator.hpp:65
KOKKOS_FUNCTION constexpr auto const & take(HeadDElem const &head, TailDElems const &... tail)
Returns a reference towards the DiscreteElement that contains the QueryTag.
Definition: discrete_element.hpp:105
std::size_t DiscreteElementType
A DiscreteCoordElement is a scalar that identifies an element of the discrete dimension.
Definition: discrete_element.hpp:48
constexpr bool is_discrete_vector_v
Definition: discrete_vector.hpp:34
KOKKOS_FUNCTION constexpr DiscreteElementType const & uid(DiscreteElement< Tag > const &tuple) noexcept
Definition: discrete_element.hpp:51
KOKKOS_FUNCTION constexpr DiscreteElement< Tags... > operator+(DiscreteElement< Tags... > const &lhs, DiscreteVector< OTags... > const &rhs)
right external binary operators: +, -
Definition: discrete_element.hpp:387
std::ostream & operator<<(std::ostream &out, DiscreteElement<> const &)
Definition: discrete_element.hpp:319
constexpr bool is_discrete_element_v
Definition: discrete_element.hpp:33
KOKKOS_FUNCTION constexpr bool operator>=(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
Definition: discrete_element.hpp:377
KOKKOS_FUNCTION constexpr bool operator<=(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
Definition: discrete_element.hpp:361
KOKKOS_FUNCTION constexpr bool operator>(DiscreteElement< Tag > const &lhs, DiscreteElement< Tag > const &rhs)
Definition: discrete_element.hpp:369
constexpr bool operator==(AlignedAllocator< T, NT > const &, AlignedAllocator< U, NU > const &) noexcept
Definition: aligned_allocator.hpp:59
KOKKOS_FUNCTION constexpr DiscreteElement< Tags... > operator-(DiscreteElement< Tags... > const &lhs, DiscreteVector< OTags... > const &rhs)
Definition: discrete_element.hpp:411
KOKKOS_FUNCTION constexpr DiscreteDomain< QueryDDims... > select(DiscreteDomain< DDims... > const &domain)
Definition: discrete_domain.hpp:366
Definition: discrete_element.hpp:24