Skip to content

Commit d9597d3

Browse files
Merge branch 'master' into removing-HPX_WITH_CXX20_SOURCE_LOCATION
2 parents cbf7e59 + 6cf6e6a commit d9597d3

80 files changed

Lines changed: 2837 additions & 391 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright (c) 2026 Ujjwal Shekhar
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+
name: Linux CI (Release, Clang P2996 Reflection)
8+
9+
on: [pull_request]
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
container: ujjwalshekhar2503/hpx-clang-ci:latest
15+
16+
steps:
17+
- uses: actions/checkout@v6
18+
- name: Configure
19+
shell: bash
20+
run: |
21+
cmake \
22+
. \
23+
-Bbuild \
24+
-GNinja \
25+
-DHPX_WITH_MALLOC=system \
26+
-DCMAKE_BUILD_TYPE=Debug \
27+
-DHPX_WITH_CXX_STANDARD=26 \
28+
-DCMAKE_C_COMPILER=clang \
29+
-DCMAKE_CXX_COMPILER=clang++ \
30+
-DCMAKE_CXX_FLAGS="-freflection-latest -stdlib=libc++ -D__cpp_lib_experimental_meta=202403L" \
31+
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -L${CLANG_P2996_LIBS} -Wl,-rpath,${CLANG_P2996_LIBS} -L${SYSTEM_LINKER_PATH} -latomic" \
32+
-DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++ -L${CLANG_P2996_LIBS} -Wl,-rpath,${CLANG_P2996_LIBS} -L${SYSTEM_LINKER_PATH} -latomic" \
33+
-DCMAKE_REQUIRED_LIBRARIES="atomic" \
34+
-DHPX_INTERNAL_CACHE_LINE_SIZE_DETECT=64 \
35+
-DHPX_WITH_FETCH_ASIO=ON \
36+
-DHPX_WITH_EXAMPLES=OFF \
37+
-DHPX_WITH_TESTS=ON \
38+
-DHPX_WITH_TESTS_MAX_THREADS_PER_LOCALITY=2 \
39+
-DHPX_SERIALIZATION_WITH_ALLOW_AUTO_GENERATE=ON \
40+
-DHPX_WITH_CHECK_MODULE_DEPENDENCIES=On
41+
- name: Build
42+
shell: bash
43+
run: |
44+
cmake --build build --target all
45+
cmake --build build --target tests.unit.modules.serialization
46+
- name: Test
47+
shell: bash
48+
run: |
49+
cd build
50+
ctest \
51+
--output-on-failure \
52+
--tests-regex "tests.unit.modules.serialization"

cmake/HPX_AddConfigTest.cmake

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,15 @@ function(hpx_check_for_cxx26_contracts)
596596
)
597597
endfunction()
598598

599+
# ##############################################################################
600+
function(hpx_check_for_cxx26_experimental_meta)
601+
add_hpx_config_test(
602+
HPX_WITH_CXX26_EXPERIMENTAL_META
603+
SOURCE cmake/tests/cxx26_experimental_meta.cpp
604+
FILE ${ARGN}
605+
)
606+
endfunction()
607+
599608
# ##############################################################################
600609
function(hpx_check_for_cxx_lambda_capture_decltype)
601610
add_hpx_config_test(

cmake/HPX_PerformCxxFeatureTests.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ function(hpx_perform_cxx_feature_tests)
134134
DEFINITIONS HPX_HAVE_CXX26_EXPERIMENTAL_SCOPE
135135
)
136136

137+
hpx_check_for_cxx26_experimental_meta(
138+
DEFINITIONS HPX_HAVE_CXX26_EXPERIMENTAL_META
139+
)
140+
137141
hpx_check_for_cxx26_contracts(DEFINITIONS HPX_HAVE_CXX26_CONTRACTS)
138142

139143
hpx_check_for_cxx_lambda_capture_decltype(

cmake/templates/hpxrun.py.in

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def run_mpi(cmd, localities, verbose):
189189
if mpiexec == '':
190190
msg = 'mpiexec not available on this platform. '
191191
msg += 'Please rerun CMake with HPX_PARCELPORT_MPI=True.'
192-
print(msg, sys.stderr)
192+
print(msg, file=sys.stderr)
193193
sys.exit(1)
194194
exec_cmd = [mpiexec, '@MPIEXEC_NUMPROC_FLAG@', str(localities)] + cmd
195195
if verbose:
@@ -282,32 +282,32 @@ def build_cmd(options, args):
282282

283283
def check_options(parser, options, args):
284284
if 0 == len(args):
285-
print('Error: You need to specify at least the application to start\n', sys.stderr)
285+
print('Error: You need to specify at least the application to start\n', file=sys.stderr)
286286
parser.print_help()
287287
sys.exit(1)
288288

289289
if not os.path.exists(args[0]):
290-
print('Executable ' + args[0] + ' does not exist', sys.stderr)
290+
print('Executable ' + args[0] + ' does not exist', file=sys.stderr)
291291
sys.exit(1)
292292

293293
if options.localities < 1:
294-
print('Can not start less than one locality', sys.stderr)
294+
print('Can not start less than one locality', file=sys.stderr)
295295
sys.exit(1)
296296

297297
if options.threads < 1 and options.threads != -1 and options.threads != -2:
298-
print('Can not start less than one thread per locality', sys.stderr)
298+
print('Can not start less than one thread per locality', file=sys.stderr)
299299
sys.exit(1)
300300

301301
check_valid_parcelport = (lambda x: x == 'mpi' or x == 'lci' or x == 'lcw' or x == 'gasnet' or x == 'tcp' or x == 'none');
302302
if not check_valid_parcelport(options.parcelport):
303-
print('Error: Parcelport option not valid\n', sys.stderr)
303+
print('Error: Parcelport option not valid\n', file=sys.stderr)
304304
parser.print_help()
305305
sys.exit(1)
306306

307307
check_valid_runwrapper = (lambda x:
308308
x == 'none' or x == 'mpi' or x == 'srun' or x =='jsrun' or x == 'gasnet' or x == 'gasnet-smp');
309309
if not check_valid_runwrapper(options.runwrapper):
310-
print('Error: Runwrapper option not valid\n', sys.stderr)
310+
print('Error: Runwrapper option not valid\n', file=sys.stderr)
311311
parser.print_help()
312312
sys.exit(1)
313313

@@ -445,7 +445,7 @@ Used by the tcp parcelport only.
445445
msg = 'Process 0 failed with an unexpected error '
446446
msg += 'code of ' + str(ret) + ' (expected ' + str(options.expected)
447447
msg += ')'
448-
print(msg, sys.stderr)
448+
print(msg, file=sys.stderr)
449449
sys.exit(1)
450450
sys.exit(0)
451451

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) 2026 Ujjwal Shekhar
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+
// test for availability of std::experimental::meta_xxx
8+
9+
#include <experimental/meta>
10+
11+
#if !defined(__cpp_lib_experimental_meta)
12+
#error "__cpp_lib_experimental_meta not defined, " \
13+
"assume meta programming features are not supported"
14+
#endif
15+
16+
int main()
17+
{
18+
constexpr auto r = ^^int;
19+
typename[:r:] x = 42;
20+
typename[:^^char:] c = '*';
21+
22+
return 0;
23+
}

examples/1d_stencil/1d_stencil_5.cpp

100644100755
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ struct partition_data
9494

9595
private:
9696
// Serialization support: even if all of the code below runs on one
97-
// locality only, we need to provide an (empty) implementation for the
97+
// locality only, we need to provide an implementation for the
9898
// serialization as all arguments passed to actions have to support this.
9999
friend class hpx::serialization::access;
100100

@@ -279,10 +279,10 @@ struct stepper
279279
space do_work(std::size_t np, std::size_t nx, std::size_t nt);
280280
};
281281

282-
// Global functions can be exposed as actions as well. That allows to invoke
282+
// Static member functions can be exposed as actions as well. That allows to invoke
283283
// those remotely. The macro HPX_PLAIN_ACTION() defines a new action type
284-
// 'heat_part_action' which wraps the global function heat_part(). It can be
285-
// used to call that function on a given locality.
284+
// 'heat_part_action' which wraps the static member function
285+
// stepper::heat_part(). It can be used to call that function on a given locality.
286286
HPX_PLAIN_ACTION(stepper::heat_part, heat_part_action)
287287

288288
///////////////////////////////////////////////////////////////////////////////

libs/core/algorithms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ if(HPX_WITH_DATAPAR)
240240
hpx/parallel/datapar/mismatch.hpp
241241
hpx/parallel/datapar/reduce.hpp
242242
hpx/parallel/datapar/replace.hpp
243+
hpx/parallel/datapar/search.hpp
243244
hpx/parallel/datapar/transfer.hpp
244245
hpx/parallel/datapar/transform_loop.hpp
245246
hpx/parallel/datapar/zip_iterator.hpp

libs/core/algorithms/include/hpx/parallel/algorithms/detail/search.hpp

Lines changed: 103 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <hpx/config.hpp>
1313
#include <hpx/modules/coroutines.hpp>
1414
#include <hpx/modules/execution.hpp>
15+
#include <hpx/modules/functional.hpp>
1516
#include <hpx/modules/tag_invoke.hpp>
1617
#include <hpx/parallel/algorithms/detail/dispatch.hpp>
1718
#include <hpx/parallel/algorithms/detail/distance.hpp>
@@ -31,6 +32,100 @@
3132
namespace hpx::parallel::detail {
3233
/// \cond NOINTERNAL
3334

35+
///////////////////////////////////////////////////////////////////////////
36+
// sequential_search dispatch tag
37+
HPX_CXX_CORE_EXPORT template <typename ExPolicy>
38+
struct sequential_search_t final
39+
: hpx::functional::detail::tag_fallback<sequential_search_t<ExPolicy>>
40+
{
41+
private:
42+
// Partitioned path: called from search::parallel() f1 for each chunk.
43+
// Checks each starting position in [base_idx, base_idx+part_size) for a
44+
// needle match; cancels tok at the first match position found.
45+
template <typename Iter1, typename Iter2, typename Token, typename Pred,
46+
typename Proj1, typename Proj2>
47+
friend inline constexpr void tag_fallback_invoke(
48+
sequential_search_t<ExPolicy>, Iter1 it, Iter2 s_first,
49+
std::size_t base_idx, std::size_t part_size, std::size_t diff,
50+
std::size_t count, Token& tok, Pred&& op, Proj1&& proj1,
51+
Proj2&& proj2)
52+
{
53+
using reference = typename std::iterator_traits<Iter1>::reference;
54+
Iter1 curr = it;
55+
util::loop_idx_n<ExPolicy>(base_idx, it, part_size, tok,
56+
[diff, count, s_first, &tok, &curr, op = HPX_FORWARD(Pred, op),
57+
proj1 = HPX_FORWARD(Proj1, proj1),
58+
proj2 = HPX_FORWARD(Proj2, proj2)](
59+
reference v, std::size_t i) mutable -> void {
60+
++curr;
61+
if (HPX_INVOKE(op, HPX_INVOKE(proj1, v),
62+
HPX_INVOKE(proj2, *s_first)))
63+
{
64+
std::size_t local_count = 1;
65+
Iter2 needle = s_first;
66+
Iter1 mid = curr;
67+
// clang-format off
68+
for (std::size_t len = 0;
69+
local_count != diff && len != count;
70+
++local_count, ++len, ++mid)
71+
// clang-format on
72+
{
73+
if (!HPX_INVOKE(op, HPX_INVOKE(proj1, *mid),
74+
HPX_INVOKE(proj2, *++needle)))
75+
break;
76+
}
77+
if (local_count == diff)
78+
tok.cancel(i);
79+
}
80+
});
81+
}
82+
};
83+
84+
///////////////////////////////////////////////////////////////////////////
85+
// sequential_search_n dispatch tag
86+
HPX_CXX_CORE_EXPORT template <typename ExPolicy>
87+
struct sequential_search_n_t final
88+
: hpx::functional::detail::tag_fallback<sequential_search_n_t<ExPolicy>>
89+
{
90+
private:
91+
// Partitioned path: called from search_n::parallel() f1 for each chunk.
92+
// Checks each starting position in [base_idx, base_idx+part_size) for
93+
// count consecutive elements equal to value_proj.
94+
template <typename Iter, typename Size, typename V, typename Token,
95+
typename Pred, typename Proj>
96+
friend inline constexpr void tag_fallback_invoke(
97+
sequential_search_n_t<ExPolicy>, Iter it, std::size_t base_idx,
98+
std::size_t part_size, std::ptrdiff_t max_start, Size count,
99+
V const& value_proj, Token& tok, Pred&& pred, Proj&& proj)
100+
{
101+
using difference_type =
102+
typename std::iterator_traits<Iter>::difference_type;
103+
using reference = typename std::iterator_traits<Iter>::reference;
104+
std::size_t idx = 0;
105+
util::loop_idx_n<ExPolicy>(base_idx, it, part_size, tok,
106+
[max_start, count, it, &value_proj, &tok, &idx,
107+
pred = HPX_FORWARD(Pred, pred),
108+
proj = HPX_FORWARD(Proj, proj)](
109+
reference, std::size_t abs_idx) mutable -> void {
110+
if (static_cast<difference_type>(abs_idx) >= max_start)
111+
return;
112+
Iter start = it;
113+
std::advance(start, static_cast<difference_type>(idx));
114+
++idx;
115+
Iter curr = start;
116+
Size matched = 0;
117+
while (matched < count &&
118+
HPX_INVOKE(pred, HPX_INVOKE(proj, *curr), value_proj))
119+
{
120+
++curr;
121+
++matched;
122+
}
123+
if (matched == count)
124+
tok.cancel(abs_idx);
125+
});
126+
}
127+
};
128+
34129
///////////////////////////////////////////////////////////////////////////
35130
// search
36131
HPX_CXX_CORE_EXPORT template <typename FwdIter, typename Sent>
@@ -69,7 +164,6 @@ namespace hpx::parallel::detail {
69164
Sent last, FwdIter2 s_first, Sent2 s_last, Pred&& op, Proj1&& proj1,
70165
Proj2&& proj2)
71166
{
72-
using reference = typename std::iterator_traits<FwdIter>::reference;
73167
using difference_type =
74168
typename std::iterator_traits<FwdIter>::difference_type;
75169
using s_difference_type =
@@ -130,38 +224,10 @@ namespace hpx::parallel::detail {
130224
proj2 = HPX_FORWARD(Proj2, proj2)](FwdIter it,
131225
std::size_t part_size,
132226
std::size_t base_idx) mutable -> void {
133-
FwdIter curr = it;
134-
135-
hpx::parallel::util::loop_idx_n<policy_type>(base_idx, it,
136-
part_size, tok,
137-
[diff, count, s_first, &tok, &curr,
138-
op = HPX_FORWARD(Pred, op),
139-
proj1 = HPX_FORWARD(Proj1, proj1),
140-
proj2 = HPX_FORWARD(Proj2, proj2)](
141-
reference v, std::size_t i) -> void {
142-
++curr;
143-
if (HPX_INVOKE(op, HPX_INVOKE(proj1, v),
144-
HPX_INVOKE(proj2, *s_first)))
145-
{
146-
difference_type local_count = 1;
147-
FwdIter2 needle = s_first;
148-
FwdIter mid = curr;
149-
150-
// clang-format off
151-
for (difference_type len = 0;
152-
local_count != diff && len != count;
153-
++local_count, ++len, ++mid)
154-
// clang-format on
155-
{
156-
if (!HPX_INVOKE(op, HPX_INVOKE(proj1, *mid),
157-
HPX_INVOKE(proj2, *++needle)))
158-
break;
159-
}
160-
161-
if (local_count == diff)
162-
tok.cancel(i);
163-
}
164-
});
227+
sequential_search_t<policy_type>{}(it, s_first, base_idx,
228+
part_size, static_cast<std::size_t>(diff),
229+
static_cast<std::size_t>(count), tok, HPX_FORWARD(Pred, op),
230+
HPX_FORWARD(Proj1, proj1), HPX_FORWARD(Proj2, proj2));
165231
};
166232

167233
auto f2 = [=](auto&&... data) mutable -> FwdIter {
@@ -278,33 +344,14 @@ namespace hpx::parallel::detail {
278344
hpx::parallel::util::cancellation_token<difference_type> tok(
279345
max_start);
280346

281-
auto f1 = [first, max_start, count, value_proj,
347+
auto f1 = [max_start, count, value_proj,
282348
pred = HPX_FORWARD(Pred, pred),
283349
proj = HPX_FORWARD(Proj, proj),
284350
tok](FwdIter it, std::size_t part_size,
285351
std::size_t base_idx) mutable -> void {
286-
util::loop_idx_n<policy_type>(base_idx, it, part_size, tok,
287-
[=, &tok](auto&&, std::size_t idx) mutable -> void {
288-
difference_type start_idx =
289-
static_cast<difference_type>(idx);
290-
if (start_idx >= max_start)
291-
return;
292-
293-
FwdIter start = first;
294-
std::advance(start, start_idx);
295-
296-
FwdIter curr = start;
297-
Size matched = 0;
298-
299-
while (matched < count && pred(proj(*curr), value_proj))
300-
{
301-
++curr;
302-
++matched;
303-
}
304-
305-
if (matched == count)
306-
tok.cancel(start_idx);
307-
});
352+
sequential_search_n_t<policy_type>{}(it, base_idx, part_size,
353+
static_cast<std::ptrdiff_t>(max_start), count, value_proj,
354+
tok, HPX_FORWARD(Pred, pred), HPX_FORWARD(Proj, proj));
308355
};
309356

310357
auto f2 = [first, last, max_start, tok](

libs/core/algorithms/include/hpx/parallel/datapar.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <hpx/parallel/datapar/mismatch.hpp>
2525
#include <hpx/parallel/datapar/reduce.hpp>
2626
#include <hpx/parallel/datapar/replace.hpp>
27+
#include <hpx/parallel/datapar/search.hpp>
2728
#include <hpx/parallel/datapar/transfer.hpp>
2829
#include <hpx/parallel/datapar/transform_loop.hpp>
2930
#include <hpx/parallel/datapar/zip_iterator.hpp>

0 commit comments

Comments
 (0)