1 //
2 // Copyright (c) 2019-2020 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "harness/compat.h"
17
18 #include <vector>
19 #include <set>
20 #include <iterator>
21 #include <algorithm>
22 #include <cstring>
23 #include "harness/testHarness.h"
24 #include "harness/deviceInfo.h"
25
26 using name_version_set = std::set<cl_name_version_khr>;
27
operator <(const cl_name_version_khr & lhs,const cl_name_version_khr & rhs)28 static bool operator<(const cl_name_version_khr& lhs,
29 const cl_name_version_khr& rhs)
30 {
31 const int cmp = strcmp(lhs.name, rhs.name);
32 if (0 == cmp)
33 {
34 return lhs.version < rhs.version;
35 }
36
37 return cmp < 0;
38 }
39
operator ==(const cl_name_version_khr & lhs,const cl_name_version_khr & rhs)40 static bool operator==(const cl_name_version_khr& lhs,
41 const cl_name_version_khr& rhs)
42 {
43 return (0 == strcmp(lhs.name, rhs.name)) && (lhs.version == rhs.version);
44 }
45
46 /* Parse major and minor version numbers out of version_string according to
47 * format, which is a scanf-format with two %u specifiers, then compare the
48 * version to the major and minor versions of version_numeric */
is_same_version(const char * const format,const char * const version_string,const cl_version_khr version_numeric)49 static bool is_same_version(const char* const format,
50 const char* const version_string,
51 const cl_version_khr version_numeric)
52 {
53 unsigned int string_major = 0;
54 unsigned int string_minor = 0;
55 const int matched =
56 sscanf(version_string, format, &string_major, &string_minor);
57
58 if (2 != matched)
59 {
60 log_error("sscanf() fail on version string \"%s\", format=\"%s\"\n",
61 version_string, format);
62 return false;
63 }
64
65 const unsigned int numeric_major = CL_VERSION_MAJOR_KHR(version_numeric);
66 const unsigned int numeric_minor = CL_VERSION_MINOR_KHR(version_numeric);
67
68 return (string_major == numeric_major) && (string_minor == numeric_minor);
69 }
70
get_platform_string(cl_platform_id platform,cl_platform_info name)71 static std::vector<char> get_platform_string(cl_platform_id platform,
72 cl_platform_info name)
73 {
74 size_t size{};
75 cl_int err = clGetPlatformInfo(platform, name, 0, nullptr, &size);
76 if (err != CL_SUCCESS)
77 {
78 log_error("clGetPlatformInfo failed\n");
79 return {};
80 }
81
82 std::vector<char> result(size);
83
84 err = clGetPlatformInfo(platform, name, size, result.data(), nullptr);
85 if (err != CL_SUCCESS)
86 {
87 log_error("clGetPlatformInfo failed\n");
88 return {};
89 }
90
91 return result;
92 }
93
get_device_string(cl_device_id device,cl_device_info name)94 static std::vector<char> get_device_string(cl_device_id device,
95 cl_device_info name)
96 {
97 size_t size{};
98 cl_int err = clGetDeviceInfo(device, name, 0, nullptr, &size);
99 if (err != CL_SUCCESS)
100 {
101 log_error("clGetDeviceInfo failed\n");
102 return {};
103 }
104
105 std::vector<char> result(size);
106
107 err = clGetDeviceInfo(device, name, size, result.data(), nullptr);
108 if (err != CL_SUCCESS)
109 {
110 log_error("clGetDeviceInfo failed\n");
111 return {};
112 }
113
114 return result;
115 }
116
117 /* Parse an extension string into a cl_name_version_khr set. Error out if we
118 * have an invalid extension string */
name_version_set_from_extension_string(char * const src,name_version_set & dest)119 static bool name_version_set_from_extension_string(char* const src,
120 name_version_set& dest)
121 {
122 for (char* token = strtok(src, " "); nullptr != token;
123 token = strtok(nullptr, " "))
124 {
125 if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(token))
126 {
127 log_error("Extension name is longer than allowed\n");
128 return false;
129 }
130
131 cl_name_version_khr name_version{};
132 strncpy(name_version.name, token, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
133
134 if (dest.find(name_version) != dest.cend())
135 {
136 log_error("Duplicate extension in extension string\n");
137 return false;
138 }
139
140 dest.insert(name_version);
141 }
142
143 return true;
144 }
145
146 /* Parse a built-in kernels string into a cl_name_version_khr set. Error out if
147 * we have an invalid built-in kernels string */
name_version_set_from_built_in_kernel_string(char * const src,name_version_set & dest)148 static bool name_version_set_from_built_in_kernel_string(char* const src,
149 name_version_set& dest)
150 {
151 for (char* token = strtok(src, ";"); nullptr != token;
152 token = strtok(nullptr, ";"))
153 {
154 if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(token))
155 {
156 log_error("Kernel name is longer than allowed\n");
157 return false;
158 }
159
160 cl_name_version_khr name_version{};
161 strncpy(name_version.name, token, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
162
163 if (dest.find(name_version) != dest.cend())
164 {
165 log_error("Duplicate kernel name in kernel string\n");
166 return false;
167 }
168
169 dest.insert(name_version);
170 }
171
172 return true;
173 }
174
175 /* Helper to log the names of elements of the set difference of two
176 * cl_name_version_khr sets */
log_name_only_set_difference(const name_version_set & lhs,const name_version_set & rhs)177 static void log_name_only_set_difference(const name_version_set& lhs,
178 const name_version_set& rhs)
179 {
180 std::vector<cl_name_version_khr> difference;
181 std::set_difference(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
182 std::back_inserter(difference));
183
184 for (const cl_name_version_khr& il : difference)
185 {
186 log_info(" %s", il.name);
187 }
188 }
189
190 /* Helper to log as IL versions the elements of the set difference of two
191 * cl_name_version_khr sets */
log_il_set_difference(const name_version_set & lhs,const name_version_set & rhs)192 static void log_il_set_difference(const name_version_set& lhs,
193 const name_version_set& rhs)
194 {
195 std::vector<cl_name_version_khr> difference;
196 std::set_difference(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
197 std::back_inserter(difference));
198
199 for (const cl_name_version_khr& il : difference)
200 {
201 const unsigned int major = CL_VERSION_MAJOR_KHR(il.version);
202 const unsigned int minor = CL_VERSION_MINOR_KHR(il.version);
203 log_info(" %s_%u.%u", il.name, major, minor);
204 }
205 }
206
207 /* Check that CL_PLATFORM_NUMERIC_VERSION_KHR returns the same version as
208 * CL_PLATFORM_VERSION */
test_extended_versioning_platform_version(cl_platform_id platform)209 static int test_extended_versioning_platform_version(cl_platform_id platform)
210 {
211 log_info("Platform versions:\n");
212
213 const std::vector<char> version_string(
214 get_platform_string(platform, CL_PLATFORM_VERSION));
215 if (version_string.empty())
216 {
217 log_error("Could not get CL platform version string\n");
218 return 1;
219 }
220
221 cl_version_khr version_numeric{};
222 cl_int err =
223 clGetPlatformInfo(platform, CL_PLATFORM_NUMERIC_VERSION_KHR,
224 sizeof(version_numeric), &version_numeric, nullptr);
225 if (err != CL_SUCCESS)
226 {
227 log_error("clGetPlatformInfo failed\n");
228 return 1;
229 }
230
231 if (!is_same_version("OpenCL %u.%u", version_string.data(),
232 version_numeric))
233 {
234 log_error(
235 "Numeric platform version does not match the version string\n");
236 return 1;
237 }
238
239 log_info("\tMatched the platform version\n");
240
241 return 0;
242 }
243
244 /* Check that CL_DEVICE{,_OPENCL_C}_NUMERIC_VERSION_KHR return the same versions
245 * as CL_DEVICE{,_OPENCL_C}_VERSION */
test_extended_versioning_device_versions(bool ext,cl_device_id deviceID)246 static int test_extended_versioning_device_versions(bool ext,
247 cl_device_id deviceID)
248 {
249 log_info("Device versions:\n");
250
251 static constexpr struct
252 {
253 cl_platform_info param_name_numeric;
254 cl_platform_info param_name_string;
255 const char* format;
256 } device_version_queries[]{
257 { CL_DEVICE_NUMERIC_VERSION_KHR, CL_DEVICE_VERSION, "OpenCL %u.%u" },
258 { CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, CL_DEVICE_OPENCL_C_VERSION,
259 "OpenCL C %u.%u" },
260 };
261
262 for (const auto& query : device_version_queries)
263 {
264 // CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR is only supported by
265 // cl_khr_extended_versioning:
266 if (!ext
267 && query.param_name_numeric
268 == CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR)
269 {
270 continue;
271 }
272
273 const std::vector<char> version_string(
274 get_device_string(deviceID, query.param_name_string));
275 if (version_string.empty())
276 {
277 log_error("Could not get CL platform version string\n");
278 return 1;
279 }
280
281 cl_version_khr version_numeric{};
282 cl_int err =
283 clGetDeviceInfo(deviceID, query.param_name_numeric,
284 sizeof(version_numeric), &version_numeric, nullptr);
285 if (err != CL_SUCCESS)
286 {
287 log_error("clGetDeviceInfo failed\n");
288 return 1;
289 }
290
291 if (!is_same_version(query.format, version_string.data(),
292 version_numeric))
293 {
294 log_error(
295 "Numeric device version does not match the version string\n");
296 return 1;
297 }
298 }
299
300 log_info("\tMatched the device OpenCL and OpenCL C versions\n");
301
302 return 0;
303 }
304
305 /* Check that the platform extension string and name_version queries return the
306 * same set */
test_extended_versioning_platform_extensions(cl_platform_id platform)307 static int test_extended_versioning_platform_extensions(cl_platform_id platform)
308 {
309 log_info("Platform extensions:\n");
310 std::vector<char> extension_string{ get_platform_string(
311 platform, CL_PLATFORM_EXTENSIONS) };
312 if (extension_string.empty())
313 {
314 log_error("Could not get CL platform extensions string\n");
315 return 1;
316 }
317
318 size_t size{};
319 cl_int err = clGetPlatformInfo(
320 platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, 0, nullptr, &size);
321 if (err != CL_SUCCESS)
322 {
323 log_error("clGetPlatformInfo failed\n");
324 return 1;
325 }
326
327 if ((size % sizeof(cl_name_version_khr)) != 0)
328 {
329 log_error("CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR return size not a "
330 "multiple of sizeof(cl_name_version_khr)\n");
331 return 1;
332 }
333
334 const size_t extension_name_vers_count = size / sizeof(cl_name_version_khr);
335 std::vector<cl_name_version_khr> extension_name_vers(
336 extension_name_vers_count);
337
338 err = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR,
339 size, extension_name_vers.data(), nullptr);
340 if (err != CL_SUCCESS)
341 {
342 log_error("clGetPlatformInfo failed\n");
343 return 1;
344 }
345
346 name_version_set extension_name_vers_set;
347 for (const auto& extension : extension_name_vers)
348 {
349 /* Extension string doesn't have versions, so set it to all zeroes for
350 * matching */
351 cl_name_version_khr name_version = extension;
352 name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
353
354 if (extension_name_vers_set.find(name_version)
355 != extension_name_vers_set.cend())
356 {
357 log_error("Duplicate extension in extension name-version array\n");
358 return 1;
359 }
360
361 extension_name_vers_set.insert(name_version);
362 }
363
364 name_version_set extension_string_set;
365 if (!name_version_set_from_extension_string(extension_string.data(),
366 extension_string_set))
367 {
368 log_error("Failed to parse platform extension string\n");
369 return 1;
370 }
371
372 if (extension_string_set != extension_name_vers_set)
373 {
374 log_error("Platform extension mismatch\n");
375
376 log_info("\tExtensions only in numeric:");
377 log_name_only_set_difference(extension_name_vers_set,
378 extension_string_set);
379 log_info("\n\tExtensions only in string:");
380 log_name_only_set_difference(extension_string_set,
381 extension_name_vers_set);
382 log_info("\n");
383
384 return 1;
385 }
386
387 log_info("\tMatched %zu extensions\n", extension_name_vers_set.size());
388
389 return 0;
390 }
391
392 /* Check that the device extension string and name_version queries return the
393 * same set */
test_extended_versioning_device_extensions(cl_device_id device)394 static int test_extended_versioning_device_extensions(cl_device_id device)
395 {
396 log_info("Device extensions:\n");
397 std::vector<char> extension_string{ get_device_string(
398 device, CL_DEVICE_EXTENSIONS) };
399 if (extension_string.empty())
400 {
401 log_error("Could not get CL device extensions string\n");
402 return 1;
403 }
404
405 size_t size{};
406 cl_int err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR,
407 0, nullptr, &size);
408 if (err != CL_SUCCESS)
409 {
410 log_error("clGetDeviceInfo failed\n");
411 return 1;
412 }
413
414 if ((size % sizeof(cl_name_version_khr)) != 0)
415 {
416 log_error("CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR return size not a "
417 "multiple of sizeof(cl_name_version_khr)\n");
418 return 1;
419 }
420
421 const size_t extension_name_vers_count = size / sizeof(cl_name_version_khr);
422 std::vector<cl_name_version_khr> extension_name_vers(
423 extension_name_vers_count);
424
425 err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, size,
426 extension_name_vers.data(), nullptr);
427 if (err != CL_SUCCESS)
428 {
429 log_error("clGetDeviceInfo failed\n");
430 return 1;
431 }
432
433 name_version_set extension_name_vers_set;
434 for (const auto& extension : extension_name_vers)
435 {
436 /* Extension string doesn't have versions, so set it to all zeroes for
437 * matching */
438 cl_name_version_khr name_version = extension;
439 name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
440
441 if (extension_name_vers_set.find(name_version)
442 != extension_name_vers_set.cend())
443 {
444 log_error("Duplicate extension in extension name-version array\n");
445 return 1;
446 }
447
448 extension_name_vers_set.insert(name_version);
449 }
450
451 name_version_set extension_string_set;
452 if (!name_version_set_from_extension_string(extension_string.data(),
453 extension_string_set))
454 {
455 log_error("Failed to parse device extension string\n");
456 return 1;
457 }
458
459 if (extension_string_set != extension_name_vers_set)
460 {
461 log_error("Device extension mismatch\n");
462
463 log_info("\tExtensions only in numeric:");
464 log_name_only_set_difference(extension_name_vers_set,
465 extension_string_set);
466 log_info("\n\tExtensions only in string:");
467 log_name_only_set_difference(extension_string_set,
468 extension_name_vers_set);
469 log_info("\n");
470
471 return 1;
472 }
473
474 log_info("\tMatched %zu extensions\n", extension_name_vers_set.size());
475
476 return 0;
477 }
478
479 /* Check that the device ILs string and numeric queries return the same set */
test_extended_versioning_device_il(cl_device_id device)480 static int test_extended_versioning_device_il(cl_device_id device)
481 {
482 log_info("Device ILs:\n");
483
484 size_t size{};
485 cl_int err = clGetDeviceInfo(device, CL_DEVICE_ILS_WITH_VERSION_KHR, 0,
486 nullptr, &size);
487 if (err != CL_SUCCESS)
488 {
489 log_error("clGetDeviceInfo failed\n");
490 return 1;
491 }
492
493 if ((size % sizeof(cl_name_version_khr)) != 0)
494 {
495 log_error("CL_DEVICE_ILS_WITH_VERSION_KHR return size not a multiple "
496 "of sizeof(cl_name_version_khr)\n");
497 return 1;
498 }
499
500 const size_t il_name_vers_count = size / sizeof(cl_name_version_khr);
501 std::vector<cl_name_version_khr> il_name_vers(il_name_vers_count);
502
503 err = clGetDeviceInfo(device, CL_DEVICE_ILS_WITH_VERSION_KHR, size,
504 il_name_vers.data(), nullptr);
505 if (err != CL_SUCCESS)
506 {
507 log_error("clGetDeviceInfo failed\n");
508 return 1;
509 }
510
511 const bool has_khr_il_program =
512 is_extension_available(device, "cl_khr_il_program");
513 const bool has_core_il_program =
514 get_device_cl_version(device) > Version(2, 0);
515
516 // IL query should return an empty list if the device does not support IL
517 // programs
518 if (!(has_khr_il_program || has_core_il_program))
519 {
520 const bool success = il_name_vers.empty();
521 if (!success)
522 {
523 log_error(
524 "No il_program support, but CL_DEVICE_ILS_WITH_VERSION_KHR "
525 "returned a non-empty list\n");
526 return 1;
527 }
528 else
529 {
530 log_info(
531 "\tNo il_program support, and CL_DEVICE_ILS_WITH_VERSION_KHR "
532 "correctly returned the empty list\n");
533 return 0;
534 }
535 }
536
537 // Pick the core or extension version of the query parameter name
538 const cl_device_info il_version_param_name =
539 has_core_il_program ? CL_DEVICE_IL_VERSION : CL_DEVICE_IL_VERSION_KHR;
540
541 std::vector<char> il_string{ get_device_string(device,
542 il_version_param_name) };
543 if (il_string.empty())
544 {
545 log_error("Couldn't get device IL string\n");
546 return 1;
547 }
548
549 name_version_set il_string_set;
550 char* saveptr_outer = nullptr;
551 for (char* token = strtok_r(il_string.data(), " ", &saveptr_outer);
552 nullptr != token; token = strtok_r(nullptr, " ", &saveptr_outer))
553 {
554 char* saveptr_inner = nullptr;
555 const char* const prefix = strtok_r(token, "_", &saveptr_inner);
556 const char* const version = strtok_r(nullptr, "", &saveptr_inner);
557
558 unsigned major = 0;
559 unsigned minor = 0;
560 const int matched = sscanf(version, "%u.%u", &major, &minor);
561 if (2 != matched)
562 {
563 log_error("IL version string scan mismatch\n");
564 return 1;
565 }
566 if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(prefix))
567 {
568 log_error("IL name longer than allowed\n");
569 return 1;
570 }
571
572 cl_name_version_khr name_version{};
573 strncpy(name_version.name, prefix, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
574 name_version.version = CL_MAKE_VERSION_KHR(major, minor, 0);
575
576 if (il_string_set.find(name_version) != il_string_set.end())
577 {
578 log_error("Duplicate IL version in IL string\n");
579 return 1;
580 }
581
582 il_string_set.insert(name_version);
583 }
584
585 name_version_set il_name_vers_set;
586 for (const auto& il : il_name_vers)
587 {
588 const unsigned major = CL_VERSION_MAJOR_KHR(il.version);
589 const unsigned minor = CL_VERSION_MINOR_KHR(il.version);
590
591 cl_name_version_khr name_version = il;
592 name_version.version = CL_MAKE_VERSION_KHR(major, minor, 0);
593
594 if (il_name_vers_set.find(name_version) != il_name_vers_set.cend())
595 {
596 log_error("Duplicate IL in name-version array\n");
597 return 1;
598 }
599
600 il_name_vers_set.insert(name_version);
601 }
602
603 if (il_string_set != il_name_vers_set)
604 {
605 log_error("Device IL mismatch\n");
606
607 log_info("\tILs only in numeric:");
608 log_il_set_difference(il_name_vers_set, il_string_set);
609 log_info("\n\tILs only in string:");
610 log_il_set_difference(il_string_set, il_name_vers_set);
611 log_info("\n");
612
613 return 1;
614 }
615
616 log_info("\tMatched %zu ILs\n", il_name_vers_set.size());
617
618 return 0;
619 }
620
test_extended_versioning_device_built_in_kernels(cl_device_id device)621 static int test_extended_versioning_device_built_in_kernels(cl_device_id device)
622 {
623 log_info("Device built-in kernels:\n");
624 std::vector<char> kernel_string{ get_device_string(
625 device, CL_DEVICE_BUILT_IN_KERNELS) };
626 if (kernel_string.empty())
627 {
628 log_error("Could not get CL device extensions string\n");
629 return 1;
630 }
631
632 size_t size{};
633 cl_int err = clGetDeviceInfo(
634 device, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, 0, nullptr, &size);
635 if (err != CL_SUCCESS)
636 {
637 log_error("clGetDeviceInfo failed\n");
638 return 1;
639 }
640
641 if ((size % sizeof(cl_name_version_khr)) != 0)
642 {
643 log_error("CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR return size not "
644 "a multiple of sizeof(cl_name_version_khr)\n");
645 return 1;
646 }
647
648 const size_t kernel_name_vers_count = size / sizeof(cl_name_version_khr);
649 std::vector<cl_name_version_khr> kernel_name_vers(kernel_name_vers_count);
650
651 err = clGetDeviceInfo(device, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR,
652 size, kernel_name_vers.data(), nullptr);
653 if (err != CL_SUCCESS)
654 {
655 log_error("clGetDeviceInfo failed\n");
656 return 1;
657 }
658
659 name_version_set kernel_name_vers_set;
660 for (const auto& kernel : kernel_name_vers)
661 {
662 cl_name_version_khr name_version = kernel;
663 name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
664
665 if (kernel_name_vers_set.find(name_version)
666 != kernel_name_vers_set.cend())
667 {
668 log_error("Duplicate kernel in kernel name-version array\n");
669 return 1;
670 }
671
672 kernel_name_vers_set.insert(name_version);
673 }
674
675 name_version_set kernel_string_set;
676 if (!name_version_set_from_built_in_kernel_string(kernel_string.data(),
677 kernel_string_set))
678 {
679 log_error("Failed to parse device kernel string\n");
680 return 1;
681 }
682
683 if (kernel_string_set != kernel_name_vers_set)
684 {
685 log_error("Device kernel mismatch\n");
686
687 log_info("\tKernels only in numeric:");
688 log_name_only_set_difference(kernel_name_vers_set, kernel_string_set);
689 log_info("\n\tKernels only in string:");
690 log_name_only_set_difference(kernel_string_set, kernel_name_vers_set);
691 log_info("\n");
692
693 return 1;
694 }
695
696 log_info("\tMatched %zu kernels\n", kernel_name_vers_set.size());
697
698 return 0;
699 }
700
701 // Assumes the core enums, structures, and macros exactly match
702 // the extension enums, structures, and macros:
703
704 static_assert(CL_PLATFORM_NUMERIC_VERSION == CL_PLATFORM_NUMERIC_VERSION_KHR,
705 "CL_PLATFORM_NUMERIC_VERSION mismatch");
706 static_assert(CL_PLATFORM_EXTENSIONS_WITH_VERSION
707 == CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR,
708 "CL_PLATFORM_EXTENSIONS_WITH_VERSION mismatch");
709
710 static_assert(CL_DEVICE_NUMERIC_VERSION == CL_DEVICE_NUMERIC_VERSION_KHR,
711 "CL_DEVICE_NUMERIC_VERSION mismatch");
712 static_assert(CL_DEVICE_EXTENSIONS_WITH_VERSION
713 == CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR,
714 "CL_DEVICE_EXTENSIONS_WITH_VERSION mismatch");
715 static_assert(CL_DEVICE_ILS_WITH_VERSION == CL_DEVICE_ILS_WITH_VERSION_KHR,
716 "CL_DEVICE_ILS_WITH_VERSION mismatch");
717 static_assert(CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION
718 == CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR,
719 "CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION mismatch");
720
721 static_assert(sizeof(cl_name_version) == sizeof(cl_name_version_khr),
722 "cl_name_version mismatch");
723
724 static_assert(CL_MAKE_VERSION(1, 2, 3) == CL_MAKE_VERSION_KHR(1, 2, 3),
725 "CL_MAKE_VERSION mismatch");
726
test_extended_versioning(cl_device_id deviceID,cl_context context,cl_command_queue ignoreQueue,int num_elements)727 int test_extended_versioning(cl_device_id deviceID, cl_context context,
728 cl_command_queue ignoreQueue, int num_elements)
729 {
730 bool ext = is_extension_available(deviceID, "cl_khr_extended_versioning");
731 bool core = get_device_cl_version(deviceID) >= Version(3, 0);
732
733 if (!ext && !core)
734 {
735 return TEST_SKIPPED_ITSELF;
736 }
737
738 cl_platform_id platform;
739 cl_int err = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform),
740 &platform, nullptr);
741 test_error(err, "clGetDeviceInfo failed\n");
742
743 int total_errors = 0;
744 total_errors += test_extended_versioning_platform_version(platform);
745 total_errors += test_extended_versioning_platform_extensions(platform);
746 total_errors += test_extended_versioning_device_versions(ext, deviceID);
747 total_errors += test_extended_versioning_device_extensions(deviceID);
748 total_errors += test_extended_versioning_device_il(deviceID);
749 total_errors += test_extended_versioning_device_built_in_kernels(deviceID);
750
751 return total_errors;
752 }
753