Skip to content
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
f0032e1
Update exception_list.hpp
charan-003 Nov 9, 2024
878e897
Update exception_list.hpp
charan-003 Nov 10, 2024
9e03e6f
Update exception_list.hpp
charan-003 Nov 10, 2024
5f31ce5
Update exception_list.hpp
charan-003 Nov 10, 2024
05f1c62
Merge branch 'STEllAR-GROUP:master' into master
charan-003 Mar 27, 2025
824eed8
Merge branch 'STEllAR-GROUP:master' into master
charan-003 May 26, 2025
31bcaa0
Merge branch 'STEllAR-GROUP:master' into master
charan-003 Aug 23, 2025
e5cc2e4
Merge branch 'STEllAR-GROUP:master' into master
charan-003 Nov 28, 2025
8849a45
Merge branch 'STEllAR-GROUP:master' into master
charan-003 Nov 29, 2025
f465cc1
Rebase feature/forward-bulk onto master
Nov 29, 2025
b71c8d0
Fix rebase conflicts: remove non-existent stdexec forwards and fix ex…
Nov 29, 2025
1f8b31b
revert a file
Nov 29, 2025
f4925c6
few changes
Nov 29, 2025
685249a
if defined stdexec
Nov 29, 2025
6d2a7ca
fix errors in foreach
Nov 29, 2025
862697f
clang format
Nov 29, 2025
e955387
for each test 1
Nov 30, 2025
39a8e05
iteration structs
Nov 30, 2025
c802802
forcing 2 threads for performance tests
Dec 1, 2025
ded57a3
Merge branch 'master' into feature/forward-bulk
charan-003 Dec 1, 2025
610b3fd
iterate over non-integral shapes manually
Dec 2, 2025
91b9649
fix
Dec 2, 2025
1a1448c
fix1
Dec 2, 2025
2f03fbb
Merge branch 'master' into feature/forward-bulk
charan-003 Dec 5, 2025
19bdc0d
Merge branch 'master' into feature/forward-bulk
charan-003 Dec 8, 2025
a9a1945
Merge branch 'master' into feature/forward-bulk
charan-003 Dec 8, 2025
c0939a7
Merge branch 'master' into feature/forward-bulk
charan-003 Jan 12, 2026
4d443ac
adding HPX_CXX_EXPORT
Jan 12, 2026
28c6c90
Merge branch 'master' into feature/forward-bulk
charan-003 Jan 19, 2026
ebead17
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 3, 2026
c8166c8
macos errors
Feb 4, 2026
fab8a3e
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 4, 2026
c3dd490
Fix formatting: remove stray '1' character from parameter list
Feb 5, 2026
587f774
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 5, 2026
6f1fcef
revert sheduling property
Feb 6, 2026
63d94d9
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 8, 2026
7bd507f
use const exp
Feb 8, 2026
3ba227e
final changes
Feb 8, 2026
6d45fe5
final changes
Feb 8, 2026
59e35f2
reference fix
Feb 8, 2026
007a706
resolve conflicts
Feb 8, 2026
c199cc1
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 8, 2026
b9a9877
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 9, 2026
42a8df8
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 13, 2026
96234f1
Merge branch 'master' into feature/forward-bulk
isidorostsa Feb 15, 2026
76a11fc
updated namespace
Feb 15, 2026
7bcbc7d
minor changes
Feb 15, 2026
e5de5a8
clang format
Feb 15, 2026
fc4e473
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 17, 2026
3d6df30
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 17, 2026
b5055e7
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 20, 2026
314b7cf
resolve conflicts
Feb 21, 2026
c488ea6
format
Feb 21, 2026
ccc8ace
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 21, 2026
3a9b56b
adding proper overloads
charan-003 Feb 24, 2026
be8f1fd
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 24, 2026
357377e
fix compile rrors in partitioner_iteration
Feb 24, 2026
a0d47a0
revert few changes
Feb 24, 2026
ceb99a0
remove ifdef
Feb 24, 2026
858cc36
Merge branch 'master' into feature/forward-bulk
charan-003 Feb 26, 2026
2005280
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 5, 2026
bd3c9a3
Support both integral and range shapes in bulk operations
charan-003 Mar 6, 2026
fc0853a
format
Mar 6, 2026
bfb9680
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 6, 2026
8671fe2
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 8, 2026
5c73f37
add exports to policies
Mar 10, 2026
a1f9336
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 10, 2026
88ff533
apply std::decay_t
Mar 10, 2026
b823699
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 11, 2026
fc9837c
Merge branch 'master' into feature/forward-bulk
charan-003 Mar 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ namespace hpx {
#else // DOXYGEN

#include <hpx/config.hpp>
#include <hpx/assert.hpp>
#include <hpx/modules/concepts.hpp>
#include <hpx/modules/datastructures.hpp>
#include <hpx/modules/executors.hpp>
Expand Down Expand Up @@ -622,6 +623,12 @@ namespace hpx::parallel {
transform_binary_projected<F_, Proj1, Proj2>{
f_, proj1_, proj2_});
}

HPX_HOST_DEVICE HPX_FORCEINLINE constexpr void operator()(
std::size_t) const noexcept
{
HPX_ASSERT(false);
}
};

HPX_CXX_CORE_EXPORT template <typename ExPolicy, typename F>
Expand Down Expand Up @@ -679,6 +686,12 @@ namespace hpx::parallel {
hpx::get<0>(iters), part_size, hpx::get<1>(iters),
hpx::get<2>(iters), f_);
}

HPX_HOST_DEVICE HPX_FORCEINLINE constexpr void operator()(
std::size_t) const noexcept
{
HPX_ASSERT(false);
}
};

///////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,78 @@
///////////////////////////////////////////////////////////////////////////////
namespace hpx::parallel::util::detail {

// Helper to detect if a type is tuple-like
template <typename T, typename = void>
struct is_tuple_like : std::false_type
{
};

template <typename T>
struct is_tuple_like<T,
std::void_t<decltype(hpx::tuple_size<std::decay_t<T>>::value)>>
: std::true_type
{
};

template <typename T>
inline constexpr bool is_tuple_like_v = is_tuple_like<T>::value;
Comment thread
hkaiser marked this conversation as resolved.
Outdated

// Hand-crafted function object allowing to replace a more complex
// bind(hpx::functional::invoke_fused(), f1, _1)
HPX_CXX_CORE_EXPORT template <typename Result, typename F>
struct partitioner_iteration
{
std::decay_t<F> f_;

// Overload for tuple-like types - unpack using index_pack
template <typename T>
requires(is_tuple_like_v<T>)
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Result operator()(T&& t)
{
using embedded_index_pack_type = hpx::util::make_index_pack<
hpx::tuple_size<std::decay_t<T>>::value>;

// NOLINTBEGIN(bugprone-use-after-move)
if constexpr (std::is_invocable_v<F, embedded_index_pack_type, T&&>)
{
return HPX_INVOKE_R(
Result, f_, embedded_index_pack_type{}, HPX_FORWARD(T, t));
}
else
{
return (*this)(embedded_index_pack_type{}, t);
}
// NOLINTEND(bugprone-use-after-move)
}

// Overload for non-tuple types (std::size_t from stdexec bulk)
template <typename T>
requires(!is_tuple_like_v<T>)
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Result operator()(T&& t)
{
return hpx::invoke_fused_r<Result>(f_, HPX_FORWARD(T, t));
return HPX_INVOKE_R(Result, f_, HPX_FORWARD(T, t));
}
Comment thread
charan-003 marked this conversation as resolved.

template <std::size_t... Is, typename... Ts>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Result operator()(
hpx::util::index_pack<Is...>, hpx::tuple<Ts...>& t)
{
return HPX_INVOKE(f_, hpx::get<Is>(t)...);
return HPX_INVOKE_R(Result, f_, hpx::get<Is>(t)...);
}

template <std::size_t... Is, typename... Ts>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Result operator()(
hpx::util::index_pack<Is...>, hpx::tuple<Ts...> const& t)
{
return HPX_INVOKE_R(Result, f_, hpx::get<Is>(t)...);
}

template <std::size_t... Is, typename... Ts>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Result operator()(
hpx::util::index_pack<Is...>, hpx::tuple<Ts...>&& t)
{
// NOLINTBEGIN(bugprone-use-after-move)
return HPX_INVOKE(f_, hpx::get<Is>(HPX_MOVE(t))...);
return HPX_INVOKE_R(Result, f_, hpx::get<Is>(HPX_MOVE(t))...);
// NOLINTEND(bugprone-use-after-move)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ namespace hpx::parallel::util {
namespace ex = hpx::execution::experimental;
if constexpr (ex::is_sender_v<decayed_items> && !is_future)
{
return ex::let_value(workitems,
return ex::let_value(HPX_FORWARD(Items, workitems),
[f = HPX_FORWARD(F, f),
cleanup = HPX_FORWARD(Cleanup, cleanup)](
auto&& all_parts) mutable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ void test_for_each()
test_for_each_sender(hpx::launch::async, par(task), IteratorTag());
test_for_each_sender(hpx::launch::sync, unseq(task), IteratorTag());
test_for_each_sender(hpx::launch::async, par_unseq(task), IteratorTag());

test_for_each_sender_bulk(hpx::launch::sync, seq(task), IteratorTag());
test_for_each_sender_bulk(hpx::launch::async, par(task), IteratorTag());
test_for_each_sender_bulk(hpx::launch::sync, unseq(task), IteratorTag());
test_for_each_sender_bulk(
hpx::launch::async, par_unseq(task), IteratorTag());
}

void for_each_test()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,13 @@ void test_for_each_exception_async(ExPolicy&& p, IteratorTag)
caught_exception = true;
test::test_num_exceptions<ExPolicy, IteratorTag>::call(p, e);
}
catch (std::runtime_error const&)
{
caught_exception = true;
}
Comment thread
charan-003 marked this conversation as resolved.
catch (...)
{
HPX_TEST(false);
caught_exception = true;
Comment thread
isidorostsa marked this conversation as resolved.
Comment thread
charan-003 marked this conversation as resolved.
}

HPX_TEST(caught_exception);
Expand Down Expand Up @@ -334,7 +338,8 @@ void test_for_each_bad_alloc_async(ExPolicy&& p, IteratorTag)
}

template <typename Policy, typename ExPolicy, typename IteratorTag>
void test_for_each_sender(Policy l, ExPolicy&& p, IteratorTag)
void test_for_each_sender(
[[maybe_unused]] Policy l, [[maybe_unused]] ExPolicy&& p, IteratorTag)
{
using base_iterator = std::vector<std::size_t>::iterator;
using iterator = test::test_iterator<base_iterator, IteratorTag>;
Expand All @@ -350,8 +355,8 @@ void test_for_each_sender(Policy l, ExPolicy&& p, IteratorTag)
auto f = [](std::size_t& v) { v = 42; };

using scheduler_t = ex::thread_pool_policy_scheduler<Policy>;

auto exec = ex::explicit_scheduler_executor(scheduler_t(l));

auto result = hpx::get<0>(
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
*tt::sync_wait(ex::just(rng, f) | hpx::ranges::for_each(p.on(exec))));
Expand All @@ -367,7 +372,51 @@ void test_for_each_sender(Policy l, ExPolicy&& p, IteratorTag)
}

template <typename Policy, typename ExPolicy, typename IteratorTag>
void test_for_each_exception_sender(Policy l, ExPolicy&& p, IteratorTag)
void test_for_each_sender_bulk(
[[maybe_unused]] Policy l, [[maybe_unused]] ExPolicy&& p, IteratorTag)
{
using base_iterator = std::vector<std::size_t>::iterator;
using iterator = test::test_iterator<base_iterator, IteratorTag>;

std::vector<std::size_t> c(10007);
std::iota(std::begin(c), std::end(c), std::rand());

namespace ex = hpx::execution::experimental;
namespace tt = hpx::this_thread::experimental;

auto rng = hpx::util::iterator_range(
iterator(std::begin(c)), iterator(std::end(c)));
auto f = [](std::size_t& v) { v = 42; };

// Test stdexec bulk sender directly (not using HPX for_each algorithm)
auto result = hpx::get<0>(
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
*tt::sync_wait(
ex::just(rng, f) | ex::let_value([](auto&& rng, auto&& f) {
auto begin_it = rng.begin();
return ex::bulk(ex::just(), rng.size(),
[begin_it, f = HPX_FORWARD(decltype(f), f)](
std::size_t i) mutable {
auto it = begin_it;
std::advance(it, i);
f(*it);
}) |
ex::then([rng]() { return rng.end(); });
})));
Comment thread
charan-003 marked this conversation as resolved.
HPX_TEST(result == iterator(std::end(c)));

// verify values
std::size_t count = 0;
std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void {
HPX_TEST_EQ(v, static_cast<std::size_t>(42));
++count;
});
HPX_TEST_EQ(count, c.size());
}

template <typename Policy, typename ExPolicy, typename IteratorTag>
void test_for_each_exception_sender(
[[maybe_unused]] Policy l, ExPolicy&& p, IteratorTag)
{
namespace ex = hpx::execution::experimental;
namespace tt = hpx::this_thread::experimental;
Expand All @@ -385,28 +434,48 @@ void test_for_each_exception_sender(Policy l, ExPolicy&& p, IteratorTag)
bool caught_exception = false;
try
{
using scheduler_t = ex::thread_pool_policy_scheduler<Policy>;

auto exec = ex::explicit_scheduler_executor(scheduler_t(l));
tt::sync_wait(ex::just(rng, f) | hpx::ranges::for_each(p.on(exec)));

HPX_TEST(false);
auto result = tt::sync_wait(
ex::just(rng, f) | ex::let_value([](auto&& rng, auto&& f) {
auto begin_it = rng.begin();
return ex::bulk(ex::just(), rng.size(),
[begin_it, f = HPX_FORWARD(decltype(f), f)](
std::size_t i) mutable {
auto it = begin_it;
std::advance(it, i);
f(*it);
});
}));

// If sync_wait returns without exception, check if result indicates error
if (!result.has_value())
{
caught_exception = true;
}
else
{
HPX_TEST(false);
}
Comment thread
charan-003 marked this conversation as resolved.
}
catch (hpx::exception_list const& e)
{
caught_exception = true;
test::test_num_exceptions<ExPolicy, IteratorTag>::call(p, e);
}
catch (std::runtime_error const&)
{
caught_exception = true;
}
Comment thread
charan-003 marked this conversation as resolved.
catch (...)
{
HPX_TEST(false);
caught_exception = true;
Comment thread
charan-003 marked this conversation as resolved.
}

HPX_TEST(caught_exception);
}

template <typename Policy, typename ExPolicy, typename IteratorTag>
void test_for_each_bad_alloc_sender(Policy l, ExPolicy&& p, IteratorTag)
void test_for_each_bad_alloc_sender(
[[maybe_unused]] Policy l, [[maybe_unused]] ExPolicy&& p, IteratorTag)
{
namespace ex = hpx::execution::experimental;
namespace tt = hpx::this_thread::experimental;
Expand All @@ -424,10 +493,17 @@ void test_for_each_bad_alloc_sender(Policy l, ExPolicy&& p, IteratorTag)
bool caught_exception = false;
try
{
using scheduler_t = ex::thread_pool_policy_scheduler<Policy>;

auto exec = ex::explicit_scheduler_executor(scheduler_t(l));
tt::sync_wait(ex::just(rng, f) | hpx::ranges::for_each(p.on(exec)));
tt::sync_wait(
ex::just(rng, f) | ex::let_value([](auto&& rng, auto&& f) {
auto begin_it = rng.begin();
return ex::bulk(ex::just(), rng.size(),
[begin_it, f = HPX_FORWARD(decltype(f), f)](
std::size_t i) mutable {
auto it = begin_it;
std::advance(it, i);
f(*it);
});
}));

HPX_TEST(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ namespace hpx::execution::experimental {
struct as_sender_sender<hpx::future<T>>
: public as_sender_sender_base<hpx::future<T>>
{
#if defined(HPX_HAVE_STDEXEC)
using sender_concept = hpx::execution::experimental::sender_t;
#else
using is_sender = void;
#endif
using future_type = hpx::future<T>;
using base_type = as_sender_sender_base<hpx::future<T>>;
using base_type::future_;
Expand Down Expand Up @@ -217,7 +221,11 @@ namespace hpx::execution::experimental {
struct as_sender_sender<hpx::shared_future<T>>
: as_sender_sender_base<hpx::shared_future<T>>
{
#if defined(HPX_HAVE_STDEXEC)
using sender_concept = hpx::execution::experimental::sender_t;
#else
using is_sender = void;
#endif
using future_type = hpx::shared_future<T>;
using base_type = as_sender_sender_base<hpx::shared_future<T>>;
using base_type::future_;
Expand Down
Loading
Loading