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

Commit c7b9604

Browse files
[SYCL] Updating tests for SYCL2020 errc conformance (#857)
in intel/llvm#5582 we are adding an update that ensures that the errc of any exception is correct as specified in the SYCL2020 spec. Here we are updating and expanding the tests to accompany Signed-off-by: Chris Perkins chris.perkins@intel.com
1 parent 7a1e72a commit c7b9604

File tree

7 files changed

+154
-12
lines changed

7 files changed

+154
-12
lines changed

SYCL/Basic/accessor/accessor.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,5 +657,53 @@ int main() {
657657
return 1;
658658
}
659659
}
660+
661+
// exceptions with illegal ranges or no_init
662+
{
663+
const size_t bufSize = 10;
664+
std::vector<int> res(bufSize);
665+
sycl::range<1> r(bufSize);
666+
sycl::buffer<int, 1> b(res.data(), r);
667+
sycl::range<1> illegalR(bufSize + 1);
668+
sycl::id<1> offset(bufSize);
669+
670+
// illegal ranges
671+
try {
672+
auto acc = b.get_access<sycl::access::mode::read_write>(illegalR, offset);
673+
assert(false && "operation should not have succeeded");
674+
} catch (sycl::exception &e) {
675+
assert(e.code() == sycl::errc::invalid && "errc should be errc::invalid");
676+
}
677+
try {
678+
sycl::queue q;
679+
q.submit([&](sycl::handler &cgh) {
680+
auto acc = b.get_access<sycl::access::mode::read_write>(cgh, illegalR);
681+
});
682+
q.wait_and_throw();
683+
assert(false &&
684+
"we should not be here. operation should not have succeeded");
685+
} catch (sycl::exception &e) {
686+
assert(e.code() == sycl::errc::invalid && "errc should be errc::invalid");
687+
}
688+
689+
// no_init incompatible with read_only
690+
try {
691+
sycl::host_accessor out{b, sycl::read_only, sycl::no_init};
692+
assert(false && "operation should have failed");
693+
} catch (sycl::exception &e) {
694+
assert(e.code() == sycl::errc::invalid && "errc should be errc::invalid");
695+
}
696+
try {
697+
sycl::queue q;
698+
q.submit([&](sycl::handler &cgh) {
699+
sycl::accessor out{b, cgh, sycl::read_only, sycl::no_init};
700+
});
701+
q.wait_and_throw();
702+
assert(false && "we should not be here. operation should have failed");
703+
} catch (sycl::exception &e) {
704+
assert(e.code() == sycl::errc::invalid && "errc should be errc::invalid");
705+
}
706+
}
707+
660708
std::cout << "Test passed" << std::endl;
661709
}

SYCL/Basic/buffer/buffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ int main() {
394394
myQueue.submit([&](handler &cgh) {
395395
accessor<int, 2, access::mode::write, access::target::device,
396396
access::placeholder::false_t>
397-
B(Buffer, cgh, range<2>(20, 20), id<2>(10, 10));
397+
B(Buffer, cgh, range<2>(10, 10), id<2>(10, 10));
398398
cgh.parallel_for<class bufferByRangeOffset>(
399399
range<2>{10, 5}, [=](id<2> index) { B[index] = 1; });
400400
});

SYCL/Basic/buffer/buffer_full_copy.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,39 @@ void check_copy_host_to_device(cl::sycl::queue &Queue) {
220220
}
221221
}
222222

223+
void check_exception_code() {
224+
sycl::queue q;
225+
226+
const size_t bufSize = 10;
227+
std::vector<int> res(bufSize);
228+
// std::iota(res.begin(), res.end(), 1);
229+
sycl::range<1> r(bufSize);
230+
sycl::buffer<int, 1> b(res.data(), r);
231+
sycl::range<1> smallRange(bufSize / 2);
232+
sycl::id<1> offset(bufSize);
233+
234+
try {
235+
q.submit([&](sycl::handler &cgh) {
236+
sycl::accessor src(b, cgh);
237+
sycl::accessor destToSmall(b, cgh, smallRange);
238+
cgh.copy(src, destToSmall);
239+
});
240+
q.wait_and_throw();
241+
242+
assert(false &&
243+
"copy with too small Dest arg should have thrown an exception");
244+
} catch (sycl::exception e) {
245+
assert(e.code() == sycl::errc::invalid);
246+
}
247+
}
248+
223249
int main() {
224250
try {
225251
cl::sycl::queue Queue;
226252
check_copy_host_to_device(Queue);
227253
check_copy_device_to_host(Queue);
228254
check_fill(Queue);
255+
check_exception_code();
229256
} catch (cl::sycl::exception &ex) {
230257
std::cerr << ex.what() << std::endl;
231258
return 1;

SYCL/Basic/buffer/subbuffer.cpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// RUN: %CPU_RUN_PLACEHOLDER %t.out
44
// RUN: %GPU_RUN_PLACEHOLDER %t.out
55
// RUN: %ACC_RUN_PLACEHOLDER %t.out
6+
7+
// UNSUPPORTED: (opencl && gpu)
8+
69
//
710
//==---------- subbuffer.cpp --- sub-buffer basic test ---------------------==//
811
//
@@ -71,26 +74,34 @@ void check1DSubBuffer(cl::sycl::queue &q) {
7174
size *= 2;
7275

7376
std::size_t offset = size / 2, subbuf_size = 10, offset_inside_subbuf = 3,
74-
subbuffer_access_range = 10;
77+
subbuffer_access_range = subbuf_size - offset_inside_subbuf; // 7.
7578
std::vector<int> vec(size);
7679
std::vector<int> vec2(subbuf_size, 0);
7780
std::iota(vec.begin(), vec.end(), 0);
7881

82+
std::cout << "buffer size: " << size << ", subbuffer start: " << offset
83+
<< std::endl;
84+
7985
try {
8086
cl::sycl::buffer<int, 1> buf(vec.data(), size);
8187
cl::sycl::buffer<int, 1> buf2(vec2.data(), subbuf_size);
88+
// subbuffer is 10 elements, starting at midpoint. (typically 32)
8289
cl::sycl::buffer<int, 1> subbuf(buf, cl::sycl::id<1>(offset),
8390
cl::sycl::range<1>(subbuf_size));
8491

92+
// test offset accessor against a subbuffer
8593
q.submit([&](cl::sycl::handler &cgh) {
94+
// accessor starts at the third element of the subbuffer
95+
// and can read for 7 more (ie to the end of the subbuffer)
8696
auto acc = subbuf.get_access<cl::sycl::access::mode::read_write>(
8797
cgh, cl::sycl::range<1>(subbuffer_access_range),
8898
cl::sycl::id<1>(offset_inside_subbuf));
89-
cgh.parallel_for<class foobar>(
90-
cl::sycl::range<1>(subbuffer_access_range - offset_inside_subbuf),
91-
[=](cl::sycl::id<1> i) { acc[i] *= -1; });
99+
// subrange is made negative. ( 32 33 34 -35 -36 -37 -38 -39 -40 -41)
100+
cgh.parallel_for<class foobar>(cl::sycl::range<1>(subbuffer_access_range),
101+
[=](cl::sycl::id<1> i) { acc[i] *= -1; });
92102
});
93103

104+
// copy results of last operation back to buf2/vec2
94105
q.submit([&](cl::sycl::handler &cgh) {
95106
auto acc_sub = subbuf.get_access<cl::sycl::access::mode::read>(cgh);
96107
auto acc_buf = buf2.get_access<cl::sycl::access::mode::write>(cgh);
@@ -99,27 +110,48 @@ void check1DSubBuffer(cl::sycl::queue &q) {
99110
[=](cl::sycl::id<1> i) { acc_buf[i] = acc_sub[i]; });
100111
});
101112

113+
// multiple entire subbuffer by 10.
114+
// now original buffer will be
115+
// (..29 30 31 | 320 330 340 -350 -360 -370 -380 -390 -400 -410 | 42 43 44
116+
// ...)
102117
q.submit([&](cl::sycl::handler &cgh) {
103118
auto acc_sub = subbuf.get_access<cl::sycl::access::mode::read_write>(
104-
cgh, cl::sycl::range<1>(subbuffer_access_range));
119+
cgh, cl::sycl::range<1>(subbuf_size));
105120
cgh.parallel_for<class foobar_1>(
106-
cl::sycl::range<1>(subbuffer_access_range),
121+
cl::sycl::range<1>(subbuf_size),
107122
[=](cl::sycl::id<1> i) { acc_sub[i] *= 10; });
108123
});
109124
q.wait_and_throw();
110125

126+
// buffers go out of scope. data must be copied back to vector no later than
127+
// this.
111128
} catch (const cl::sycl::exception &e) {
112129
std::cerr << e.what() << std::endl;
113130
assert(false && "Exception was caught");
114131
}
115132

133+
// check buffer data in the area of the subbuffer
134+
// OCL:GPU confused => 320 330 340 -350 -360 -370 -380 39 40 41
135+
// every other device => 320 330 340 -350 -360 -370 -380 -390 -400 -410
116136
for (int i = offset; i < offset + subbuf_size; ++i)
117137
assert(vec[i] == (i < offset + offset_inside_subbuf ? i * 10 : i * -10) &&
118-
"Invalid result in 1d sub buffer");
138+
"Invalid result in buffer overlapped by 1d sub buffer");
139+
140+
// check buffer data in the area OUTSIDE the subbuffer
141+
for (int i = 0; i < size; i++) {
142+
if (i < offset)
143+
assert(vec[i] == i && "data preceding subbuffer incorrectly altered");
144+
145+
if (i > offset + subbuf_size)
146+
assert(vec[i] == i && "data following subbuffer incorrectly altered");
147+
}
119148

149+
// check the copy of the subbuffer data after the first operation
150+
// OCL:GPU => 32 33 34 -35 -36 -37 -38 0 0 0
151+
// everyone else => 32 33 34 -35 -36 -37 -38 -39 -40 -41
120152
for (int i = 0; i < subbuf_size; ++i)
121153
assert(vec2[i] == (i < 3 ? (offset + i) : (offset + i) * -1) &&
122-
"Invalid result in 1d sub buffer");
154+
"Invalid result in captured 1d sub buffer, vec2");
123155
}
124156

125157
void checkExceptions() {

SYCL/Basic/interop/get_native_ze.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,14 @@ int main() {
3232
ze_result_t Err = zeKernelGetProperties(Handle, &KernelProperties);
3333
assert(Err == ZE_RESULT_SUCCESS);
3434

35+
// SYCL2020 4.5.1.2 - verify exception errc
36+
try {
37+
// this test is L0 only, so we ask for an unavailable backend.
38+
auto BE2 = sycl::get_native<sycl::backend::opencl>(Q);
39+
assert(false && "we should not be here.");
40+
} catch (sycl::exception e) {
41+
assert(e.code() == sycl::errc::backend_mismatch && "wrong error code");
42+
}
43+
3544
return 0;
3645
}

SYCL/Basic/partition_supported.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ int main() {
7575
return -1;
7676
}
7777
}
78+
auto maxUnits = dev.get_info<sycl::info::device::max_compute_units>();
79+
try {
80+
std::vector<sycl::device> v = dev.create_sub_devices<
81+
sycl::info::partition_property::partition_equally>(maxUnits + 1);
82+
std::cerr << "create_sub_devices with more than max_compute_units should "
83+
"have thrown an error"
84+
<< std::endl;
85+
return -1;
86+
} catch (sycl::exception &ex) {
87+
if (ex.code() != sycl::errc::invalid) {
88+
std::cerr << "while an exception was correctly thrown, it has the "
89+
"wrong error code"
90+
"we should have received"
91+
<< sycl::errc::invalid << "but instead got"
92+
<< ex.code().value() << std::endl;
93+
return -1;
94+
}
95+
}
7896
} else {
7997
try {
8098
auto subDevices = dev.create_sub_devices<
@@ -85,6 +103,12 @@ int main() {
85103
<< std::endl;
86104
return -1;
87105
} catch (const cl::sycl::feature_not_supported &e) {
106+
if (e.code() != sycl::errc::feature_not_supported) {
107+
std::cerr
108+
<< "error code should be errc::feature_not_supported instead of "
109+
<< e.code().value() << std::endl;
110+
return -1;
111+
}
88112
} catch (...) {
89113
std::cerr << "device::create_sub_device(info::partition_affinity_domain) "
90114
"should have thrown cl::sycl::feature_not_supported"

SYCL/Basic/queue/queue.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ int main() {
124124
context Context(deviceA);
125125
queue Queue(Context, deviceB);
126126
assert(Context == Queue.get_context());
127-
} catch (std::exception &e) {
128-
std::cout << "Exception check passed: " << e.what() << std::endl;
129-
GotException = true;
127+
} catch (sycl::exception &e) {
128+
if (e.code() == sycl::errc::invalid) {
129+
std::cout << "Exception check passed: " << e.what() << std::endl;
130+
GotException = true;
131+
}
130132
}
131133
assert(GotException);
132134
}

0 commit comments

Comments
 (0)