DDC 0.1.0
Loading...
Searching...
No Matches
parallel_for_each.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 <cstddef>
8#include <string>
9#include <type_traits>
10#include <utility>
11
12#include <Kokkos_Core.hpp>
13
14#include "ddc/ddc_to_kokkos_execution_policy.hpp"
15#include "ddc/detail/kokkos.hpp"
16#include "ddc/discrete_domain.hpp"
17#include "ddc/discrete_element.hpp"
18
19namespace ddc {
20
21namespace detail {
22
23template <class F, class... DDims>
24class ForEachKokkosLambdaAdapter
25{
26 template <class T>
27 using index_type = DiscreteElementType;
28
29 F m_f;
30
31public:
32 explicit ForEachKokkosLambdaAdapter(F const& f) : m_f(f) {}
33
34 template <std::size_t N = sizeof...(DDims), std::enable_if_t<(N == 0), bool> = true>
35 void operator()([[maybe_unused]] index_type<void> unused_id) const
36 {
37 m_f(DiscreteElement<>());
38 }
39
40 template <std::size_t N = sizeof...(DDims), std::enable_if_t<(N == 0), bool> = true>
41 KOKKOS_FUNCTION void operator()(
42 use_annotated_operator,
43 [[maybe_unused]] index_type<void> unused_id) const
44 {
45 m_f(DiscreteElement<>());
46 }
47
48 template <std::size_t N = sizeof...(DDims), std::enable_if_t<(N > 0), bool> = true>
49 void operator()(index_type<DDims>... ids) const
50 {
51 m_f(DiscreteElement<DDims...>(ids...));
52 }
53
54 template <std::size_t N = sizeof...(DDims), std::enable_if_t<(N > 0), bool> = true>
55 KOKKOS_FUNCTION void operator()(use_annotated_operator, index_type<DDims>... ids) const
56 {
57 m_f(DiscreteElement<DDims...>(ids...));
58 }
59};
60
61template <class ExecSpace, class Functor, class... DDims>
62void for_each_kokkos(
63 std::string const& label,
64 ExecSpace const& execution_space,
65 DiscreteDomain<DDims...> const& domain,
66 Functor const& f) noexcept
67{
68 Kokkos::parallel_for(
69 label,
70 ddc_to_kokkos_execution_policy(execution_space, domain),
71 ForEachKokkosLambdaAdapter<Functor, DDims...>(f));
72}
73
74} // namespace detail
75
76/** iterates over a nD domain using a given `Kokkos` execution space
77 * @param[in] label name for easy identification of the parallel_for_each algorithm
78 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
79 * @param[in] domain the domain over which to iterate
80 * @param[in] f a functor taking an index as parameter
81 */
82template <class ExecSpace, class... DDims, class Functor>
84 std::string const& label,
85 ExecSpace const& execution_space,
86 DiscreteDomain<DDims...> const& domain,
87 Functor&& f) noexcept
88{
89 detail::for_each_kokkos(label, execution_space, domain, std::forward<Functor>(f));
90}
91
92/** iterates over a nD domain using a given `Kokkos` execution space
93 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
94 * @param[in] domain the domain over which to iterate
95 * @param[in] f a functor taking an index as parameter
96 */
97template <class ExecSpace, class... DDims, class Functor>
98std::enable_if_t<Kokkos::is_execution_space_v<ExecSpace>> parallel_for_each(
99 ExecSpace const& execution_space,
100 DiscreteDomain<DDims...> const& domain,
101 Functor&& f) noexcept
102{
103 detail::for_each_kokkos(
104 "ddc_for_each_default",
105 execution_space,
106 domain,
107 std::forward<Functor>(f));
108}
109
110/** iterates over a nD domain using the `Kokkos` default execution space
111 * @param[in] label name for easy identification of the parallel_for_each algorithm
112 * @param[in] domain the domain over which to iterate
113 * @param[in] f a functor taking an index as parameter
114 */
115template <class... DDims, class Functor>
117 std::string const& label,
118 DiscreteDomain<DDims...> const& domain,
119 Functor&& f) noexcept
120{
121 parallel_for_each(label, Kokkos::DefaultExecutionSpace(), domain, std::forward<Functor>(f));
122}
123
124/** iterates over a nD domain using the `Kokkos` default execution space
125 * @param[in] domain the domain over which to iterate
126 * @param[in] f a functor taking an index as parameter
127 */
128template <class... DDims, class Functor>
129void parallel_for_each(DiscreteDomain<DDims...> const& domain, Functor&& f) noexcept
130{
131 parallel_for_each(
132 "ddc_for_each_default",
133 Kokkos::DefaultExecutionSpace(),
134 domain,
135 std::forward<Functor>(f));
136}
137
138} // namespace ddc
friend class DiscreteDomain
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement()=default
The top-level namespace of DDC.
std::enable_if_t< Kokkos::is_execution_space_v< ExecSpace > > parallel_for_each(ExecSpace const &execution_space, DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using a given Kokkos execution space
void parallel_for_each(std::string const &label, DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using the Kokkos default execution space
void parallel_for_each(std::string const &label, ExecSpace const &execution_space, DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using a given Kokkos execution space
void parallel_for_each(DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using the Kokkos default execution space