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.
25 * @file link-program.c
30 * clLinkProgram(cl_context context,
31 * cl_uint num_devices, const cl_device_id device_list,
32 * const char *options,
33 * cl_uint num_input_programs, const cl_program *input_programs,
34 * void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
36 * cl_int *errcode_ret)
39 #include "piglit-framework-cl-api.h"
42 PIGLIT_CL_API_TEST_CONFIG_BEGIN
44 config
.name
= "clLinkProgram";
45 config
.version_min
= 12;
47 config
.run_per_platform
= true;
48 config
.create_context
= true;
50 PIGLIT_CL_API_TEST_CONFIG_END
53 const char* strings
[] = {
54 "int get_number(void) { return 42; }\n",
55 "int get_number(void);\n",
56 "kernel void test_kernel(void) { int i = get_number(); }\n",
57 "int get_number(void) { return 0; }\n"
60 #if defined(CL_VERSION_1_2)
62 compile_program(cl_context context
,
63 cl_uint num_devices
, const cl_device_id
*device_list
,
64 cl_uint count
, const char **strings
,
65 const char* err_str
) {
69 /* Create program with source */
70 program
= clCreateProgramWithSource(context
,
75 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
77 "Failed (error code: %s): Create program with source (for the %s).\n",
78 piglit_cl_get_error_name(errNo
), err_str
);
83 errNo
= clCompileProgram(program
,
84 num_devices
, device_list
,
89 if(!piglit_cl_check_error(errNo
, CL_SUCCESS
)) {
91 fprintf(stderr
, "Failed (error code: %s): Compile program (for the %s).\n",
92 piglit_cl_get_error_name(errNo
), err_str
);
94 for(i
= 0; i
< num_devices
; ++i
) {
95 char *build_log
= piglit_cl_get_program_build_info(program
, device_list
[i
], CL_PROGRAM_BUILD_LOG
);
96 fprintf(stderr
, "Build log:\n%s\n", build_log
);
100 clReleaseProgram(program
);
108 test(cl_context context
,
109 cl_uint num_devices
, const cl_device_id
*device_list
,
111 cl_uint num_input_programs
, const cl_program
*input_programs
,
112 void (CL_CALLBACK
*pfn_notify
)(cl_program program
, void *user_data
),
114 cl_program
*ret_program
,
115 cl_int expected_error
, enum piglit_result
* result
,
116 const char* test_str
) {
120 program
= clLinkProgram(context
,
121 num_devices
, device_list
,
123 num_input_programs
, input_programs
,
124 pfn_notify
, user_data
,
128 *ret_program
= program
;
131 clReleaseProgram(program
);
134 if(!piglit_cl_check_error(errNo
, expected_error
)) {
135 fprintf(stderr
, "Failed (error code: %s): %s.\n",
136 piglit_cl_get_error_name(errNo
), test_str
);
137 piglit_merge_result(result
, PIGLIT_FAIL
);
146 piglit_cl_test(const int argc
,
148 const struct piglit_cl_api_test_config
* config
,
149 const struct piglit_cl_api_test_env
* env
)
151 #if defined(CL_VERSION_1_2)
152 enum piglit_result result
= PIGLIT_PASS
;
154 bool linker_available
;
156 cl_program_binary_type
* binary_type
;
157 cl_program compiled_programs
[2];
158 cl_program function_prog
;
159 cl_program kernel_prog
;
160 cl_program linked_prog
;
162 linker_available
= false;
163 for(i
= 0; i
< env
->context
->num_devices
; ++i
) {
164 cl_bool
* dev_linker
=
165 piglit_cl_get_device_info(env
->context
->device_ids
[i
],
166 CL_DEVICE_LINKER_AVAILABLE
);
169 linker_available
|= true;
174 if (!linker_available
)
177 /* Create compiled program */
178 function_prog
= compile_program(env
->context
->cl_ctx
,
179 env
->context
->num_devices
, env
->context
->device_ids
,
182 kernel_prog
= compile_program(env
->context
->cl_ctx
,
183 env
->context
->num_devices
, env
->context
->device_ids
,
187 if (!function_prog
|| !kernel_prog
) {
188 clReleaseProgram(function_prog
);
189 clReleaseProgram(kernel_prog
);
193 compiled_programs
[0] = function_prog
;
194 compiled_programs
[1] = kernel_prog
;
196 /*** Normal usage ***/
197 test(env
->context
->cl_ctx
,
198 env
->context
->num_devices
, env
->context
->device_ids
,
200 1, compiled_programs
,
203 CL_SUCCESS
, &result
, "Link program as library");
205 for(i
= 0; i
< env
->context
->num_devices
; ++i
) {
206 binary_type
= piglit_cl_get_program_build_info(linked_prog
,
207 env
->context
->device_ids
[i
],
208 CL_PROGRAM_BINARY_TYPE
);
209 if (*binary_type
!= CL_PROGRAM_BINARY_TYPE_LIBRARY
) {
210 piglit_merge_result(&result
, PIGLIT_FAIL
);
212 "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_LIBRARY.\n");
217 clReleaseProgram(linked_prog
);
219 test(env
->context
->cl_ctx
,
220 env
->context
->num_devices
, env
->context
->device_ids
,
222 2, compiled_programs
,
225 CL_SUCCESS
, &result
, "Link program as executable");
227 for(i
= 0; i
< env
->context
->num_devices
; ++i
) {
228 binary_type
= piglit_cl_get_program_build_info(linked_prog
,
229 env
->context
->device_ids
[i
],
230 CL_PROGRAM_BINARY_TYPE
);
231 if (*binary_type
!= CL_PROGRAM_BINARY_TYPE_EXECUTABLE
) {
232 piglit_merge_result(&result
, PIGLIT_FAIL
);
234 "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_EXECUTABLE.\n");
243 * CL_INVALID_VALUE if device_list is NULL and num_devices is greater than
244 * zero, or if device_list is not NULL and num_devices is zero
246 test(env
->context
->cl_ctx
,
247 env
->context
->num_devices
, NULL
,
249 2, compiled_programs
,
252 CL_INVALID_VALUE
, &result
,
253 "Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero");
255 test(env
->context
->cl_ctx
,
256 0, env
->context
->device_ids
,
258 2, compiled_programs
,
261 CL_INVALID_VALUE
, &result
,
262 "Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero");
265 * CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL
266 * or if num_input_programs is zero and input_programs is not NULL
267 * or if num_input_programs is not zero and input_programs is NULL
269 test(env
->context
->cl_ctx
,
270 env
->context
->num_devices
, env
->context
->device_ids
,
275 CL_INVALID_VALUE
, &result
,
276 "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL");
278 test(env
->context
->cl_ctx
,
279 env
->context
->num_devices
, env
->context
->device_ids
,
281 0, compiled_programs
,
284 CL_INVALID_VALUE
, &result
,
285 "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is not NULL");
287 test(env
->context
->cl_ctx
,
288 env
->context
->num_devices
, env
->context
->device_ids
,
293 CL_INVALID_VALUE
, &result
,
294 "Trigger CL_INVALID_VALUE if num_input_programs is not zero and input_programs is NULL");
297 * CL_INVALID_PROGRAM if programs specified in input_programs are not valid program objects
302 * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
304 test(env
->context
->cl_ctx
,
305 env
->context
->num_devices
, env
->context
->device_ids
,
307 2, compiled_programs
,
310 CL_INVALID_VALUE
, &result
,
311 "Trigger CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL");
314 * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not in the
315 * list of devices associated with context
320 * CL_INVALID_LINKER_OPTIONS if the linker options specified by options are
323 test(env
->context
->cl_ctx
,
324 env
->context
->num_devices
, env
->context
->device_ids
,
325 "-invalid- --link-- options",
326 2, compiled_programs
,
329 CL_INVALID_LINKER_OPTIONS
, &result
,
330 "Trigger CL_INVALID_LINKER_OPTIONS if the linker options specified by options are invalid");
333 * CL_INVALID_OPERATION if the compilation or build of a program executable
334 * for any of the devices listed in device_list by a previous call to
335 * clCompileProgram or clBuildProgram for program has not completed
340 * CL_INVALID_OPERATION if the rules for devices containing compiled binaries
341 * or libraries as described in input_programs argument above are not followed
343 compiled_programs
[0] = linked_prog
;
344 test(env
->context
->cl_ctx
,
345 env
->context
->num_devices
, env
->context
->device_ids
,
347 2, compiled_programs
,
350 CL_INVALID_OPERATION
, &result
,
351 "Trigger CL_INVALID_OPERATION if the rules for devices containing compiled binaries or libraries as described in input_programs argument above are not followed");
354 * CL_LINKER_NOT_AVAILABLE if a linker is not available
355 * i.e. CL_DEVICE_LINKER_AVAILABLE specified in the table of allowed values
356 * for param_name for clGetDeviceInfo is set to CL_FALSE.
358 for(i
= 0; i
< env
->context
->num_devices
; ++i
) {
359 cl_bool
* dev_linker
=
360 piglit_cl_get_device_info(env
->context
->device_ids
[i
],
361 CL_DEVICE_LINKER_AVAILABLE
);
363 test(env
->context
->cl_ctx
,
364 1, &env
->context
->device_ids
[i
],
366 2, compiled_programs
,
369 CL_LINKER_NOT_AVAILABLE
, &result
,
370 "Trigger CL_LINKER_NOT_AVAILABLE if a linker is not available");
376 /* Release programs */
377 clReleaseProgram(function_prog
);
378 clReleaseProgram(kernel_prog
);
379 clReleaseProgram(linked_prog
);
382 * CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries
385 function_prog
= compile_program(env
->context
->cl_ctx
,
386 env
->context
->num_devices
, env
->context
->device_ids
,
388 "2nd function program");
389 kernel_prog
= compile_program(env
->context
->cl_ctx
,
390 env
->context
->num_devices
, env
->context
->device_ids
,
392 "2nd kernel program");
394 if (!function_prog
|| !kernel_prog
) {
395 result
= PIGLIT_FAIL
;
397 compiled_programs
[0] = function_prog
;
398 compiled_programs
[1] = kernel_prog
;
400 test(env
->context
->cl_ctx
,
401 env
->context
->num_devices
, env
->context
->device_ids
,
403 2, compiled_programs
,
406 CL_LINK_PROGRAM_FAILURE
, &result
,
407 "Trigger CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries and/or libraries");
410 /* Release programs */
411 clReleaseProgram(function_prog
);
412 clReleaseProgram(kernel_prog
);