34using namespace Kokkos::utils::callbacks;
36class TEST_CATEGORY(ParallelForTest)
55 template <
typename...>
typename SndrAdptr,
56 bool ExptIsDispatchingSender,
57 template <
typename>
typename ExptTransformSenderType
64 using label_t = std::string;
66 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
69 using pfor_sndr_t = SndrAdptr<schd_sndr_t, TEST_EXECUTION_SPACE, label_t, functor_t, policy_t>;
73 static_assert(std::same_as<Kokkos::Execution::Impl::exec_of_t<pfor_sndr_t>, TEST_EXECUTION_SPACE>);
79 static_assert(!stdexec::dependent_sender<pfor_sndr_t>);
81 stdexec::get_completion_signatures<pfor_sndr_t>()
82 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
85 static_assert(std::same_as<
86 stdexec::__completion_domain_of_t<stdexec::set_value_t, pfor_sndr_t, stdexec::env<>>,
91 static_assert(std::same_as<
97 static_assert(stdexec::sender_to<pfor_sndr_t, Tests::Utils::SinkReceiver>);
99 static_assert(std::same_as<
100 stdexec::transform_sender_result_t<pfor_sndr_t, stdexec::env_of_t<Tests::Utils::SinkReceiver>>,
104 TEST_EXECUTION_SPACE,
110 static_assert(stdexec::__nothrow_connectable<pfor_sndr_t, Tests::Utils::SinkReceiver>);
115template <
typename Sndr,
typename Exec,
typename Label,
typename Functor,
typename Policy>
121template <
typename Sndr,
typename Exec,
typename Label,
typename Functor,
typename Policy>
140 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
145 static_assert(stdexec::__applicable<
148 const stdexec::env<>&
154static_assert(test_sndr_is_transformable());
157template <
typename IterSpace>
168 static_assert(stdexec::__detail::__has_nothrow_transform_sender<
170 stdexec::set_value_t,
178 decltype(std::declval<typename stdexec::transform_sender_result_t<pfor_sndr_t, stdexec::env<>>::closure_t>()
180 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>
187 test_pfor_sndr_with_index_space_transforms_into_pfor_sndr_with_range_policy<Kokkos::range_slice<size_t, size_t>>());
188static_assert(test_pfor_sndr_with_index_space_transforms_into_pfor_sndr_with_range_policy<Kokkos::dims<1>>());
191template <
typename ViewType>
194 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
202 static_assert(std::is_nothrow_move_constructible_v<closure_t>);
207static_assert(test_closure_traits<typename TEST_CATEGORY(ParallelForTest)::view_s_t>());
208static_assert(test_closure_traits<std::span<int>>());
214 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>,
220 constexpr int size = 32;
222 const auto [num_teams, team_size] = [&]() {
224#if defined(KOKKOS_ENABLE_HPX)
225 if constexpr (std::same_as<TEST_EXECUTION_SPACE, Kokkos::Experimental::HPX>) {
226 return std::make_tuple(size, 1);
229 const int team_size_ = std::bit_floor(
static_cast<unsigned short>(std::min(
exec.concurrency(), size / 2)));
230 return std::make_tuple(size / team_size_, team_size_);
233 ASSERT_EQ(team_size * num_teams, size);
235 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
242 Kokkos::TeamPolicy<TEST_EXECUTION_SPACE>(num_teams, team_size),
245 stdexec::sync_wait(std::move(chain));
247 ASSERT_EQ(witness(), size / 2 * (size - 1));
250template <
typename ViewType, Kokkos::ExecutionSpace Exec>
253 const ViewType& witness,
255 return stdexec::schedule(esc.get_scheduler())
257 "passing label, execution policy and functor",
258 Kokkos::RangePolicy<Exec>(0, size),
271 constexpr size_t size = 10;
273 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
282 testing::ElementsAre(
290 ASSERT_EQ(witness(), 4 * size / 2 * (size - 1) + (4 + 5));
295 constexpr size_t size = 10;
297 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
305 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
309 .prev = size / 2 * (size - 1), .value = 4, .data = witness.data()})
313 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, 2 * size),
318 testing::ElementsAre(
324 ASSERT_EQ(witness(), size / 2 * (size - 1) + 4 + 2 * size * (2 * size - 1) / 2);
329 constexpr size_t size = 10;
331 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
337 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
340 using chain_t =
decltype(chain);
343 stdexec::get_completion_signatures<chain_t>()
344 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
347 std::same_as<stdexec::__completion_domain_of_t<stdexec::set_value_t, chain_t>, stdexec::indeterminate_domain<>>);
350 auto starts_on = stdexec::starts_on(esc.
get_scheduler(), std::move(chain));
352 using starts_on_t =
decltype(starts_on);
354 static_assert(stdexec::__has_eptr_completion<chain_t>);
355 static_assert(!stdexec::dependent_sender<starts_on_t>);
357 stdexec::get_completion_signatures<starts_on_t>()
358 == stdexec::completion_signatures<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>{});
366 static_assert(stdexec::__is_instance_of<
367 stdexec::transform_sender_result_t<
369 stdexec::env_of_t<Kokkos::Execution::Impl::SyncWait::Receiver<TEST_EXECUTION_SPACE>>
371 stdexec::__seq::__sndr
376 ASSERT_THAT(recorded_events, [&]() {
378 return testing::ElementsAre(
383 return testing::ElementsAre(
389 ASSERT_EQ(witness(), size / 2 * (size - 1));
394 constexpr size_t size = 10;
396 const view_s_t data(Kokkos::view_alloc(
exec,
"data - shared space"));
398 std::atomic<size_t> count = 0;
404 stdexec::sender
auto sndr =
405 stdexec::read_env(stdexec::get_allocator)
411 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
415 ASSERT_EQ(data(), 0) <<
"Eager execution is not allowed.";
419 ASSERT_THAT(recorded_events, [&]() {
421 return testing::ElementsAre(
426 return testing::ElementsAre(
432 ASSERT_EQ(data(), size / 2 * (size - 1));
434 ASSERT_EQ(value, 42);
444 const Kokkos::RangePolicy<TEST_EXECUTION_SPACE> policy(0, 1);
450 const stdexec::operation_state
auto opstate_from_lvalue_functor = stdexec::connect(
454 ASSERT_EQ(counter_t::copy_assignments, 0);
455 ASSERT_EQ(counter_t::copy_constructions, 1);
456 ASSERT_EQ(counter_t::move_assignments, 0);
457 ASSERT_EQ(counter_t::move_constructions, 6);
462 const stdexec::operation_state
auto closure_from_xvalue_functor = stdexec::connect(
466 ASSERT_EQ(counter_t::copy_assignments, 0);
467 ASSERT_EQ(counter_t::copy_constructions, 0);
468 ASSERT_EQ(counter_t::move_assignments, 0);
469 ASSERT_EQ(counter_t::move_constructions, 7);
474 const stdexec::operation_state
auto closure_from_prvalue_functor = stdexec::connect(
478 ASSERT_EQ(counter_t::copy_assignments, 0);
479 ASSERT_EQ(counter_t::copy_constructions, 0);
480 ASSERT_EQ(counter_t::move_assignments, 0);
481 ASSERT_EQ(counter_t::move_constructions, 7);
constexpr std::string dispatch_label(const Exec &, const std::string_view label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_SINGLE(_exec_, _label_)
#define MATCHER_FOR_WAIT_EVENT(_record_event_variant_)
#define MATCHER_FOR_BEGIN_PFOR(_exec_, _label_)
#define MATCHER_FOR_RECORD_EVENT(_exec_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
#define TEST_CATEGORY(_name_)
RecorderListener< EventDiscardMatcher< TEST_EXECUTION_SPACE >, BeginFenceEvent, BeginParallelForEvent, BeginSingleEvent, Kokkos::Execution::Impl::RecordEvent, Kokkos::Execution::Impl::WaitEvent > recorder_listener_t
Concept for a sender whose completion scheduler is Kokkos::Execution::ExecutionSpaceImpl::Scheduler.
Concept that constrains the type of a sender that dispatches a functor for execution.
std::invoke_result_t< stdexec::get_completion_scheduler_t< Tag >, stdexec::env_of_t< Sndr >, Env... > completion_scheduler_of_t
Retrieve the completion scheduler for a given completion tag.
constexpr auto display_string_of() noexcept -> std::string_view
constexpr parallel_for_t parallel_for
Kokkos::Execution::ExecutionSpaceImpl::ParallelForSender< Kokkos::Execution::parallel_for_t, Sndr, Exec, Kokkos::Execution::Impl::ParallelForData< Functor, Policy, Kokkos::Execution::Impl::Label< Label > > > pfor_impl_t
consteval bool test_pfor_sndr_with_index_space_transforms_into_pfor_sndr_with_range_policy()
consteval bool test_sndr_traits()
auto closure_object_creation_overloads(const size_t size, const ViewType &witness, const Kokkos::Execution::ExecutionSpaceContext< Exec > &esc) -> stdexec::sender auto
consteval bool test_closure_traits()
consteval bool test_sndr_is_transformable()
Kokkos::Execution::Impl::ParallelForSender< Sndr, Kokkos::Execution::Impl::ParallelForData< Functor, Policy, Kokkos::Execution::Impl::Label< Label > > > pfor_generic_t
auto record_sync_wait(Sndr &&sndr)
consteval bool check_continues_on_after_just_stopped()
constexpr check_rcvr_env_queryable_with_t< true, Queries... > check_rcvr_env_queryable_with
auto round_trip_allocate(Allocator &allocator, T &&value)
Tests::Utils::Functors::NoOp< false, false, false > NoOp
Matcher to filter out events that are just noise for tests.
Execution context using a Kokkos execution space under the hood.
auto get_scheduler() const noexcept -> ExecutionSpaceImpl::Scheduler< execution_space >
Scheduler for a Kokkos execution space.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling record.
Event to be sent to Kokkos::utils::callbacks::dispatch when calling wait.
Custom algorithm for the Kokkos::parallel_for construct.
Kokkos::View< value_t, Kokkos::SharedSpace > view_s_t
Kokkos::Execution::ExecutionSpaceContext< Exec > context_t
Count construction, move/copy construction, move/copy assignment and destruction atomically on host.
Load the value at data and check it is equal to prev. Then, add value to it.
A receiver that can handle all completions and does nothing with them.
A minimal tracking allocator.