|
1 | 1 | // REQUIRES: opencl, opencl_icd, cm-compiler
|
2 |
| -// UNSUPPORTED: accelerator |
3 | 2 |
|
4 | 3 | // RUN: %{build} -Wno-error=deprecated-declarations -DRUN_KERNELS %opencl_lib -o %t.out
|
5 | 4 | // RUN: %{run} %t.out
|
|
18 | 17 | using byte = unsigned char;
|
19 | 18 |
|
20 | 19 | #ifdef RUN_KERNELS
|
| 20 | +std::tuple<unsigned long, unsigned long> GetOCLVersion(sycl::device Device) { |
| 21 | + cl_int Err; |
| 22 | + cl_device_id ClDevice = sycl::get_native<sycl::backend::opencl>(Device); |
| 23 | + |
| 24 | + size_t VersionSize = 0; |
| 25 | + Err = clGetDeviceInfo(ClDevice, CL_DEVICE_VERSION, 0, nullptr, &VersionSize); |
| 26 | + assert(Err == CL_SUCCESS); |
| 27 | + |
| 28 | + std::string Version(VersionSize, '\0'); |
| 29 | + Err = clGetDeviceInfo(ClDevice, CL_DEVICE_VERSION, VersionSize, |
| 30 | + Version.data(), nullptr); |
| 31 | + assert(Err == CL_SUCCESS); |
| 32 | + |
| 33 | + std::string_view Prefix = "OpenCL "; |
| 34 | + size_t VersionBegin = Version.find_first_of(" "); |
| 35 | + size_t VersionEnd = Version.find_first_of(" ", VersionBegin + 1); |
| 36 | + size_t VersionSeparator = Version.find_first_of(".", VersionBegin + 1); |
| 37 | + |
| 38 | + bool HaveOCLPrefix = |
| 39 | + std::equal(Prefix.begin(), Prefix.end(), Version.begin()); |
| 40 | + |
| 41 | + assert(HaveOCLPrefix && VersionBegin != std::string::npos && |
| 42 | + VersionEnd != std::string::npos && |
| 43 | + VersionSeparator != std::string::npos); |
| 44 | + |
| 45 | + std::string VersionMajor{Version.begin() + VersionBegin + 1, |
| 46 | + Version.begin() + VersionSeparator}; |
| 47 | + std::string VersionMinor{Version.begin() + VersionSeparator + 1, |
| 48 | + Version.begin() + VersionEnd}; |
| 49 | + |
| 50 | + unsigned long OCLMajor = strtoul(VersionMajor.c_str(), nullptr, 10); |
| 51 | + unsigned long OCLMinor = strtoul(VersionMinor.c_str(), nullptr, 10); |
| 52 | + |
| 53 | + assert(OCLMajor > 0 && (OCLMajor > 2 || OCLMinor <= 2) && |
| 54 | + OCLMajor != UINT_MAX && OCLMinor != UINT_MAX); |
| 55 | + |
| 56 | + return std::make_tuple(OCLMajor, OCLMinor); |
| 57 | +} |
| 58 | + |
| 59 | +bool testSupported(sycl::queue &Queue) { |
| 60 | + if (Queue.get_backend() != sycl::backend::opencl) |
| 61 | + return false; |
| 62 | + |
| 63 | + sycl::device Device = Queue.get_device(); |
| 64 | + auto [OCLMajor, OCLMinor] = GetOCLVersion(Device); |
| 65 | + |
| 66 | + // Creating a program from IL is only supported on >=2.1 or if |
| 67 | + // cl_khr_il_program is supported on the device. |
| 68 | + return (OCLMajor == 2 && OCLMinor >= 1) || OCLMajor > 2 || |
| 69 | + Device.has_extension("cl_khr_il_program"); |
| 70 | +} |
| 71 | + |
21 | 72 | sycl::kernel getSYCLKernelWithIL(sycl::queue &Queue,
|
22 | 73 | const std::vector<byte> &IL) {
|
23 | 74 | sycl::context Context = Queue.get_context();
|
24 | 75 |
|
25 |
| - cl_int Err; |
26 |
| - cl_program ClProgram = |
27 |
| - clCreateProgramWithIL(sycl::get_native<sycl::backend::opencl>(Context), |
28 |
| - IL.data(), IL.size(), &Err); |
| 76 | + cl_int Err = 0; |
| 77 | + cl_program ClProgram = 0; |
| 78 | + |
| 79 | + sycl::device Device = Queue.get_device(); |
| 80 | + auto [OCLMajor, OCLMinor] = GetOCLVersion(Device); |
| 81 | + if ((OCLMajor == 2 && OCLMinor >= 1) || OCLMajor > 2) { |
| 82 | + // clCreateProgramWithIL is supported if OCL version >=2.1. |
| 83 | + ClProgram = |
| 84 | + clCreateProgramWithIL(sycl::get_native<sycl::backend::opencl>(Context), |
| 85 | + IL.data(), IL.size(), &Err); |
| 86 | + } else { |
| 87 | + // Fall back to using extension function for building IR. |
| 88 | + using ApiFuncT = |
| 89 | + cl_program(CL_API_CALL *)(cl_context, const void *, size_t, cl_int *); |
| 90 | + ApiFuncT FuncPtr = |
| 91 | + reinterpret_cast<ApiFuncT>(clGetExtensionFunctionAddressForPlatform( |
| 92 | + sycl::get_native<sycl::backend::opencl>(Context.get_platform()), |
| 93 | + "clCreateProgramWithILKHR")); |
| 94 | + |
| 95 | + assert(FuncPtr != nullptr); |
| 96 | + |
| 97 | + ClProgram = FuncPtr(sycl::get_native<sycl::backend::opencl>(Context), |
| 98 | + IL.data(), IL.size(), &Err); |
| 99 | + } |
29 | 100 | assert(Err == CL_SUCCESS);
|
30 | 101 |
|
31 | 102 | Err = clBuildProgram(ClProgram, 0, nullptr, nullptr, nullptr, nullptr);
|
|
0 commit comments