Depends on liboffload PR: https://github.com/llvm/llvm-project/pull/194333. The approach with void sycl_kernel_launch(pack of arguments) implies that we can use or copy arguments only during that call. Since it pass only kernel arguments as parameters and returns void - we have to split setting of extra kernel data like event dependencies and range and getting result event from arguments handling and direct kernel submision if it is possible. Key stages: 1) passing to queue (or handler in future) dependency events and range (for parallel_for), saving them in queue (copy/move). 2) wrapping kernel arguments into typeless wrappers (pointer based, initially no copy) and passing to the queue. Then depending on scenario (without host tasks and accessors we should be able to submit everything directly) collection of arguments is converted to preferred liboffload structure (no copy of objects, copy of pointers) and passed to liboffload or RT does deep copy of provided arguments (simple copy of pointer of USM and copy of value for other arguments) to keep them alive till kernel enqueue outside parent submit call. 3) getting event associated with kernel enqueue. Key notes: 1) Having these 3 separated calls is not the best solution but the only one allowing to avoid copy for some scenarios (otherwise we have to do deep copy always and then do joined kernel submission outside sycl_kernel_launch scope). 2) submit must be thread-safe. Since we have 3 calls we need to keep kernel params and resulting event in a per queue + per thread/per kernel way. To achieve this without copy and joined kernel submission queue (in future - handler) stores thread_local data for kernel submission. thread_local can't be used for non-static class members so they are static. Given: same queue can be used from different threads but thread can't use different queues at the same moment; that means that we actually need per thread storage. This is part of the SYCL support upstreaming effort. The relevant RFCs can be found here: https://discourse.llvm.org/t/rfc-add-full-support-for-the-sycl-programming-model/74080 https://discourse.llvm.org/t/rfc-sycl-runtime-upstreaming/74479 --------- Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
54 lines
953 B
C++
54 lines
953 B
C++
// REQUIRES: any-device
|
|
// RUN: %clangxx -fsycl %s -o %t.out
|
|
// RUN: %t.out
|
|
|
|
#include <iostream>
|
|
|
|
#include <sycl/sycl.hpp>
|
|
|
|
using namespace sycl;
|
|
|
|
class Kernel1;
|
|
|
|
bool check(backend be) {
|
|
switch (be) {
|
|
case backend::opencl:
|
|
case backend::level_zero:
|
|
case backend::cuda:
|
|
case backend::hip:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void return_fail() {
|
|
std::cout << "Failed" << std::endl;
|
|
exit(1);
|
|
}
|
|
|
|
int main() {
|
|
for (const auto &plt : platform::get_platforms()) {
|
|
if (!check(plt.get_backend())) {
|
|
return_fail();
|
|
}
|
|
|
|
auto device = plt.get_devices()[0];
|
|
if (device.get_backend() != plt.get_backend()) {
|
|
return_fail();
|
|
}
|
|
|
|
queue q(device);
|
|
if (q.get_backend() != plt.get_backend()) {
|
|
return_fail();
|
|
}
|
|
|
|
event e = q.single_task<Kernel1>([]() {});
|
|
if (e.get_backend() != plt.get_backend()) {
|
|
return_fail();
|
|
}
|
|
}
|
|
std::cout << "Passed" << std::endl;
|
|
return 0;
|
|
}
|