26using namespace Kokkos::utils::callbacks;
34 using variant_t =
typename recorder_listener_t::event_variant_t;
43template <
template <
typename,
typename,
typename,
typename>
class SndrAdptr>
49 using label_t = std::string;
51 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
52 using pfor_sndr_t = SndrAdptr<schd_sndr_t, label_t, functor_t, policy_t>;
56 static_assert(std::same_as<Kokkos::Execution::ExecutionSpaceImpl::exec_of_t<pfor_sndr_t>, TEST_EXECUTION_SPACE>);
62 using completion_signatures_t = stdexec::__completion_signatures_of_t<pfor_sndr_t, stdexec::env<>>;
64 static_assert(stdexec::__mset_eq<
65 stdexec::__mset<stdexec::set_value_t(), stdexec::set_error_t(std::exception_ptr)>,
66 completion_signatures_t
70 static_assert(std::same_as<
71 stdexec::__completion_domain_of_t<stdexec::set_value_t, pfor_sndr_t, stdexec::env<>>,
76 static_assert(std::same_as<
77 stdexec::__completion_scheduler_of_t<stdexec::set_value_t, pfor_sndr_t, stdexec::env<>>,
82 static_assert(stdexec::sender_to<pfor_sndr_t, Tests::Utils::SinkReceiver>);
84 static_assert(std::same_as<
85 stdexec::transform_sender_result_t<pfor_sndr_t, stdexec::env_of_t<Tests::Utils::SinkReceiver>>,
90#if defined(KOKKOS_COMPILER_CLANG) && defined(KOKKOS_ENABLE_CUDA)
98 static_assert(!std::is_nothrow_move_constructible_v<typename ParallelForTest::view_s_t>);
99 static_assert(!std::is_nothrow_move_constructible_v<functor_t>);
101 static_assert(!std::is_nothrow_move_constructible_v<closure_t>);
102 static_assert(!stdexec::__nothrow_connectable<pfor_sndr_t, Tests::Utils::SinkReceiver>);
105 static_assert(stdexec::__nothrow_connectable<pfor_sndr_t, Tests::Utils::SinkReceiver>);
119 using label_t = std::string;
121 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
127 static_assert(std::same_as<
128 stdexec::__data_of<pfor_sndr_t>,
132 static_assert(stdexec::__nbr_children_of<pfor_sndr_t> == 1);
133 static_assert(std::same_as<stdexec::__child_of<pfor_sndr_t>, schd_sndr_t>);
136 static_assert(stdexec::__applicable<
139 const stdexec::env<>&
147template <
typename ViewType,
bool ExpectNoThrowMoveConstructible>
150 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
156 static_assert(std::is_nothrow_move_constructible_v<closure_t> == ExpectNoThrowMoveConstructible);
161#if defined(KOKKOS_COMPILER_CLANG) && defined(KOKKOS_ENABLE_CUDA)
170 constexpr int size = 32;
172 const auto [num_teams, team_size] = [&]() {
174#if defined(KOKKOS_ENABLE_HPX)
175 if constexpr (std::same_as<TEST_EXECUTION_SPACE, Kokkos::Experimental::HPX>) {
176 return std::make_tuple(size, 1);
179 const int team_size_ = std::bit_floor(
static_cast<unsigned short>(std::min(
exec.concurrency(), size / 2)));
180 return std::make_tuple(size / team_size_, team_size_);
183 ASSERT_EQ(team_size * num_teams, size);
185 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
192 Kokkos::TeamPolicy<TEST_EXECUTION_SPACE>(num_teams, team_size),
195 stdexec::sync_wait(std::move(chain));
197 ASSERT_EQ(witness(), size / 2 * (size - 1));
200template <
typename ViewType, Kokkos::ExecutionSpace Exec>
203 const ViewType& witness,
205 auto chain = stdexec::schedule(esc.get_scheduler())
207 "passing label, execution policy and functor",
208 Kokkos::RangePolicy<Exec>(0, size),
213 if constexpr (std::same_as<Exec, Kokkos::DefaultExecutionSpace>) {
214 return std::move(chain)
225 constexpr size_t size = 10;
227 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
229 const auto recorded_events = recorder_listener_t::record(
231 stdexec::sync_wait(std::move(chain));
234 unsigned short int ievent = 0;
236 ASSERT_GE(recorded_events.size(), 3);
247 if constexpr (std::same_as<TEST_EXECUTION_SPACE, Kokkos::DefaultExecutionSpace>) {
256 ASSERT_EQ(witness(), ievent * size / 2 * (size - 1));
261 constexpr size_t size = 10;
263 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
269 std::format(
"{}: hello from pfor", Kokkos::Impl::TypeInfo<TEST_EXECUTION_SPACE>::name()),
270 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
274 .prev = size / 2 * (size - 1), .value = 4, .data = witness.data()})
276 std::format(
"{}: hello again from pfor", Kokkos::Impl::TypeInfo<TEST_EXECUTION_SPACE>::name()),
277 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, 2 * size),
281 recorder_listener_t::record([chain = std::move(chain)]()
mutable { stdexec::sync_wait(std::move(chain)); }),
282 testing::ElementsAre(
288 ASSERT_EQ(witness(), size / 2 * (size - 1) + 4 + 2 * size * (2 * size - 1) / 2);
293 constexpr size_t size = 10;
295 const view_s_t witness(Kokkos::view_alloc(
exec,
"data - shared space"));
297 auto sndr = stdexec::just()
299 std::format(
"{}: hello from pfor", Kokkos::Impl::TypeInfo<TEST_EXECUTION_SPACE>::name()),
300 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(0, size),
304 auto starts_on = stdexec::starts_on(esc.get_scheduler(), std::move(sndr));
307 recorder_listener_t::record(
308 [starts_on = std::move(starts_on)]()
mutable { stdexec::sync_wait(std::move(starts_on)); }),
309 testing::ElementsAre(
313 ASSERT_EQ(witness(), size / 2 * (size - 1));
constexpr std::string dispatch_label(const Exec &, Label &&label)
Get the dispatch label from Exec and label.
#define MATCHER_FOR_BEGIN_PFOR(_exec_, _label_)
#define MATCHER_FOR_BEGIN_FENCE(_exec_, _label_)
static constexpr bool on_device
RecorderListener< EventDiscardMatcher< TEST_EXECUTION_SPACE >, BeginFenceEvent, BeginParallelForEvent > recorder_listener_t
typename recorder_listener_t::event_variant_t variant_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.
constexpr parallel_for_t parallel_for
auto ElementAt(const size_t index, ElementMatcher &&matcher)
consteval bool test_closure_traits()
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_sndr_decomposition()
constexpr bool on_device()
Execution context using a Kokkos execution space under the hood.
auto get_scheduler() const noexcept -> ExecutionSpaceImpl::Scheduler< Exec >
Scheduler for a Kokkos execution space.
Custom algorithm for the Kokkos::parallel_for construct.
decltype(stdexec::schedule(std::declval< scheduler_t >())) schedule_sender_t
Kokkos::View< value_t, Kokkos::SharedSpace > view_s_t
Kokkos::Execution::ExecutionSpaceContext< Exec > context_t
Load the value at data and check it is equal to prev. Then, add value to it.