1 //
2 // Copyright (c) 2017 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 "testBase.h"
17 #include "harness/typeWrappers.h"
18 #include "harness/testHarness.h"
19 #include <ctype.h>
20 #include <string.h>
21
22 const char *sample_single_param_kernel[] = {
23 "__kernel void sample_test(__global int *src)\n"
24 "{\n"
25 " size_t tid = get_global_id(0);\n"
26 "\n"
27 "}\n"
28 };
29
30
31 const char *sample_read_image_kernel_pattern[] = {
32 "__kernel void sample_test( __global float *result, ",
33 " )\n"
34 "{\n"
35 " sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | "
36 "CLK_FILTER_NEAREST;\n"
37 " size_t tid = get_global_id(0);\n"
38 " result[0] = 0.0f;\n",
39 "\n"
40 "}\n"
41 };
42
43 const char *sample_write_image_kernel_pattern[] = {
44 "__kernel void sample_test( ",
45 " )\n"
46 "{\n"
47 " size_t tid = get_global_id(0);\n",
48 "\n"
49 "}\n"
50 };
51
52
53 const char *sample_large_parmam_kernel_pattern[] = {
54 "__kernel void sample_test(%s, __global long *result)\n"
55 "{\n"
56 "result[0] = 0;\n"
57 "%s"
58 "\n"
59 "}\n"
60 };
61
62 const char *sample_large_int_parmam_kernel_pattern[] = {
63 "__kernel void sample_test(%s, __global int *result)\n"
64 "{\n"
65 "result[0] = 0;\n"
66 "%s"
67 "\n"
68 "}\n"
69 };
70
71 const char *sample_sampler_kernel_pattern[] = {
72 "__kernel void sample_test( read_only image2d_t src, __global int4 *dst",
73 ", sampler_t sampler%d",
74 ")\n"
75 "{\n"
76 " size_t tid = get_global_id(0);\n",
77 " dst[ 0 ] = read_imagei( src, sampler%d, (int2)( 0, 0 ) );\n",
78 "\n"
79 "}\n"
80 };
81
82 const char *sample_const_arg_kernel[] = {
83 "__kernel void sample_test(__constant int *src1, __global int *dst)\n"
84 "{\n"
85 " size_t tid = get_global_id(0);\n"
86 "\n"
87 " dst[tid] = src1[tid];\n"
88 "\n"
89 "}\n"
90 };
91
92 const char *sample_local_arg_kernel[] = {
93 "__kernel void sample_test(__local int *src1, __global int *global_src, "
94 "__global int *dst)\n"
95 "{\n"
96 " size_t tid = get_global_id(0);\n"
97 "\n"
98 " src1[tid] = global_src[tid];\n"
99 " barrier(CLK_GLOBAL_MEM_FENCE);\n"
100 " dst[tid] = src1[tid];\n"
101 "\n"
102 "}\n"
103 };
104
105 const char *sample_const_max_arg_kernel_pattern =
106 "__kernel void sample_test(__constant int *src1 %s, __global int *dst)\n"
107 "{\n"
108 " int tid = get_global_id(0);\n"
109 "\n"
110 " dst[tid] = src1[tid];\n"
111 "%s"
112 "\n"
113 "}\n";
114
test_min_max_thread_dimensions(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)115 int test_min_max_thread_dimensions(cl_device_id deviceID, cl_context context,
116 cl_command_queue queue, int num_elements)
117 {
118 int error, retVal;
119 unsigned int maxThreadDim, threadDim, i;
120 clProgramWrapper program;
121 clKernelWrapper kernel;
122 clMemWrapper streams[1];
123 size_t *threads, *localThreads;
124 cl_event event;
125 cl_int event_status;
126
127
128 /* Get the max thread dimensions */
129 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
130 sizeof(maxThreadDim), &maxThreadDim, NULL);
131 test_error(error, "Unable to get max work item dimensions from device");
132
133 if (maxThreadDim < 3)
134 {
135 log_error("ERROR: Reported max work item dimensions is less than "
136 "required! (%d)\n",
137 maxThreadDim);
138 return -1;
139 }
140
141 log_info("Reported max thread dimensions of %d.\n", maxThreadDim);
142
143 /* Create a kernel to test with */
144 if (create_single_kernel_helper(context, &program, &kernel, 1,
145 sample_single_param_kernel, "sample_test")
146 != 0)
147 {
148 return -1;
149 }
150
151 /* Create some I/O streams */
152 streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
153 sizeof(cl_int) * 100, NULL, &error);
154 if (streams[0] == NULL)
155 {
156 log_error("ERROR: Creating test array failed!\n");
157 return -1;
158 }
159
160 /* Set the arguments */
161 error = clSetKernelArg(kernel, 0, sizeof(streams[0]), &streams[0]);
162 test_error(error, "Unable to set kernel arguments");
163
164 retVal = 0;
165
166 /* Now try running the kernel with up to that many threads */
167 for (threadDim = 1; threadDim <= maxThreadDim; threadDim++)
168 {
169 threads = (size_t *)malloc(sizeof(size_t) * maxThreadDim);
170 localThreads = (size_t *)malloc(sizeof(size_t) * maxThreadDim);
171 for (i = 0; i < maxThreadDim; i++)
172 {
173 threads[i] = 1;
174 localThreads[i] = 1;
175 }
176
177 error = clEnqueueNDRangeKernel(queue, kernel, maxThreadDim, NULL,
178 threads, localThreads, 0, NULL, &event);
179 test_error(error, "Failed clEnqueueNDRangeKernel");
180
181 // Verify that the event does not return an error from the execution
182 error = clWaitForEvents(1, &event);
183 test_error(error, "clWaitForEvent failed");
184 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
185 sizeof(event_status), &event_status, NULL);
186 test_error(
187 error,
188 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
189 clReleaseEvent(event);
190 if (event_status < 0)
191 test_error(error, "Kernel execution event returned error");
192
193 /* All done */
194 free(threads);
195 free(localThreads);
196 }
197
198 return retVal;
199 }
200
201
test_min_max_work_items_sizes(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)202 int test_min_max_work_items_sizes(cl_device_id deviceID, cl_context context,
203 cl_command_queue queue, int num_elements)
204 {
205 int error;
206 size_t *deviceMaxWorkItemSize;
207 unsigned int maxWorkItemDim;
208
209 /* Get the max work item dimensions */
210 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
211 sizeof(maxWorkItemDim), &maxWorkItemDim, NULL);
212 test_error(error, "Unable to get max work item dimensions from device");
213
214 log_info("CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS returned %d\n",
215 maxWorkItemDim);
216 deviceMaxWorkItemSize = (size_t *)malloc(sizeof(size_t) * maxWorkItemDim);
217 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_ITEM_SIZES,
218 sizeof(size_t) * maxWorkItemDim,
219 deviceMaxWorkItemSize, NULL);
220 test_error(error, "clDeviceInfo for CL_DEVICE_MAX_WORK_ITEM_SIZES failed");
221
222 unsigned int i;
223 int errors = 0;
224 for (i = 0; i < maxWorkItemDim; i++)
225 {
226 if (deviceMaxWorkItemSize[i] < 1)
227 {
228 log_error("MAX_WORK_ITEM_SIZE in dimension %d is invalid: %lu\n", i,
229 deviceMaxWorkItemSize[i]);
230 errors++;
231 }
232 else
233 {
234 log_info("Dimension %d has max work item size %lu\n", i,
235 deviceMaxWorkItemSize[i]);
236 }
237 }
238
239 free(deviceMaxWorkItemSize);
240
241 if (errors) return -1;
242 return 0;
243 }
244
245
test_min_max_work_group_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)246 int test_min_max_work_group_size(cl_device_id deviceID, cl_context context,
247 cl_command_queue queue, int num_elements)
248 {
249 int error;
250 size_t deviceMaxThreadSize;
251
252 /* Get the max thread dimensions */
253 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE,
254 sizeof(deviceMaxThreadSize), &deviceMaxThreadSize,
255 NULL);
256 test_error(error, "Unable to get max work group size from device");
257
258 log_info("Reported %ld max device work group size.\n", deviceMaxThreadSize);
259
260 if (deviceMaxThreadSize == 0)
261 {
262 log_error("ERROR: Max work group size is reported as zero!\n");
263 return -1;
264 }
265 return 0;
266 }
267
test_min_max_read_image_args(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)268 int test_min_max_read_image_args(cl_device_id deviceID, cl_context context,
269 cl_command_queue queue, int num_elements)
270 {
271 int error;
272 unsigned int maxReadImages, i;
273 unsigned int deviceAddressSize;
274 clProgramWrapper program;
275 char readArgLine[128], *programSrc;
276 const char *readArgPattern = ", read_only image2d_t srcimg%d";
277 clKernelWrapper kernel;
278 clMemWrapper *streams, result;
279 size_t threads[2];
280 cl_image_format image_format_desc;
281 size_t maxParameterSize;
282 cl_event event;
283 cl_int event_status;
284 cl_float image_data[4 * 4];
285 float image_result = 0.0f;
286 float actual_image_result;
287 cl_uint minRequiredReadImages = gIsEmbedded ? 8 : 128;
288 cl_device_type deviceType;
289
290 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
291 image_format_desc.image_channel_order = CL_RGBA;
292 image_format_desc.image_channel_data_type = CL_FLOAT;
293
294 /* Get the max read image arg count */
295 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_READ_IMAGE_ARGS,
296 sizeof(maxReadImages), &maxReadImages, NULL);
297 test_error(error, "Unable to get max read image arg count from device");
298
299 if (maxReadImages < minRequiredReadImages)
300 {
301 log_error("ERROR: Reported max read image arg count is less than "
302 "required! (%d)\n",
303 maxReadImages);
304 return -1;
305 }
306
307 log_info("Reported %d max read image args.\n", maxReadImages);
308
309 error =
310 clGetDeviceInfo(deviceID, CL_DEVICE_ADDRESS_BITS,
311 sizeof(deviceAddressSize), &deviceAddressSize, NULL);
312 test_error(error, "Unable to query CL_DEVICE_ADDRESS_BITS for device");
313 deviceAddressSize /= 8; // convert from bits to bytes
314
315
316 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PARAMETER_SIZE,
317 sizeof(maxParameterSize), &maxParameterSize, NULL);
318 test_error(error, "Unable to get max parameter size from device");
319
320 if (!gIsEmbedded && maxReadImages >= 128 && maxParameterSize == 1024)
321 {
322 error = clGetDeviceInfo(deviceID, CL_DEVICE_TYPE, sizeof(deviceType),
323 &deviceType, NULL);
324 test_error(error, "Unable to get device type from device");
325
326 if (deviceType != CL_DEVICE_TYPE_CUSTOM)
327 {
328 maxReadImages = 127;
329 }
330 }
331 // Subtract the size of the result
332 maxParameterSize -= deviceAddressSize;
333
334 // Calculate the number we can use
335 if (maxParameterSize / deviceAddressSize < maxReadImages)
336 {
337 log_info("WARNING: Max parameter size of %d bytes limits test to %d "
338 "max image arguments.\n",
339 (int)maxParameterSize,
340 (int)(maxParameterSize / deviceAddressSize));
341 maxReadImages = (unsigned int)(maxParameterSize / deviceAddressSize);
342 }
343
344 /* Create a program with that many read args */
345 programSrc = (char *)malloc(strlen(sample_read_image_kernel_pattern[0])
346 + (strlen(readArgPattern) + 6) * (maxReadImages)
347 + strlen(sample_read_image_kernel_pattern[1])
348 + 1 + 40240);
349
350 strcpy(programSrc, sample_read_image_kernel_pattern[0]);
351 strcat(programSrc, "read_only image2d_t srcimg0");
352 for (i = 0; i < maxReadImages - 1; i++)
353 {
354 sprintf(readArgLine, readArgPattern, i + 1);
355 strcat(programSrc, readArgLine);
356 }
357 strcat(programSrc, sample_read_image_kernel_pattern[1]);
358 for (i = 0; i < maxReadImages; i++)
359 {
360 sprintf(
361 readArgLine,
362 "\tresult[0] += read_imagef( srcimg%d, sampler, (int2)(0,0)).x;\n",
363 i);
364 strcat(programSrc, readArgLine);
365 }
366 strcat(programSrc, sample_read_image_kernel_pattern[2]);
367
368 error =
369 create_single_kernel_helper(context, &program, &kernel, 1,
370 (const char **)&programSrc, "sample_test");
371 test_error(error, "Failed to create the program and kernel.");
372 free(programSrc);
373
374 result = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float), NULL,
375 &error);
376 test_error(error, "clCreateBufer failed");
377
378 /* Create some I/O streams */
379 streams = new clMemWrapper[maxReadImages + 1];
380 for (i = 0; i < maxReadImages; i++)
381 {
382 image_data[0] = i;
383 image_result += image_data[0];
384 streams[i] =
385 create_image_2d(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
386 &image_format_desc, 4, 4, 0, image_data, &error);
387 test_error(error, "Unable to allocate test image");
388 }
389
390 error = clSetKernelArg(kernel, 0, sizeof(result), &result);
391 test_error(error, "Unable to set kernel arguments");
392
393 /* Set the arguments */
394 for (i = 1; i < maxReadImages + 1; i++)
395 {
396 error =
397 clSetKernelArg(kernel, i, sizeof(streams[i - 1]), &streams[i - 1]);
398 test_error(error, "Unable to set kernel arguments");
399 }
400
401 /* Now try running the kernel */
402 threads[0] = threads[1] = 1;
403 error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, threads, NULL, 0,
404 NULL, &event);
405 test_error(error, "clEnqueueNDRangeKernel failed");
406
407 // Verify that the event does not return an error from the execution
408 error = clWaitForEvents(1, &event);
409 test_error(error, "clWaitForEvent failed");
410 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
411 sizeof(event_status), &event_status, NULL);
412 test_error(error,
413 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
414 clReleaseEvent(event);
415 if (event_status < 0)
416 test_error(error, "Kernel execution event returned error");
417
418 error = clEnqueueReadBuffer(queue, result, CL_TRUE, 0, sizeof(cl_float),
419 &actual_image_result, 0, NULL, NULL);
420 test_error(error, "clEnqueueReadBuffer failed");
421
422 delete[] streams;
423
424 if (actual_image_result != image_result)
425 {
426 log_error("Result failed to verify. Got %g, expected %g.\n",
427 actual_image_result, image_result);
428 return 1;
429 }
430
431 return 0;
432 }
433
test_min_max_write_image_args(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)434 int test_min_max_write_image_args(cl_device_id deviceID, cl_context context,
435 cl_command_queue queue, int num_elements)
436 {
437 int error;
438 unsigned int maxWriteImages, i;
439 clProgramWrapper program;
440 char writeArgLine[128], *programSrc;
441 const char *writeArgPattern = ", write_only image2d_t dstimg%d";
442 clKernelWrapper kernel;
443 clMemWrapper *streams;
444 size_t threads[2];
445 cl_image_format image_format_desc;
446 size_t maxParameterSize;
447 cl_event event;
448 cl_int event_status;
449 cl_uint minRequiredWriteImages = gIsEmbedded ? 1 : 8;
450
451
452 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
453 image_format_desc.image_channel_order = CL_RGBA;
454 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
455
456 /* Get the max read image arg count */
457 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WRITE_IMAGE_ARGS,
458 sizeof(maxWriteImages), &maxWriteImages, NULL);
459 test_error(error, "Unable to get max write image arg count from device");
460
461 if (maxWriteImages == 0)
462 {
463 log_info(
464 "WARNING: Device reports 0 for a max write image arg count (write "
465 "image arguments unsupported). Skipping test (implicitly passes). "
466 "This is only valid if the number of image formats is also 0.\n");
467 return 0;
468 }
469
470 if (maxWriteImages < minRequiredWriteImages)
471 {
472 log_error("ERROR: Reported max write image arg count is less than "
473 "required! (%d)\n",
474 maxWriteImages);
475 return -1;
476 }
477
478 log_info("Reported %d max write image args.\n", maxWriteImages);
479
480 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PARAMETER_SIZE,
481 sizeof(maxParameterSize), &maxParameterSize, NULL);
482 test_error(error, "Unable to get max parameter size from device");
483
484 // Calculate the number we can use
485 if (maxParameterSize / sizeof(cl_mem) < maxWriteImages)
486 {
487 log_info("WARNING: Max parameter size of %d bytes limits test to %d "
488 "max image arguments.\n",
489 (int)maxParameterSize,
490 (int)(maxParameterSize / sizeof(cl_mem)));
491 maxWriteImages = (unsigned int)(maxParameterSize / sizeof(cl_mem));
492 }
493
494 /* Create a program with that many write args + 1 */
495 programSrc = (char *)malloc(
496 strlen(sample_write_image_kernel_pattern[0])
497 + (strlen(writeArgPattern) + 6) * (maxWriteImages + 1)
498 + strlen(sample_write_image_kernel_pattern[1]) + 1 + 40240);
499
500 strcpy(programSrc, sample_write_image_kernel_pattern[0]);
501 strcat(programSrc, "write_only image2d_t dstimg0");
502 for (i = 1; i < maxWriteImages; i++)
503 {
504 sprintf(writeArgLine, writeArgPattern, i);
505 strcat(programSrc, writeArgLine);
506 }
507 strcat(programSrc, sample_write_image_kernel_pattern[1]);
508 for (i = 0; i < maxWriteImages; i++)
509 {
510 sprintf(writeArgLine,
511 "\twrite_imagef( dstimg%d, (int2)(0,0), (float4)(0,0,0,0));\n",
512 i);
513 strcat(programSrc, writeArgLine);
514 }
515 strcat(programSrc, sample_write_image_kernel_pattern[2]);
516
517 error =
518 create_single_kernel_helper(context, &program, &kernel, 1,
519 (const char **)&programSrc, "sample_test");
520 test_error(error, "Failed to create the program and kernel.");
521 free(programSrc);
522
523
524 /* Create some I/O streams */
525 streams = new clMemWrapper[maxWriteImages + 1];
526 for (i = 0; i < maxWriteImages; i++)
527 {
528 streams[i] =
529 create_image_2d(context, CL_MEM_READ_WRITE, &image_format_desc, 16,
530 16, 0, NULL, &error);
531 test_error(error, "Unable to allocate test image");
532 }
533
534 /* Set the arguments */
535 for (i = 0; i < maxWriteImages; i++)
536 {
537 error = clSetKernelArg(kernel, i, sizeof(streams[i]), &streams[i]);
538 test_error(error, "Unable to set kernel arguments");
539 }
540
541 /* Now try running the kernel */
542 threads[0] = threads[1] = 16;
543 error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, threads, NULL, 0,
544 NULL, &event);
545 test_error(error, "clEnqueueNDRangeKernel failed.");
546
547 // Verify that the event does not return an error from the execution
548 error = clWaitForEvents(1, &event);
549 test_error(error, "clWaitForEvent failed");
550 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
551 sizeof(event_status), &event_status, NULL);
552 test_error(error,
553 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
554 clReleaseEvent(event);
555 if (event_status < 0)
556 test_error(error, "Kernel execution event returned error");
557
558 /* All done */
559 delete[] streams;
560 return 0;
561 }
562
test_min_max_mem_alloc_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)563 int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context,
564 cl_command_queue queue, int num_elements)
565 {
566 int error;
567 cl_ulong maxAllocSize, memSize, minSizeToTry;
568 clMemWrapper memHdl;
569
570 cl_ulong requiredAllocSize;
571
572 if (gIsEmbedded)
573 requiredAllocSize = 1 * 1024 * 1024;
574 else
575 requiredAllocSize = 128 * 1024 * 1024;
576
577 /* Get the max mem alloc size */
578 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
579 sizeof(maxAllocSize), &maxAllocSize, NULL);
580 test_error(error, "Unable to get max mem alloc size from device");
581
582 error = clGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE,
583 sizeof(memSize), &memSize, NULL);
584 test_error(error, "Unable to get global memory size from device");
585
586 if (memSize > (cl_ulong)SIZE_MAX)
587 {
588 memSize = (cl_ulong)SIZE_MAX;
589 }
590
591 if (maxAllocSize < requiredAllocSize)
592 {
593 log_error("ERROR: Reported max allocation size is less than required "
594 "%lldMB! (%llu or %lluMB, from a total mem size of %lldMB)\n",
595 (requiredAllocSize / 1024) / 1024, maxAllocSize,
596 (maxAllocSize / 1024) / 1024, (memSize / 1024) / 1024);
597 return -1;
598 }
599
600 requiredAllocSize = ((memSize / 4) > (1024 * 1024 * 1024))
601 ? 1024 * 1024 * 1024
602 : memSize / 4;
603
604 if (gIsEmbedded)
605 requiredAllocSize = (requiredAllocSize < 1 * 1024 * 1024)
606 ? 1 * 1024 * 1024
607 : requiredAllocSize;
608 else
609 requiredAllocSize = (requiredAllocSize < 128 * 1024 * 1024)
610 ? 128 * 1024 * 1024
611 : requiredAllocSize;
612
613 if (maxAllocSize < requiredAllocSize)
614 {
615 log_error(
616 "ERROR: Reported max allocation size is less than required of "
617 "total memory! (%llu or %lluMB, from a total mem size of %lluMB)\n",
618 maxAllocSize, (maxAllocSize / 1024) / 1024,
619 (requiredAllocSize / 1024) / 1024);
620 return -1;
621 }
622
623 log_info("Reported max allocation size of %lld bytes (%gMB) and global mem "
624 "size of %lld bytes (%gMB).\n",
625 maxAllocSize, maxAllocSize / (1024.0 * 1024.0), requiredAllocSize,
626 requiredAllocSize / (1024.0 * 1024.0));
627
628 if (memSize < maxAllocSize)
629 {
630 log_info("Global memory size is less than max allocation size, using "
631 "that.\n");
632 maxAllocSize = memSize;
633 }
634
635 minSizeToTry = maxAllocSize / 16;
636 while (maxAllocSize > (maxAllocSize / 4))
637 {
638
639 log_info("Trying to create a buffer of size of %lld bytes (%gMB).\n",
640 maxAllocSize, (double)maxAllocSize / (1024.0 * 1024.0));
641 memHdl = clCreateBuffer(context, CL_MEM_READ_ONLY, (size_t)maxAllocSize,
642 NULL, &error);
643 if (error == CL_MEM_OBJECT_ALLOCATION_FAILURE
644 || error == CL_OUT_OF_RESOURCES || error == CL_OUT_OF_HOST_MEMORY)
645 {
646 log_info("\tAllocation failed at size of %lld bytes (%gMB).\n",
647 maxAllocSize, (double)maxAllocSize / (1024.0 * 1024.0));
648 maxAllocSize -= minSizeToTry;
649 continue;
650 }
651 test_error(error, "clCreateBuffer failed for maximum sized buffer.");
652 return 0;
653 }
654 log_error("Failed to allocate even %lld bytes (%gMB).\n", maxAllocSize,
655 (double)maxAllocSize / (1024.0 * 1024.0));
656 return -1;
657 }
658
test_min_max_image_2d_width(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)659 int test_min_max_image_2d_width(cl_device_id deviceID, cl_context context,
660 cl_command_queue queue, int num_elements)
661 {
662 int error;
663 size_t maxDimension;
664 clMemWrapper streams[1];
665 cl_image_format image_format_desc;
666 cl_ulong maxAllocSize;
667 cl_uint minRequiredDimension;
668
669 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
670
671 auto version = get_device_cl_version(deviceID);
672 if (version == Version(1, 0))
673 {
674 minRequiredDimension = gIsEmbedded ? 2048 : 4096;
675 }
676 else
677 {
678 minRequiredDimension = gIsEmbedded ? 2048 : 8192;
679 }
680
681
682 /* Just get any ol format to test with */
683 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE2D,
684 CL_MEM_READ_WRITE, 0, &image_format_desc);
685 test_error(error, "Unable to obtain suitable image format to test with!");
686
687 /* Get the max 2d image width */
688 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE2D_MAX_WIDTH,
689 sizeof(maxDimension), &maxDimension, NULL);
690 test_error(error, "Unable to get max image 2d width from device");
691
692 if (maxDimension < minRequiredDimension)
693 {
694 log_error(
695 "ERROR: Reported max image 2d width is less than required! (%d)\n",
696 (int)maxDimension);
697 return -1;
698 }
699 log_info("Max reported width is %ld.\n", maxDimension);
700
701 /* Verify we can use the format */
702 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
703 image_format_desc.image_channel_order = CL_RGBA;
704 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
705 CL_MEM_OBJECT_IMAGE2D, &image_format_desc))
706 {
707 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
708 return -1;
709 }
710
711 /* Verify that we can actually allocate an image that large */
712 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
713 sizeof(maxAllocSize), &maxAllocSize, NULL);
714 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
715 if ((cl_ulong)maxDimension * 1 * 4 > maxAllocSize)
716 {
717 log_error("Can not allocate a large enough image (min size: %lld "
718 "bytes, max allowed: %lld bytes) to test.\n",
719 (cl_ulong)maxDimension * 1 * 4, maxAllocSize);
720 return -1;
721 }
722
723 log_info("Attempting to create an image of size %d x 1 = %gMB.\n",
724 (int)maxDimension, ((float)maxDimension * 4 / 1024.0 / 1024.0));
725
726 /* Try to allocate a very big image */
727 streams[0] = create_image_2d(context, CL_MEM_READ_ONLY, &image_format_desc,
728 maxDimension, 1, 0, NULL, &error);
729 if ((streams[0] == NULL) || (error != CL_SUCCESS))
730 {
731 print_error(error, "Image 2D creation failed for maximum width");
732 return -1;
733 }
734
735 return 0;
736 }
737
test_min_max_image_2d_height(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)738 int test_min_max_image_2d_height(cl_device_id deviceID, cl_context context,
739 cl_command_queue queue, int num_elements)
740 {
741 int error;
742 size_t maxDimension;
743 clMemWrapper streams[1];
744 cl_image_format image_format_desc;
745 cl_ulong maxAllocSize;
746 cl_uint minRequiredDimension;
747
748 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
749
750 auto version = get_device_cl_version(deviceID);
751 if (version == Version(1, 0))
752 {
753 minRequiredDimension = gIsEmbedded ? 2048 : 4096;
754 }
755 else
756 {
757 minRequiredDimension = gIsEmbedded ? 2048 : 8192;
758 }
759
760 /* Just get any ol format to test with */
761 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE2D,
762 CL_MEM_READ_WRITE, 0, &image_format_desc);
763 test_error(error, "Unable to obtain suitable image format to test with!");
764
765 /* Get the max 2d image width */
766 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
767 sizeof(maxDimension), &maxDimension, NULL);
768 test_error(error, "Unable to get max image 2d height from device");
769
770 if (maxDimension < minRequiredDimension)
771 {
772 log_error(
773 "ERROR: Reported max image 2d height is less than required! (%d)\n",
774 (int)maxDimension);
775 return -1;
776 }
777 log_info("Max reported height is %ld.\n", maxDimension);
778
779 /* Verify we can use the format */
780 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
781 image_format_desc.image_channel_order = CL_RGBA;
782 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
783 CL_MEM_OBJECT_IMAGE2D, &image_format_desc))
784 {
785 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
786 return -1;
787 }
788
789 /* Verify that we can actually allocate an image that large */
790 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
791 sizeof(maxAllocSize), &maxAllocSize, NULL);
792 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
793 if ((cl_ulong)maxDimension * 1 * 4 > maxAllocSize)
794 {
795 log_error("Can not allocate a large enough image (min size: %lld "
796 "bytes, max allowed: %lld bytes) to test.\n",
797 (cl_ulong)maxDimension * 1 * 4, maxAllocSize);
798 return -1;
799 }
800
801 log_info("Attempting to create an image of size 1 x %d = %gMB.\n",
802 (int)maxDimension, ((float)maxDimension * 4 / 1024.0 / 1024.0));
803
804 /* Try to allocate a very big image */
805 streams[0] = create_image_2d(context, CL_MEM_READ_ONLY, &image_format_desc,
806 1, maxDimension, 0, NULL, &error);
807 if ((streams[0] == NULL) || (error != CL_SUCCESS))
808 {
809 print_error(error, "Image 2D creation failed for maximum height");
810 return -1;
811 }
812
813 return 0;
814 }
815
test_min_max_image_3d_width(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)816 int test_min_max_image_3d_width(cl_device_id deviceID, cl_context context,
817 cl_command_queue queue, int num_elements)
818 {
819 int error;
820 size_t maxDimension;
821 clMemWrapper streams[1];
822 cl_image_format image_format_desc;
823 cl_ulong maxAllocSize;
824
825
826 PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(deviceID)
827
828 /* Just get any ol format to test with */
829 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE3D,
830 CL_MEM_READ_ONLY, 0, &image_format_desc);
831 test_error(error, "Unable to obtain suitable image format to test with!");
832
833 /* Get the max 2d image width */
834 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE3D_MAX_WIDTH,
835 sizeof(maxDimension), &maxDimension, NULL);
836 test_error(error, "Unable to get max image 3d width from device");
837
838 if (maxDimension < 2048)
839 {
840 log_error(
841 "ERROR: Reported max image 3d width is less than required! (%d)\n",
842 (int)maxDimension);
843 return -1;
844 }
845 log_info("Max reported width is %ld.\n", maxDimension);
846
847 /* Verify we can use the format */
848 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
849 image_format_desc.image_channel_order = CL_RGBA;
850 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
851 CL_MEM_OBJECT_IMAGE3D, &image_format_desc))
852 {
853 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
854 return -1;
855 }
856
857 /* Verify that we can actually allocate an image that large */
858 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
859 sizeof(maxAllocSize), &maxAllocSize, NULL);
860 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
861 if ((cl_ulong)maxDimension * 2 * 4 > maxAllocSize)
862 {
863 log_error("Can not allocate a large enough image (min size: %lld "
864 "bytes, max allowed: %lld bytes) to test.\n",
865 (cl_ulong)maxDimension * 2 * 4, maxAllocSize);
866 return -1;
867 }
868
869 log_info("Attempting to create an image of size %d x 1 x 2 = %gMB.\n",
870 (int)maxDimension,
871 (2 * (float)maxDimension * 4 / 1024.0 / 1024.0));
872
873 /* Try to allocate a very big image */
874 streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &image_format_desc,
875 maxDimension, 1, 2, 0, 0, NULL, &error);
876 if ((streams[0] == NULL) || (error != CL_SUCCESS))
877 {
878 print_error(error, "Image 3D creation failed for maximum width");
879 return -1;
880 }
881
882 return 0;
883 }
884
test_min_max_image_3d_height(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)885 int test_min_max_image_3d_height(cl_device_id deviceID, cl_context context,
886 cl_command_queue queue, int num_elements)
887 {
888 int error;
889 size_t maxDimension;
890 clMemWrapper streams[1];
891 cl_image_format image_format_desc;
892 cl_ulong maxAllocSize;
893
894
895 PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(deviceID)
896
897 /* Just get any ol format to test with */
898 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE3D,
899 CL_MEM_READ_ONLY, 0, &image_format_desc);
900 test_error(error, "Unable to obtain suitable image format to test with!");
901
902 /* Get the max 2d image width */
903 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE3D_MAX_HEIGHT,
904 sizeof(maxDimension), &maxDimension, NULL);
905 test_error(error, "Unable to get max image 3d height from device");
906
907 if (maxDimension < 2048)
908 {
909 log_error(
910 "ERROR: Reported max image 3d height is less than required! (%d)\n",
911 (int)maxDimension);
912 return -1;
913 }
914 log_info("Max reported height is %ld.\n", maxDimension);
915
916 /* Verify we can use the format */
917 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
918 image_format_desc.image_channel_order = CL_RGBA;
919 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
920 CL_MEM_OBJECT_IMAGE3D, &image_format_desc))
921 {
922 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
923 return -1;
924 }
925
926 /* Verify that we can actually allocate an image that large */
927 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
928 sizeof(maxAllocSize), &maxAllocSize, NULL);
929 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
930 if ((cl_ulong)maxDimension * 2 * 4 > maxAllocSize)
931 {
932 log_error("Can not allocate a large enough image (min size: %lld "
933 "bytes, max allowed: %lld bytes) to test.\n",
934 (cl_ulong)maxDimension * 2 * 4, maxAllocSize);
935 return -1;
936 }
937
938 log_info("Attempting to create an image of size 1 x %d x 2 = %gMB.\n",
939 (int)maxDimension,
940 (2 * (float)maxDimension * 4 / 1024.0 / 1024.0));
941
942 /* Try to allocate a very big image */
943 streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &image_format_desc,
944 1, maxDimension, 2, 0, 0, NULL, &error);
945 if ((streams[0] == NULL) || (error != CL_SUCCESS))
946 {
947 print_error(error, "Image 3D creation failed for maximum height");
948 return -1;
949 }
950
951 return 0;
952 }
953
954
test_min_max_image_3d_depth(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)955 int test_min_max_image_3d_depth(cl_device_id deviceID, cl_context context,
956 cl_command_queue queue, int num_elements)
957 {
958 int error;
959 size_t maxDimension;
960 clMemWrapper streams[1];
961 cl_image_format image_format_desc;
962 cl_ulong maxAllocSize;
963
964
965 PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(deviceID)
966
967 /* Just get any ol format to test with */
968 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE3D,
969 CL_MEM_READ_ONLY, 0, &image_format_desc);
970 test_error(error, "Unable to obtain suitable image format to test with!");
971
972 /* Get the max 2d image width */
973 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE3D_MAX_DEPTH,
974 sizeof(maxDimension), &maxDimension, NULL);
975 test_error(error, "Unable to get max image 3d depth from device");
976
977 if (maxDimension < 2048)
978 {
979 log_error(
980 "ERROR: Reported max image 3d depth is less than required! (%d)\n",
981 (int)maxDimension);
982 return -1;
983 }
984 log_info("Max reported depth is %ld.\n", maxDimension);
985
986 /* Verify we can use the format */
987 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
988 image_format_desc.image_channel_order = CL_RGBA;
989 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
990 CL_MEM_OBJECT_IMAGE3D, &image_format_desc))
991 {
992 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
993 return -1;
994 }
995
996 /* Verify that we can actually allocate an image that large */
997 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
998 sizeof(maxAllocSize), &maxAllocSize, NULL);
999 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
1000 if ((cl_ulong)maxDimension * 1 * 4 > maxAllocSize)
1001 {
1002 log_error("Can not allocate a large enough image (min size: %lld "
1003 "bytes, max allowed: %lld bytes) to test.\n",
1004 (cl_ulong)maxDimension * 1 * 4, maxAllocSize);
1005 return -1;
1006 }
1007
1008 log_info("Attempting to create an image of size 1 x 1 x %d = %gMB.\n",
1009 (int)maxDimension, ((float)maxDimension * 4 / 1024.0 / 1024.0));
1010
1011 /* Try to allocate a very big image */
1012 streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &image_format_desc,
1013 1, 1, maxDimension, 0, 0, NULL, &error);
1014 if ((streams[0] == NULL) || (error != CL_SUCCESS))
1015 {
1016 print_error(error, "Image 3D creation failed for maximum depth");
1017 return -1;
1018 }
1019
1020 return 0;
1021 }
1022
test_min_max_image_array_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1023 int test_min_max_image_array_size(cl_device_id deviceID, cl_context context,
1024 cl_command_queue queue, int num_elements)
1025 {
1026 int error;
1027 size_t maxDimension;
1028 clMemWrapper streams[1];
1029 cl_image_format image_format_desc;
1030 cl_ulong maxAllocSize;
1031 size_t minRequiredDimension = gIsEmbedded ? 256 : 2048;
1032
1033 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID);
1034
1035 /* Just get any ol format to test with */
1036 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE2D_ARRAY,
1037 CL_MEM_READ_WRITE, 0, &image_format_desc);
1038 test_error(error, "Unable to obtain suitable image format to test with!");
1039
1040 /* Get the max image array width */
1041 error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE,
1042 sizeof(maxDimension), &maxDimension, NULL);
1043 test_error(error, "Unable to get max image array size from device");
1044
1045 if (maxDimension < minRequiredDimension)
1046 {
1047 log_error("ERROR: Reported max image array size is less than required! "
1048 "(%d)\n",
1049 (int)maxDimension);
1050 return -1;
1051 }
1052 log_info("Max reported image array size is %ld.\n", maxDimension);
1053
1054 /* Verify we can use the format */
1055 image_format_desc.image_channel_data_type = CL_UNORM_INT8;
1056 image_format_desc.image_channel_order = CL_RGBA;
1057 if (!is_image_format_supported(context, CL_MEM_READ_ONLY,
1058 CL_MEM_OBJECT_IMAGE2D_ARRAY,
1059 &image_format_desc))
1060 {
1061 log_error("CL_UNORM_INT8 CL_RGBA not supported. Can not test.");
1062 return -1;
1063 }
1064
1065 /* Verify that we can actually allocate an image that large */
1066 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
1067 sizeof(maxAllocSize), &maxAllocSize, NULL);
1068 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
1069 if ((cl_ulong)maxDimension * 1 * 4 > maxAllocSize)
1070 {
1071 log_error("Can not allocate a large enough image (min size: %lld "
1072 "bytes, max allowed: %lld bytes) to test.\n",
1073 (cl_ulong)maxDimension * 1 * 4, maxAllocSize);
1074 return -1;
1075 }
1076
1077 log_info("Attempting to create an image of size 1 x 1 x %d = %gMB.\n",
1078 (int)maxDimension, ((float)maxDimension * 4 / 1024.0 / 1024.0));
1079
1080 /* Try to allocate a very big image */
1081 streams[0] =
1082 create_image_2d_array(context, CL_MEM_READ_ONLY, &image_format_desc, 1,
1083 1, maxDimension, 0, 0, NULL, &error);
1084 if ((streams[0] == NULL) || (error != CL_SUCCESS))
1085 {
1086 print_error(error,
1087 "2D Image Array creation failed for maximum array size");
1088 return -1;
1089 }
1090
1091 return 0;
1092 }
1093
test_min_max_image_buffer_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1094 int test_min_max_image_buffer_size(cl_device_id deviceID, cl_context context,
1095 cl_command_queue queue, int num_elements)
1096 {
1097 int error;
1098 size_t maxDimensionPixels;
1099 clMemWrapper streams[2];
1100 cl_image_format image_format_desc = { 0 };
1101 cl_ulong maxAllocSize;
1102 size_t minRequiredDimension = gIsEmbedded ? 2048 : 65536;
1103 unsigned int i = 0;
1104 size_t pixelBytes = 0;
1105
1106 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID);
1107
1108 /* Get the max memory allocation size */
1109 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
1110 sizeof(maxAllocSize), &maxAllocSize, NULL);
1111 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE.");
1112
1113 /* Get the max image array width */
1114 error =
1115 clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE,
1116 sizeof(maxDimensionPixels), &maxDimensionPixels, NULL);
1117 test_error(error, "Unable to get max image buffer size from device");
1118
1119 if (maxDimensionPixels < minRequiredDimension)
1120 {
1121 log_error("ERROR: Reported max image buffer size is less than "
1122 "required! (%d)\n",
1123 (int)maxDimensionPixels);
1124 return -1;
1125 }
1126 log_info("Max reported image buffer size is %ld pixels.\n",
1127 maxDimensionPixels);
1128
1129 pixelBytes = maxAllocSize / maxDimensionPixels;
1130 if (pixelBytes == 0)
1131 {
1132 log_error("Value of CL_DEVICE_IMAGE_MAX_BUFFER_SIZE is greater than "
1133 "CL_MAX_MEM_ALLOC_SIZE so there is no way to allocate image "
1134 "of maximum size!\n");
1135 return -1;
1136 }
1137
1138 error = -1;
1139 for (i = pixelBytes; i > 0; --i)
1140 {
1141 error = get_8_bit_image_format(context, CL_MEM_OBJECT_IMAGE1D,
1142 CL_MEM_READ_ONLY, i, &image_format_desc);
1143 if (error == CL_SUCCESS)
1144 {
1145 pixelBytes = i;
1146 break;
1147 }
1148 }
1149 test_error(error,
1150 "Device does not support format to be used to allocate image of "
1151 "CL_DEVICE_IMAGE_MAX_BUFFER_SIZE\n");
1152
1153 log_info("Attempting to create an 1D image with channel order %s from "
1154 "buffer of size %d = %gMB.\n",
1155 GetChannelOrderName(image_format_desc.image_channel_order),
1156 (int)maxDimensionPixels,
1157 ((float)maxDimensionPixels * pixelBytes / 1024.0 / 1024.0));
1158
1159 /* Try to allocate a buffer */
1160 streams[0] = clCreateBuffer(context, CL_MEM_READ_ONLY,
1161 maxDimensionPixels * pixelBytes, NULL, &error);
1162 if ((streams[0] == NULL) || (error != CL_SUCCESS))
1163 {
1164 print_error(error,
1165 "Buffer creation failed for maximum image buffer size");
1166 return -1;
1167 }
1168
1169 /* Try to allocate a 1D image array from buffer */
1170 streams[1] =
1171 create_image_1d(context, CL_MEM_READ_ONLY, &image_format_desc,
1172 maxDimensionPixels, 0, NULL, streams[0], &error);
1173 if ((streams[0] == NULL) || (error != CL_SUCCESS))
1174 {
1175 print_error(error,
1176 "1D Image from buffer creation failed for maximum image "
1177 "buffer size");
1178 return -1;
1179 }
1180
1181 return 0;
1182 }
1183
1184
test_min_max_parameter_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1185 int test_min_max_parameter_size(cl_device_id deviceID, cl_context context,
1186 cl_command_queue queue, int num_elements)
1187 {
1188 int error, retVal, i;
1189 size_t maxSize;
1190 char *programSrc;
1191 char *ptr;
1192 size_t numberExpected;
1193 long numberOfIntParametersToTry;
1194 char *argumentLine, *codeLines;
1195 void *data;
1196 cl_long long_result, expectedResult;
1197 cl_int int_result;
1198 size_t decrement;
1199 cl_event event;
1200 cl_int event_status;
1201 bool embeddedNoLong = gIsEmbedded && !gHasLong;
1202
1203
1204 /* Get the max param size */
1205 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PARAMETER_SIZE,
1206 sizeof(maxSize), &maxSize, NULL);
1207 test_error(error, "Unable to get max parameter size from device");
1208
1209
1210 if (((!gIsEmbedded) && (maxSize < 1024))
1211 || ((gIsEmbedded) && (maxSize < 256)))
1212 {
1213 log_error(
1214 "ERROR: Reported max parameter size is less than required! (%d)\n",
1215 (int)maxSize);
1216 return -1;
1217 }
1218
1219 /* The embedded profile without cles_khr_int64 extension does not require
1220 * longs, so use ints */
1221 if (embeddedNoLong)
1222 numberOfIntParametersToTry = numberExpected =
1223 (maxSize - sizeof(cl_mem)) / sizeof(cl_int);
1224 else
1225 numberOfIntParametersToTry = numberExpected =
1226 (maxSize - sizeof(cl_mem)) / sizeof(cl_long);
1227
1228 decrement = (size_t)(numberOfIntParametersToTry / 8);
1229 if (decrement < 1) decrement = 1;
1230 log_info("Reported max parameter size of %d bytes.\n", (int)maxSize);
1231
1232 while (numberOfIntParametersToTry > 0)
1233 {
1234 // These need to be inside to be deallocated automatically on each loop
1235 // iteration.
1236 clProgramWrapper program;
1237 clMemWrapper mem;
1238 clKernelWrapper kernel;
1239
1240 if (embeddedNoLong)
1241 {
1242 log_info(
1243 "Trying a kernel with %ld int arguments (%ld bytes) and one "
1244 "cl_mem (%ld bytes) for %ld bytes total.\n",
1245 numberOfIntParametersToTry,
1246 sizeof(cl_int) * numberOfIntParametersToTry, sizeof(cl_mem),
1247 sizeof(cl_mem) + numberOfIntParametersToTry * sizeof(cl_int));
1248 }
1249 else
1250 {
1251 log_info(
1252 "Trying a kernel with %ld long arguments (%ld bytes) and one "
1253 "cl_mem (%ld bytes) for %ld bytes total.\n",
1254 numberOfIntParametersToTry,
1255 sizeof(cl_long) * numberOfIntParametersToTry, sizeof(cl_mem),
1256 sizeof(cl_mem) + numberOfIntParametersToTry * sizeof(cl_long));
1257 }
1258
1259 // Allocate memory for the program storage
1260 data = malloc(sizeof(cl_long) * numberOfIntParametersToTry);
1261
1262 argumentLine =
1263 (char *)malloc(sizeof(char) * numberOfIntParametersToTry * 32);
1264 codeLines =
1265 (char *)malloc(sizeof(char) * numberOfIntParametersToTry * 32);
1266 programSrc = (char *)malloc(sizeof(char)
1267 * (numberOfIntParametersToTry * 64 + 1024));
1268 argumentLine[0] = '\0';
1269 codeLines[0] = '\0';
1270 programSrc[0] = '\0';
1271
1272 // Generate our results
1273 expectedResult = 0;
1274 for (i = 0; i < (int)numberOfIntParametersToTry; i++)
1275 {
1276 if (gHasLong)
1277 {
1278 ((cl_long *)data)[i] = i;
1279 expectedResult += i;
1280 }
1281 else
1282 {
1283 ((cl_int *)data)[i] = i;
1284 expectedResult += i;
1285 }
1286 }
1287
1288 // Build the program
1289 if (gHasLong)
1290 sprintf(argumentLine, "%s", "long arg0");
1291 else
1292 sprintf(argumentLine, "%s", "int arg0");
1293
1294 sprintf(codeLines, "%s", "result[0] += arg0;");
1295 for (i = 1; i < (int)numberOfIntParametersToTry; i++)
1296 {
1297 if (gHasLong)
1298 sprintf(argumentLine + strlen(argumentLine), ", long arg%d", i);
1299 else
1300 sprintf(argumentLine + strlen(argumentLine), ", int arg%d", i);
1301
1302 sprintf(codeLines + strlen(codeLines), "\nresult[0] += arg%d;", i);
1303 }
1304
1305 /* Create a kernel to test with */
1306 sprintf(programSrc,
1307 gHasLong ? sample_large_parmam_kernel_pattern[0]
1308 : sample_large_int_parmam_kernel_pattern[0],
1309 argumentLine, codeLines);
1310
1311 ptr = programSrc;
1312 if (create_single_kernel_helper(context, &program, &kernel, 1,
1313 (const char **)&ptr, "sample_test")
1314 != 0)
1315 {
1316 log_info("Create program failed, decrementing number of parameters "
1317 "to try.\n");
1318 numberOfIntParametersToTry -= decrement;
1319 continue;
1320 }
1321
1322 /* Try to set a large argument to the kernel */
1323 retVal = 0;
1324
1325 mem = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_long), NULL,
1326 &error);
1327 test_error(error, "clCreateBuffer failed");
1328
1329 for (i = 0; i < (int)numberOfIntParametersToTry; i++)
1330 {
1331 if (gHasLong)
1332 error = clSetKernelArg(kernel, i, sizeof(cl_long),
1333 &(((cl_long *)data)[i]));
1334 else
1335 error = clSetKernelArg(kernel, i, sizeof(cl_int),
1336 &(((cl_int *)data)[i]));
1337
1338 if (error != CL_SUCCESS)
1339 {
1340 log_info("clSetKernelArg failed (%s), decrementing number of "
1341 "parameters to try.\n",
1342 IGetErrorString(error));
1343 numberOfIntParametersToTry -= decrement;
1344 break;
1345 }
1346 }
1347 if (error != CL_SUCCESS) continue;
1348
1349
1350 error = clSetKernelArg(kernel, i, sizeof(cl_mem), &mem);
1351 if (error != CL_SUCCESS)
1352 {
1353 log_info("clSetKernelArg failed (%s), decrementing number of "
1354 "parameters to try.\n",
1355 IGetErrorString(error));
1356 numberOfIntParametersToTry -= decrement;
1357 continue;
1358 }
1359
1360 size_t globalDim[3] = { 1, 1, 1 }, localDim[3] = { 1, 1, 1 };
1361 error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, globalDim,
1362 localDim, 0, NULL, &event);
1363 if (error != CL_SUCCESS)
1364 {
1365 log_info("clEnqueueNDRangeKernel failed (%s), decrementing number "
1366 "of parameters to try.\n",
1367 IGetErrorString(error));
1368 numberOfIntParametersToTry -= decrement;
1369 continue;
1370 }
1371
1372 // Verify that the event does not return an error from the execution
1373 error = clWaitForEvents(1, &event);
1374 test_error(error, "clWaitForEvent failed");
1375 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
1376 sizeof(event_status), &event_status, NULL);
1377 test_error(
1378 error,
1379 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
1380 clReleaseEvent(event);
1381 if (event_status < 0)
1382 test_error(error, "Kernel execution event returned error");
1383
1384 if (gHasLong)
1385 error = clEnqueueReadBuffer(queue, mem, CL_TRUE, 0, sizeof(cl_long),
1386 &long_result, 0, NULL, NULL);
1387 else
1388 error = clEnqueueReadBuffer(queue, mem, CL_TRUE, 0, sizeof(cl_int),
1389 &int_result, 0, NULL, NULL);
1390
1391 test_error(error, "clEnqueueReadBuffer failed")
1392
1393 free(data);
1394 free(argumentLine);
1395 free(codeLines);
1396 free(programSrc);
1397
1398 if (gHasLong)
1399 {
1400 if (long_result != expectedResult)
1401 {
1402 log_error("Expected result (%lld) does not equal actual result "
1403 "(%lld).\n",
1404 expectedResult, long_result);
1405 numberOfIntParametersToTry -= decrement;
1406 continue;
1407 }
1408 else
1409 {
1410 log_info("Results verified at %ld bytes of arguments.\n",
1411 sizeof(cl_mem)
1412 + numberOfIntParametersToTry * sizeof(cl_long));
1413 break;
1414 }
1415 }
1416 else
1417 {
1418 if (int_result != expectedResult)
1419 {
1420 log_error("Expected result (%lld) does not equal actual result "
1421 "(%d).\n",
1422 expectedResult, int_result);
1423 numberOfIntParametersToTry -= decrement;
1424 continue;
1425 }
1426 else
1427 {
1428 log_info("Results verified at %ld bytes of arguments.\n",
1429 sizeof(cl_mem)
1430 + numberOfIntParametersToTry * sizeof(cl_int));
1431 break;
1432 }
1433 }
1434 }
1435
1436 if (numberOfIntParametersToTry == (long)numberExpected) return 0;
1437 return -1;
1438 }
1439
test_min_max_samplers(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1440 int test_min_max_samplers(cl_device_id deviceID, cl_context context,
1441 cl_command_queue queue, int num_elements)
1442 {
1443 int error;
1444 cl_uint maxSamplers, i;
1445 clProgramWrapper program;
1446 clKernelWrapper kernel;
1447 char *programSrc, samplerLine[1024];
1448 size_t maxParameterSize;
1449 cl_event event;
1450 cl_int event_status;
1451 cl_uint minRequiredSamplers = gIsEmbedded ? 8 : 16;
1452
1453
1454 PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
1455
1456 /* Get the max value */
1457 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_SAMPLERS,
1458 sizeof(maxSamplers), &maxSamplers, NULL);
1459 test_error(error, "Unable to get max sampler count from device");
1460
1461 if (maxSamplers < minRequiredSamplers)
1462 {
1463 log_error(
1464 "ERROR: Reported max sampler count is less than required! (%d)\n",
1465 (int)maxSamplers);
1466 return -1;
1467 }
1468
1469 log_info("Reported max %d samplers.\n", maxSamplers);
1470
1471 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PARAMETER_SIZE,
1472 sizeof(maxParameterSize), &maxParameterSize, NULL);
1473 test_error(error, "Unable to get max parameter size from device");
1474
1475 // Subtract the size of the result
1476 maxParameterSize -= 2 * sizeof(cl_mem);
1477
1478 // Calculate the number we can use
1479 if (maxParameterSize / sizeof(cl_sampler) < maxSamplers)
1480 {
1481 log_info("WARNING: Max parameter size of %d bytes limits test to %d "
1482 "max sampler arguments.\n",
1483 (int)maxParameterSize,
1484 (int)(maxParameterSize / sizeof(cl_sampler)));
1485 maxSamplers = (unsigned int)(maxParameterSize / sizeof(cl_sampler));
1486 }
1487
1488 /* Create a kernel to test with */
1489 programSrc = (char *)malloc(
1490 (strlen(sample_sampler_kernel_pattern[1]) + 8) * (maxSamplers)
1491 + strlen(sample_sampler_kernel_pattern[0])
1492 + strlen(sample_sampler_kernel_pattern[2])
1493 + (strlen(sample_sampler_kernel_pattern[3]) + 8) * maxSamplers
1494 + strlen(sample_sampler_kernel_pattern[4]));
1495 strcpy(programSrc, sample_sampler_kernel_pattern[0]);
1496 for (i = 0; i < maxSamplers; i++)
1497 {
1498 sprintf(samplerLine, sample_sampler_kernel_pattern[1], i);
1499 strcat(programSrc, samplerLine);
1500 }
1501 strcat(programSrc, sample_sampler_kernel_pattern[2]);
1502 for (i = 0; i < maxSamplers; i++)
1503 {
1504 sprintf(samplerLine, sample_sampler_kernel_pattern[3], i);
1505 strcat(programSrc, samplerLine);
1506 }
1507 strcat(programSrc, sample_sampler_kernel_pattern[4]);
1508
1509
1510 error =
1511 create_single_kernel_helper(context, &program, &kernel, 1,
1512 (const char **)&programSrc, "sample_test");
1513 test_error(error, "Failed to create the program and kernel.");
1514
1515 // We have to set up some fake parameters so it'll work
1516 clSamplerWrapper *samplers = new clSamplerWrapper[maxSamplers];
1517
1518 cl_image_format format = { CL_RGBA, CL_SIGNED_INT8 };
1519
1520 clMemWrapper image = create_image_2d(context, CL_MEM_READ_WRITE, &format,
1521 16, 16, 0, NULL, &error);
1522 test_error(error, "Unable to create a test image");
1523
1524 clMemWrapper stream =
1525 clCreateBuffer(context, CL_MEM_READ_WRITE, 16, NULL, &error);
1526 test_error(error, "Unable to create test buffer");
1527
1528 error = clSetKernelArg(kernel, 0, sizeof(cl_mem), &image);
1529 error |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &stream);
1530 test_error(error, "Unable to set kernel arguments");
1531 for (i = 0; i < maxSamplers; i++)
1532 {
1533 samplers[i] = clCreateSampler(context, CL_FALSE, CL_ADDRESS_NONE,
1534 CL_FILTER_NEAREST, &error);
1535 test_error(error, "Unable to create sampler");
1536
1537 error = clSetKernelArg(kernel, 2 + i, sizeof(cl_sampler), &samplers[i]);
1538 test_error(error, "Unable to set sampler argument");
1539 }
1540
1541 size_t globalDim[3] = { 1, 1, 1 }, localDim[3] = { 1, 1, 1 };
1542 error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, globalDim, localDim,
1543 0, NULL, &event);
1544 test_error(
1545 error,
1546 "clEnqueueNDRangeKernel failed with maximum number of samplers.");
1547
1548 // Verify that the event does not return an error from the execution
1549 error = clWaitForEvents(1, &event);
1550 test_error(error, "clWaitForEvent failed");
1551 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
1552 sizeof(event_status), &event_status, NULL);
1553 test_error(error,
1554 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
1555 clReleaseEvent(event);
1556 if (event_status < 0)
1557 test_error(error, "Kernel execution event returned error");
1558
1559 free(programSrc);
1560 delete[] samplers;
1561 return 0;
1562 }
1563
1564 #define PASSING_FRACTION 4
test_min_max_constant_buffer_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1565 int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
1566 cl_command_queue queue, int num_elements)
1567 {
1568 int error;
1569 clProgramWrapper program;
1570 clKernelWrapper kernel;
1571 size_t threads[1], localThreads[1];
1572 cl_int *constantData, *resultData;
1573 cl_ulong maxSize, stepSize, currentSize, maxGlobalSize, maxAllocSize;
1574 int i;
1575 cl_event event;
1576 cl_int event_status;
1577 MTdata d;
1578
1579 /* Verify our test buffer won't be bigger than allowed */
1580 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
1581 sizeof(maxSize), &maxSize, 0);
1582 test_error(error, "Unable to get max constant buffer size");
1583
1584 if ((0 == gIsEmbedded && maxSize < 64L * 1024L) || maxSize < 1L * 1024L)
1585 {
1586 log_error("ERROR: Reported max constant buffer size less than required "
1587 "by OpenCL 1.0 (reported %d KB)\n",
1588 (int)(maxSize / 1024L));
1589 return -1;
1590 }
1591
1592 log_info("Reported max constant buffer size of %lld bytes.\n", maxSize);
1593
1594 // Limit test buffer size to 1/8 of CL_DEVICE_GLOBAL_MEM_SIZE
1595 error = clGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE,
1596 sizeof(maxGlobalSize), &maxGlobalSize, 0);
1597 test_error(error, "Unable to get CL_DEVICE_GLOBAL_MEM_SIZE");
1598
1599 if (maxSize > maxGlobalSize / 8) maxSize = maxGlobalSize / 8;
1600
1601 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
1602 sizeof(maxAllocSize), &maxAllocSize, 0);
1603 test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE ");
1604
1605 if (maxSize > maxAllocSize) maxSize = maxAllocSize;
1606
1607 /* Create a kernel to test with */
1608 if (create_single_kernel_helper(context, &program, &kernel, 1,
1609 sample_const_arg_kernel, "sample_test")
1610 != 0)
1611 {
1612 return -1;
1613 }
1614
1615 /* Try the returned max size and decrease it until we get one that works. */
1616 stepSize = maxSize / 16;
1617 currentSize = maxSize;
1618 int allocPassed = 0;
1619 d = init_genrand(gRandomSeed);
1620 while (!allocPassed && currentSize >= maxSize / PASSING_FRACTION)
1621 {
1622 log_info("Attempting to allocate constant buffer of size %lld bytes\n",
1623 maxSize);
1624
1625 /* Create some I/O streams */
1626 size_t sizeToAllocate =
1627 ((size_t)currentSize / sizeof(cl_int)) * sizeof(cl_int);
1628 size_t numberOfInts = sizeToAllocate / sizeof(cl_int);
1629 constantData = (cl_int *)malloc(sizeToAllocate);
1630 if (constantData == NULL)
1631 {
1632 log_error("Failed to allocate memory for constantData!\n");
1633 free_mtdata(d);
1634 return EXIT_FAILURE;
1635 }
1636
1637 for (i = 0; i < (int)(numberOfInts); i++)
1638 constantData[i] = (int)genrand_int32(d);
1639
1640 clMemWrapper streams[3];
1641 streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR,
1642 sizeToAllocate, constantData, &error);
1643 test_error(error, "Creating test array failed");
1644 streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeToAllocate,
1645 NULL, &error);
1646 test_error(error, "Creating test array failed");
1647
1648
1649 /* Set the arguments */
1650 error = clSetKernelArg(kernel, 0, sizeof(streams[0]), &streams[0]);
1651 test_error(error, "Unable to set indexed kernel arguments");
1652 error = clSetKernelArg(kernel, 1, sizeof(streams[1]), &streams[1]);
1653 test_error(error, "Unable to set indexed kernel arguments");
1654
1655
1656 /* Test running the kernel and verifying it */
1657 threads[0] = numberOfInts;
1658 localThreads[0] = 1;
1659 log_info("Filling constant buffer with %d cl_ints (%d bytes).\n",
1660 (int)threads[0], (int)(threads[0] * sizeof(cl_int)));
1661
1662 error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads,
1663 localThreads, 0, NULL, &event);
1664 /* If we failed due to a resource issue, reduce the size and try again.
1665 */
1666 if ((error == CL_OUT_OF_RESOURCES)
1667 || (error == CL_MEM_OBJECT_ALLOCATION_FAILURE)
1668 || (error == CL_OUT_OF_HOST_MEMORY))
1669 {
1670 log_info("Kernel enqueue failed at size %lld, trying at a reduced "
1671 "size.\n",
1672 currentSize);
1673 currentSize -= stepSize;
1674 free(constantData);
1675 continue;
1676 }
1677 test_error(
1678 error,
1679 "clEnqueueNDRangeKernel with maximum constant buffer size failed.");
1680
1681 // Verify that the event does not return an error from the execution
1682 error = clWaitForEvents(1, &event);
1683 test_error(error, "clWaitForEvent failed");
1684 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
1685 sizeof(event_status), &event_status, NULL);
1686 test_error(
1687 error,
1688 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
1689 clReleaseEvent(event);
1690 if (event_status < 0)
1691 {
1692 if ((event_status == CL_OUT_OF_RESOURCES)
1693 || (event_status == CL_MEM_OBJECT_ALLOCATION_FAILURE)
1694 || (event_status == CL_OUT_OF_HOST_MEMORY))
1695 {
1696 log_info("Kernel event indicates failure at size %lld, trying "
1697 "at a reduced size.\n",
1698 currentSize);
1699 currentSize -= stepSize;
1700 free(constantData);
1701 continue;
1702 }
1703 else
1704 {
1705 test_error(error, "Kernel execution event returned error");
1706 }
1707 }
1708
1709 /* Otherwise we did not fail due to resource issues. */
1710 allocPassed = 1;
1711
1712 resultData = (cl_int *)malloc(sizeToAllocate);
1713 if (resultData == NULL)
1714 {
1715 log_error("Failed to allocate memory for resultData!\n");
1716 free(constantData);
1717 free_mtdata(d);
1718 return EXIT_FAILURE;
1719 }
1720
1721 error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
1722 sizeToAllocate, resultData, 0, NULL, NULL);
1723 test_error(error, "clEnqueueReadBuffer failed");
1724
1725 for (i = 0; i < (int)(numberOfInts); i++)
1726 if (constantData[i] != resultData[i])
1727 {
1728 log_error("Data failed to verify: constantData[%d]=%d != "
1729 "resultData[%d]=%d\n",
1730 i, constantData[i], i, resultData[i]);
1731 free(constantData);
1732 free(resultData);
1733 free_mtdata(d);
1734 d = NULL;
1735 return -1;
1736 }
1737
1738 free(constantData);
1739 free(resultData);
1740 }
1741 free_mtdata(d);
1742 d = NULL;
1743
1744 if (allocPassed)
1745 {
1746 if (currentSize < maxSize / PASSING_FRACTION)
1747 {
1748 log_error("Failed to allocate at least 1/8 of the reported "
1749 "constant size.\n");
1750 return -1;
1751 }
1752 else if (currentSize != maxSize)
1753 {
1754 log_info("Passed at reduced size. (%lld of %lld bytes)\n",
1755 currentSize, maxSize);
1756 return 0;
1757 }
1758 return 0;
1759 }
1760 return -1;
1761 }
1762
test_min_max_constant_args(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1763 int test_min_max_constant_args(cl_device_id deviceID, cl_context context,
1764 cl_command_queue queue, int num_elements)
1765 {
1766 int error;
1767 clProgramWrapper program;
1768 clKernelWrapper kernel;
1769 clMemWrapper *streams;
1770 size_t threads[1], localThreads[1];
1771 cl_uint i, maxArgs;
1772 cl_ulong maxSize;
1773 cl_ulong maxParameterSize;
1774 size_t individualBufferSize;
1775 char *programSrc, *constArgs, *str2;
1776 char str[512];
1777 const char *ptr;
1778 cl_event event;
1779 cl_int event_status;
1780
1781
1782 /* Verify our test buffer won't be bigger than allowed */
1783 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_CONSTANT_ARGS,
1784 sizeof(maxArgs), &maxArgs, 0);
1785 test_error(error, "Unable to get max constant arg count");
1786
1787 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PARAMETER_SIZE,
1788 sizeof(maxParameterSize), &maxParameterSize, NULL);
1789 test_error(error, "Unable to get max parameter size from device");
1790
1791 // Subtract the size of the result
1792 maxParameterSize -= sizeof(cl_mem);
1793
1794 // Calculate the number we can use
1795 if (maxParameterSize / sizeof(cl_mem) < maxArgs)
1796 {
1797 log_info("WARNING: Max parameter size of %d bytes limits test to %d "
1798 "max image arguments.\n",
1799 (int)maxParameterSize,
1800 (int)(maxParameterSize / sizeof(cl_mem)));
1801 maxArgs = (unsigned int)(maxParameterSize / sizeof(cl_mem));
1802 }
1803
1804
1805 if (maxArgs < (gIsEmbedded ? 4 : 8))
1806 {
1807 log_error("ERROR: Reported max constant arg count less than required "
1808 "by OpenCL 1.0 (reported %d)\n",
1809 (int)maxArgs);
1810 return -1;
1811 }
1812
1813 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
1814 sizeof(maxSize), &maxSize, 0);
1815 test_error(error, "Unable to get max constant buffer size");
1816 individualBufferSize = (maxSize / 2) / maxArgs;
1817
1818 log_info(
1819 "Reported max constant arg count of %u and max constant buffer "
1820 "size of %llu. Test will attempt to allocate half of that, or %llu "
1821 "buffers of size %zu.\n",
1822 maxArgs, maxSize, maxArgs, individualBufferSize);
1823
1824 str2 = (char *)malloc(sizeof(char) * 32 * (maxArgs + 2));
1825 constArgs = (char *)malloc(sizeof(char) * 32 * (maxArgs + 2));
1826 programSrc = (char *)malloc(sizeof(char) * 32 * 2 * (maxArgs + 2) + 1024);
1827
1828 /* Create a test program */
1829 constArgs[0] = 0;
1830 str2[0] = 0;
1831 for (i = 0; i < maxArgs - 1; i++)
1832 {
1833 sprintf(str, ", __constant int *src%d", (int)(i + 2));
1834 strcat(constArgs, str);
1835 sprintf(str2 + strlen(str2), "\tdst[tid] += src%d[tid];\n",
1836 (int)(i + 2));
1837 if (strlen(str2) > (sizeof(char) * 32 * (maxArgs + 2) - 32)
1838 || strlen(constArgs) > (sizeof(char) * 32 * (maxArgs + 2) - 32))
1839 {
1840 log_info("Limiting number of arguments tested to %d due to test "
1841 "program allocation size.\n",
1842 i);
1843 break;
1844 }
1845 }
1846 sprintf(programSrc, sample_const_max_arg_kernel_pattern, constArgs, str2);
1847
1848 /* Create a kernel to test with */
1849 ptr = programSrc;
1850 if (create_single_kernel_helper(context, &program, &kernel, 1, &ptr,
1851 "sample_test")
1852 != 0)
1853 {
1854 return -1;
1855 }
1856
1857 /* Create some I/O streams */
1858 streams = new clMemWrapper[maxArgs + 1];
1859 for (i = 0; i < maxArgs + 1; i++)
1860 {
1861 streams[i] = clCreateBuffer(context, CL_MEM_READ_WRITE,
1862 individualBufferSize, NULL, &error);
1863 test_error(error, "Creating test array failed");
1864 }
1865
1866 /* Set the arguments */
1867 for (i = 0; i < maxArgs + 1; i++)
1868 {
1869 error = clSetKernelArg(kernel, i, sizeof(streams[i]), &streams[i]);
1870 test_error(error, "Unable to set kernel argument");
1871 }
1872
1873 /* Test running the kernel and verifying it */
1874 threads[0] = (size_t)10;
1875 while (threads[0] * sizeof(cl_int) > individualBufferSize) threads[0]--;
1876
1877 error = get_max_common_work_group_size(context, kernel, threads[0],
1878 &localThreads[0]);
1879 test_error(error, "Unable to get work group size to use");
1880
1881 error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads,
1882 localThreads, 0, NULL, &event);
1883 test_error(error, "clEnqueueNDRangeKernel failed");
1884
1885 // Verify that the event does not return an error from the execution
1886 error = clWaitForEvents(1, &event);
1887 test_error(error, "clWaitForEvent failed");
1888 error = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS,
1889 sizeof(event_status), &event_status, NULL);
1890 test_error(error,
1891 "clGetEventInfo for CL_EVENT_COMMAND_EXECUTION_STATUS failed");
1892 clReleaseEvent(event);
1893 if (event_status < 0)
1894 test_error(error, "Kernel execution event returned error");
1895
1896 error = clFinish(queue);
1897 test_error(error, "clFinish failed.");
1898
1899 delete[] streams;
1900 free(str2);
1901 free(constArgs);
1902 free(programSrc);
1903 return 0;
1904 }
1905
test_min_max_compute_units(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1906 int test_min_max_compute_units(cl_device_id deviceID, cl_context context,
1907 cl_command_queue queue, int num_elements)
1908 {
1909 int error;
1910 cl_uint value;
1911
1912
1913 error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_COMPUTE_UNITS,
1914 sizeof(value), &value, 0);
1915 test_error(error, "Unable to get compute unit count");
1916
1917 if (value < 1)
1918 {
1919 log_error("ERROR: Reported compute unit count less than required by "
1920 "OpenCL 1.0 (reported %d)\n",
1921 (int)value);
1922 return -1;
1923 }
1924
1925 log_info("Reported %d max compute units.\n", value);
1926
1927 return 0;
1928 }
1929
test_min_max_address_bits(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1930 int test_min_max_address_bits(cl_device_id deviceID, cl_context context,
1931 cl_command_queue queue, int num_elements)
1932 {
1933 int error;
1934 cl_uint value;
1935
1936
1937 error = clGetDeviceInfo(deviceID, CL_DEVICE_ADDRESS_BITS, sizeof(value),
1938 &value, 0);
1939 test_error(error, "Unable to get address bit count");
1940
1941 if (value != 32 && value != 64)
1942 {
1943 log_error("ERROR: Reported address bit count not valid by OpenCL 1.0 "
1944 "(reported %d)\n",
1945 (int)value);
1946 return -1;
1947 }
1948
1949 log_info("Reported %d device address bits.\n", value);
1950
1951 return 0;
1952 }
1953
test_min_max_single_fp_config(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1954 int test_min_max_single_fp_config(cl_device_id deviceID, cl_context context,
1955 cl_command_queue queue, int num_elements)
1956 {
1957 int error;
1958 cl_device_fp_config value;
1959 char profile[128] = "";
1960
1961 error = clGetDeviceInfo(deviceID, CL_DEVICE_SINGLE_FP_CONFIG, sizeof(value),
1962 &value, 0);
1963 test_error(error, "Unable to get device single fp config");
1964
1965 // Check to see if we are an embedded profile device
1966 if ((error = clGetDeviceInfo(deviceID, CL_DEVICE_PROFILE, sizeof(profile),
1967 profile, NULL)))
1968 {
1969 log_error("FAILURE: Unable to get CL_DEVICE_PROFILE: error %d\n",
1970 error);
1971 return error;
1972 }
1973
1974 if (0 == strcmp(profile, "EMBEDDED_PROFILE"))
1975 { // embedded device
1976
1977 if (0 == (value & (CL_FP_ROUND_TO_NEAREST | CL_FP_ROUND_TO_ZERO)))
1978 {
1979 log_error("FAILURE: embedded device supports neither "
1980 "CL_FP_ROUND_TO_NEAREST or CL_FP_ROUND_TO_ZERO\n");
1981 return -1;
1982 }
1983 }
1984 else
1985 { // Full profile
1986 if ((value & (CL_FP_ROUND_TO_NEAREST | CL_FP_INF_NAN))
1987 != (CL_FP_ROUND_TO_NEAREST | CL_FP_INF_NAN))
1988 {
1989 log_error("ERROR: Reported single fp config doesn't meet minimum "
1990 "set by OpenCL 1.0 (reported 0x%08x)\n",
1991 (int)value);
1992 return -1;
1993 }
1994 }
1995 return 0;
1996 }
1997
test_min_max_double_fp_config(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)1998 int test_min_max_double_fp_config(cl_device_id deviceID, cl_context context,
1999 cl_command_queue queue, int num_elements)
2000 {
2001 int error;
2002 cl_device_fp_config value;
2003
2004 error = clGetDeviceInfo(deviceID, CL_DEVICE_DOUBLE_FP_CONFIG, sizeof(value),
2005 &value, 0);
2006 test_error(error, "Unable to get device double fp config");
2007
2008 if (value == 0) return 0;
2009
2010 if ((value
2011 & (CL_FP_FMA | CL_FP_ROUND_TO_NEAREST | CL_FP_ROUND_TO_ZERO
2012 | CL_FP_ROUND_TO_INF | CL_FP_INF_NAN | CL_FP_DENORM))
2013 != (CL_FP_FMA | CL_FP_ROUND_TO_NEAREST | CL_FP_ROUND_TO_ZERO
2014 | CL_FP_ROUND_TO_INF | CL_FP_INF_NAN | CL_FP_DENORM))
2015 {
2016 log_error("ERROR: Reported double fp config doesn't meet minimum set "
2017 "by OpenCL 1.0 (reported 0x%08x)\n",
2018 (int)value);
2019 return -1;
2020 }
2021 return 0;
2022 }
2023
test_min_max_local_mem_size(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2024 int test_min_max_local_mem_size(cl_device_id deviceID, cl_context context,
2025 cl_command_queue queue, int num_elements)
2026 {
2027 int error;
2028 clProgramWrapper program;
2029 clKernelWrapper kernel;
2030 clMemWrapper streams[3];
2031 size_t threads[1], localThreads[1];
2032 cl_int *localData, *resultData;
2033 cl_ulong maxSize, kernelLocalUsage, min_max_local_mem_size;
2034 Version device_version;
2035 int i;
2036 int err = 0;
2037 MTdata d;
2038
2039 /* Verify our test buffer won't be bigger than allowed */
2040 error = clGetDeviceInfo(deviceID, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(maxSize),
2041 &maxSize, 0);
2042 test_error(error, "Unable to get max local buffer size");
2043
2044 try
2045 {
2046 device_version = get_device_cl_version(deviceID);
2047 } catch (const std::runtime_error &e)
2048 {
2049 log_error("%s", e.what());
2050 return -1;
2051 }
2052
2053 if (!gIsEmbedded)
2054 {
2055 if (device_version == Version(1, 0))
2056 min_max_local_mem_size = 16L * 1024L;
2057 else
2058 min_max_local_mem_size = 32L * 1024L;
2059 }
2060 else
2061 {
2062 min_max_local_mem_size = 1L * 1024L;
2063 }
2064
2065 if (maxSize < min_max_local_mem_size)
2066 {
2067 const std::string version_as_string = device_version.to_string();
2068 log_error("ERROR: Reported local mem size less than required by OpenCL "
2069 "%s (reported %d KB)\n",
2070 version_as_string.c_str(), (int)(maxSize / 1024L));
2071 return -1;
2072 }
2073
2074 log_info("Reported max local buffer size for device: %lld bytes.\n",
2075 maxSize);
2076
2077 /* Create a kernel to test with */
2078 if (create_single_kernel_helper(context, &program, &kernel, 1,
2079 sample_local_arg_kernel, "sample_test")
2080 != 0)
2081 {
2082 return -1;
2083 }
2084
2085 error = clGetKernelWorkGroupInfo(kernel, deviceID, CL_KERNEL_LOCAL_MEM_SIZE,
2086 sizeof(kernelLocalUsage),
2087 &kernelLocalUsage, NULL);
2088 test_error(error,
2089 "clGetKernelWorkGroupInfo for CL_KERNEL_LOCAL_MEM_SIZE failed");
2090
2091 log_info("Reported local buffer usage for kernel "
2092 "(CL_KERNEL_LOCAL_MEM_SIZE): %lld bytes.\n",
2093 kernelLocalUsage);
2094
2095 /* Create some I/O streams */
2096 size_t sizeToAllocate =
2097 ((size_t)(maxSize - kernelLocalUsage) / sizeof(cl_int))
2098 * sizeof(cl_int);
2099 size_t numberOfInts = sizeToAllocate / sizeof(cl_int);
2100
2101 log_info("Attempting to use %zu bytes of local memory.\n", sizeToAllocate);
2102
2103 localData = (cl_int *)malloc(sizeToAllocate);
2104 d = init_genrand(gRandomSeed);
2105 for (i = 0; i < (int)(numberOfInts); i++)
2106 localData[i] = (int)genrand_int32(d);
2107 free_mtdata(d);
2108 d = NULL;
2109
2110 streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeToAllocate,
2111 localData, &error);
2112 test_error(error, "Creating test array failed");
2113 streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeToAllocate,
2114 NULL, &error);
2115 test_error(error, "Creating test array failed");
2116
2117
2118 /* Set the arguments */
2119 error = clSetKernelArg(kernel, 0, sizeToAllocate, NULL);
2120 test_error(error, "Unable to set indexed kernel arguments");
2121 error = clSetKernelArg(kernel, 1, sizeof(streams[0]), &streams[0]);
2122 test_error(error, "Unable to set indexed kernel arguments");
2123 error = clSetKernelArg(kernel, 2, sizeof(streams[1]), &streams[1]);
2124 test_error(error, "Unable to set indexed kernel arguments");
2125
2126
2127 /* Test running the kernel and verifying it */
2128 threads[0] = numberOfInts;
2129 localThreads[0] = 1;
2130 log_info("Creating local buffer with %zu cl_ints (%zu bytes).\n",
2131 numberOfInts, sizeToAllocate);
2132
2133 cl_event evt;
2134 cl_int evt_err;
2135 error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads,
2136 localThreads, 0, NULL, &evt);
2137 test_error(error, "clEnqueueNDRangeKernel failed");
2138
2139 error = clFinish(queue);
2140 test_error(error, "clFinish failed");
2141
2142 error = clGetEventInfo(evt, CL_EVENT_COMMAND_EXECUTION_STATUS,
2143 sizeof evt_err, &evt_err, NULL);
2144 test_error(error, "clGetEventInfo with maximum local buffer size failed.");
2145
2146 if (evt_err != CL_COMPLETE)
2147 {
2148 print_error(evt_err, "Kernel event returned error");
2149 clReleaseEvent(evt);
2150 return -1;
2151 }
2152
2153 resultData = (cl_int *)malloc(sizeToAllocate);
2154
2155 error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, sizeToAllocate,
2156 resultData, 0, NULL, NULL);
2157 test_error(error, "clEnqueueReadBuffer failed");
2158
2159 for (i = 0; i < (int)(numberOfInts); i++)
2160 if (localData[i] != resultData[i])
2161 {
2162 clReleaseEvent(evt);
2163 free(localData);
2164 free(resultData);
2165 log_error("Results failed to verify.\n");
2166 return -1;
2167 }
2168 clReleaseEvent(evt);
2169 free(localData);
2170 free(resultData);
2171
2172 return err;
2173 }
2174
test_min_max_kernel_preferred_work_group_size_multiple(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2175 int test_min_max_kernel_preferred_work_group_size_multiple(
2176 cl_device_id deviceID, cl_context context, cl_command_queue queue,
2177 int num_elements)
2178 {
2179 int err;
2180 clProgramWrapper program;
2181 clKernelWrapper kernel;
2182
2183 size_t max_local_workgroup_size[3];
2184 size_t max_workgroup_size = 0, preferred_workgroup_size = 0;
2185
2186 err = create_single_kernel_helper(context, &program, &kernel, 1,
2187 sample_local_arg_kernel, "sample_test");
2188 test_error(err, "Failed to build kernel/program.");
2189
2190 err = clGetKernelWorkGroupInfo(kernel, deviceID, CL_KERNEL_WORK_GROUP_SIZE,
2191 sizeof(max_workgroup_size),
2192 &max_workgroup_size, NULL);
2193 test_error(err, "clGetKernelWorkgroupInfo failed.");
2194
2195 err = clGetKernelWorkGroupInfo(
2196 kernel, deviceID, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE,
2197 sizeof(preferred_workgroup_size), &preferred_workgroup_size, NULL);
2198 test_error(err, "clGetKernelWorkgroupInfo failed.");
2199
2200 err = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_ITEM_SIZES,
2201 sizeof(max_local_workgroup_size),
2202 max_local_workgroup_size, NULL);
2203 test_error(err, "clGetDeviceInfo failed for CL_DEVICE_MAX_WORK_ITEM_SIZES");
2204
2205 // Since the preferred size is only a performance hint, we can only really
2206 // check that we get a sane value back
2207 log_info("size: %ld preferred: %ld max: %ld\n", max_workgroup_size,
2208 preferred_workgroup_size, max_local_workgroup_size[0]);
2209
2210 if (preferred_workgroup_size > max_workgroup_size)
2211 {
2212 log_error("ERROR: Reported preferred workgroup multiple larger than "
2213 "max workgroup size (preferred %ld, max %ld)\n",
2214 preferred_workgroup_size, max_workgroup_size);
2215 return -1;
2216 }
2217
2218 return 0;
2219 }
2220
test_min_max_execution_capabilities(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2221 int test_min_max_execution_capabilities(cl_device_id deviceID,
2222 cl_context context,
2223 cl_command_queue queue,
2224 int num_elements)
2225 {
2226 int error;
2227 cl_device_exec_capabilities value;
2228
2229
2230 error = clGetDeviceInfo(deviceID, CL_DEVICE_EXECUTION_CAPABILITIES,
2231 sizeof(value), &value, 0);
2232 test_error(error, "Unable to get execution capabilities");
2233
2234 if ((value & CL_EXEC_KERNEL) != CL_EXEC_KERNEL)
2235 {
2236 log_error("ERROR: Reported execution capabilities less than required "
2237 "by OpenCL 1.0 (reported 0x%08x)\n",
2238 (int)value);
2239 return -1;
2240 }
2241 return 0;
2242 }
2243
test_min_max_queue_properties(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2244 int test_min_max_queue_properties(cl_device_id deviceID, cl_context context,
2245 cl_command_queue queue, int num_elements)
2246 {
2247 int error;
2248 cl_command_queue_properties value;
2249
2250
2251 error = clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES,
2252 sizeof(value), &value, 0);
2253 test_error(error, "Unable to get queue properties");
2254
2255 if ((value & CL_QUEUE_PROFILING_ENABLE) != CL_QUEUE_PROFILING_ENABLE)
2256 {
2257 log_error("ERROR: Reported queue properties less than required by "
2258 "OpenCL 1.0 (reported 0x%08x)\n",
2259 (int)value);
2260 return -1;
2261 }
2262 return 0;
2263 }
2264
test_min_max_device_version(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2265 int test_min_max_device_version(cl_device_id deviceID, cl_context context,
2266 cl_command_queue queue, int num_elements)
2267 {
2268 // Query for the device version.
2269 Version device_cl_version = get_device_cl_version(deviceID);
2270 log_info("Returned version %s.\n", device_cl_version.to_string().c_str());
2271
2272 // Make sure 2.x devices support required extensions for 2.x
2273 // note: these extensions are **not** required for devices
2274 // supporting OpenCL-3.0
2275 const char *requiredExtensions2x[] = {
2276 "cl_khr_3d_image_writes",
2277 "cl_khr_image2d_from_buffer",
2278 "cl_khr_depth_images",
2279 };
2280
2281 // Make sure 1.1 devices support required extensions for 1.1
2282 const char *requiredExtensions11[] = {
2283 "cl_khr_global_int32_base_atomics",
2284 "cl_khr_global_int32_extended_atomics",
2285 "cl_khr_local_int32_base_atomics",
2286 "cl_khr_local_int32_extended_atomics",
2287 "cl_khr_byte_addressable_store",
2288 };
2289
2290
2291 if (device_cl_version >= Version(1, 1))
2292 {
2293 log_info("Checking for required extensions for OpenCL 1.1 and later "
2294 "devices...\n");
2295 for (int i = 0; i < ARRAY_SIZE(requiredExtensions11); i++)
2296 {
2297 if (!is_extension_available(deviceID, requiredExtensions11[i]))
2298 {
2299 log_error("ERROR: Required extension for 1.1 and greater "
2300 "devices is not in extension string: %s\n",
2301 requiredExtensions11[i]);
2302 return -1;
2303 }
2304 else
2305 log_info("\t%s\n", requiredExtensions11[i]);
2306 }
2307
2308 if (device_cl_version >= Version(1, 2))
2309 {
2310 log_info("Checking for required extensions for OpenCL 1.2 and "
2311 "later devices...\n");
2312 // The only required extension for an OpenCL-1.2 device is
2313 // cl_khr_fp64 and it is only required if double precision is
2314 // supported.
2315 cl_device_fp_config doubles_supported;
2316 cl_int error = clGetDeviceInfo(deviceID, CL_DEVICE_DOUBLE_FP_CONFIG,
2317 sizeof(doubles_supported),
2318 &doubles_supported, 0);
2319 test_error(error, "Unable to get device double fp config");
2320 if (doubles_supported)
2321 {
2322 if (!is_extension_available(deviceID, "cl_khr_fp64"))
2323 {
2324 log_error(
2325 "ERROR: Required extension for 1.2 and greater devices "
2326 "is not in extension string: cl_khr_fp64\n");
2327 }
2328 else
2329 {
2330 log_info("\t%s\n", "cl_khr_fp64");
2331 }
2332 }
2333 }
2334
2335 if (device_cl_version >= Version(2, 0)
2336 && device_cl_version < Version(3, 0))
2337 {
2338 log_info("Checking for required extensions for OpenCL 2.0, 2.1 and "
2339 "2.2 devices...\n");
2340 for (int i = 0; i < ARRAY_SIZE(requiredExtensions2x); i++)
2341 {
2342 if (!is_extension_available(deviceID, requiredExtensions2x[i]))
2343 {
2344 log_error("ERROR: Required extension for 2.0, 2.1 and 2.2 "
2345 "devices is not in extension string: %s\n",
2346 requiredExtensions2x[i]);
2347 return -1;
2348 }
2349 else
2350 {
2351 log_info("\t%s\n", requiredExtensions2x[i]);
2352 }
2353 }
2354 }
2355 }
2356 else
2357 log_info("WARNING: skipping required extension test -- OpenCL 1.0 "
2358 "device.\n");
2359 return 0;
2360 }
2361
test_min_max_language_version(cl_device_id deviceID,cl_context context,cl_command_queue queue,int num_elements)2362 int test_min_max_language_version(cl_device_id deviceID, cl_context context,
2363 cl_command_queue queue, int num_elements)
2364 {
2365 cl_int error;
2366 cl_char buffer[4098];
2367 size_t length;
2368
2369 // Device version should fit the regex "OpenCL [0-9]+\.[0-9]+ *.*"
2370 error = clGetDeviceInfo(deviceID, CL_DEVICE_OPENCL_C_VERSION,
2371 sizeof(buffer), buffer, &length);
2372 test_error(error, "Unable to get device opencl c version string");
2373 if (memcmp(buffer, "OpenCL C ", strlen("OpenCL C ")) != 0)
2374 {
2375 log_error("ERROR: Initial part of device language version string does "
2376 "not match required format! (returned: \"%s\")\n",
2377 (char *)buffer);
2378 return -1;
2379 }
2380
2381 log_info("Returned version \"%s\".\n", buffer);
2382
2383 char *p1 = (char *)buffer + strlen("OpenCL C ");
2384 while (*p1 == ' ') p1++;
2385 char *p2 = p1;
2386 if (!isdigit(*p2))
2387 {
2388 log_error("ERROR: Major revision number must follow space behind "
2389 "OpenCL C! (returned %s)\n",
2390 (char *)buffer);
2391 return -1;
2392 }
2393 while (isdigit(*p2)) p2++;
2394 if (*p2 != '.')
2395 {
2396 log_error("ERROR: Version number must contain a decimal point! "
2397 "(returned: %s)\n",
2398 (char *)buffer);
2399 return -1;
2400 }
2401 char *p3 = p2 + 1;
2402 if (!isdigit(*p3))
2403 {
2404 log_error("ERROR: Minor revision number is missing or does not abut "
2405 "the decimal point! (returned %s)\n",
2406 (char *)buffer);
2407 return -1;
2408 }
2409 while (isdigit(*p3)) p3++;
2410 if (*p3 != ' ')
2411 {
2412 log_error("ERROR: A space must appear after the minor version! "
2413 "(returned: %s)\n",
2414 (char *)buffer);
2415 return -1;
2416 }
2417 *p2 = ' '; // Put in a space for atoi below.
2418 p2++;
2419
2420 int major = atoi(p1);
2421 int minor = atoi(p2);
2422 int minor_revision = 2;
2423
2424 if (major * 10 + minor < 10 + minor_revision)
2425 {
2426 // If the language version did not match, check to see if
2427 // OPENCL_1_0_DEVICE is set.
2428 if (getenv("OPENCL_1_0_DEVICE"))
2429 {
2430 log_info("WARNING: This test was run with OPENCL_1_0_DEVICE "
2431 "defined! This is not a OpenCL 1.1 or OpenCL 1.2 "
2432 "compatible device!!!\n");
2433 }
2434 else if (getenv("OPENCL_1_1_DEVICE"))
2435 {
2436 log_info(
2437 "WARNING: This test was run with OPENCL_1_1_DEVICE defined! "
2438 "This is not a OpenCL 1.2 compatible device!!!\n");
2439 }
2440 else
2441 {
2442 log_error("ERROR: OpenCL device language version returned is less "
2443 "than 1.%d! (Returned: %s)\n",
2444 minor_revision, (char *)buffer);
2445 return -1;
2446 }
2447 }
2448
2449 // Sanity checks on the returned values
2450 if (length != (strlen((char *)buffer) + 1))
2451 {
2452 log_error("ERROR: Returned length of version string does not match "
2453 "actual length (actual: %d, returned: %d)\n",
2454 (int)strlen((char *)buffer), (int)length);
2455 return -1;
2456 }
2457
2458 return 0;
2459 }
2460