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
,
303 /* run tests per each device */
304 for(j
= 0; j
< num_devices
; j
++) {
307 device_id
= device_ids
[j
];
310 if(config
->device_regex
!= NULL
) {
313 device_name
= piglit_cl_get_device_info(device_id
,
315 if(regexec(&device_regex
, device_name
, 0, NULL
, 0)) {
316 printf("\n# Skipping device %s because it does not match device_regex.\n\n",
324 /* Check device extensions */
325 if(!check_device_extensions(device_id
, config
->require_device_extensions
)) {
329 /* Check platform version */
330 if(platform_version
< final_version
) {
331 printf("# Platform supporting only version %d.%d. Running test on that version.\n",
332 platform_version
/10, platform_version
%10);
333 final_version
= platform_version
;
335 /* Check device version */
336 device_version
= piglit_cl_get_device_version(device_id
);
337 if(device_version
< final_version
) {
338 printf("# Device supporting only version %d.%d. Running test on that version.\n",
339 device_version
/10, device_version
%10);
340 final_version
= device_version
;
343 print_test_info(config
, version
, platform_id
, device_id
);
344 piglit_merge_result(&result
,
345 config
->_test_run(argc
,
357 if(config
->platform_regex
!= NULL
) {
358 regfree(&platform_regex
);
360 if(config
->device_regex
!= NULL
) {
361 regfree(&device_regex
);
368 if(config
->clean_func
!= NULL
) {
369 config
->clean_func(argc
, (const char**)argv
, config
);
372 /* Report merged result */
373 printf("# Result:\n");
374 piglit_report_result(result
);
380 /* Get command-line/environment variables */
383 piglit_cl_get_arg_value(const int argc
, const char *argv
[], const char* arg
)
386 char* full_arg
= calloc(strlen(arg
) + 2, sizeof(char));
387 full_arg
= strcpy(full_arg
, "-");
388 full_arg
= strcat(full_arg
, arg
);
390 for (i
= 1; i
< argc
; i
++) {
391 if (!strcmp(argv
[i
], full_arg
)) {
394 "Argument error: %s requires a value\n",
397 piglit_report_result(PIGLIT_WARN
);
410 piglit_cl_get_unnamed_arg(const int argc
, const char *argv
[], int index
)
415 for (i
= 1; i
< argc
; i
++) {
416 if (strncmp(argv
[i
], "-", 1)) {
418 if((count
- 1) == index
) {
430 piglit_cl_is_arg_defined(const int argc
, const char *argv
[], const char* arg
)
433 char* full_arg
= calloc(strlen(arg
) + 2, sizeof(char));
434 full_arg
= strcpy(full_arg
, "-");
435 full_arg
= strcat(full_arg
, arg
);
437 for (i
= 1; i
< argc
; i
++) {
438 if (!strcmp(argv
[i
], full_arg
)) {
449 piglit_cl_get_version_arg(int argc
, const char** argv
)
451 int version_major
= 0;
452 int version_minor
= 0;
454 const char* version_str
;
456 /* First check argument then environment */
457 version_str
= piglit_cl_get_arg_value(argc
, argv
, "version");
458 if(version_str
== NULL
) {
459 version_str
= getenv("PIGLIT_CL_VERSION");
462 if(version_str
!= NULL
) {
463 if(sscanf(version_str
, "%i.%i", &version_major
, &version_minor
) != 2) {
469 return version_major
*10 + version_minor
;
473 piglit_cl_get_platform_arg(const int argc
, const char** argv
,
474 cl_platform_id
* platform_id
)
477 const char* arg_value
;
479 /* First check argument then environment */
480 arg_value
= piglit_cl_get_arg_value(argc
, argv
, "platform");
481 if(arg_value
== NULL
) {
482 arg_value
= getenv("PIGLIT_CL_PLATFORM");
485 if(arg_value
!= NULL
) {
486 unsigned int num_platforms
;
487 cl_platform_id
* platform_ids
;
489 num_platforms
= piglit_cl_get_platform_ids(&platform_ids
);
491 for(i
= 0; i
< num_platforms
; i
++) {
492 char* platform_name
= piglit_cl_get_platform_info(platform_ids
[i
],
495 if(!strncmp(arg_value
, platform_name
, strlen(arg_value
))) {
496 *platform_id
= platform_ids
[i
];
508 "Could not find platform: %s\n",
510 piglit_report_result(PIGLIT_WARN
);
517 piglit_cl_get_device_arg(const int argc
, const char** argv
,
518 cl_platform_id platform_id
, cl_device_id
* device_id
)
521 const char* arg_value
;
523 /* First check argument then environment */
524 arg_value
= piglit_cl_get_arg_value(argc
, argv
, "device");
525 if(arg_value
== NULL
) {
526 arg_value
= getenv("PIGLIT_CL_DEVICE");
529 if(arg_value
!= NULL
) {
530 unsigned int num_devices
;
531 cl_device_id
* device_ids
;
533 num_devices
= piglit_cl_get_device_ids(platform_id
,
537 for(i
= 0; i
< num_devices
; i
++) {
538 char* device_name
= piglit_cl_get_device_info(device_ids
[i
],
541 if(!strncmp(arg_value
, device_name
, strlen(arg_value
))) {
542 *device_id
= device_ids
[i
];
554 "Could not find device: %s\n",
556 piglit_report_result(PIGLIT_WARN
);
562 bool piglit_cl_framework_check_local_work_size(
563 cl_device_id device_id
,
564 size_t *local_work_size
)
567 size_t workgroup_size
= 1;
568 size_t *max_workgroup_size
= piglit_cl_get_device_info(device_id
,
569 CL_DEVICE_MAX_WORK_GROUP_SIZE
);
570 size_t *max_workitem_sizes
= piglit_cl_get_device_info(device_id
,
571 CL_DEVICE_MAX_WORK_ITEM_SIZES
);
574 if (!local_work_size
) {
578 if (!max_workgroup_size
|| !max_workitem_sizes
) {
583 for (i
= 0; i
< 3; i
++) {
584 size_t local_size
= local_work_size
[i
];
585 if (local_size
> max_workitem_sizes
[i
]) {
589 if (local_size
> 0) {
590 workgroup_size
*= local_size
;
594 if (workgroup_size
> *max_workgroup_size
) {
598 free(max_workgroup_size
);
599 free(max_workitem_sizes
);