@@ -89,6 +89,71 @@ pi_result piPluginGetLastError(char **message) {
89
89
return ErrorMessageCode;
90
90
}
91
91
92
+ static cl_int getPlatformVersion (cl_platform_id plat,
93
+ OCLV::OpenCLVersion &version) {
94
+ cl_int ret_err = CL_INVALID_VALUE;
95
+
96
+ size_t platVerSize = 0 ;
97
+ ret_err =
98
+ clGetPlatformInfo (plat, CL_PLATFORM_VERSION, 0 , nullptr , &platVerSize);
99
+
100
+ std::string platVer (platVerSize, ' \0 ' );
101
+ ret_err = clGetPlatformInfo (plat, CL_PLATFORM_VERSION, platVerSize,
102
+ platVer.data (), nullptr );
103
+
104
+ if (ret_err != CL_SUCCESS)
105
+ return ret_err;
106
+
107
+ version = OCLV::OpenCLVersion (platVer);
108
+ if (!version.isValid ())
109
+ return CL_INVALID_PLATFORM;
110
+
111
+ return ret_err;
112
+ }
113
+
114
+ static cl_int getDeviceVersion (cl_device_id dev, OCLV::OpenCLVersion &version) {
115
+ cl_int ret_err = CL_INVALID_VALUE;
116
+
117
+ size_t devVerSize = 0 ;
118
+ ret_err = clGetDeviceInfo (dev, CL_DEVICE_VERSION, 0 , nullptr , &devVerSize);
119
+
120
+ std::string devVer (devVerSize, ' \0 ' );
121
+ ret_err = clGetDeviceInfo (dev, CL_DEVICE_VERSION, devVerSize, devVer.data (),
122
+ nullptr );
123
+
124
+ if (ret_err != CL_SUCCESS)
125
+ return ret_err;
126
+
127
+ version = OCLV::OpenCLVersion (devVer);
128
+ if (!version.isValid ())
129
+ return CL_INVALID_DEVICE;
130
+
131
+ return ret_err;
132
+ }
133
+
134
+ static cl_int checkDeviceExtensions (cl_device_id dev,
135
+ const std::vector<std::string> &exts,
136
+ bool &supported) {
137
+ cl_int ret_err = CL_INVALID_VALUE;
138
+
139
+ size_t extSize = 0 ;
140
+ ret_err = clGetDeviceInfo (dev, CL_DEVICE_EXTENSIONS, 0 , nullptr , &extSize);
141
+
142
+ std::string extStr (extSize, ' \0 ' );
143
+ ret_err = clGetDeviceInfo (dev, CL_DEVICE_EXTENSIONS, extSize, extStr.data (),
144
+ nullptr );
145
+
146
+ if (ret_err != CL_SUCCESS)
147
+ return ret_err;
148
+
149
+ supported = true ;
150
+ for (const std::string &ext : exts)
151
+ if (!(supported = (extStr.find (ext) != std::string::npos)))
152
+ break ;
153
+
154
+ return ret_err;
155
+ }
156
+
92
157
// USM helper function to get an extension function pointer
93
158
template <const char *FuncName, typename T>
94
159
static pi_result getExtFuncFromContext (pi_context context, T *fptr) {
@@ -215,17 +280,18 @@ pi_result piDeviceGetInfo(pi_device device, pi_device_info paramName,
215
280
case PI_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES:
216
281
return PI_ERROR_INVALID_VALUE;
217
282
case PI_DEVICE_INFO_ATOMIC_64: {
218
- size_t extSize;
219
- cl_bool result = clGetDeviceInfo (
220
- cast<cl_device_id>(device), CL_DEVICE_EXTENSIONS, 0 , nullptr , &extSize);
221
- std::string extStr (extSize, ' \0 ' );
222
- result = clGetDeviceInfo (cast<cl_device_id>(device), CL_DEVICE_EXTENSIONS,
223
- extSize, &extStr.front (), nullptr );
224
- if (extStr.find (" cl_khr_int64_base_atomics" ) == std::string::npos ||
225
- extStr.find (" cl_khr_int64_extended_atomics" ) == std::string::npos)
226
- result = false ;
227
- else
228
- result = true ;
283
+ cl_int ret_err = CL_SUCCESS;
284
+ cl_bool result = CL_FALSE;
285
+ bool supported = false ;
286
+
287
+ ret_err = checkDeviceExtensions (
288
+ cast<cl_device_id>(device),
289
+ {" cl_khr_int64_base_atomics" , " cl_khr_int64_extended_atomics" },
290
+ supported);
291
+ if (ret_err != CL_SUCCESS)
292
+ return static_cast <pi_result>(ret_err);
293
+
294
+ result = supported;
229
295
std::memcpy (paramValue, &result, sizeof (cl_bool));
230
296
return PI_SUCCESS;
231
297
}
@@ -402,18 +468,6 @@ pi_result piQueueCreate(pi_context context, pi_device device,
402
468
403
469
CHECK_ERR_SET_NULL_RET (ret_err, queue, ret_err);
404
470
405
- size_t platVerSize;
406
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_VERSION, 0 , nullptr ,
407
- &platVerSize);
408
-
409
- CHECK_ERR_SET_NULL_RET (ret_err, queue, ret_err);
410
-
411
- std::string platVer (platVerSize, ' \0 ' );
412
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_VERSION, platVerSize,
413
- &platVer.front (), nullptr );
414
-
415
- CHECK_ERR_SET_NULL_RET (ret_err, queue, ret_err);
416
-
417
471
// Check that unexpected bits are not set.
418
472
assert (!(properties &
419
473
~(PI_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
@@ -425,9 +479,12 @@ pi_result piQueueCreate(pi_context context, pi_device device,
425
479
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_PROFILING_ENABLE |
426
480
CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
427
481
428
- if (platVer.find (" OpenCL 1.0" ) != std::string::npos ||
429
- platVer.find (" OpenCL 1.1" ) != std::string::npos ||
430
- platVer.find (" OpenCL 1.2" ) != std::string::npos) {
482
+ OCLV::OpenCLVersion version;
483
+ ret_err = getPlatformVersion (curPlatform, version);
484
+
485
+ CHECK_ERR_SET_NULL_RET (ret_err, queue, ret_err);
486
+
487
+ if (version >= OCLV::V2_0) {
431
488
*queue = cast<pi_queue>(clCreateCommandQueue (
432
489
cast<cl_context>(context), cast<cl_device_id>(device),
433
490
cast<cl_command_queue_properties>(properties) & SupportByOpenCL,
@@ -482,38 +539,51 @@ pi_result piProgramCreate(pi_context context, const void *il, size_t length,
482
539
483
540
CHECK_ERR_SET_NULL_RET (ret_err, res_program, CL_INVALID_CONTEXT);
484
541
485
- size_t devVerSize;
486
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_VERSION, 0 , nullptr ,
487
- &devVerSize);
488
- std::string devVer (devVerSize, ' \0 ' );
489
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_VERSION, devVerSize,
490
- &devVer.front (), nullptr );
542
+ OCLV::OpenCLVersion platVer;
543
+ ret_err = getPlatformVersion (curPlatform, platVer);
491
544
492
545
CHECK_ERR_SET_NULL_RET (ret_err, res_program, CL_INVALID_CONTEXT);
493
546
494
547
pi_result err = PI_SUCCESS;
495
- if (devVer.find (" OpenCL 1.0" ) == std::string::npos &&
496
- devVer.find (" OpenCL 1.1" ) == std::string::npos &&
497
- devVer.find (" OpenCL 1.2" ) == std::string::npos &&
498
- devVer.find (" OpenCL 2.0" ) == std::string::npos) {
548
+ if (platVer >= OCLV::V2_1) {
549
+
550
+ /* Make sure all devices support CL 2.1 or newer as well. */
551
+ for (cl_device_id dev : devicesInCtx) {
552
+ OCLV::OpenCLVersion devVer;
553
+
554
+ ret_err = getDeviceVersion (dev, devVer);
555
+ CHECK_ERR_SET_NULL_RET (ret_err, res_program, CL_INVALID_CONTEXT);
556
+
557
+ /* If the device does not support CL 2.1 or greater, we need to make sure
558
+ * it supports the cl_khr_il_program extension.
559
+ */
560
+ if (devVer < OCLV::V2_1) {
561
+ bool supported = false ;
562
+
563
+ ret_err = checkDeviceExtensions (dev, {" cl_khr_il_program" }, supported);
564
+ CHECK_ERR_SET_NULL_RET (ret_err, res_program, CL_INVALID_CONTEXT);
565
+
566
+ if (!supported)
567
+ return cast<pi_result>(CL_INVALID_OPERATION);
568
+ }
569
+ }
499
570
if (res_program != nullptr )
500
571
*res_program = cast<pi_program>(clCreateProgramWithIL (
501
572
cast<cl_context>(context), il, length, cast<cl_int *>(&err)));
502
573
return err;
503
574
}
504
575
505
- size_t extSize;
506
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_EXTENSIONS, 0 , nullptr ,
507
- &extSize);
508
- std::string extStr (extSize, ' \0 ' );
509
- ret_err = clGetPlatformInfo (curPlatform, CL_PLATFORM_EXTENSIONS, extSize,
510
- &extStr.front (), nullptr );
576
+ /* If none of the devices conform with CL 2.1 or newer make sure they all
577
+ * support the cl_khr_il_program extension.
578
+ */
579
+ for (cl_device_id dev : devicesInCtx) {
580
+ bool supported = false ;
511
581
512
- if ( ret_err != CL_SUCCESS ||
513
- extStr. find ( " cl_khr_il_program " ) == std::string::npos) {
514
- if (res_program != nullptr )
515
- *res_program = nullptr ;
516
- return cast<pi_result>(CL_INVALID_CONTEXT );
582
+ ret_err = checkDeviceExtensions (dev, { " cl_khr_il_program " }, supported);
583
+ CHECK_ERR_SET_NULL_RET (ret_err, res_program, CL_INVALID_CONTEXT);
584
+
585
+ if (!supported)
586
+ return cast<pi_result>(CL_INVALID_OPERATION );
517
587
}
518
588
519
589
using apiFuncT =
0 commit comments