[Piglit] [PATCH] cl: add clLinkProgram test
Timothy Arceri
t_arceri at yahoo.com.au
Fri Jul 31 07:07:33 PDT 2015
On Tue, 2015-07-28 at 17:33 +0200, 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.
>
> v3:
> Add to cl.py
>
> Reviewed-by: Tom Stellard <thomas.stellard at amd.com>
> ---
> Please note that clLinkProgram is not available in Mesa yet
> so it could wait a bit before been pushed
Since its already reviewed doesn't seem any reason to hold it up.
I've pushed this for you.
>
> tests/cl.py | 1 +
> tests/cl/api/CMakeLists.cl.txt | 1 +
> tests/cl/api/link-program.c | 394
> +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 396 insertions(+)
> create mode 100644 tests/cl/api/link-program.c
>
> diff --git a/tests/cl.py b/tests/cl.py
> index c55d3dd..4668ddc 100644
> --- a/tests/cl.py
> +++ b/tests/cl.py
> @@ -67,6 +67,7 @@ with profile.group_manager(PiglitCLTest, 'api') as g:
> g(['cl-api-create-program-with-source'], 'clCreateProgramWithSource')
> g(['cl-api-build-program'], 'clBuildProgram')
> g(['cl-api-compile-program'], 'clCompileProgram')
> + g(['cl-api-link-program'], 'clLinkProgram')
> g(['cl-api-get-program-info'], 'clGetProgramInfo')
> g(['cl-api-get-program-build-info'], 'clGetProgramBuildInfo')
> g(['cl-api-retain_release-program'],
> 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
> +}
More information about the Piglit
mailing list