|
| 1 | +// REQUIRES: CUDA || HIP |
| 2 | +// RUN: %{build} %if hip %{ -DSYCL_EXT_ONEAPI_BACKEND_HIP %} %else %{ %if cuda %{ -DSYCL_EXT_ONEAPI_BACKEND_CUDA_EXPERIMENTAL %} %else %{ %if level_zero %{ -DSYCL_EXT_ONEAPI_BACKEND_L0 %} %} %} -o %t.out |
| 3 | + |
| 4 | +#include <sycl/sycl.hpp> |
| 5 | +using namespace sycl; |
| 6 | + |
| 7 | +#ifdef SYCL_EXT_ONEAPI_BACKEND_CUDA_EXPERIMENTAL |
| 8 | +#include <sycl/ext/oneapi/experimental/backend/cuda.hpp> |
| 9 | +constexpr auto BACKEND = backend::ext_oneapi_cuda; |
| 10 | +using nativeDevice = CUdevice; |
| 11 | +using nativeQueue = CUstream; |
| 12 | +using nativeEvent = CUevent; |
| 13 | +#elif defined(SYCL_EXT_ONEAPI_BACKEND_HIP) |
| 14 | +#include <sycl/ext/oneapi/backend/hip.hpp> |
| 15 | +constexpr auto BACKEND = backend::ext_oneapi_hip; |
| 16 | +using nativeDevice = hipDevice_t; |
| 17 | +using nativeQueue = hipStream_t; |
| 18 | +using nativeEvent = hipEvent_t; |
| 19 | +#elif defined(SYCL_EXT_ONEAPI_BACKEND_L0) |
| 20 | +constexpr auto BACKEND = backend::ext_oneapi_level_zero; |
| 21 | +using nativeDevice = ze_device_handle_t; |
| 22 | +using nativeQueue = ze_command_queue_handle_t; |
| 23 | +using nativeEvent = ze_event_handle_t; |
| 24 | +#else |
| 25 | +constexpr auto BACKEND = backend::opencl; |
| 26 | +using nativeDevice = cl_device; |
| 27 | +using nativeQueue = cl_command_queue; |
| 28 | +using nativeEvent = cl_event; |
| 29 | +#endif |
| 30 | + |
| 31 | +constexpr int N = 100; |
| 32 | +constexpr int VAL = 3; |
| 33 | + |
| 34 | +int main() { |
| 35 | + |
| 36 | + assert(static_cast<bool>( |
| 37 | + std::is_same_v<backend_traits<BACKEND>::return_type<device>, |
| 38 | + nativeDevice>)); |
| 39 | + assert(static_cast<bool>( |
| 40 | + std::is_same_v<backend_traits<BACKEND>::return_type<queue>, |
| 41 | + nativeQueue>)); |
| 42 | + assert(static_cast<bool>( |
| 43 | + std::is_same_v<backend_traits<BACKEND>::return_type<event>, |
| 44 | + nativeEvent>)); |
| 45 | + |
| 46 | + device Device; |
| 47 | + backend_traits<BACKEND>::return_type<device> NativeDevice = |
| 48 | + get_native<BACKEND>(Device); |
| 49 | + // Create sycl device with a native device. |
| 50 | + auto InteropDevice = make_device<BACKEND>(NativeDevice); |
| 51 | + |
| 52 | + context Context(InteropDevice); |
| 53 | + |
| 54 | + // Create sycl queue with device created from a native device. |
| 55 | + queue Queue(InteropDevice, {sycl::property::queue::in_order()}); |
| 56 | + backend_traits<BACKEND>::return_type<queue> NativeQueue = |
| 57 | + get_native<BACKEND>(Queue); |
| 58 | + auto InteropQueue = make_queue<BACKEND>(NativeQueue, Context); |
| 59 | + |
| 60 | + auto A = (int *)malloc_device(N * sizeof(int), InteropQueue); |
| 61 | + std::vector<int> vec(N, 0); |
| 62 | + |
| 63 | + auto Event = Queue.submit([&](handler &h) { |
| 64 | + h.parallel_for<class kern1>(range<1>(N), |
| 65 | + [=](id<1> item) { A[item] = VAL; }); |
| 66 | + }); |
| 67 | + |
| 68 | + backend_traits<BACKEND>::return_type<event> NativeEvent = |
| 69 | + get_native<BACKEND>(Event); |
| 70 | + // Create sycl event with a native event. |
| 71 | + event InteropEvent = make_event<BACKEND>(NativeEvent, Context); |
| 72 | + |
| 73 | + // depends_on sycl event created from a native event. |
| 74 | + auto Event2 = InteropQueue.submit([&](handler &h) { |
| 75 | + h.depends_on(InteropEvent); |
| 76 | + h.parallel_for<class kern2>(range<1>(N), [=](id<1> item) { A[item]++; }); |
| 77 | + }); |
| 78 | + |
| 79 | + auto Event3 = InteropQueue.memcpy(&vec[0], A, N * sizeof(int), Event2); |
| 80 | + Event3.wait(); |
| 81 | + |
| 82 | + free(A, InteropQueue); |
| 83 | + |
| 84 | + for (const auto &val : vec) { |
| 85 | + assert(val == VAL + 1); |
| 86 | + } |
| 87 | + |
| 88 | + return 0; |
| 89 | +} |
0 commit comments