|
17 | 17 | #include <CL/sycl/detail/cl.h>
|
18 | 18 | #include <CL/sycl/detail/pi.h>
|
19 | 19 |
|
| 20 | +#include <algorithm> |
20 | 21 | #include <cassert>
|
21 | 22 | #include <cstring>
|
22 | 23 | #include <iostream>
|
23 | 24 | #include <limits>
|
24 | 25 | #include <map>
|
| 26 | +#include <set> |
| 27 | +#include <sstream> |
25 | 28 | #include <string>
|
26 | 29 | #include <vector>
|
27 | 30 |
|
|
33 | 36 | }
|
34 | 37 |
|
35 | 38 | const char SupportedVersion[] = _PI_H_VERSION_STRING;
|
| 39 | +std::set<std::string> SupportedExtensions; |
36 | 40 |
|
37 | 41 | // Want all the needed casts be explicit, do not define conversion operators.
|
38 | 42 | template <class To, class From> To cast(From value) {
|
@@ -66,6 +70,39 @@ CONSTFIX char clSetProgramSpecializationConstantName[] =
|
66 | 70 |
|
67 | 71 | #undef CONSTFIX
|
68 | 72 |
|
| 73 | +// Helper to get extensions that are common for all devices within a context |
| 74 | +pi_result getSupportedExtensionsWithinContext(pi_context context) { |
| 75 | + size_t deviceCount; |
| 76 | + cl_int ret_err = |
| 77 | + clGetContextInfo(cast<cl_context>(context), CL_CONTEXT_DEVICES, 0, |
| 78 | + nullptr, &deviceCount); |
| 79 | + if (ret_err != CL_SUCCESS || deviceCount < 1) |
| 80 | + return PI_INVALID_CONTEXT; |
| 81 | + std::vector<cl_device_id> devicesInCtx(deviceCount); |
| 82 | + ret_err = clGetContextInfo( |
| 83 | + cast<cl_context>(context), CL_CONTEXT_DEVICES, |
| 84 | + deviceCount * sizeof(cl_device_id), devicesInCtx.data(), nullptr); |
| 85 | + |
| 86 | + size_t retSize; |
| 87 | + for (size_t i = 0; i != deviceCount; ++i) { |
| 88 | + ret_err = clGetDeviceInfo(devicesInCtx[i], CL_DEVICE_EXTENSIONS, 0, |
| 89 | + nullptr, &retSize); |
| 90 | + if (ret_err != CL_SUCCESS) |
| 91 | + return PI_INVALID_DEVICE; |
| 92 | + std::string extensions(retSize, '\0'); |
| 93 | + ret_err = clGetDeviceInfo(devicesInCtx[i], CL_DEVICE_EXTENSIONS, |
| 94 | + retSize, &extensions[0], nullptr); |
| 95 | + if (ret_err != CL_SUCCESS) |
| 96 | + return PI_INVALID_DEVICE; |
| 97 | + std::string extension; |
| 98 | + std::stringstream ss(extensions); |
| 99 | + while (getline(ss, extension, ' ')) |
| 100 | + SupportedExtensions.insert(extension); |
| 101 | + } |
| 102 | + return cast<pi_result>(ret_err); |
| 103 | +} |
| 104 | + |
| 105 | + |
69 | 106 | // USM helper function to get an extension function pointer
|
70 | 107 | template <const char *FuncName, typename T>
|
71 | 108 | static pi_result getExtFuncFromContext(pi_context context, T *fptr) {
|
@@ -535,36 +572,18 @@ pi_result piMemBufferCreate(pi_context context, pi_mem_flags flags, size_t size,
|
535 | 572 | properties + propSize);
|
536 | 573 | // Go through buffer properties. If there is one, that shall be propagated
|
537 | 574 | // to an OpenCL runtime - check if this property is being supported.
|
538 |
| - for (auto prop = supported.begin(); prop != supported.end(); ++prop) { |
539 |
| - // Check if PI_MEM_CHANNEL_INTEL property is supported. If it's not - |
540 |
| - // just ignore it, as it's an optimization hint. |
541 |
| - if (*prop == PI_MEM_CHANNEL_INTEL) { |
542 |
| - size_t deviceCount; |
543 |
| - cl_int ret_err = |
544 |
| - clGetContextInfo(cast<cl_context>(context), CL_CONTEXT_DEVICES, 0, |
545 |
| - nullptr, &deviceCount); |
546 |
| - if (ret_err != CL_SUCCESS || deviceCount < 1) |
547 |
| - return PI_INVALID_CONTEXT; |
548 |
| - std::vector<cl_device_id> devicesInCtx(deviceCount); |
549 |
| - ret_err = clGetContextInfo( |
550 |
| - cast<cl_context>(context), CL_CONTEXT_DEVICES, |
551 |
| - deviceCount * sizeof(cl_device_id), devicesInCtx.data(), nullptr); |
552 |
| - |
553 |
| - size_t retSize; |
554 |
| - ret_err = clGetDeviceInfo(devicesInCtx[0], CL_DEVICE_EXTENSIONS, 0, |
555 |
| - nullptr, &retSize); |
556 |
| - if (ret_err != CL_SUCCESS) |
557 |
| - return PI_INVALID_DEVICE; |
558 |
| - std::string extensions(retSize, '\0'); |
559 |
| - ret_err = clGetDeviceInfo(devicesInCtx[0], CL_DEVICE_EXTENSIONS, |
560 |
| - retSize, &extensions[0], nullptr); |
561 |
| - if (ret_err != CL_SUCCESS) |
562 |
| - return PI_INVALID_DEVICE; |
563 |
| - |
564 |
| - size_t pos = extensions.find("cl_intel_mem_channel_property"); |
565 |
| - if (pos == std::string::npos) |
| 575 | + for (const auto &prop = supported.begin(); prop != supported.end(); |
| 576 | + ++(*prop)) { |
| 577 | + if (!SupportedExtensions.empty()) |
| 578 | + ret_err = getSupportedExtensionsWithinContext(context); |
| 579 | + // Check if PI_MEM_PROPERTIES_CHANNEL property is supported. If it's |
| 580 | + // not - just ignore it, as it's an optimization hint. |
| 581 | + if (*prop == PI_MEM_PROPERTIES_CHANNEL) { |
| 582 | + if (SupportedExtensions.find("cl_intel_mem_channel_property") != |
| 583 | + SupportedExtensions.end()) |
566 | 584 | supported.erase(prop);
|
567 |
| - } |
| 585 | + } else |
| 586 | + assert("Unsupported property found"); |
568 | 587 | }
|
569 | 588 | if (!supported.empty()) {
|
570 | 589 | *ret_mem =
|
|
0 commit comments