[Piglit] [PATCH v2] cl: add clLinkProgram test

EdB edb+piglit at sigluy.net
Tue Jan 6 12:20:47 PST 2015


I don't have commit acces. Can someone push it?

Le 2014-12-19 20:41, Tom Stellard a écrit :
> On Fri, Dec 19, 2014 at 02:39:06PM +0100, EdB wrote:
>> v2:
>> Use piglit_cl_get_program_build_info instead of 
>> piglit_cl_get_program_info,
>> I was expected it to fail so I didn't paid attention.
>> 
>> Remove "-invalid- --link-- options" on CL_INVALID_OPERATION test.
> 
> Reviewed-by: Tom Stellard <thomas.stellard at amd.com>
> 
>> ---
>>  tests/cl/api/CMakeLists.cl.txt |   1 +
>>  tests/cl/api/link-program.c    | 394 
>> +++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 395 insertions(+)
>>  create mode 100644 tests/cl/api/link-program.c
>> 
>> diff --git a/tests/cl/api/CMakeLists.cl.txt 
>> b/tests/cl/api/CMakeLists.cl.txt
>> index 7e78491..b598528 100644
>> --- a/tests/cl/api/CMakeLists.cl.txt
>> +++ b/tests/cl/api/CMakeLists.cl.txt
>> @@ -31,6 +31,7 @@ piglit_cl_add_api_test (create-program-with-source 
>> create-program-with-source.c)
>>  piglit_cl_add_api_test (retain_release-program 
>> retain_release-program.c)
>>  piglit_cl_add_api_test (build-program build-program.c)
>>  piglit_cl_add_api_test (compile-program compile-program.c)
>> +piglit_cl_add_api_test (link-program link-program.c)
>>  piglit_cl_add_api_test (unload-compiler unload-compiler.c)
>>  piglit_cl_add_api_test (get-program-info get-program-info.c)
>>  piglit_cl_add_api_test (get-program-build-info 
>> get-program-build-info.c)
>> diff --git a/tests/cl/api/link-program.c b/tests/cl/api/link-program.c
>> new file mode 100644
>> index 0000000..e98f428
>> --- /dev/null
>> +++ b/tests/cl/api/link-program.c
>> @@ -0,0 +1,394 @@
>> +/*
>> + * Copyright © 2014 EdB <edb+piglit at sigluy.net>
>> + *
>> + * Permission is hereby granted, free of charge, to any person 
>> obtaining a
>> + * copy of this software and associated documentation files (the 
>> "Software"),
>> + * to deal in the Software without restriction, including without 
>> limitation
>> + * the rights to use, copy, modify, merge, publish, distribute, 
>> sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom 
>> the
>> + * Software is furnished to do so, subject to the following 
>> conditions:
>> + *
>> + * The above copyright notice and this permission notice (including 
>> the next
>> + * paragraph) shall be included in all copies or substantial portions 
>> of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
>> EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
>> MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT 
>> SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 
>> OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
>> ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
>> OTHER
>> + * DEALINGS IN THE SOFTWARE.
>> + */
>> +
>> +/**
>> + * @file link-program.c
>> + *
>> + * Test API function:
>> + *
>> + *   cl_program
>> + *   clLinkProgram(cl_context context,
>> + *         cl_uint num_devices, const cl_device_id device_list,
>> + *         const char *options,
>> + *         cl_uint num_input_programs, const cl_program 
>> *input_programs,
>> + *         void (CL_CALLBACK *pfn_notify)(cl_program program, void 
>> *user_data),
>> + *         void *user_data,
>> + *         cl_int *errcode_ret)
>> + */
>> +
>> +#include "piglit-framework-cl-api.h"
>> +
>> +
>> +PIGLIT_CL_API_TEST_CONFIG_BEGIN
>> +
>> +	config.name = "clLinkProgram";
>> +	config.version_min = 12;
>> +
>> +	config.run_per_platform = true;
>> +	config.create_context = true;
>> +
>> +PIGLIT_CL_API_TEST_CONFIG_END
>> +
>> +
>> +const char* strings[] = {
>> +	"int get_number() { return 42; }",
>> +	"int get_number();\n",
>> +	"kernel void test_kernel() { int i = get_number(); }",
>> +	"int get_number() { return 0; }"
>> +};
>> +
>> +#if defined(CL_VERSION_1_2)
>> +static cl_program
>> +compile_program(cl_context context,
>> +                cl_uint num_devices, const cl_device_id *device_list,
>> +                cl_uint count, const char **strings,
>> +                const char* err_str) {
>> +	cl_int errNo;
>> +	cl_program program;
>> +
>> +	/* Create program with source */
>> +	program = clCreateProgramWithSource(context,
>> +	                                    count,
>> +	                                    strings,
>> +	                                    NULL,
>> +	                                    &errNo);
>> +	if(!piglit_cl_check_error(errNo, CL_SUCCESS)) {
>> +		fprintf(stderr,
>> +		        "Failed (error code: %s): Create program with source (for 
>> the %s).\n",
>> +		        piglit_cl_get_error_name(errNo), err_str);
>> +		return NULL;
>> +	}
>> +
>> +	/* Compile program */
>> +	errNo = clCompileProgram(program,
>> +	                       num_devices, device_list,
>> +	                       " ",
>> +	                       0, NULL, NULL,
>> +	                       NULL, NULL);
>> +
>> +	if(!piglit_cl_check_error(errNo, CL_SUCCESS)) {
>> +		fprintf(stderr, "Failed (error code: %s): Compile program (for the 
>> %s).\n",
>> +		        piglit_cl_get_error_name(errNo), err_str);
>> +		clReleaseProgram(program);
>> +		return NULL;
>> +	}
>> +
>> +	return program;
>> +}
>> +
>> +static bool
>> +test(cl_context context,
>> +     cl_uint num_devices, const cl_device_id *device_list,
>> +     const char *options,
>> +     cl_uint num_input_programs, const cl_program *input_programs,
>> +     void (CL_CALLBACK *pfn_notify)(cl_program program, void 
>> *user_data),
>> +     void *user_data,
>> +     cl_program *ret_program,
>> +     cl_int expected_error, enum piglit_result* result,
>> +     const char* test_str) {
>> +	cl_program program;
>> +	cl_int errNo;
>> +
>> +	program = clLinkProgram(context,
>> +	                        num_devices, device_list,
>> +	                        options,
>> +	                        num_input_programs, input_programs,
>> +	                        pfn_notify, user_data,
>> +	                        &errNo);
>> +
>> +	if (ret_program) {
>> +		*ret_program = program;
>> +	} else {
>> +		if (program)
>> +			clReleaseProgram(program);
>> +	}
>> +
>> +	if(!piglit_cl_check_error(errNo, expected_error)) {
>> +		fprintf(stderr, "Failed (error code: %s): %s.\n",
>> +		        piglit_cl_get_error_name(errNo), test_str);
>> +		piglit_merge_result(result, PIGLIT_FAIL);
>> +		return false;
>> +	}
>> +
>> +	return true;
>> +}
>> +#endif
>> +
>> +enum piglit_result
>> +piglit_cl_test(const int argc,
>> +               const char** argv,
>> +               const struct piglit_cl_api_test_config* config,
>> +               const struct piglit_cl_api_test_env* env)
>> +{
>> +#if defined(CL_VERSION_1_2)
>> +	enum piglit_result result = PIGLIT_PASS;
>> +
>> +	int i;
>> +	cl_program_binary_type* binary_type;
>> +	cl_program compiled_programs[2];
>> +	cl_program function_prog;
>> +	cl_program kernel_prog;
>> +	cl_program linked_prog;
>> +
>> +	/* Create compiled program */
>> +	function_prog = compile_program(env->context->cl_ctx,
>> +	                                env->context->num_devices, 
>> env->context->device_ids,
>> +	                                1, &strings[0],
>> +	                                "function program");
>> +	kernel_prog = compile_program(env->context->cl_ctx,
>> +	                              env->context->num_devices, 
>> env->context->device_ids,
>> +	                              2, &strings[1],
>> +                                 "kernel program");
>> +
>> +	if (!function_prog || !kernel_prog) {
>> +		clReleaseProgram(function_prog);
>> +		clReleaseProgram(kernel_prog);
>> +		return PIGLIT_FAIL;
>> +	}
>> +
>> +	compiled_programs[0] = function_prog;
>> +	compiled_programs[1] = kernel_prog;
>> +
>> +/*** Normal usage ***/
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "-create-library",
>> +	     1, compiled_programs,
>> +	     NULL, NULL,
>> +	     &linked_prog,
>> +	     CL_SUCCESS, &result, "Link program as library");
>> +
>> +	for(i = 0; i < env->context->num_devices; ++i) {
>> +		binary_type = piglit_cl_get_program_build_info(linked_prog,
>> +		                                               
>> env->context->device_ids[i],
>> +		                                               
>> CL_PROGRAM_BINARY_TYPE);
>> +		if (*binary_type != CL_PROGRAM_BINARY_TYPE_LIBRARY) {
>> +			piglit_merge_result(&result, PIGLIT_FAIL);
>> +			fprintf(stderr,
>> +		           "Failed: binary is not of type 
>> CL_PROGRAM_BINARY_TYPE_LIBRARY.\n");
>> +		}
>> +		free(binary_type);
>> +	}
>> +
>> +	clReleaseProgram(linked_prog);
>> +
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     2, compiled_programs,
>> +	     NULL, NULL,
>> +	     &linked_prog,
>> +	     CL_SUCCESS, &result, "Link program as executable");
>> +
>> +	for(i = 0; i < env->context->num_devices; ++i) {
>> +		binary_type = piglit_cl_get_program_build_info(linked_prog,
>> +		                                               
>> env->context->device_ids[i],
>> +		                                               
>> CL_PROGRAM_BINARY_TYPE);
>> +		if (*binary_type != CL_PROGRAM_BINARY_TYPE_EXECUTABLE) {
>> +			piglit_merge_result(&result, PIGLIT_FAIL);
>> +			fprintf(stderr,
>> +		           "Failed: binary is not of type 
>> CL_PROGRAM_BINARY_TYPE_EXECUTABLE.\n");
>> +		}
>> +		free(binary_type);
>> +	}
>> +
>> +
>> +/*** Errors ***/
>> +
>> +	/*
>> +	 * CL_INVALID_VALUE if device_list is NULL and num_devices is 
>> greater than
>> +	 * zero, or if device_list is not NULL and num_devices is zero
>> +	 */
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, NULL,
>> +	     "",
>> +	     2, compiled_programs,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if device_list is NULL and 
>> num_devices is greater than zero");
>> +
>> +	test(env->context->cl_ctx,
>> +	     0, env->context->device_ids,
>> +	     "",
>> +	     2, compiled_programs,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if device_list is not NULL and 
>> num_devices is zero");
>> +
>> +	/*
>> +	 * CL_INVALID_VALUE if num_input_programs is zero and input_programs 
>> is NULL
>> +	 * or if num_input_programs is zero and input_programs is not NULL
>> +	 * or if num_input_programs is not zero and input_programs is NULL
>> +	 */
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     0, NULL,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if num_input_programs is zero and 
>> input_programs is NULL");
>> +
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     0, compiled_programs,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if num_input_programs is zero and 
>> input_programs is not NULL");
>> +
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     2, NULL,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if num_input_programs is not zero and 
>> input_programs is NULL");
>> +
>> +	/*
>> +	 * CL_INVALID_PROGRAM if programs specified in input_programs are 
>> not valid program objects
>> +	 */
>> +
>> +
>> +	/*
>> +	 * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
>> +	 */
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     2, compiled_programs,
>> +	     NULL, &i,
>> +	     NULL,
>> +	     CL_INVALID_VALUE, &result,
>> +	     "Trigger CL_INVALID_VALUE if pfn_notify is NULL but user_data 
>> is not NULL");
>> +
>> +	/*
>> +	 * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not 
>> in the
>> +	 * list of devices associated with context
>> +	 */
>> +
>> +
>> +	/*
>> +	 * CL_INVALID_LINKER_OPTIONS if the linker options specified by 
>> options are
>> +	 * invalid
>> +	 */
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "-invalid- --link-- options",
>> +	     2, compiled_programs,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_LINKER_OPTIONS, &result,
>> +	     "Trigger CL_INVALID_LINKER_OPTIONS if the linker options 
>> specified by options are invalid");
>> +
>> +	/*
>> +	 * CL_INVALID_OPERATION if the compilation or build of a program 
>> executable
>> +	 * for any of the devices listed in device_list by a previous call 
>> to
>> +	 * clCompileProgram or clBuildProgram for program has not completed
>> +	 */
>> +
>> +
>> +	/*
>> +	 * CL_INVALID_OPERATION if the rules for devices containing compiled 
>> binaries
>> +	 * or libraries as described in input_programs argument above are 
>> not followed
>> +	 */
>> +	compiled_programs[0] = linked_prog;
>> +	test(env->context->cl_ctx,
>> +	     env->context->num_devices, env->context->device_ids,
>> +	     "",
>> +	     2, compiled_programs,
>> +	     NULL, NULL,
>> +	     NULL,
>> +	     CL_INVALID_OPERATION, &result,
>> +	     "Trigger CL_INVALID_OPERATION if the rules for devices 
>> containing compiled binaries or libraries as described in 
>> input_programs argument above are not followed");
>> +
>> +	/*
>> +	 * CL_LINKER_NOT_AVAILABLE if a linker is not available
>> +	 * i.e. CL_DEVICE_LINKER_AVAILABLE specified in the table of allowed 
>> values
>> +	 * for param_name for clGetDeviceInfo is set to CL_FALSE.
>> +	 */
>> +	for(i = 0; i < env->context->num_devices; ++i) {
>> +		cl_bool* linker_available =
>> +			piglit_cl_get_device_info(env->context->device_ids[i],
>> +			                          CL_DEVICE_LINKER_AVAILABLE);
>> +			if(!(*linker_available)) {
>> +				test(env->context->cl_ctx,
>> +				     env->context->num_devices, env->context->device_ids,
>> +				     "",
>> +				     2, compiled_programs,
>> +				     NULL, NULL,
>> +				     NULL,
>> +				     CL_LINKER_NOT_AVAILABLE, &result,
>> +				     "Trigger CL_LINKER_NOT_AVAILABLE if a linker is not 
>> available");
>> +		}
>> +		free(linker_available);
>> +	}
>> +
>> +
>> +/* Release programs */
>> +	clReleaseProgram(function_prog);
>> +	clReleaseProgram(kernel_prog);
>> +	clReleaseProgram(linked_prog);
>> +
>> +	/*
>> +	 * CL_LINK_PROGRAM_FAILURE if there is a failure to link the 
>> compiled binaries
>> +	 * and/or libraries.
>> +	 */
>> +	function_prog = compile_program(env->context->cl_ctx,
>> +	                                env->context->num_devices, 
>> env->context->device_ids,
>> +	                                1, &strings[0],
>> +	                                "2nd function program");
>> +	kernel_prog = compile_program(env->context->cl_ctx,
>> +	                              env->context->num_devices, 
>> env->context->device_ids,
>> +	                              2, &strings[2],
>> +                                 "2nd kernel program");
>> +
>> +	if (!function_prog || !kernel_prog) {
>> +		result = PIGLIT_FAIL;
>> +	} else {
>> +		compiled_programs[0] = function_prog;
>> +		compiled_programs[1] = kernel_prog;
>> +
>> +		test(env->context->cl_ctx,
>> +		     env->context->num_devices, env->context->device_ids,
>> +		     "",
>> +		     2, compiled_programs,
>> +		     NULL, NULL,
>> +		     NULL,
>> +		     CL_LINK_PROGRAM_FAILURE, &result,
>> +		     "Trigger CL_LINK_PROGRAM_FAILURE if there is a failure to link 
>> the compiled binaries and/or libraries");
>> +	}
>> +
>> +/* Release programs */
>> +	clReleaseProgram(function_prog);
>> +	clReleaseProgram(kernel_prog);
>> +
>> +	return result;
>> +#else
>> +	return PIGLIT_SKIP;
>> +#endif
>> +}
>> --
>> 2.2.0
>> 
>> _______________________________________________
>> Piglit mailing list
>> Piglit at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/piglit


More information about the Piglit mailing list