2 * Copyright © 2012 Blaž Tomažič <blaz.tomazic@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
27 #include "piglit-framework-cl.h"
30 /* Default test header configuration values */
31 const struct piglit_cl_test_config_header
32 PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER
= {
36 .run_per_platform
= false,
37 .run_per_device
= false,
39 .platform_regex
= NULL
,
42 .require_platform_extensions
= NULL
,
43 .require_device_extensions
= NULL
,
50 /* Print test configuration */
52 print_test_info(const struct piglit_cl_test_config_header
* config
,
54 const cl_platform_id platform_id
,
55 const cl_device_id device_id
) {
56 if(config
->run_per_platform
|| config
->run_per_device
) {
59 platform_name
= piglit_cl_get_platform_info(platform_id
,
62 printf("# Running on:\n"
66 if(config
->run_per_device
) {
67 char* device_name
= piglit_cl_get_device_info(device_id
,
70 printf("# Device: %s\n", device_name
);
75 printf("# OpenCL version: %d.%d\n", version
/10, version
%10);
83 /* Check extensions */
85 bool check_platform_extensions(cl_platform_id platform_id
, char* extensions
)
92 pch
= strtok(extensions
, " ");
95 && !piglit_cl_is_platform_extension_supported(platform_id
, pch
)) {
96 char* platform_name
= piglit_cl_get_platform_info(platform_id
,
98 printf("\n# Skipping platform %s because extension %s is not supported.\n\n",
104 pch
= strtok(NULL
, " ");
110 bool check_device_extensions(cl_device_id device_id
, char* extensions
)
117 pch
= strtok(extensions
, " ");
120 && !piglit_cl_is_device_extension_supported(device_id
, pch
)) {
121 char* device_name
= piglit_cl_get_device_info(device_id
,
123 printf("\n# Skipping device %s because extension %s is not supported.\n\n",
129 pch
= strtok(NULL
, " ");
135 /* Run the test(s) */
136 int piglit_cl_framework_run(int argc
, char** argv
)
138 enum piglit_result result
= PIGLIT_SKIP
;
141 cl_platform_id platform_id
= NULL
;
142 cl_device_id device_id
= NULL
;
144 /* Get test configuration */
145 struct piglit_cl_test_config_header
*config
=
146 piglit_cl_get_test_config(argc
,
148 &PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER
);
150 /* Check that config is valid */
151 // run_per_platform, run_per_device
152 if(config
->run_per_platform
&& config
->run_per_device
) {
154 "Invalid configuration, only one of run_per_platform and run_per_device can be true.\n");
155 piglit_report_result(PIGLIT_WARN
);
159 if(config
->init_func
!= NULL
) {
160 config
->init_func(argc
, (const char**)argv
, config
);
163 /* Print test name and file */
164 printf("## Test: %s (%s) ##\n\n", config
->name
!= NULL
? config
->name
: "",
167 /* Get version to test against */
168 version
= piglit_cl_get_version_arg(argc
, (const char **)argv
);
170 if(version
> PIGLIT_CL_VERSION
) {
171 printf("Piglit was compiled with lower OpenCL version (%d.%d) than version argument: %d.%d.\n",
172 PIGLIT_CL_VERSION
/10, PIGLIT_CL_VERSION
%10,
173 version
/10, version
%10);
174 piglit_report_result(PIGLIT_SKIP
);
178 * If version was not provided on the command line, set it to
179 * the version against which Piglit was compiled (PIGLIT_CL_VERSION)
181 version
= PIGLIT_CL_VERSION
;
184 /* Run the actual test */
185 if(!(config
->run_per_platform
|| config
->run_per_device
)) {
186 print_test_info(config
, version
, NULL
, NULL
);
187 result
= config
->_test_run(argc
, (const char**)argv
, (void*)config
,
188 version
, NULL
, NULL
);
190 /* Run tests per platform or device */
192 regex_t platform_regex
;
193 regex_t device_regex
;
195 bool platform_defined
;
196 unsigned int num_platforms
;
197 cl_platform_id
* platform_ids
= NULL
;
200 if( config
->platform_regex
!= NULL
201 && regcomp(&platform_regex
, config
->platform_regex
, REG_EXTENDED
| REG_NEWLINE
)) {
203 "Regex to filter platforms is invalid, ignoring it.\n");
204 regcomp(&platform_regex
, "", REG_EXTENDED
| REG_NEWLINE
);
205 piglit_merge_result(&result
, PIGLIT_WARN
);
207 if( config
->device_regex
!= NULL
208 && regcomp(&device_regex
, config
->device_regex
, REG_EXTENDED
| REG_NEWLINE
)) {
210 "Regex to filter devices is invalid, ignoring it.\n");
211 regcomp(&device_regex
, "", REG_EXTENDED
| REG_NEWLINE
);
212 piglit_merge_result(&result
, PIGLIT_WARN
);
215 /* check for command-line/environment platform */
216 platform_defined
= piglit_cl_get_platform_arg(argc
, (const char**)argv
,
219 /* generate platforms list */
220 if(platform_defined
) {
221 /* use platform defined by command-line/environment */
223 platform_ids
= malloc(sizeof(cl_platform_id
));
224 platform_ids
[0] = platform_id
;
226 /* use all available platforms */
227 num_platforms
= piglit_cl_get_platform_ids(&platform_ids
);
230 /* execute test for each platform in platforms list */
231 for(i
= 0; i
< num_platforms
; i
++) {
232 int final_version
= version
;
233 int platform_version
;
235 platform_id
= platform_ids
[i
];
237 /* Filter platform */
238 if(config
->platform_regex
!= NULL
) {
241 platform_name
= piglit_cl_get_platform_info(platform_id
,
243 if(regexec(&platform_regex
, platform_name
, 0, NULL
, 0)) {
244 printf("\n# Skipping platform %s because it does not match platform_regex.\n\n",
252 /* Check platform extensions */
253 if(!check_platform_extensions(platform_id
, config
->require_platform_extensions
)) {
257 /* Get platform version */
258 platform_version
= piglit_cl_get_platform_version(platform_id
);
260 if(config
->run_per_platform
) {
261 /* Check platform version */
262 if(platform_version
< final_version
) {
263 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
264 platform_version
/10, platform_version
%10);
265 final_version
= platform_version
;
268 /* run test on platform */
269 print_test_info(config
, final_version
, platform_id
, NULL
);
270 piglit_merge_result(&result
,
271 config
->_test_run(argc
,
277 } else { //config->run_per_device
281 unsigned int num_devices
;
282 cl_device_id
* device_ids
;
284 /* check for command-line/environment device */
285 device_defined
= piglit_cl_get_device_arg(argc
,
290 /* generate devices list */
292 /* use device defined by command-line/environment */
294 device_ids
= malloc(sizeof(cl_device_id
));
295 device_ids
[0] = device_id
;
297 /* use all available devices */
298 num_devices
= piglit_cl_get_device_ids(platform_id
,
301 /* Check that we have at least 1 device. */
303 char* platform_name
=
304 piglit_cl_get_platform_info(platform_id
, CL_PLATFORM_NAME
);
305 printf("\n# skipping platform %s because it has 0 devices\n\n",
311 /* run tests per each device */
312 for(j
= 0; j
< num_devices
; j
++) {
315 device_id
= device_ids
[j
];
318 if(config
->device_regex
!= NULL
) {
321 device_name
= piglit_cl_get_device_info(device_id
,
323 if(regexec(&device_regex
, device_name
, 0, NULL
, 0)) {
324 printf("\n# Skipping device %s because it does not match device_regex.\n\n",
332 /* Check device extensions */
333 if(!check_device_extensions(device_id
, config
->require_device_extensions
)) {
337 /* Check platform version */
338 if(platform_version
< final_version
) {
339 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
340 platform_version
/10, platform_version
%10);
341 final_version
= platform_version
;
343 /* Check device version */
344 device_version
= piglit_cl_get_device_version(device_id
);
345 if(device_version
< final_version
) {
346 printf("# Device supporting only version %d.%d. Running test on that version.\n",
347 device_version
/10, device_version
%10);
348 final_version
= device_version
;
351 print_test_info(config
, version
, platform_id
, device_id
);
352 piglit_merge_result(&result
,
353 config
->_test_run(argc
,
365 if(config
->platform_regex
!= NULL
) {
366 regfree(&platform_regex
);
368 if(config
->device_regex
!= NULL
) {
369 regfree(&device_regex
);
376 if(config
->clean_func
!= NULL
) {
377 config
->clean_func(argc
, (const char**)argv
, config
);
380 /* Report merged result */
381 printf("# Result:\n");
382 piglit_report_result(result
);
388 /* Get command-line/environment variables */
391 piglit_cl_get_arg_value(const int argc
, const char *argv
[], const char* arg
)
394 char* full_arg
= calloc(strlen(arg
) + 2, sizeof(char));
395 full_arg
= strcpy(full_arg
, "-");
396 full_arg
= strcat(full_arg
, arg
);
398 for (i
= 1; i
< argc
; i
++) {
399 if (!strcmp(argv
[i
], full_arg
)) {
402 "Argument error: %s requires a value\n",
405 piglit_report_result(PIGLIT_WARN
);
418 piglit_cl_get_unnamed_arg(const int argc
, const char *argv
[], int index
)
423 for (i
= 1; i
< argc
; i
++) {
424 if (strncmp(argv
[i
], "-", 1)) {
426 if((count
- 1) == index
) {
438 piglit_cl_is_arg_defined(const int argc
, const char *argv
[], const char* arg
)
441 char* full_arg
= calloc(strlen(arg
) + 2, sizeof(char));
442 full_arg
= strcpy(full_arg
, "-");
443 full_arg
= strcat(full_arg
, arg
);
445 for (i
= 1; i
< argc
; i
++) {
446 if (!strcmp(argv
[i
], full_arg
)) {
457 piglit_cl_get_version_arg(int argc
, const char** argv
)
459 int version_major
= 0;
460 int version_minor
= 0;
462 const char* version_str
;
464 /* First check argument then environment */
465 version_str
= piglit_cl_get_arg_value(argc
, argv
, "version");
466 if(version_str
== NULL
) {
467 version_str
= getenv("PIGLIT_CL_VERSION");
470 if(version_str
!= NULL
) {
471 if(sscanf(version_str
, "%i.%i", &version_major
, &version_minor
) != 2) {
477 return version_major
*10 + version_minor
;
481 piglit_cl_get_platform_arg(const int argc
, const char** argv
,
482 cl_platform_id
* platform_id
)
485 const char* arg_value
;
487 /* First check argument then environment */
488 arg_value
= piglit_cl_get_arg_value(argc
, argv
, "platform");
489 if(arg_value
== NULL
) {
490 arg_value
= getenv("PIGLIT_CL_PLATFORM");
493 if(arg_value
!= NULL
) {
494 unsigned int num_platforms
;
495 cl_platform_id
* platform_ids
;
497 num_platforms
= piglit_cl_get_platform_ids(&platform_ids
);
499 for(i
= 0; i
< num_platforms
; i
++) {
500 char* platform_name
= piglit_cl_get_platform_info(platform_ids
[i
],
503 if(!strncmp(arg_value
, platform_name
, strlen(arg_value
))) {
504 *platform_id
= platform_ids
[i
];
516 "Could not find platform: %s\n",
518 piglit_report_result(PIGLIT_WARN
);
525 piglit_cl_get_device_arg(const int argc
, const char** argv
,
526 cl_platform_id platform_id
, cl_device_id
* device_id
)
529 const char* arg_value
;
531 /* First check argument then environment */
532 arg_value
= piglit_cl_get_arg_value(argc
, argv
, "device");
533 if(arg_value
== NULL
) {
534 arg_value
= getenv("PIGLIT_CL_DEVICE");
537 if(arg_value
!= NULL
) {
538 unsigned int num_devices
;
539 cl_device_id
* device_ids
;
541 num_devices
= piglit_cl_get_device_ids(platform_id
,
545 for(i
= 0; i
< num_devices
; i
++) {
546 char* device_name
= piglit_cl_get_device_info(device_ids
[i
],
549 if(!strncmp(arg_value
, device_name
, strlen(arg_value
))) {
550 *device_id
= device_ids
[i
];
562 "Could not find device: %s\n",
564 piglit_report_result(PIGLIT_WARN
);
570 bool piglit_cl_framework_check_local_work_size(
571 cl_device_id device_id
,
572 size_t *local_work_size
)
575 size_t workgroup_size
= 1;
576 size_t *max_workgroup_size
= piglit_cl_get_device_info(device_id
,
577 CL_DEVICE_MAX_WORK_GROUP_SIZE
);
578 size_t *max_workitem_sizes
= piglit_cl_get_device_info(device_id
,
579 CL_DEVICE_MAX_WORK_ITEM_SIZES
);
582 if (!local_work_size
) {
586 if (!max_workgroup_size
|| !max_workitem_sizes
) {
591 for (i
= 0; i
< 3; i
++) {
592 size_t local_size
= local_work_size
[i
];
593 if (local_size
> max_workitem_sizes
[i
]) {
597 if (local_size
> 0) {
598 workgroup_size
*= local_size
;
602 if (workgroup_size
> *max_workgroup_size
) {
606 free(max_workgroup_size
);
607 free(max_workitem_sizes
);