7#include <oneapi/dpl/execution>
8#include <oneapi/dpl/numeric>
10#include <oneapi/dpl/async>
12#include <dr/concepts/concepts.hpp>
13#include <dr/detail/onedpl_direct_iterator.hpp>
14#include <dr/sp/algorithms/execution_policy.hpp>
15#include <dr/sp/init.hpp>
16#include <sycl/sycl.hpp>
22template <
typename T,
typename ExecutionPolicy,
23 std::bidirectional_iterator Iter,
typename Fn>
24auto reduce_no_init_async(ExecutionPolicy &&policy, Iter first, Iter last,
29 std::iter_value_t<Iter> init = *new_last;
34 return oneapi::dpl::experimental::reduce_async(
35 std::forward<ExecutionPolicy>(policy), d_first, d_last,
36 static_cast<T
>(init), std::forward<Fn>(fn));
39template <
typename T,
typename ExecutionPolicy,
40 std::bidirectional_iterator Iter,
typename Fn>
41 requires(sycl::has_known_identity_v<Fn, T>)
42auto reduce_no_init_async(ExecutionPolicy &&policy, Iter first, Iter last,
47 return oneapi::dpl::experimental::reduce_async(
48 std::forward<ExecutionPolicy>(policy), d_first, d_last,
49 sycl::known_identity_v<Fn, T>, std::forward<Fn>(fn));
58T reduce(ExecutionPolicy &&policy, R &&r, T init, BinaryOp &&binary_op) {
61 std::is_same_v<std::remove_cvref_t<ExecutionPolicy>, device_policy>);
63 if constexpr (std::is_same_v<std::remove_cvref_t<ExecutionPolicy>,
65 using future_t =
decltype(oneapi::dpl::experimental::reduce_async(
66 __detail::dpl_policy(0), dr::ranges::segments(r)[0].begin(),
67 dr::ranges::segments(r)[0].end(), init, binary_op));
69 std::vector<future_t> futures;
71 for (
auto &&segment : dr::ranges::segments(r)) {
72 auto &&local_policy = __detail::dpl_policy(dr::ranges::rank(segment));
74 auto dist = rng::distance(segment);
77 }
else if (dist == 1) {
78 init = binary_op(init, *rng::begin(segment));
82 auto future = reduce_no_init_async<T>(local_policy, rng::begin(segment),
83 rng::end(segment), binary_op);
85 futures.push_back(std::move(future));
88 for (
auto &&f : futures) {
89 init = binary_op(init, f.get());
98template <
typename ExecutionPolicy, dr::distributed_range R,
typename T>
99T reduce(ExecutionPolicy &&policy, R &&r, T init) {
100 return reduce(std::forward<ExecutionPolicy>(policy), std::forward<R>(r), init,
104template <
typename ExecutionPolicy, dr::distributed_range R>
105rng::range_value_t<R> reduce(ExecutionPolicy &&policy, R &&r) {
106 return reduce(std::forward<ExecutionPolicy>(policy), std::forward<R>(r),
107 rng::range_value_t<R>{}, std::plus<>());
112template <
typename ExecutionPolicy, dr::distributed_iterator Iter>
113std::iter_value_t<Iter> reduce(ExecutionPolicy &&policy, Iter first,
115 return reduce(std::forward<ExecutionPolicy>(policy),
116 rng::subrange(first, last), std::iter_value_t<Iter>{},
120template <
typename ExecutionPolicy, dr::distributed_iterator Iter,
typename T>
121T reduce(ExecutionPolicy &&policy, Iter first, Iter last, T init) {
122 return reduce(std::forward<ExecutionPolicy>(policy),
123 rng::subrange(first, last), init, std::plus<>());
128T reduce(ExecutionPolicy &&policy, Iter first, Iter last, T init,
129 BinaryOp &&binary_op) {
130 return reduce(std::forward<ExecutionPolicy>(policy),
131 rng::subrange(first, last), init,
132 std::forward<BinaryOp>(binary_op));
137template <dr::distributed_range R> rng::range_value_t<R> reduce(R &&r) {
138 return reduce(dr::sp::par_unseq, std::forward<R>(r));
141template <dr::distributed_range R,
typename T> T reduce(R &&r, T init) {
142 return reduce(dr::sp::par_unseq, std::forward<R>(r), init);
145template <dr::distributed_range R,
typename T,
typename BinaryOp>
146T reduce(R &&r, T init, BinaryOp &&binary_op) {
147 return reduce(dr::sp::par_unseq, std::forward<R>(r), init,
148 std::forward<BinaryOp>(binary_op));
151template <dr::distributed_iterator Iter>
152std::iter_value_t<Iter> reduce(Iter first, Iter last) {
153 return reduce(dr::sp::par_unseq, first, last);
156template <dr::distributed_iterator Iter,
typename T>
157T reduce(Iter first, Iter last, T init) {
158 return reduce(dr::sp::par_unseq, first, last, init);
161template <dr::distributed_iterator Iter,
typename T,
typename BinaryOp>
162T reduce(Iter first, Iter last, T init, BinaryOp &&binary_op) {
163 return reduce(dr::sp::par_unseq, first, last, init,
164 std::forward<BinaryOp>(binary_op));
Definition: onedpl_direct_iterator.hpp:15
Definition: concepts.hpp:31
Definition: concepts.hpp:20