1#include "gtest/gtest.h"
3#include "Kokkos_Macros.hpp"
4#ifdef KOKKOS_ENABLE_EXPERIMENTAL_CXX20_MODULES
7# include "Kokkos_Core.hpp"
40 return std::is_constant_evaluated();
84 static_assert(std::is_aggregate_v<typename ParallelReduceDataTest::data_t>);
85 static_assert(std::is_aggregate_v<typename ParallelReduceDataTest::labeled_data_t>);
86 static_assert(std::is_aggregate_v<typename ParallelReduceDataTest::multi_data_t>);
89 static_assert(std::is_nothrow_move_constructible_v<typename ParallelReduceDataTest::data_t>);
90 static_assert(std::is_nothrow_move_constructible_v<typename ParallelReduceDataTest::labeled_data_t>);
91 static_assert(std::is_nothrow_move_constructible_v<typename ParallelReduceDataTest::multi_data_t>);
95 std::same_as<typename ParallelReduceDataTest::data_t::functor_t, typename ParallelReduceDataTest::functor_t>);
96 static_assert(std::same_as<
101 std::same_as<typename ParallelReduceDataTest::data_t::reducer_t, typename ParallelReduceDataTest::reducer_t>);
103 std::same_as<typename ParallelReduceDataTest::data_t::properties_t, Kokkos::Execution::Impl::properties<>>);
104 static_assert(std::same_as<
121 static_assert(std::alignment_of_v<typename ParallelReduceDataTest::functor_t> == 1);
124 static_assert(std::alignment_of_v<typename ParallelReduceDataTest::iter_space_t> == 4);
127 static_assert(std::alignment_of_v<typename ParallelReduceDataTest::reducer_t> == 1);
129 static_assert(std::is_empty_v<typename ParallelReduceDataTest::functor_t>);
130 static_assert(std::is_standard_layout_v<typename ParallelReduceDataTest::data_t>);
131 static_assert(std::is_empty_v<typename ParallelReduceDataTest::reducer_t>);
156 Kokkos::RangePolicy<TEST_EXECUTION_SPACE>,
161 constexpr labeled_data_iter_space_t with_iter_space{
168 const auto with_range_policy = with_iter_space.transform_policy_or_iter_space(
169 [](
const auto& pol) {
return Kokkos::RangePolicy<TEST_EXECUTION_SPACE>(pol.first, pol.last); });
171 static_assert(std::same_as<
decltype(with_range_policy),
const labeled_data_range_policy_t>);
173 ASSERT_EQ(with_range_policy.policy_or_iter_space.begin(), 4);
174 ASSERT_EQ(with_range_policy.policy_or_iter_space.end(), 6);
189 using data_with_counter_t =
196 const auto data_from_xvalue = std::move(from_xvalue).transform_policy_or_iter_space([](
const auto&) {
199 ASSERT_EQ(counter_t::copy_assignments, 0);
200 ASSERT_EQ(counter_t::copy_constructions, 0);
201 ASSERT_EQ(counter_t::move_assignments, 0);
202#if defined(KOKKOS_COMPILER_CLANG) || defined(KOKKOS_COMPILER_INTEL_LLVM)
203 ASSERT_EQ(counter_t::move_constructions, 3);
205 ASSERT_EQ(counter_t::move_constructions, 2);
212 const auto data_from_prvalue = data_with_counter_t{counter_t{}, counter_t{},
iter_space_t{},
reducer_t{}}
213 .transform_policy_or_iter_space(
215 ASSERT_EQ(counter_t::copy_assignments, 0);
216 ASSERT_EQ(counter_t::copy_constructions, 0);
217 ASSERT_EQ(counter_t::move_assignments, 0);
218#if defined(KOKKOS_COMPILER_CLANG) || defined(KOKKOS_COMPILER_INTEL_LLVM)
219 ASSERT_EQ(counter_t::move_constructions, 3);
221 ASSERT_EQ(counter_t::move_constructions, 2);
228 using label_t = std::string;
229 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
230 using reducer_t = Kokkos::View<int, TEST_EXECUTION_SPACE>;
233 std::declval<label_t>(),
234 std::declval<policy_t>(),
236 std::declval<reducer_t>())));
239 std::declval<const label_t&>(),
240 std::declval<policy_t>(),
242 std::declval<reducer_t>())));
245 std::declval<const char*>(),
246 std::declval<policy_t>(),
248 std::declval<reducer_t>())));
251 std::declval<label_t>(),
252 std::declval<policy_t>(),
254 std::declval<reducer_t>())));
257 std::declval<label_t>(),
258 std::declval<policy_t>(),
260 std::declval<reducer_t>())));
262 static_assert(
noexcept(
265 std::declval<label_t>(),
266 std::declval<policy_t>(),
268 std::declval<reducer_t>())));
270 static_assert(!
noexcept(
273 std::declval<const label_t&>(),
274 std::declval<policy_t>(),
276 std::declval<reducer_t>())));
283 std::declval<policy_t>(),
285 std::declval<reducer_t>(),
286 std::declval<label_of_string_t>())));
290 std::declval<policy_t>(),
292 std::declval<reducer_t>(),
293 std::declval<const label_of_string_t&>())));
304 const auto clsr_label =
306 static_assert(std::same_as<
307 decltype(clsr_literal),
308 const stdexec::__closure<
309 Kokkos::Execution::parallel_reduce_t,
310 Kokkos::dims<1, int>,
316 static_assert(std::same_as<
317 decltype(clsr_label),
318 const stdexec::__closure<
319 Kokkos::Execution::parallel_reduce_t,
320 Kokkos::dims<1, int>,
335 using reducer_t = functor_t;
339 Kokkos::dims<1, int>{42},
346 static_assert(std::same_as<
347 decltype(clsr_props),
349 stdexec::just_t::__sender<>,
352 Kokkos::dims<1, int>,
369 using just_sndr_t =
decltype(stdexec::just());
374 using policy_t = Kokkos::RangePolicy<TEST_EXECUTION_SPACE>;
375 using reducer_t = Kokkos::View<int, TEST_EXECUTION_SPACE>;
380 static_assert(stdexec::__sender_for<pred_sndr_t, Kokkos::Execution::parallel_reduce_t>);
382 static_assert(std::same_as<stdexec::__data_of<pred_sndr_t>, pred_data_t>);
384 static_assert(stdexec::__nbr_children_of<pred_sndr_t> == 1);
385 static_assert(std::same_as<stdexec::__child_of<pred_sndr_t>, just_sndr_t>);
393TEST(ParallelReduceTest, closure_object_creation_perfectly_forwards_functor) {
396 const Kokkos::RangePolicy<TEST_EXECUTION_SPACE> policy(0, 1);
397 const Kokkos::View<int, TEST_EXECUTION_SPACE> reducer;
404 ASSERT_EQ(counter_t::copy_constructions, 1);
405 ASSERT_EQ(counter_t::move_constructions, 0);
408 const auto closure_from_xvalue_functor =
411 ASSERT_EQ(counter_t::copy_constructions, 1);
412 ASSERT_EQ(counter_t::move_constructions, 1);
417 ASSERT_EQ(counter_t::copy_constructions, 1);
418 ASSERT_EQ(counter_t::move_constructions, 2);
Kokkos::Execution::Impl::ParallelReduceData< functor_t, iter_space_t, reducer_t > data_t
Kokkos::range_slice< int, int > iter_space_t
Kokkos::Execution::Impl::ParallelReduceData< functor_t, iter_space_t, reducer_t, Kokkos::Execution::Impl::Label< std::string_view > > labeled_data_t
Kokkos::Execution::Impl::ParallelReduceData< functor_t, iter_space_t, reducer_t, Kokkos::Execution::Impl::Label< std::string >, std::monostate > multi_data_t
Tests::Utils::Functors::NoOp< false, false, false > functor_t
Label(T) -> Label< std::string >
consteval Impl::Label< std::string_view > label(std::string_view str) noexcept
constexpr parallel_reduce_t parallel_reduce
consteval bool test_parallel_reduce_many_properties()
consteval bool test_parallel_reduce_data_size()
consteval bool test_parallel_reduce_in_constant_expression()
consteval bool test_parallel_reduce_sndr_decomposition()
consteval bool test_parallel_reduce_data_concept()
consteval bool test_parallel_reduce_data_traits()
consteval bool test_label_storage()
consteval bool test_parallel_reduce_noexcept_contract()
ExecPolicyOrIterSpace policy_or_iter_space_t
properties< Properties... > properties_t
Count construction, move/copy construction, move/copy assignment and destruction atomically on host.