Skip to content

Commit fad00cc

Browse files
Add e2e test for queue::fill with a range of pattern sizes (#16544)
Add a new e2e test to validate queue::fill outputs for any pattern size between 1 and 32 bytes. Backend implementations of this feature commonly branch on the pattern size to implement an optimized path for specific values. This test ensures a wide range of cases is tested, including also odd numbers of bytes. Re-adds #15991 reverted in #16465 with changes to fix #16434. --------- Co-authored-by: Udit Kumar Agarwal <[email protected]>
1 parent bd2fcdc commit fad00cc

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

sycl/test-e2e/USM/fill_any_size.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// RUN: %{build} -o %t1.out
2+
// RUN: %{run} %t1.out
3+
// clang-format off
4+
// UNSUPPORTED: (opencl && cpu)
5+
// UNSUPPORTED-TRACKER: https://github.com/oneapi-src/unified-runtime/issues/2440
6+
// clang-format on
7+
8+
/**
9+
* Test of the queue::fill interface with a range of pattern sizes and values.
10+
*
11+
* Loops over pattern sizes from 1 to MaxPatternSize bytes and calls queue::fill
12+
* with std::array<uint8_t,Size> for the pattern. Two pattern values are tested,
13+
* all zeros and value=index+42. The output is copied back to host and
14+
* validated.
15+
*/
16+
17+
#include <array>
18+
#include <cstdio>
19+
#include <sycl/detail/core.hpp>
20+
#include <sycl/usm.hpp>
21+
22+
constexpr size_t MaxPatternSize{32}; // Bytes.
23+
constexpr size_t NumElements{10};
24+
constexpr bool verbose{false};
25+
26+
template <size_t PatternSize, bool SameValue>
27+
int test(sycl::queue &q, uint8_t firstValue = 0) {
28+
using T = std::array<uint8_t, PatternSize>;
29+
T value{};
30+
31+
// Initialize the pattern value on host.
32+
for (size_t i{0}; i < PatternSize; ++i) {
33+
if constexpr (SameValue) {
34+
value[i] = firstValue;
35+
} else {
36+
value[i] = firstValue + i;
37+
}
38+
}
39+
40+
// Allocate memory on the device.
41+
T *dptr{sycl::malloc_device<T>(NumElements, q)};
42+
43+
// Fill the device memory with the pattern.
44+
q.fill(dptr, value, NumElements).wait();
45+
46+
// Copy back the filled memory to host.
47+
std::array<T, NumElements> host{};
48+
q.copy<T>(dptr, host.data(), NumElements).wait();
49+
50+
// Validate whether the filled memory contains the expected values.
51+
bool pass{true};
52+
for (size_t i{0}; i < NumElements; ++i) {
53+
for (size_t j{0}; j < PatternSize; ++j) {
54+
if (host[i][j] != value[j]) {
55+
pass = false;
56+
}
57+
}
58+
}
59+
60+
// Release the device memory allocation.
61+
sycl::free(dptr, q);
62+
63+
// Print info on failure or in verbose mode.
64+
if (!pass || verbose) {
65+
printf("Pattern size %3zu bytes, %s values (initial %3u) %s\n", PatternSize,
66+
(SameValue ? " equal" : "varied"), firstValue,
67+
(pass ? "== PASS ==" : "== FAIL =="));
68+
}
69+
70+
return !pass;
71+
}
72+
73+
template <size_t Size> int testOneSize(sycl::queue &q) {
74+
return test<Size, true>(q, 0) + test<Size, false>(q, 42);
75+
}
76+
77+
template <size_t... Sizes>
78+
int testSizes(sycl::queue &q, std::index_sequence<Sizes...>) {
79+
return (testOneSize<1u + Sizes>(q) + ...);
80+
}
81+
82+
int main() {
83+
sycl::queue q{};
84+
int failures = testSizes(q, std::make_index_sequence<MaxPatternSize>{});
85+
if (failures > 0) {
86+
printf("%d / %zu tests failed\n", failures, 2u * MaxPatternSize);
87+
} else {
88+
printf("All %zu tests passed\n", 2u * MaxPatternSize);
89+
}
90+
return failures;
91+
}

0 commit comments

Comments
 (0)