diff options
author | EdB <edb+piglit@sigluy.net> | 2015-07-28 17:33:15 +0200 |
---|---|---|
committer | Timothy Arceri <t_arceri@yahoo.com.au> | 2015-08-01 00:04:50 +1000 |
commit | 1613114272d43bf6016ed8e3ac57a460c5928a14 (patch) | |
tree | ff1b1dc780d08207c2426fd559edc58a65e5979d /tests/cl | |
parent | 573689194cbcc66632d7a1a5c6e0951501c01123 (diff) |
cl: add clLinkProgram test
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@amd.com>
Diffstat (limited to 'tests/cl')
-rw-r--r-- | tests/cl/api/CMakeLists.cl.txt | 1 | ||||
-rw-r--r-- | tests/cl/api/link-program.c | 394 |
2 files changed, 395 insertions, 0 deletions
diff --git a/tests/cl/api/CMakeLists.cl.txt b/tests/cl/api/CMakeLists.cl.txt index 7e7849138..b59852878 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 000000000..e98f42810 --- /dev/null +++ b/tests/cl/api/link-program.c @@ -0,0 +1,394 @@ +/* + * Copyright © 2014 EdB <edb+piglit@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 +} |