-
Notifications
You must be signed in to change notification settings - Fork 801
[SYCL] Implement backend content extension #16633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
464174d
217270c
776a3ed
3080741
12bdf3f
a4f6372
c15a31a
0ba58c7
50018cb
b20f042
2c7b110
b884eec
36f4095
5d4a6bf
273f6df
192cf75
5d7d500
5050a3c
ab765f9
e8be859
fa68a24
74c0772
78e7ae6
b2594e8
5b88761
ccdd15c
e4914b8
21f4a9b
91853e0
70c168a
a43e3b4
cc5189e
7b8458c
ab163f7
247932e
688521d
c1a5ea7
bb5b787
a3f837d
d6a2ca5
d5c214c
587941f
2e38117
4ee145e
3308fac
bc695cf
3b2691f
cf94a3e
743c9a7
97637cf
afe72b8
d1f2644
910ce34
d267155
a9e1e21
2c916f6
16186ba
77eda18
a29db25
248fc93
c666340
4ccce5a
2e4d7f8
9aa2184
6a88f93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // RUN: %{build} %cuda_options -o %t.out | ||
| // RUN: %{run} %t.out | ||
| // REQUIRES: cuda, cuda_dev_kit | ||
|
|
||
| #include <cuda.h> | ||
| #include <sycl/backend.hpp> | ||
| #include <sycl/detail/core.hpp> | ||
| #include <vector> | ||
|
|
||
| int main() { | ||
| sycl::queue q; | ||
| sycl::context ctxt = q.get_context(); | ||
| sycl::kernel_id k_id = sycl::get_kernel_id<class mykernel>(); | ||
| auto bundle = | ||
| sycl::get_kernel_bundle<sycl::bundle_state::executable>(ctxt, {k_id}); | ||
| assert(!bundle.empty()); | ||
| sycl::kernel krn = bundle.get_kernel(k_id); | ||
| sycl::buffer<int> buf(sycl::range<1>(1)); | ||
| q.submit([&](sycl::handler &cgh) { | ||
| sycl::accessor acc(buf, cgh); | ||
| cgh.single_task<class mykernel>(krn, [=]() { acc[0] = 42; }); | ||
| }); | ||
| const auto img = *(bundle.begin()); | ||
| const auto bytes = img.ext_oneapi_get_backend_content(); | ||
| CUmodule m; | ||
| CUresult result = | ||
| cuModuleLoadData(&m, reinterpret_cast<const void *>(bytes.data())); | ||
| assert(result == CUDA_SUCCESS); | ||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| // REQUIRES: level_zero, level_zero_dev_kit, aspect-usm_shared_allocations | ||
| // RUN: %{build} %level_zero_options -fno-sycl-dead-args-optimization -o %t.out | ||
| // RUN: %{run} %t.out | ||
| // | ||
| #include <level_zero/ze_api.h> | ||
| #include <sycl/detail/core.hpp> | ||
| #include <sycl/ext/oneapi/backend/level_zero.hpp> | ||
| #include <sycl/ext/oneapi/free_function_queries.hpp> | ||
| #include <sycl/usm.hpp> | ||
| #include <vector> | ||
|
|
||
| namespace syclext = sycl::ext::oneapi; | ||
| namespace syclexp = sycl::ext::oneapi::experimental; | ||
|
|
||
| extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY( | ||
| (syclexp::nd_range_kernel<1>)) void iota(int *ptr) { | ||
| size_t id = syclext::this_work_item::get_nd_item<1>().get_global_linear_id(); | ||
| ptr[id] = 42; | ||
| } | ||
|
|
||
| int main() { | ||
| sycl::queue q; | ||
| sycl::context ctxt = q.get_context(); | ||
| sycl::device d = ctxt.get_devices()[0]; | ||
| // The following ifndef is required due to a number of limitations of free | ||
| // function kernels. See CMPLRLLVM-61498. | ||
| // TODO: Remove it once these limitations are no longer there. | ||
| #ifndef __SYCL_DEVICE_ONLY__ | ||
| // First, run the kernel using the SYCL API. | ||
| auto bundle = sycl::get_kernel_bundle<sycl::bundle_state::executable>(ctxt); | ||
| sycl::kernel_id iota_id = syclexp::get_kernel_id<iota>(); | ||
| sycl::kernel k_iota = bundle.get_kernel(iota_id); | ||
| int *ptr = sycl::malloc_shared<int>(1, q); | ||
| *ptr = 0; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.set_args(ptr); | ||
| cgh.parallel_for(sycl::nd_range{{1}, {1}}, k_iota); | ||
| }).wait(); | ||
|
|
||
| // Now, run the kernel by first getting its image as an executable, | ||
| // making an L0 kernel out of it and then making a SYCL kernel out of | ||
| // the L0 kernel. Run this kernel on the SYCL API and verify | ||
| // that it has the same result as the kernel that was run directly on SYCL | ||
| // API. First, get a kernel bundle that contains the kernel "iota". | ||
| auto exe_bndl = sycl::get_kernel_bundle<sycl::bundle_state::executable>( | ||
| ctxt, {d}, | ||
| [&](const sycl::device_image<sycl::bundle_state::executable> &img) { | ||
| return img.has_kernel(iota_id, d); | ||
| }); | ||
| assert(!exe_bndl.empty()); | ||
| std::vector<std::byte> bytes; | ||
| const sycl::device_image<sycl::bundle_state::executable> &img = | ||
| *(exe_bndl.begin()); | ||
| bytes = img.ext_oneapi_get_backend_content(); | ||
|
|
||
| auto ZeContext = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(ctxt); | ||
| auto ZeDevice = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(d); | ||
|
|
||
| ze_result_t status; | ||
| ze_module_desc_t moduleDesc = { | ||
| ZE_STRUCTURE_TYPE_MODULE_DESC, | ||
| nullptr, | ||
| ZE_MODULE_FORMAT_IL_SPIRV, | ||
| bytes.size(), | ||
| reinterpret_cast<unsigned char *>(bytes.data()), | ||
| nullptr, | ||
| nullptr}; | ||
| ze_module_handle_t ZeModule; | ||
| status = zeModuleCreate(ZeContext, ZeDevice, &moduleDesc, &ZeModule, nullptr); | ||
| assert(status == ZE_RESULT_SUCCESS); | ||
|
|
||
| ze_kernel_desc_t kernelDesc = {ZE_STRUCTURE_TYPE_KERNEL_DESC, nullptr, 0, | ||
| "__sycl_kernel_iota"}; | ||
| ze_kernel_handle_t ZeKernel; | ||
| status = zeKernelCreate(ZeModule, &kernelDesc, &ZeKernel); | ||
| assert(status == ZE_RESULT_SUCCESS); | ||
| sycl::kernel k_iota_twin = | ||
| sycl::make_kernel<sycl::backend::ext_oneapi_level_zero>( | ||
| {sycl::make_kernel_bundle<sycl::backend::ext_oneapi_level_zero, | ||
| sycl::bundle_state::executable>({ZeModule}, | ||
| ctxt), | ||
| ZeKernel}, | ||
| ctxt); | ||
| int *ptr_twin = sycl::malloc_shared<int>(1, q); | ||
| *ptr_twin = 1; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.set_args(ptr_twin); | ||
| cgh.parallel_for(sycl::nd_range{{1}, {1}}, k_iota_twin); | ||
| }).wait(); | ||
| assert(*ptr_twin == *ptr); | ||
| sycl::free(ptr, q); | ||
| sycl::free(ptr_twin, q); | ||
| #endif | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // REQUIRES: opencl, opencl_icd, aspect-usm_shared_allocations | ||
| // RUN: %{build} %opencl_lib -fno-sycl-dead-args-optimization -o %t.out | ||
| // RUN: %{run} %t.out | ||
| // | ||
| #include <sycl/backend.hpp> | ||
| #include <sycl/detail/cl.h> | ||
| #include <sycl/detail/core.hpp> | ||
| #include <sycl/ext/oneapi/free_function_queries.hpp> | ||
| #include <sycl/usm.hpp> | ||
| #include <vector> | ||
|
|
||
| namespace syclext = sycl::ext::oneapi; | ||
| namespace syclexp = sycl::ext::oneapi::experimental; | ||
|
|
||
| extern "C" SYCL_EXT_ONEAPI_FUNCTION_PROPERTY( | ||
| (syclexp::nd_range_kernel<1>)) void iota(int *ptr) { | ||
| size_t id = syclext::this_work_item::get_nd_item<1>().get_global_linear_id(); | ||
| ptr[id] = 42; | ||
| } | ||
|
|
||
| int main() { | ||
| sycl::queue q; | ||
| sycl::context ctxt = q.get_context(); | ||
| sycl::device d = ctxt.get_devices()[0]; | ||
| // The following ifndef is required due to a number of limitations of free | ||
| // function kernels. See CMPLRLLVM-61498. | ||
| // TODO: Remove it once these limitations are no longer there. | ||
| #ifndef __SYCL_DEVICE_ONLY__ | ||
| // First, run the kernel using the SYCL API. | ||
|
|
||
| auto bundle = sycl::get_kernel_bundle<sycl::bundle_state::executable>(ctxt); | ||
| sycl::kernel_id iota_id = syclexp::get_kernel_id<iota>(); | ||
| sycl::kernel k_iota = bundle.get_kernel(iota_id); | ||
|
|
||
| int *ptr = sycl::malloc_shared<int>(1, q); | ||
| *ptr = 0; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.set_args(ptr); | ||
| cgh.parallel_for(sycl::nd_range{{1}, {1}}, k_iota); | ||
| }).wait(); | ||
| // Now, run the kernel by first getting its image as an executable, | ||
| // making an OCL kernel out of it and then making a SYCL kernel out of | ||
| // the OCL kernel. Run this kernel on the SYCL API and verify | ||
| // that it has the same result as the kernel that was run directly on SYCL | ||
| // API. First, get a kernel bundle that contains the kernel "iota". | ||
| auto exe_bndl = sycl::get_kernel_bundle<sycl::bundle_state::executable>( | ||
| ctxt, {d}, | ||
| [&](const sycl::device_image<sycl::bundle_state::executable> &img) { | ||
| return img.has_kernel(iota_id, d); | ||
| }); | ||
| assert(!exe_bndl.empty()); | ||
| std::vector<std::byte> bytes; | ||
| const sycl::device_image<sycl::bundle_state::executable> &img = | ||
| *(exe_bndl.begin()); | ||
| bytes = img.ext_oneapi_get_backend_content(); | ||
| std::cout << bytes.size() << std::endl; | ||
| auto clContext = sycl::get_native<sycl::backend::opencl>(ctxt); | ||
| auto clDevice = sycl::get_native<sycl::backend::opencl>(d); | ||
|
|
||
| cl_int status; | ||
| auto clProgram = clCreateProgramWithIL( | ||
| clContext, reinterpret_cast<unsigned char *>(bytes.data()), bytes.size(), | ||
| &status); | ||
| assert(status == CL_SUCCESS); | ||
| status = clBuildProgram(clProgram, 1, &clDevice, "", nullptr, nullptr); | ||
| assert(status == CL_SUCCESS); | ||
| auto clKernel = clCreateKernel(clProgram, "__sycl_kernel_iota", &status); | ||
| assert(status == CL_SUCCESS); | ||
| sycl::kernel k_iota_twin = | ||
| sycl::make_kernel<sycl::backend::opencl>(clKernel, ctxt); | ||
| int *ptr_twin = sycl::malloc_shared<int>(1, q); | ||
| *ptr_twin = 1; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.set_args(ptr_twin); | ||
| cgh.parallel_for(sycl::nd_range{{1}, {1}}, k_iota_twin); | ||
| }).wait(); | ||
| assert(*ptr_twin == *ptr); | ||
| sycl::free(ptr, q); | ||
| sycl::free(ptr_twin, q); | ||
| #endif | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // RUN: %{build} -std=c++20 -o %t.out | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We had some complains from Codeplay developers about such tests.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you point me to a thread where I can have a look at the concerns?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have a link, try searching through git log with changes containing |
||
| // RUN: %{run} %t.out | ||
|
|
||
| #include <sycl/detail/core.hpp> | ||
| #include <sycl/kernel_bundle.hpp> | ||
| #include <type_traits> | ||
|
|
||
| int main() { | ||
| sycl::queue q; | ||
| sycl::context ctxt = q.get_context(); | ||
| sycl::buffer<int> buf(sycl::range<1>(1)); | ||
| sycl::kernel_id k_id = sycl::get_kernel_id<class mykernel>(); | ||
| auto bundle = | ||
| sycl::get_kernel_bundle<sycl::bundle_state::executable>(ctxt, {k_id}); | ||
| assert(!bundle.empty()); | ||
| sycl::kernel krn = bundle.get_kernel(k_id); | ||
| q.submit([&](sycl::handler &cgh) { | ||
| sycl::accessor acc(buf, cgh); | ||
| cgh.single_task<class mykernel>(krn, [=]() { acc[0] = 42; }); | ||
| }); | ||
| sycl::backend backend; | ||
| std::vector<std::byte> bytes; | ||
| #ifdef __cpp_lib_span | ||
| std::span<const std::byte> bytes_view; | ||
| #endif | ||
| for (const auto &img : bundle) { | ||
| // Check that all 3 functions of the api return correct types and compile. | ||
| // Furthermore, check that the backend corresponds to the backend of the | ||
| // bundle Check that the view of the content is indeed equal to the | ||
| // content. | ||
| static_assert(std::is_same_v<decltype(img.ext_oneapi_get_backend()), | ||
| decltype(backend)>); | ||
| static_assert(std::is_same_v<decltype(img.ext_oneapi_get_backend_content()), | ||
| decltype(bytes)>); | ||
| backend = img.ext_oneapi_get_backend(); | ||
| assert(backend == bundle.get_backend()); | ||
| bytes = img.ext_oneapi_get_backend_content(); | ||
| #ifdef __cpp_lib_span | ||
| static_assert( | ||
| std ::is_same_v<decltype(img.ext_oneapi_get_backend_content_view()), | ||
| decltype(bytes_view)>); | ||
| bytes_view = img.ext_oneapi_get_backend_content_view(); | ||
| assert(bytes_view.size() == bytes.size()); | ||
| for (size_t i = 0; i < bytes.size(); ++i) { | ||
| assert(bytes[i] == bytes_view[i]); | ||
| } | ||
| #endif | ||
| } | ||
| return 0; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.