1+ // Copyright (c) 2026 Bharath Kollanur
2+ //
3+ // SPDX-License-Identifier: BSL-1.0
4+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
7+ #include < hpx/algorithm.hpp>
8+ #include < hpx/execution.hpp>
9+ #include < hpx/init.hpp>
10+ #include < hpx/modules/testing.hpp>
11+
12+ #include < cstddef>
13+ #include < cstdint>
14+ #include < numeric>
15+ #include < vector>
16+
17+ struct partition_hooks_parameters
18+ {
19+ explicit partition_hooks_parameters (std::size_t max_partitions)
20+ : values_(max_partitions, std::pair<std::size_t , std::size_t >{0 , 0 })
21+ , seen_(max_partitions, 0 )
22+ {
23+ }
24+
25+ template <typename Executor>
26+ friend void tag_override_invoke (
27+ hpx::execution::experimental::mark_partition_t ,
28+ partition_hooks_parameters& self, Executor&&, std::size_t partition,
29+ std::size_t a, std::size_t b) noexcept
30+ {
31+ HPX_ASSERT (partition < self.values_ .size ());
32+ self.values_ [partition] = {a, b};
33+ self.seen_ [partition] = 1 ;
34+ }
35+
36+ std::size_t count_seen () const
37+ {
38+ std::size_t c = 0 ;
39+ for (auto v : seen_)
40+ c += (v != 0 );
41+ return c;
42+ }
43+
44+ std::vector<std::pair<std::size_t , std::size_t >> values_;
45+ std::vector<unsigned char > seen_;
46+ };
47+
48+ namespace hpx ::execution::experimental {
49+ template <>
50+ struct is_executor_parameters <partition_hooks_parameters> : std::true_type
51+ {
52+ };
53+ } // namespace hpx::execution::experimental
54+
55+ void test_mark_partition_sync ()
56+ {
57+ std::vector<std::uint64_t > left (200000 );
58+ std::vector<std::uint64_t > right (200000 );
59+ std::vector<std::uint64_t > out (left.size () + right.size ());
60+
61+ std::iota (left.begin (), left.end (), std::uint64_t (0 ));
62+ std::iota (right.begin (), right.end (), std::uint64_t (left.size ()));
63+ hpx::execution::experimental::chunking_parameters exec_params{};
64+ hpx::execution::experimental::collect_chunking_parameters collect_params (
65+ exec_params);
66+
67+ partition_hooks_parameters params (left.size () + right.size ());
68+
69+ auto policy =
70+ hpx::execution::par.with (std::ref (collect_params), std::ref (params));
71+ hpx::merge (policy, left.begin (), left.end (), right.begin (), right.end (),
72+ out.begin ());
73+
74+ HPX_TEST (std::is_sorted (out.begin (), out.end ()));
75+ HPX_TEST_EQ (params.count_seen (), exec_params.num_chunks );
76+ }
77+
78+ void test_mark_partition_async ()
79+ {
80+ std::vector<std::uint64_t > left (200000 );
81+ std::vector<std::uint64_t > right (200000 );
82+ std::vector<std::uint64_t > out (left.size () + right.size ());
83+
84+ std::iota (left.begin (), left.end (), std::uint64_t (0 ));
85+ std::iota (right.begin (), right.end (), std::uint64_t (left.size ()));
86+
87+ hpx::execution::experimental::chunking_parameters exec_params{};
88+ hpx::execution::experimental::collect_chunking_parameters collect_params (
89+ exec_params);
90+
91+ partition_hooks_parameters params (left.size () + right.size ());
92+
93+ auto policy = hpx::execution::par (hpx::execution::task)
94+ .with (std::ref (params), std::ref (collect_params));
95+ auto f = hpx::merge (policy, left.begin (), left.end (), right.begin (),
96+ right.end (), out.begin ());
97+ auto result_iter = f.get ();
98+ HPX_UNUSED (result_iter);
99+
100+ HPX_TEST (std::is_sorted (out.begin (), out.end ()));
101+ HPX_TEST_EQ (params.count_seen (), exec_params.num_chunks );
102+ }
103+
104+ int hpx_main (hpx::program_options::variables_map&)
105+ {
106+ test_mark_partition_sync ();
107+ test_mark_partition_async ();
108+
109+ return hpx::local::finalize ();
110+ }
111+
112+ int main (int argc, char * argv[])
113+ {
114+ using namespace hpx ::program_options;
115+
116+ options_description desc_commandline (
117+ " Usage: " HPX_APPLICATION_STRING " [options]" );
118+
119+ std::vector<std::string> const cfg = {" hpx.os_threads=all" };
120+
121+ hpx::local::init_params init_args;
122+ init_args.desc_cmdline = desc_commandline;
123+ init_args.cfg = cfg;
124+
125+ HPX_TEST_EQ_MSG (hpx::local::init (hpx_main, argc, argv, init_args), 0 ,
126+ " HPX main exited with non-zero status" );
127+
128+ return hpx::util::report_errors ();
129+ }
0 commit comments