IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
TypeUtils.h
Go to the documentation of this file.
1//
2// Type Utilities
3// Metaprogramming utility functions for type manipulation
4//
5
6#ifndef IPPL_TYPE_UTILS_H
7#define IPPL_TYPE_UTILS_H
8
9#include <Kokkos_Core.hpp>
10
11#include "Types/Variant.h"
12
14
15namespace ippl {
16 namespace detail {
17
24 template <typename Check, typename... Collection>
25 struct IsUnique {
26 constexpr static bool enable = !std::disjunction_v<std::is_same<Check, Collection>...>;
27 typedef Check type;
28 };
29
38 template <template <typename> class Wrapper>
39 struct WrapUnique {
40 template <typename Check, typename... Collection>
41 struct Verifier {
42 typedef Wrapper<Check> type;
43 constexpr static bool enable =
44 !std::disjunction_v<std::is_same<type, Collection>...>;
45 };
46 };
47
55 template <bool B, typename T>
56 using ConditionalType = std::conditional_t<B, T, void>;
57
65 template <typename Type, typename...>
66 struct IsEnabled {
67 constexpr static bool enable = !std::is_void_v<Type>;
68 typedef Type type;
69 };
70
74 template <typename, typename, template <typename...> class Verifier = IsUnique>
76
80 template <template <typename...> class Verifier>
81 struct ConstructVariant<std::variant<>, std::variant<>, Verifier> {
82 typedef std::variant<> type;
83 };
84
89 template <typename... T, template <typename...> class Verifier>
90 struct ConstructVariant<std::variant<>, std::variant<T...>, Verifier> {
91 typedef std::variant<T...> type;
92 };
93
119 template <typename Next, typename... ToAdd, typename... Added,
120 template <typename...> class Verifier>
121 struct ConstructVariant<std::variant<Next, ToAdd...>, std::variant<Added...>, Verifier> {
122 // Convenience aliases
123 template <bool B, class T, class F>
124 using cond = std::conditional_t<B, T, F>;
125 template <typename... T>
126 using variant = std::variant<T...>;
127
128 using Check = Verifier<Next, Added...>;
129
130 typedef cond<
131 Check::enable,
132 // The verifier has indicated that this type should be added
133 typename ConstructVariant<variant<ToAdd...>,
134 variant<typename Check::type, Added...>, Verifier>::type,
135 // The verifier has indicated that the type should not be added
136 typename ConstructVariant<variant<ToAdd...>, variant<Added...>, Verifier>::type>
138 };
139
145 template <typename... Types>
147 typename ConstructVariant<std::variant<Types...>, std::variant<>, IsEnabled>::type;
148
153 template <typename... Types>
155 typename ConstructVariant<std::variant<Types...>, std::variant<>, IsUnique>::type;
156
166 template <template <typename...> class Verifier, typename... Types>
168 typename ConstructVariant<std::variant<Types...>, std::variant<>, Verifier>::type;
169
176 template <template <typename...> class Type, typename Pack>
177 struct Forward;
178
182 template <template <typename...> class Type, typename... Spaces>
183 struct Forward<Type, std::variant<Spaces...>> {
184 using type = Type<Spaces...>;
185 };
186
190 template <template <typename...> class Type, typename T, typename... Properties>
191 struct Forward<Type, Kokkos::View<T, Properties...>> {
192 using type = Type<Properties...>;
193 };
194
202 template <template <typename...> class Type, typename View>
204 using view_type = typename View::uniform_type;
206 };
207
211 template <template <typename...> class Type>
214 Kokkos::HostSpace, Kokkos::SharedSpace, Kokkos::SharedHostPinnedSpace
215#ifdef KOKKOS_ENABLE_CUDA
216 ,
217 Kokkos::CudaSpace, Kokkos::CudaHostPinnedSpace, Kokkos::CudaUVMSpace
218#endif
219#ifdef KOKKOS_ENABLE_HIP
220 ,
221 Kokkos::HIPSpace, Kokkos::HIPHostPinnedSpace, Kokkos::HIPManagedSpace
222#endif
223#ifdef KOKKOS_ENABLE_SYCL
224 ,
225 Kokkos::Experimental::SYCLDeviceUSMSpace, Kokkos::Experimental::SYCLHostUSMSpace,
226 Kokkos::Experimental::SYCLSharedUSMSpace
227#endif
228 >;
229
230 using unique_exec_spaces = VariantFromUniqueTypes<Kokkos::DefaultExecutionSpace
231#ifdef KOKKOS_ENABLE_OPENMP
232 ,
233 Kokkos::OpenMP
234#endif
235#ifdef KOKKOS_ENABLE_OPENMPTARGET
236 ,
237 Kokkos::OpenMPTarget
238#endif
239#ifdef KOKKOS_ENABLE_THREADS
240 ,
241 Kokkos::Threads
242#endif
243#ifdef KOKKOS_ENABLE_SERIAL
244 ,
245 Kokkos::Serial
246#endif
247#ifdef KOKKOS_ENABLE_CUDA
248 ,
249 Kokkos::Cuda
250#endif
251#ifdef KOKKOS_ENABLE_HIP
252 ,
253 Kokkos::HIP
254#endif
255#ifdef KOKKOS_ENABLE_SYCL
256 ,
257 Kokkos::Experimental::SYCL
258#endif
259#ifdef KOKKOS_ENABLE_HPX
260 ,
261 Kokkos::HPX
262#endif
263 >;
264
267 };
268
275 template <template <typename> class Type, typename... Spaces>
277 template <typename T, typename... Ts>
279
280 using Types = VariantWithVerifier<Verifier, Spaces...>;
281
282 std::array<Types, sizeof...(Spaces)> elements_m;
283
289 template <typename Space, unsigned Idx = 0>
290 constexpr static unsigned spaceToIndex() {
291 static_assert(Idx < sizeof...(Spaces));
292 if constexpr (std::is_same_v<Space,
293 std::tuple_element_t<Idx, std::tuple<Spaces...>>>) {
294 return Idx;
295 } else {
297 }
298 // Silences incorrect nvcc warning: missing return statement at end of non-void
299 // function
300 throw IpplException("detail::MultispaceContainer::spaceToIndex",
301 "Unreachable state");
302 }
303
307 template <typename Space>
309 elements_m[spaceToIndex<Space>()] = Type<Space>{};
310 }
311
316 template <typename MemorySpace, typename Filter,
317 std::enable_if_t<std::is_null_pointer_v<std::decay_t<Filter>>, int> = 0>
318 constexpr bool copyToSpace(Filter&&) {
319 return true;
320 }
321
322 template <typename MemorySpace, typename Filter,
323 std::enable_if_t<!std::is_null_pointer_v<std::decay_t<Filter>>, int> = 0>
324 bool copyToSpace(Filter&& predicate) {
325 return predicate.template operator()<MemorySpace>();
326 }
327
328 public:
330
341 template <typename DataType, typename Filter = std::nullptr_t>
342 MultispaceContainer(const DataType& data, Filter&& predicate = nullptr)
344 using space = typename DataType::memory_space;
345 static_assert(std::is_same_v<DataType, Type<space>>);
346
348 copyToOtherSpaces<space>(predicate);
349 }
350
358 template <typename Space, typename Filter = std::nullptr_t>
359 void copyToOtherSpaces(Filter&& predicate = nullptr) {
360 forAll([&]<typename DataType>(DataType& dst) {
361 using memory_space = typename DataType::memory_space;
362 if constexpr (!std::is_same_v<Space, memory_space>) {
363 if (copyToSpace<memory_space>(predicate)) {
364 dst = Kokkos::create_mirror_view_and_copy(
365 Kokkos::view_alloc(memory_space{}, Kokkos::WithoutInitializing),
366 get<Space>());
367 }
368 }
369 });
370 }
371
377 template <typename Space>
378 const Type<Space>& get() const {
380 }
381
382 template <typename Space>
383 Type<Space>& get() {
385 }
386
392 template <typename Functor>
393 void forAll(Functor&& f) const {
394 (f(get<Spaces>()), ...);
395 }
396
397 template <typename Functor>
398 void forAll(Functor&& f) {
399 (f(get<Spaces>()), ...);
400 }
401 };
402
407 template <template <typename> class Type>
409 template <typename... Spaces>
410 using container_type = MultispaceContainer<Type, Spaces...>;
411
413
414 // Static factory function that takes a lambda to initialize each memory space
415 template <typename Functor>
416 static type createContainer(Functor&& initFunc) {
417 return type{std::forward<Functor>(initFunc)};
418 }
419 };
420
427 template <typename Functor>
428 void runForAllSpaces(Functor&& f) {
429 using all_spaces = typename TypeForAllSpaces<std::variant>::memory_spaces_type;
430 auto runner = [&]<typename... Spaces>(const std::variant<Spaces...>&) {
431 (f.template operator()<Spaces>(), ...);
432 };
433 runner(all_spaces{});
434 }
435 } // namespace detail
436} // namespace ippl
437
438#endif
STL namespace.
KOKKOS_INLINE_FUNCTION auto & get(::ippl::Tuple< Ts... > &t)
Definition Tuple.h:362
Definition Archive.h:20
typename ConstructVariant< std::variant< Types... >, std::variant<>, IsEnabled >::type VariantFromConditionalTypes
Definition TypeUtils.h:146
std::conditional_t< B, T, void > ConditionalType
Definition TypeUtils.h:56
typename ConstructVariant< std::variant< Types... >, std::variant<>, Verifier >::type VariantWithVerifier
Definition TypeUtils.h:167
void runForAllSpaces(Functor &&f)
Definition TypeUtils.h:428
typename ConstructVariant< std::variant< Types... >, std::variant<>, IsUnique >::type VariantFromUniqueTypes
Definition TypeUtils.h:154
static constexpr bool enable
Definition TypeUtils.h:26
static constexpr bool enable
Definition TypeUtils.h:43
static constexpr bool enable
Definition TypeUtils.h:67
cond< Check::enable, typename ConstructVariant< variant< ToAdd... >, variant< typename Check::type, Added... >, Verifier >::type, typename ConstructVariant< variant< ToAdd... >, variant< Added... >, Verifier >::type > type
Definition TypeUtils.h:137
typename View::uniform_type view_type
Definition TypeUtils.h:204
typename Forward< Type, view_type >::type type
Definition TypeUtils.h:205
typename Forward< Type, unique_memory_spaces >::type memory_spaces_type
Definition TypeUtils.h:265
typename Forward< Type, unique_exec_spaces >::type exec_spaces_type
Definition TypeUtils.h:266
VariantFromUniqueTypes< Kokkos::HostSpace, Kokkos::SharedSpace, Kokkos::SharedHostPinnedSpace > unique_memory_spaces
Definition TypeUtils.h:213
VariantFromUniqueTypes< Kokkos::DefaultExecutionSpace > unique_exec_spaces
Definition TypeUtils.h:230
VariantWithVerifier< Verifier, Spaces... > Types
Definition TypeUtils.h:280
MultispaceContainer(const DataType &data, Filter &&predicate=nullptr)
Definition TypeUtils.h:342
bool copyToSpace(Filter &&predicate)
Definition TypeUtils.h:324
constexpr bool copyToSpace(Filter &&)
Definition TypeUtils.h:318
void forAll(Functor &&f) const
Definition TypeUtils.h:393
const Type< Space > & get() const
Definition TypeUtils.h:378
typename WrapUnique< Type >::template Verifier< T, Ts... > Verifier
Definition TypeUtils.h:278
static constexpr unsigned spaceToIndex()
Definition TypeUtils.h:290
void copyToOtherSpaces(Filter &&predicate=nullptr)
Definition TypeUtils.h:359
std::array< Types, sizeof...(Spaces)> elements_m
Definition TypeUtils.h:282
typename TypeForAllSpaces< container_type >::memory_spaces_type type
Definition TypeUtils.h:412
static type createContainer(Functor &&initFunc)
Definition TypeUtils.h:416
MultispaceContainer< Type, Spaces... > container_type
Definition TypeUtils.h:410