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.
24 #include "piglit-framework-cl-program.h"
27 /* Default test configuration values */
28 const struct piglit_cl_program_test_config
29 PIGLIT_CL_DEFAULT_PROGRAM_TEST_CONFIG
= {
32 .need_image_support
= false,
34 .program_source
= NULL
,
35 .program_source_file
= NULL
,
36 .program_binary
= NULL
,
37 .program_binary_file
= NULL
,
39 .build_options
= NULL
,
40 .expect_build_fail
= false,
45 /* Return default values for test configuration */
47 piglit_cl_get_empty_program_test_config()
49 return &PIGLIT_CL_DEFAULT_PROGRAM_TEST_CONFIG
;
52 /* Check configuration */
53 void piglit_cl_program_test_init(const int argc
,
57 struct piglit_cl_program_test_config
* config
= void_config
;
60 if(config
->_init_test
!= NULL
) {
61 config
->_init_test(argc
, argv
, void_config
);
64 /* Check that config is valid */
65 // run_per_device, run_per_platform
66 if(!(config
->run_per_device
|| config
->run_per_platform
)) {
67 fprintf(stderr
, "Invalid configuration, neither run_per_device nor run_per_platform is set to true.\n");
68 piglit_report_result(PIGLIT_WARN
);
71 if(config
->clc_version_min
== 0) {
72 config
->clc_version_min
= 10;
74 if(config
->clc_version_min
<= 0) {
75 fprintf(stderr
, "Invalid configuration, clc_version_min is %d.\n",
76 config
->clc_version_min
);
77 piglit_report_result(PIGLIT_WARN
);
80 if(config
->clc_version_max
< 0) {
81 fprintf(stderr
, "Invalid configuration, clc_version_max is %d.\n",
82 config
->clc_version_max
);
83 piglit_report_result(PIGLIT_WARN
);
85 if( config
->clc_version_max
> 0
86 && config
->clc_version_max
< config
->clc_version_min
) {
87 fprintf(stderr
, "Invalid configuration, clc_version_max (%d) is lower than clc_version_min (%d).\n",
88 config
->clc_version_max
, config
->clc_version_min
);
89 piglit_report_result(PIGLIT_WARN
);
92 if(!( /* one must be different than NULL */
93 ( config
->program_source
!= NULL
94 || config
->program_source_file
!= NULL
95 || config
->program_binary
!= NULL
96 || config
->program_binary_file
!= NULL
98 && /* the other three must be NULL */
99 ( ( config
->program_source_file
== NULL
100 && config
->program_binary
== NULL
101 && config
->program_binary_file
== NULL
)
102 || ( config
->program_source
== NULL
103 && config
->program_binary
== NULL
104 && config
->program_binary_file
== NULL
)
105 || ( config
->program_source
== NULL
106 && config
->program_source_file
== NULL
107 && config
->program_binary_file
== NULL
)
108 || ( config
->program_source
== NULL
109 && config
->program_source_file
== NULL
110 && config
->program_binary
== NULL
)
113 fprintf(stderr
, "Invalid configuration, one and only one of program_* must be defined.\n");
114 piglit_report_result(PIGLIT_WARN
);
116 // build_fail and kernel_name
117 if(config
->expect_build_fail
&& config
->kernel_name
!= NULL
) {
118 fprintf(stderr
, "Invalid configuration, kernel_name cannot be defined when build_fail is true.\n");
119 piglit_report_result(PIGLIT_WARN
);
123 /* Run by piglit_cl_framework_run() */
125 piglit_cl_program_test_run(const int argc
,
129 cl_platform_id platform_id
,
130 cl_device_id device_id
)
132 enum piglit_result result
;
134 struct piglit_cl_program_test_config
* config
= void_config
;
135 struct piglit_cl_program_test_env env
= {
150 char* build_options
= malloc(1 * sizeof(char));
151 unsigned int num_devices
;
152 cl_device_id
* device_ids
;
154 build_options
[0] = '\0';
156 /* Set environment */
157 env
.platform_id
= platform_id
;
158 env
.device_id
= device_id
;
159 env
.version
= version
;
162 if(config
->run_per_platform
) {
163 num_devices
= piglit_cl_get_device_ids(platform_id
,
168 /* Check OpenCL C version to test against */
169 if(config
->run_per_platform
) {
170 for(i
= 0; i
< num_devices
; i
++) {
171 int device_clc_version
=
172 piglit_cl_get_device_cl_c_version(device_ids
[i
]);
174 if(device_clc_version
< env
.clc_version
|| env
.clc_version
== 0) {
175 env
.clc_version
= device_clc_version
;
178 } else { // config->run_per_device
179 env
.clc_version
= piglit_cl_get_device_cl_c_version(device_id
);
181 if(env
.clc_version
> version
) {
182 printf("# Lowering OpenCL C version to %d.%d because of OpenCL version.\n",
183 version
/10, version
%10);
184 env
.clc_version
= version
;
186 if( config
->clc_version_max
> 0
187 && env
.clc_version
> config
->clc_version_max
) {
188 printf("# Lowering OpenCL C version to %d.%d because of clc_version_max.\n",
189 config
->clc_version_max
/10, config
->clc_version_max
%10);
190 env
.clc_version
= config
->clc_version_max
;
192 if(env
.clc_version
< config
->clc_version_min
) {
193 printf("Trying to run test with OpenCL C version (%d.%d) ""lower than clc_version_min: %d\n",
194 env
.clc_version
/10, env
.clc_version
%10,
195 config
->clc_version_min
);
199 printf("# OpenCL C version: %d.%d\n",
200 env
.clc_version
/10, env
.clc_version
%10);
203 if(config
->run_per_platform
) {
204 env
.context
= piglit_cl_create_context(platform_id
, device_ids
,
206 } else { // config->run_per_device
207 env
.context
= piglit_cl_create_context(platform_id
, &device_id
, 1);
210 if(config
->need_image_support
) {
211 bool image_support
= false;
212 if(config
->run_per_platform
) {
213 image_support
= piglit_cl_get_context_image_support(env
.context
);
214 } else { // config->run_per_device
215 image_support
= piglit_cl_get_device_image_support(env
.device_id
);
219 printf("Test need image support and none was found\n");
224 if(env
.context
== NULL
) {
228 /* Set build options */
229 if(config
->build_options
!= NULL
) {
230 char* old
= build_options
;
231 build_options
= malloc((strlen(old
) + strlen(config
->build_options
) + 1) * sizeof(char));
232 strcpy(build_options
, old
);
233 sprintf(build_options
+strlen(old
), "%s", config
->build_options
);
237 if(env
.clc_version
> 10) {
238 //If -cl-std was already in config->build_options, use what the test requested
239 if (!strstr(build_options
, "-cl-std")){
240 char* template = " -cl-std=CL%d.%d";
241 char* old
= build_options
;
242 build_options
= malloc((strlen(old
) + strlen(template) + 1) * sizeof(char));
243 strcpy(build_options
, old
);
244 sprintf(build_options
+strlen(old
), template, env
.clc_version
/10,
250 printf("# Build options: %s\n", build_options
);
252 /* Create and build program */
253 if(config
->program_source
!= NULL
) {
254 if(!config
->expect_build_fail
) {
255 env
.program
= piglit_cl_build_program_with_source(env
.context
,
257 &config
->program_source
,
260 env
.program
= piglit_cl_fail_build_program_with_source(env
.context
,
262 &config
->program_source
,
265 } else if(config
->program_source_file
!= NULL
) {
267 char* program_source
;
269 program_source
= piglit_load_text_file(config
->program_source_file
, &size
);
270 if(program_source
!= NULL
&& size
> 0) {
271 if(!config
->expect_build_fail
) {
272 env
.program
= piglit_cl_build_program_with_source(env
.context
,
277 env
.program
= piglit_cl_fail_build_program_with_source(env
.context
,
283 fprintf(stderr
, "Program source file %s does not exists or is empty\n",
284 config
->program_source_file
);
287 free(program_source
);
288 } else if(config
->program_binary
!= NULL
) {
289 size_t length
= strlen((char*)config
->program_binary
);
291 if(!config
->expect_build_fail
) {
292 env
.program
= piglit_cl_build_program_with_binary(env
.context
,
294 &config
->program_binary
,
297 env
.program
= piglit_cl_fail_build_program_with_binary(env
.context
,
299 &config
->program_binary
,
302 } else if(config
->program_binary_file
!= NULL
) {
304 size_t* lengths
= malloc(sizeof(size_t) * env
.context
->num_devices
);
305 unsigned char** program_binaries
= malloc(sizeof(unsigned char*) * env
.context
->num_devices
);
307 ((char**)program_binaries
)[0] =
308 piglit_load_text_file(config
->program_binary_file
, &length
);
310 for(i
= 1; i
< env
.context
->num_devices
; i
++) {
311 lengths
[i
] = lengths
[0];
312 program_binaries
[i
] = program_binaries
[0];
315 if(((char**)program_binaries
)[0] != NULL
&& length
> 0) {
316 if(!config
->expect_build_fail
) {
317 env
.program
= piglit_cl_build_program_with_binary(env
.context
,
322 env
.program
= piglit_cl_fail_build_program_with_binary(env
.context
,
328 fprintf(stderr
, "Program binary file %s does not exists or is empty\n",
329 config
->program_source_file
);
333 free(program_binaries
[0]);
334 free(program_binaries
);
340 if(env
.program
== NULL
) {
344 /* Create kernel(s) */
345 if(config
->kernel_name
!= NULL
) {
346 env
.kernel
= piglit_cl_create_kernel(env
.program
, config
->kernel_name
);
348 if(env
.kernel
== NULL
) {
353 /* Release retrieved device IDs */
354 if(config
->run_per_platform
) {
359 /* Run the actual test */
360 result
= config
->_program_test(argc
, argv
, config
, &env
);
363 /* Release kernel(s) */
364 if(env
.kernel
!= NULL
) {
365 clReleaseKernel(env
.kernel
);
368 /* Release program */
369 clReleaseProgram(env
.program
);
371 /* Release context */
372 piglit_cl_release_context(env
.context
);