2 * Copyright © 2014 EdB <edb+piglit@sigluy.net>
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.
23 * created from build-program.c
24 * Copyright © 2012 Blaž Tomažič <blaz.tomazic@gmail.com>
28 * @file compile-program.c
32 * cl_int clCompileProgram(cl_program d_prog, cl_uint num_devs,
33 * const cl_device_id *d_devs, const char *p_opts,
34 * cl_uint num_headers, const cl_program *d_header_progs,
35 * const char **headers_names,
36 * void (*pfn_notify)(cl_program, void *),
40 #include "piglit-framework-cl-api.h"
43 PIGLIT_CL_API_TEST_CONFIG_BEGIN
45 config
.name
= "clCompileProgram";
46 config
.version_min
= 12;
48 config
.run_per_platform
= true;
49 config
.create_context
= true;
51 PIGLIT_CL_API_TEST_CONFIG_END
54 const char* strings
[] = {
55 "#include \"header.h\"\n",
56 "kernel void dummy_kernel() { w_int i = 0; }",
57 "kernel void dummy_kernel() { int i = 0; }"
60 const char* headers_strings
[] = {
62 "int w_int;" //to trigger invalid
65 const char* headers_names
[] = {
69 const char* empty_strings
[] = {
73 #if defined(CL_VERSION_1_2)
75 test(cl_program program
,
76 cl_uint num_devices
, const cl_device_id
*device_list
,
78 cl_uint num_headers
, const cl_program
*d_header_progs
, const char **headers_names
,
79 void (CL_CALLBACK
*pfn_notify
)(cl_program program
, void *user_data
), void *user_data
,
80 cl_int expected_error
,
81 enum piglit_result
* result
,
82 const char* test_str
) {
85 errNo
= clCompileProgram(program
,
86 num_devices
, device_list
,
88 num_headers
, d_header_progs
, headers_names
,
89 pfn_notify
, user_data
);
91 if(!piglit_cl_check_error(errNo
, expected_error
)) {
92 fprintf(stderr
, "Failed (error code: %s): %s.\n",
93 piglit_cl_get_error_name(errNo
), test_str
);
94 piglit_merge_result(result
, PIGLIT_FAIL
);
103 piglit_cl_test(const int argc
,
105 const struct piglit_cl_api_test_config
* config
,
106 const struct piglit_cl_api_test_env
* env
)
108 #if defined(CL_VERSION_1_2)
109 enum piglit_result result
= PIGLIT_PASS
;
114 cl_program header_invalid
;
116 cl_program temp_program
;
117 cl_kernel kernel
= NULL
;
119 /*** Normal usage ***/
124 header
= clCreateProgramWithSource(env
->context
->cl_ctx
,
129 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
131 "Failed (error code: %s): Create program with source.\n",
132 piglit_cl_get_error_name(errNo
));
136 program
= clCreateProgramWithSource(env
->context
->cl_ctx
,
141 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
143 "Failed (error code: %s): Create program with source.\n",
144 piglit_cl_get_error_name(errNo
));
148 test(program
, env
->context
->num_devices
, env
->context
->device_ids
,
150 1, &header
, headers_names
,
152 CL_SUCCESS
, &result
, "Compile program");
155 // TODO: test callback
160 * CL_INVALID_PROGRAM if program is not a valid program object.
162 test(NULL
, env
->context
->num_devices
, env
->context
->device_ids
,
164 1, &header
, headers_names
,
166 CL_INVALID_PROGRAM
, &result
,
167 "Trigger CL_INVALID_PROGRAM if program is not a valid program object");
170 * CL_INVALID_VALUE if device_list is NULL and num_devices is greater than
171 * zero, or if device_list is not NULL and num_devices is zero.
173 test(program
, 1, NULL
,
175 1, &header
, headers_names
,
177 CL_INVALID_VALUE
, &result
,
178 "Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero");
179 test(program
, 0, env
->context
->device_ids
,
181 1, &header
, headers_names
,
183 CL_INVALID_VALUE
, &result
,
184 "Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero");
187 * CL_INVALID_VALUE if num_input_headers is zero and header_include_names or
188 * input_headers are not NULL or if num_input_headers is not zero and
189 * header_include_names or input_headers are NULL.
191 test(program
, 0, env
->context
->device_ids
,
195 CL_INVALID_VALUE
, &result
,
196 "Trigger CL_INVALID_VALUE if num_input_headers is zero and header_include_names or input_headers are not NULL");
197 test(program
, 0, env
->context
->device_ids
,
199 0, NULL
, headers_names
,
201 CL_INVALID_VALUE
, &result
,
202 "Trigger CL_INVALID_VALUE if num_input_headers is zero and header_include_names or input_headers are not NULL");
203 test(program
, 0, env
->context
->device_ids
,
207 CL_INVALID_VALUE
, &result
,
208 "Trigger CL_INVALID_VALUE if num_input_headers is not zero and header_include_names or input_headers are NULL.");
209 test(program
, 0, env
->context
->device_ids
,
211 1, NULL
, headers_names
,
213 CL_INVALID_VALUE
, &result
,
214 "Trigger CL_INVALID_VALUE if num_input_headers is not zero and header_include_names or input_headers are NULL.");
218 * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
220 test(program
, env
->context
->num_devices
, env
->context
->device_ids
,
222 1, &header
, headers_names
,
224 CL_INVALID_VALUE
, &result
,
225 "Trigger CL_INVALID_VALUE if pfn_notify is NULL and user_data is not NULL");
228 * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not in the
229 * list of devices associated with program.
235 * CL_INVALID_COMPILER_OPTIONS if the build options specified by options are
238 test(program
, env
->context
->num_devices
, env
->context
->device_ids
,
239 "-invalid- --build-- options",
240 1, &header
, headers_names
,
242 CL_INVALID_COMPILER_OPTIONS
, &result
,
243 "Trigger CL_INVALID_COMPILER_OPTIONS if the build options specified by options are invalid");
246 * CL_INVALID_OPERATION if the compilation or build of a program executable for any of
247 * the devices listed in device_list by a previous call to clCompileProgram or
248 * clBuildProgram for program has not completed.
254 * CL_COMPILER_NOT_AVAILABLE if program is created with
255 * clCreateProgramWithSource and a compiler is not available i.e.
256 * CL_DEVICE_COMPILER_AVAILABLE specified in the table of OpenCL Device
257 * Queries for clGetDeviceInfo is set to CL_FALSE.
259 * Note: If this is true for any device, then a normal usage test returns a
262 for(i
= 0; i
< env
->context
->num_devices
; i
++) {
263 cl_bool
* compiler_available
=
264 piglit_cl_get_device_info(env
->context
->device_ids
[i
],
265 CL_DEVICE_COMPILER_AVAILABLE
);
266 if(!(*compiler_available
)) {
267 test(program
, env
->context
->num_devices
, env
->context
->device_ids
,
269 1, &header
, headers_names
,
271 CL_COMPILER_NOT_AVAILABLE
, &result
,
272 "Trigger CL_COMPILER_NOT_AVAILABLE if program is created with clCreateProgramWithSource and a compiler is not available");
274 free(compiler_available
);
278 * CL_COMPILE_PROGRAM_FAILURE if there is a failure to compile the program source.
279 * This error will be returned if clCompileProgram does not return until the compile has
282 header_invalid
= clCreateProgramWithSource(env
->context
->cl_ctx
,
287 if(piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
288 test(program
, env
->context
->num_devices
, env
->context
->device_ids
,
290 1, &header_invalid
, headers_names
,
292 CL_COMPILE_PROGRAM_FAILURE
, &result
,
293 "Trigger CL_COMPILE_PROGRAM_FAILURE if there is a failure to compile the program source");
294 clReleaseProgram(header_invalid
);
298 * CL_INVALID_OPERATION if there are kernel objects attached to program.
300 temp_program
= clCreateProgramWithSource(env
->context
->cl_ctx
,
305 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
307 "Failed (error code: %s): Create temp program with source.\n",
308 piglit_cl_get_error_name(errNo
));
309 piglit_merge_result(&result
, PIGLIT_FAIL
);;
311 errNo
= clBuildProgram(temp_program
,
312 env
->context
->num_devices
, env
->context
->device_ids
,
315 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
316 fprintf(stderr
, "Failed (error code: %s): clBuildProgram.\n",
317 piglit_cl_get_error_name(errNo
));
318 piglit_merge_result(&result
, PIGLIT_FAIL
);
320 kernel
= clCreateKernel(temp_program
, "dummy_kernel", &errNo
);
321 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
322 fprintf(stderr
, "Failed (error code: %s): clCreateKernel.\n",
323 piglit_cl_get_error_name(errNo
));
324 piglit_merge_result(&result
, PIGLIT_FAIL
);
326 test(temp_program
, env
->context
->num_devices
, env
->context
->device_ids
,
328 1, &header
, headers_names
,
330 CL_INVALID_OPERATION
, &result
,
331 "Trigger CL_INVALID_OPERATION if there are kernel objects attached to program");
335 clReleaseKernel(kernel
);
336 clReleaseProgram(temp_program
);
339 * CL_SUCCESS when compiling an empty string
341 temp_program
= clCreateProgramWithSource(env
->context
->cl_ctx
,
346 if(piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
347 test(temp_program
, env
->context
->num_devices
, env
->context
->device_ids
,
352 "CL_SUCCESS when compiling an empty string.");
353 clReleaseProgram(temp_program
);
357 * CL_INVALID_OPERATION if program was not created with
358 * clCreateProgramWithSource.
365 clReleaseProgram(header
);
366 clReleaseProgram(program
);