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

Commit 5ee56a3

Browse files
authored
[SYCL] next portion of the tests (#33)
* Add/move tests covering different kernel param types * Add test covering loading kernel images from file * Added kernel/program compile/build tests * Add multi_ptr test * add function pointer tests * add functor tests * test for context with multiple devices * XFAIL kernel and program tests failing on CUDA
1 parent 6d15120 commit 5ee56a3

24 files changed

+1736
-5
lines changed

SYCL/Basic/config/allowlist.cpp renamed to SYCL/Basic/Config/allowlist.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ using namespace cl;
2020

2121
static void replaceSpecialCharacters(std::string &Str) {
2222
// Replace common special symbols with '.' which matches to any character
23-
std::replace_if(Str.begin(), Str.end(),
24-
[](const char Sym) { return '(' == Sym || ')' == Sym; }, '.');
23+
std::replace_if(
24+
Str.begin(), Str.end(),
25+
[](const char Sym) { return '(' == Sym || ')' == Sym; }, '.');
2526
}
2627

2728
int main() {
File renamed without changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// UNSUPPORTED: cuda
2+
// CUDA does not support SPIR-V.
3+
4+
// RUN: %clangxx -fsycl-device-only -fno-sycl-use-bitcode -Xclang -fsycl-int-header=%t.h -c %s -o %t.spv -I %sycl_include -Xclang -verify-ignore-unexpected=note,warning -Wno-sycl-strict
5+
// RUN: %clangxx -include %t.h %s -o %t.out -lsycl -I %sycl_include -Xclang -verify-ignore-unexpected=note,warning
6+
// RUN: env SYCL_BE=%sycl_be SYCL_USE_KERNEL_SPV=%t.spv %t.out | FileCheck %s
7+
// CHECK: Passed
8+
9+
#include <CL/sycl.hpp>
10+
#include <iostream>
11+
12+
using namespace cl::sycl;
13+
14+
int main(int argc, char **argv) {
15+
int data = 5;
16+
17+
try {
18+
queue myQueue;
19+
buffer<int, 1> buf(&data, range<1>(1));
20+
21+
event e = myQueue.submit([&](handler &cgh) {
22+
auto ptr = buf.get_access<access::mode::read_write>(cgh);
23+
24+
cgh.single_task<class my_kernel>([=]() { ptr[0]++; });
25+
});
26+
e.wait_and_throw();
27+
28+
} catch (cl::sycl::exception const &e) {
29+
std::cerr << "SYCL exception caught:\n";
30+
std::cerr << e.what() << "\n";
31+
return 2;
32+
} catch (...) {
33+
std::cerr << "unknown exception caught\n";
34+
return 1;
35+
}
36+
37+
if (data == 6) {
38+
std::cout << "Passed\n";
39+
return 0;
40+
} else {
41+
std::cout << "Failed: " << data << "!= 6(gold)\n";
42+
return 1;
43+
}
44+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// UNSUPPORTED: windows
2+
// UNSUPPORTED: cuda || level_zero
3+
// CUDA does not support the function pointer as kernel argument extension.
4+
// Hangs on level zero
5+
6+
// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -std=c++14 -fsycl %s -o %t.out
7+
// RUN: %HOST_RUN_PLACEHOLDER %t.out
8+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
9+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
10+
// FIXME: This test should use runtime early exit once correct check for
11+
// corresponding extension is implemented
12+
13+
#include <CL/sycl.hpp>
14+
15+
#include <algorithm>
16+
#include <iostream>
17+
#include <vector>
18+
19+
[[intel::device_indirectly_callable]] extern "C" int add(int A, int B) {
20+
return A + B;
21+
}
22+
23+
int main() {
24+
const int Size = 10;
25+
std::vector<long> A(Size, 1);
26+
std::vector<long> B(Size, 2);
27+
28+
cl::sycl::queue Q;
29+
cl::sycl::device D = Q.get_device();
30+
cl::sycl::context C = Q.get_context();
31+
cl::sycl::program P(C);
32+
33+
P.build_with_kernel_type<class K>();
34+
cl::sycl::kernel KE = P.get_kernel<class K>();
35+
36+
auto FptrStorage = cl::sycl::ONEAPI::get_device_func_ptr(&add, "add", P, D);
37+
if (!D.is_host()) {
38+
// FIXME: update this check with query to supported extension
39+
// For now, we don't have runtimes that report required OpenCL extension and
40+
// it is hard to understand should this functionality be supported or not.
41+
// So, let's skip this test if FptrStorage is 0, which means that by some
42+
// reason we failed to obtain device function pointer. Just to avoid false
43+
// alarms
44+
if (0 == FptrStorage) {
45+
std::cout << "Test PASSED. (it was actually skipped)" << std::endl;
46+
return 0;
47+
}
48+
}
49+
50+
cl::sycl::buffer<long> BufA(A.data(), cl::sycl::range<1>(Size));
51+
cl::sycl::buffer<long> BufB(B.data(), cl::sycl::range<1>(Size));
52+
53+
Q.submit([&](cl::sycl::handler &CGH) {
54+
auto AccA =
55+
BufA.template get_access<cl::sycl::access::mode::read_write>(CGH);
56+
auto AccB = BufB.template get_access<cl::sycl::access::mode::read>(CGH);
57+
CGH.parallel_for<class K>(
58+
KE, cl::sycl::range<1>(Size), [=](cl::sycl::id<1> Index) {
59+
auto Fptr =
60+
cl::sycl::ONEAPI::to_device_func_ptr<decltype(add)>(FptrStorage);
61+
AccA[Index] = Fptr(AccA[Index], AccB[Index]);
62+
});
63+
});
64+
65+
auto HostAcc = BufA.get_access<cl::sycl::access::mode::read>();
66+
auto *Data = HostAcc.get_pointer();
67+
68+
if (std::all_of(Data, Data + Size, [](long V) { return V == 3; })) {
69+
std::cout << "Test PASSED." << std::endl;
70+
} else {
71+
std::cout << "Test FAILED." << std::endl;
72+
for (int I = 0; I < Size; ++I) {
73+
std::cout << HostAcc[I] << " ";
74+
}
75+
std::cout << std::endl;
76+
}
77+
78+
return 0;
79+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// UNSUPPORTED: windows
2+
// UNSUPPORTED: cuda || level_zero
3+
// CUDA does not support the function pointer as kernel argument extension.
4+
// Hangs on level zero
5+
6+
// RUN: %clangxx -Xclang -fsycl-allow-func-ptr -std=c++14 -fsycl %s -o %t.out
7+
// RUN: %HOST_RUN_PLACEHOLDER %t.out
8+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
9+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
10+
// FIXME: This test should use runtime early exit once correct check for
11+
// corresponding extension is implemented
12+
13+
#include <CL/sycl.hpp>
14+
15+
#include <algorithm>
16+
#include <iostream>
17+
#include <vector>
18+
19+
[[intel::device_indirectly_callable]] extern "C" int add(int A, int B) {
20+
return A + B;
21+
}
22+
23+
[[intel::device_indirectly_callable]] extern "C" int sub(int A, int B) {
24+
return A - B;
25+
}
26+
27+
int main() {
28+
const int Size = 10;
29+
30+
cl::sycl::queue Q;
31+
cl::sycl::device D = Q.get_device();
32+
cl::sycl::context C = Q.get_context();
33+
cl::sycl::program P(C);
34+
35+
P.build_with_kernel_type<class K>();
36+
cl::sycl::kernel KE = P.get_kernel<class K>();
37+
38+
cl::sycl::buffer<cl::sycl::ONEAPI::device_func_ptr_holder_t> DispatchTable(2);
39+
{
40+
auto DTAcc =
41+
DispatchTable.get_access<cl::sycl::access::mode::discard_write>();
42+
DTAcc[0] = cl::sycl::ONEAPI::get_device_func_ptr(&add, "add", P, D);
43+
DTAcc[1] = cl::sycl::ONEAPI::get_device_func_ptr(&sub, "sub", P, D);
44+
if (!D.is_host()) {
45+
// FIXME: update this check with query to supported extension
46+
// For now, we don't have runtimes that report required OpenCL extension
47+
// and it is hard to understand should this functionality be supported or
48+
// not. So, let's skip this test if DTAcc[i] is 0, which means that by
49+
// some reason we failed to obtain device function pointer. Just to avoid
50+
// false alarms
51+
if (0 == DTAcc[0] || 0 == DTAcc[1]) {
52+
std::cout << "Test PASSED. (it was actually skipped)" << std::endl;
53+
return 0;
54+
}
55+
}
56+
}
57+
58+
for (int Mode = 0; Mode < 2; ++Mode) {
59+
std::vector<int> A(Size, 1);
60+
std::vector<int> B(Size, 2);
61+
62+
cl::sycl::buffer<int> bufA(A.data(), cl::sycl::range<1>(Size));
63+
cl::sycl::buffer<int> bufB(B.data(), cl::sycl::range<1>(Size));
64+
65+
Q.submit([&](cl::sycl::handler &CGH) {
66+
auto AccA =
67+
bufA.template get_access<cl::sycl::access::mode::read_write>(CGH);
68+
auto AccB = bufB.template get_access<cl::sycl::access::mode::read>(CGH);
69+
auto AccDT =
70+
DispatchTable.template get_access<cl::sycl::access::mode::read>(CGH);
71+
CGH.parallel_for<class K>(
72+
KE, cl::sycl::range<1>(Size), [=](cl::sycl::id<1> Index) {
73+
auto FP = cl::sycl::ONEAPI::to_device_func_ptr<int(int, int)>(
74+
AccDT[Mode]);
75+
76+
AccA[Index] = FP(AccA[Index], AccB[Index]);
77+
});
78+
});
79+
80+
auto HostAcc = bufA.get_access<cl::sycl::access::mode::read>();
81+
82+
int Reference = Mode == 0 ? 3 : -1;
83+
auto *Data = HostAcc.get_pointer();
84+
85+
if (std::all_of(Data, Data + Size,
86+
[=](long V) { return V == Reference; })) {
87+
std::cout << "Test " << Mode << " PASSED." << std::endl;
88+
} else {
89+
std::cout << "Test " << Mode << " FAILED." << std::endl;
90+
for (int I = 0; I < Size; ++I) {
91+
std::cout << HostAcc[I] << " ";
92+
}
93+
std::cout << std::endl;
94+
}
95+
}
96+
97+
return 0;
98+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -o %t.out %s
2+
// RUN: %HOST_RUN_PLACEHOLDER %t.out
3+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
5+
// RUN: %ACC_RUN_PLACEHOLDER %t.out
6+
7+
#include <CL/sycl.hpp>
8+
#include <cassert>
9+
10+
constexpr auto sycl_read_write = cl::sycl::access::mode::read_write;
11+
constexpr auto sycl_global_buffer = cl::sycl::access::target::global_buffer;
12+
13+
struct SecondBase {
14+
SecondBase(int _E) : E(_E) {}
15+
int E;
16+
};
17+
18+
struct InnerFieldBase {
19+
InnerFieldBase(int _D) : D(_D) {}
20+
int D;
21+
};
22+
23+
struct InnerField : public InnerFieldBase {
24+
InnerField(int _C, int _D) : C(_C), InnerFieldBase(_D) {}
25+
int C;
26+
};
27+
28+
struct Base {
29+
Base(int _B, int _C, int _D) : B(_B), InnerObj(_C, _D) {}
30+
int B;
31+
InnerField InnerObj;
32+
};
33+
34+
struct Derived : public Base, public SecondBase {
35+
Derived(int _A, int _B, int _C, int _D, int _E,
36+
cl::sycl::accessor<int, 1, sycl_read_write, sycl_global_buffer> &_Acc)
37+
: A(_A), Acc(_Acc), /*Out(_Out),*/ Base(_B, _C, _D), SecondBase(_E) {}
38+
void operator()() const {
39+
Acc[0] = this->A + this->B + this->InnerObj.C + this->InnerObj.D + this->E;
40+
}
41+
42+
int A;
43+
cl::sycl::accessor<int, 1, sycl_read_write, sycl_global_buffer> Acc;
44+
};
45+
46+
int main() {
47+
int A[] = {10};
48+
{
49+
cl::sycl::queue Q;
50+
cl::sycl::buffer<int, 1> Buf(A, 1);
51+
52+
Q.submit([&](cl::sycl::handler &cgh) {
53+
auto Acc = Buf.get_access<sycl_read_write, sycl_global_buffer>(cgh);
54+
Derived F = {1, 2, 3, 4, 5, Acc /*, Out*/};
55+
cgh.single_task(F);
56+
});
57+
}
58+
assert(A[0] == 15);
59+
return 0;
60+
}

0 commit comments

Comments
 (0)