• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/libs/core/algorithms/include/hpx/parallel/algorithms/detail/dispatch.hpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//  Copyright (c) 2021 Giannis Gonidelis
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#pragma once
9

10
#include <hpx/config.hpp>
11
#include <hpx/algorithms/traits/segmented_iterator_traits.hpp>
12
#include <hpx/modules/datastructures.hpp>
13
#include <hpx/modules/errors.hpp>
14
#include <hpx/modules/execution.hpp>
15
#include <hpx/modules/executors.hpp>
16
#include <hpx/modules/type_support.hpp>
17
#include <hpx/parallel/util/detail/algorithm_result.hpp>
18
#include <hpx/parallel/util/detail/scoped_executor_parameters.hpp>
19
#include <hpx/parallel/util/result_types.hpp>
20

21
#include <exception>
22
#if defined(HPX_HAVE_CXX17_STD_EXECUTION_POLICES)
23
#include <execution>
24
#endif
25
#include <type_traits>
26
#include <utility>
27

28
namespace hpx::parallel::detail {
29

30
    ///////////////////////////////////////////////////////////////////////////
31
    HPX_CXX_EXPORT template <typename Result>
32
    struct local_algorithm_result
33
    {
34
        using type = typename hpx::traits::segmented_local_iterator_traits<
35
            Result>::local_raw_iterator;
36
    };
37

38
    HPX_CXX_EXPORT template <typename Result1, typename Result2>
39
    struct local_algorithm_result<util::in_out_result<Result1, Result2>>
40
    {
41
        using type1 = typename hpx::traits::segmented_local_iterator_traits<
42
            Result1>::local_raw_iterator;
43
        using type2 = typename hpx::traits::segmented_local_iterator_traits<
44
            Result2>::local_raw_iterator;
45

46
        using type = util::in_out_result<type1, type2>;
47
    };
48

49
    HPX_CXX_EXPORT template <typename Result>
50
    struct local_algorithm_result<util::min_max_result<Result>>
51
    {
52
        using type1 = typename hpx::traits::segmented_local_iterator_traits<
53
            Result>::local_raw_iterator;
54

55
        using type = util::min_max_result<type1>;
56
    };
57

58
    HPX_CXX_EXPORT template <typename Result1, typename Result2,
59
        typename Result3>
60
    struct local_algorithm_result<
61
        util::in_in_out_result<Result1, Result2, Result3>>
62
    {
63
        using type1 = typename hpx::traits::segmented_local_iterator_traits<
64
            Result1>::local_raw_iterator;
65
        using type2 = typename hpx::traits::segmented_local_iterator_traits<
66
            Result2>::local_raw_iterator;
67
        using type3 = typename hpx::traits::segmented_local_iterator_traits<
68
            Result3>::local_raw_iterator;
69

70
        using type = util::in_in_out_result<type1, type2, type3>;
71
    };
72

73
    template <>
74
    struct local_algorithm_result<void>
75
    {
76
        using type = void;
77
    };
78

79
    HPX_CXX_EXPORT template <typename T>
80
    using local_algorithm_result_t = typename local_algorithm_result<T>::type;
81

82
    ///////////////////////////////////////////////////////////////////////////
83
    HPX_CXX_EXPORT template <typename Derived, typename Result = void>
84
    struct algorithm
85
    {
86
    private:
87
        [[nodiscard]] constexpr Derived const& derived() const noexcept
88
        {
89
            return static_cast<Derived const&>(*this);
90
        }
91

92
    public:
93
        using result_type = Result;
94
        using local_result_type = local_algorithm_result_t<result_type>;
95

10✔
96
        // NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility)
4✔
97
        explicit constexpr algorithm(char const* const name) noexcept
98
          : name_(name)
99
        {
100
        }
101

102
        ///////////////////////////////////////////////////////////////////////
103
        // this equivalent to sequential execution
4✔
104
        // clang-format off
105
        template <typename ExPolicy, typename... Args>
106
        HPX_HOST_DEVICE decltype(auto) operator()(
107
            ExPolicy&& policy, Args&&... args) const
108
        // clang-format on
109
        {
110
#if !defined(__CUDA_ARCH__)
111
            try
112
            {
113
#endif
114
                using parameters_type =
115
                    typename std::decay_t<ExPolicy>::executor_parameters_type;
116
                using executor_type =
117
                    typename std::decay_t<ExPolicy>::executor_type;
118

119
                hpx::parallel::util::detail::scoped_executor_parameters_ref<
4✔
120
                    parameters_type, executor_type>
4✔
121
                    scoped_param(policy.parameters(), policy.executor());
122

123
                return Derived::sequential(
×
124
                    HPX_FORWARD(ExPolicy, policy), HPX_FORWARD(Args, args)...);
125
#if !defined(__CUDA_ARCH__)
126
            }
127
            catch (...)
128
            {
129
                // this does not return
130
                using policy_type =
131
                    decltype(hpx::execution::experimental::to_non_task(
132
                        std::declval<ExPolicy&&>()));
×
133

134
                return hpx::parallel::detail::handle_exception<policy_type,
135
                    std::conditional_t<std::is_void_v<local_result_type>,
136
                        hpx::util::unused_type, local_result_type>>::call();
137
            }
138
#endif
139
        }
140

141
    public:
4✔
142
        ///////////////////////////////////////////////////////////////////////
143
        // main sequential dispatch entry points
144
        template <typename ExPolicy, typename... Args>
145
        constexpr decltype(auto) call2(
146
            ExPolicy&& policy, std::true_type, Args&&... args) const
147
        {
148
            using result_handler =
149
                hpx::parallel::util::detail::algorithm_result<ExPolicy,
150
                    local_result_type>;
151

152
            decltype(auto) exec = policy.executor();    // avoid use after move
153
            if constexpr (hpx::is_async_execution_policy_v<ExPolicy>)
154
            {
155
                // specialization for all task-based (asynchronous) execution
156
                // policies
157

158
                // run the launched task on the requested executor
159
                return result_handler::get(execution::async_execute(
160
                    exec, derived(), policy, HPX_FORWARD(Args, args)...));
2✔
161
            }
162
            else if constexpr (std::is_void_v<local_result_type>)
2✔
163
            {
164
                execution::sync_execute(
165
                    exec, derived(), policy, HPX_FORWARD(Args, args)...);
166
                return result_handler::get();
167
            }
2✔
168
            else
169
            {
170
                return result_handler::get(execution::sync_execute(
171
                    exec, derived(), policy, HPX_FORWARD(Args, args)...));
172
            }
173
        }
174

175
        // main parallel dispatch entry point
176
        template <typename ExPolicy, typename... Args>
177
        HPX_FORCEINLINE static constexpr decltype(auto) call2(
178
            ExPolicy&& policy, std::false_type, Args&&... args)
179
        {
180
            using result_handler =
181
                hpx::parallel::util::detail::algorithm_result<ExPolicy,
182
                    local_result_type>;
183

184
            using result = decltype(Derived::parallel(
185
                HPX_FORWARD(ExPolicy, policy), HPX_FORWARD(Args, args)...));
1✔
186

187
            if constexpr (std::is_void_v<result>)
188
            {
189
                Derived::parallel(
190
                    HPX_FORWARD(ExPolicy, policy), HPX_FORWARD(Args, args)...);
191
                return result_handler::get();
5✔
192
            }
8✔
193
            else
194
            {
195
                return result_handler::get(Derived::parallel(
196
                    HPX_FORWARD(ExPolicy, policy), HPX_FORWARD(Args, args)...));
197
            }
198
        }
199

200
        template <typename ExPolicy, typename... Args>
201
        HPX_FORCEINLINE constexpr decltype(auto) call(
8✔
202
            ExPolicy&& policy, Args&&... args)
203
        {
204
            using is_seq = hpx::is_sequenced_execution_policy<ExPolicy>;
205
            return call2(HPX_FORWARD(ExPolicy, policy), is_seq(),
206
                HPX_FORWARD(Args, args)...);
207
        }
208

209
#if defined(HPX_HAVE_CXX17_STD_EXECUTION_POLICES)
210
        // main dispatch entry points for std execution policies
211
        template <typename... Args>
212
        HPX_FORCEINLINE constexpr decltype(auto) call(
213
            std::execution::sequenced_policy, Args&&... args)
214
        {
215
            return call2(hpx::execution::seq, std::true_type(),
216
                HPX_FORWARD(Args, args)...);
217
        }
218

219
        template <typename... Args>
220
        HPX_FORCEINLINE constexpr decltype(auto) call(
221
            std::execution::parallel_policy, Args&&... args)
222
        {
223
            return call2(hpx::execution::par, std::false_type(),
224
                HPX_FORWARD(Args, args)...);
225
        }
226

227
        template <typename... Args>
228
        HPX_FORCEINLINE constexpr decltype(auto) call(
229
            std::execution::parallel_unsequenced_policy, Args&&... args)
230
        {
231
            return call2(hpx::execution::par_unseq, std::false_type(),
232
                HPX_FORWARD(Args, args)...);
233
        }
234

235
#if defined(HPX_HAVE_CXX20_STD_EXECUTION_POLICES)
236
        template <typename... Args>
237
        HPX_FORCEINLINE constexpr decltype(auto) call(
238
            std::execution::unsequenced_policy, Args&&... args)
239
        {
240
            return call2(hpx::execution::unseq, std::false_type(),
241
                HPX_FORWARD(Args, args)...);
242
        }
243
#endif
244
#endif
245

246
    private:
247
        char const* const name_;
248

249
        friend class hpx::serialization::access;
250

251
        template <typename Archive>
252
        static constexpr void serialize(Archive&, unsigned int) noexcept
253
        {
254
            // no need to serialize 'name_' as it is always initialized by the
255
            // default constructor of the derived class
256
        }
257
    };
258
}    // namespace hpx::parallel::detail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc