Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit ebc797d

Browse files
[SYCL] Add a test targeting internal reduction APIs
That way we can bypass strategy selection and test any of them with the same type/operation.
1 parent 5d63e2a commit ebc797d

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

SYCL/Reduction/reduction_internal.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
3+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %ACC_RUN_PLACEHOLDER %t.out
5+
6+
#include <sycl/sycl.hpp>
7+
using namespace sycl;
8+
9+
template <int Dims> auto get_global_range(range<Dims> Range) { return Range; }
10+
template <int Dims> auto get_global_range(nd_range<Dims> NDRange) {
11+
return NDRange.get_global_range();
12+
}
13+
14+
template <int Dims, bool WithOffset>
15+
auto get_global_id(item<Dims, WithOffset> Item) {
16+
return Item.get_id();
17+
}
18+
template <int Dims> auto get_global_id(nd_item<Dims> NDItem) {
19+
return NDItem.get_global_id();
20+
}
21+
22+
template <int Dims> auto get_global_id(id<Dims> Id) { return Id; }
23+
24+
template <bool UseUSM, bool InitToIdentity,
25+
detail::reduction::strategy Strategy, typename RangeTy>
26+
static void test(RangeTy Range) {
27+
queue q;
28+
29+
// We can select strategy explicitly so no need to test all combinations of
30+
// types/operations.
31+
using T = int;
32+
using BinOpTy = std::plus<T>;
33+
34+
T Init{19};
35+
36+
auto Red = [&]() {
37+
if constexpr (UseUSM)
38+
return malloc_device<T>(1, q);
39+
else
40+
return buffer<T, 1>{1};
41+
}();
42+
auto GetRedAcc = [&](handler &cgh) {
43+
if constexpr (UseUSM)
44+
return Red;
45+
else
46+
return accessor{Red, cgh};
47+
};
48+
49+
q.submit([&](handler &cgh) {
50+
auto RedAcc = GetRedAcc(cgh);
51+
cgh.single_task([=]() { RedAcc[0] = Init; });
52+
}).wait();
53+
54+
q.submit([&](handler &cgh) {
55+
auto RedSycl = [&]() {
56+
if constexpr (UseUSM)
57+
if constexpr (InitToIdentity)
58+
return reduction(Red, BinOpTy{},
59+
property::reduction::initialize_to_identity{});
60+
else
61+
return reduction(Red, BinOpTy{});
62+
else if constexpr (InitToIdentity)
63+
return reduction(Red, cgh, BinOpTy{},
64+
property::reduction::initialize_to_identity{});
65+
else
66+
return reduction(Red, cgh, BinOpTy{});
67+
}();
68+
detail::reduction_parallel_for<detail::auto_name, Strategy>(
69+
cgh, Range, ext::oneapi::experimental::detail::empty_properties_t{},
70+
RedSycl, [=](auto Item, auto &Red) { Red.combine(T{1}); });
71+
}).wait();
72+
73+
auto *Result = malloc_shared<T>(1, q);
74+
q.submit([&](handler &cgh) {
75+
auto RedAcc = GetRedAcc(cgh);
76+
cgh.single_task([=]() { *Result = RedAcc[0]; });
77+
}).wait();
78+
79+
auto N = get_global_range(Range).size();
80+
int Expected = InitToIdentity ? N : Init + N;
81+
#ifdef __PRETTY_FUNCTION__
82+
std::cout << __PRETTY_FUNCTION__ << ": " << *Result << ", expected "
83+
<< Expected << std::endl;
84+
#endif
85+
assert(*Result == Expected);
86+
87+
if constexpr (UseUSM)
88+
free(Red, q);
89+
free(Result, q);
90+
}
91+
92+
template <int... Inds, class F>
93+
void loop_impl(std::integer_sequence<int, Inds...>, F &&f) {
94+
(f(std::integral_constant<int, Inds>{}), ...);
95+
}
96+
97+
template <int count, class F> void loop(F &&f) {
98+
loop_impl(std::make_integer_sequence<int, count>{}, std::forward<F>(f));
99+
}
100+
101+
template <bool UseUSM, bool InitToIdentity, typename RangeTy>
102+
void testAllStrategies(RangeTy Range) {
103+
loop<(int)detail::reduction::strategy::multi>([&](auto Id) {
104+
constexpr auto Strategy =
105+
// Skip auto_select == 0.
106+
detail::reduction::strategy{decltype(Id)::value + 1};
107+
test<UseUSM, InitToIdentity, Strategy>(Range);
108+
});
109+
}
110+
111+
int main() {
112+
auto TestRange = [](auto Range) {
113+
testAllStrategies<true, true>(Range);
114+
testAllStrategies<true, false>(Range);
115+
testAllStrategies<false, true>(Range);
116+
testAllStrategies<false, false>(Range);
117+
};
118+
119+
TestRange(range<1>{42});
120+
TestRange(range<2>{8, 8});
121+
TestRange(range<3>{7, 7, 5});
122+
TestRange(nd_range<1>{range<1>{7}, range<1>{7}});
123+
TestRange(nd_range<1>{range<1>{3 * 3}, range<1>{3}});
124+
125+
// TODO: Strategies historically adopted from sycl::range implementation only
126+
// support 1-Dim case.
127+
//
128+
// TestRange(nd_range<2>{range<2>{7, 3}, range<2> {7, 3}});
129+
// TestRange(nd_range<2>{range<2>{14, 9}, range<2> {7, 3}});
130+
return 0;
131+
}

0 commit comments

Comments
 (0)