|
| 1 | +// REQUIRES: cuda |
| 2 | +// RUN: %clangxx %s -I%opencl_include_dir -I%cuda_toolkit_include -o %t.out -lcuda -lsycl |
| 3 | +// RUN: env SYCL_DEVICE_TYPE=GPU %t.out |
| 4 | + |
| 5 | +//==---------- primary_context.cpp - SYCL cuda primary context test --------==// |
| 6 | +// |
| 7 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 8 | +// See https://llvm.org/LICENSE.txt for license information. |
| 9 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +#include <CL/sycl.hpp> |
| 14 | +#include <CL/sycl/detail/pi_cuda.hpp> |
| 15 | +#include <cuda.h> |
| 16 | +#include <iostream> |
| 17 | + |
| 18 | +using namespace cl::sycl; |
| 19 | + |
| 20 | +class other_device_selector : public default_selector { |
| 21 | +public: |
| 22 | + |
| 23 | + other_device_selector(const device &dev) : exclude_device{dev} {} |
| 24 | + |
| 25 | + int operator()(const device &dev) const { |
| 26 | + if (dev == exclude_device) { |
| 27 | + return -1; |
| 28 | + } |
| 29 | + return default_selector::operator()(dev); |
| 30 | + } |
| 31 | +private: |
| 32 | + const device &exclude_device; |
| 33 | +}; |
| 34 | + |
| 35 | +int main() { |
| 36 | + try { |
| 37 | + context c; |
| 38 | + } catch (device_error e) { |
| 39 | + std::cout << "Failed to create device for context" << std::endl; |
| 40 | + } |
| 41 | + |
| 42 | + device deviceA = default_selector().select_device(); |
| 43 | + device deviceB = other_device_selector(deviceA).select_device(); |
| 44 | + { |
| 45 | + std::cout << "create single context" << std::endl; |
| 46 | + context Context(deviceA, async_handler{}, true); |
| 47 | + |
| 48 | + CUdevice cudaDevice = reinterpret_cast<pi_device>(deviceA.get())->get(); |
| 49 | + CUcontext cudaContext = reinterpret_cast<pi_context>(Context.get())->get(); |
| 50 | + |
| 51 | + CUcontext primaryCudaContext; |
| 52 | + cuDevicePrimaryCtxRetain(&primaryCudaContext, cudaDevice); |
| 53 | + |
| 54 | + assert(cudaContext == primaryCudaContext); |
| 55 | + |
| 56 | + cuDevicePrimaryCtxRelease(cudaDevice); |
| 57 | + } |
| 58 | + { |
| 59 | + std::cout << "create multiple contexts for one device" << std::endl; |
| 60 | + context Context1(deviceA, async_handler{}, true); |
| 61 | + context Context2(deviceA, async_handler{}, true); |
| 62 | + |
| 63 | + CUcontext cudaContext1 = |
| 64 | + reinterpret_cast<pi_context>(Context1.get())->get(); |
| 65 | + CUcontext cudaContext2 = |
| 66 | + reinterpret_cast<pi_context>(Context2.get())->get(); |
| 67 | + |
| 68 | + assert(cudaContext1 == cudaContext2); |
| 69 | + } |
| 70 | + if (deviceA != deviceB) { |
| 71 | + std::cout << "create multiple contexts for multiple devices" << std::endl; |
| 72 | + context ContextA(deviceA, async_handler{}, true); |
| 73 | + context ContextB(deviceB, async_handler{}, true); |
| 74 | + |
| 75 | + CUcontext cudaContextA = |
| 76 | + reinterpret_cast<pi_context>(ContextA.get())->get(); |
| 77 | + CUcontext cudaContextB = |
| 78 | + reinterpret_cast<pi_context>(ContextB.get())->get(); |
| 79 | + |
| 80 | + assert(cudaContextA != cudaContextB); |
| 81 | + } |
| 82 | +} |
0 commit comments