[Beignet] [PATCH 30/57] Implement all program related API in cl_api_program.c
junyan.he at inbox.com
junyan.he at inbox.com
Sun Jun 11 05:50:16 UTC 2017
From: Junyan He <junyan.he at intel.com>
Signed-off-by: Junyan He <junyan.he at intel.com>
---
runtime/cl_api_program.c | 632 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 632 insertions(+)
create mode 100644 runtime/cl_api_program.c
diff --git a/runtime/cl_api_program.c b/runtime/cl_api_program.c
new file mode 100644
index 0000000..18f48ce
--- /dev/null
+++ b/runtime/cl_api_program.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "cl_alloc.h"
+#include "cl_context.h"
+#include "cl_device_id.h"
+#include "cl_program.h"
+#include <string.h>
+
+cl_int
+clGetProgramInfo(cl_program program,
+ cl_program_info param_name,
+ size_t param_value_size,
+ void *param_value,
+ size_t *param_value_size_ret)
+{
+ const void *src_ptr = NULL;
+ size_t src_size = 0;
+ const char *ret_str = "";
+ cl_int ref;
+ cl_uint num_dev, kernels_num;
+ cl_int i;
+
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ return CL_INVALID_PROGRAM;
+ }
+
+ if (param_name == CL_PROGRAM_REFERENCE_COUNT) {
+ ref = CL_OBJECT_GET_REF(program);
+ src_ptr = &ref;
+ src_size = sizeof(cl_int);
+ } else if (param_name == CL_PROGRAM_CONTEXT) {
+ src_ptr = &program->ctx;
+ src_size = sizeof(cl_context);
+ } else if (param_name == CL_PROGRAM_NUM_DEVICES) {
+ num_dev = program->ctx->device_num;
+ src_ptr = &num_dev;
+ src_size = sizeof(cl_uint);
+ } else if (param_name == CL_PROGRAM_DEVICES) {
+ src_ptr = program->ctx->devices;
+ src_size = program->ctx->device_num * sizeof(cl_device_id);
+ } else if (param_name == CL_PROGRAM_NUM_KERNELS) {
+ cl_int err;
+ kernels_num = 0;
+ err = cl_program_get_kernel_names(program, &kernels_num, 0, NULL, NULL);
+ if (err != CL_SUCCESS)
+ return err;
+
+ src_ptr = &kernels_num;
+ src_size = sizeof(cl_uint);
+ } else if (param_name == CL_PROGRAM_SOURCE) {
+ if (!program->source) {
+ src_ptr = ret_str;
+ src_size = 1;
+ } else {
+ src_ptr = program->source;
+ src_size = strlen(program->source) + 1;
+ }
+ } else if (param_name == CL_PROGRAM_KERNEL_NAMES) {
+ return cl_program_get_kernel_names(program, NULL, param_value_size,
+ (char *)param_value, param_value_size_ret);
+ } else if (param_name == CL_PROGRAM_BINARY_SIZES) {
+ cl_program_for_device pd = NULL;
+ size_t *bin_sz = param_value;
+
+ if (param_value && param_value_size < program->ctx->device_num * sizeof(size_t))
+ return CL_INVALID_VALUE;
+
+ if (param_value_size_ret)
+ *param_value_size_ret = program->ctx->device_num * sizeof(size_t);
+
+ if (param_value) {
+ for (i = 0; i < program->ctx->device_num; i++) {
+ DEV_PRIVATE_DATA(program, program->ctx->devices[i], pd);
+ if (pd->binary == NULL || pd->binary_type == CL_PROGRAM_BINARY_TYPE_NONE) {
+ bin_sz[i] = 0;
+ } else {
+ bin_sz[i] = pd->binary_sz;
+ }
+ }
+ }
+ return CL_SUCCESS;
+ } else if (param_name == CL_PROGRAM_BINARIES) {
+ cl_program_for_device pd = NULL;
+ char **bin_ptr = param_value;
+
+ if (param_value && param_value_size < program->ctx->device_num * sizeof(char *))
+ return CL_INVALID_VALUE;
+
+ if (param_value_size_ret)
+ *param_value_size_ret = program->ctx->device_num * sizeof(char *);
+
+ bin_ptr = param_value;
+ if (param_value) {
+ for (i = 0; i < program->ctx->device_num; i++) {
+ if (bin_ptr[i] == NULL)
+ continue;
+
+ DEV_PRIVATE_DATA(program, program->ctx->devices[i], pd);
+
+ if (pd->binary == NULL || pd->binary_type == CL_PROGRAM_BINARY_TYPE_NONE) {
+ bin_ptr[i][0] = 0;
+ } else {
+ memcpy(bin_ptr[i], pd->binary, pd->binary_sz);
+ }
+ }
+ }
+ return CL_SUCCESS;
+ } else {
+ return CL_INVALID_VALUE;
+ }
+
+ return cl_get_info_helper(src_ptr, src_size,
+ param_value, param_value_size, param_value_size_ret);
+}
+
+cl_int
+clRetainProgram(cl_program program)
+{
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ return CL_INVALID_PROGRAM;
+ }
+
+ cl_program_add_ref(program);
+ return CL_SUCCESS;
+}
+
+cl_int
+clReleaseProgram(cl_program program)
+{
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ return CL_INVALID_PROGRAM;
+ }
+
+ cl_program_delete(program);
+ return CL_SUCCESS;
+}
+
+cl_int
+clGetProgramBuildInfo(cl_program program,
+ cl_device_id device,
+ cl_program_build_info param_name,
+ size_t param_value_size,
+ void *param_value,
+ size_t *param_value_size_ret)
+{
+ const void *src_ptr = NULL;
+ size_t src_size = 0;
+ const char *ret_str = "";
+ cl_int err = CL_SUCCESS;
+ size_t result = 0;
+ cl_program_for_device pd;
+
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ return CL_INVALID_PROGRAM;
+ }
+
+ if (device == NULL)
+ return CL_INVALID_DEVICE;
+
+ err = cl_devices_list_check(1, (const cl_device_id *)&device);
+ if (err != CL_SUCCESS)
+ return err;
+
+ cl_devices_list_include_check(program->ctx->device_num, program->ctx->devices,
+ 1, (const cl_device_id *)&device);
+ if (err != CL_SUCCESS)
+ return err;
+
+ DEV_PRIVATE_DATA(program, device, pd);
+
+ if (param_name == CL_PROGRAM_BUILD_STATUS) {
+ src_ptr = &program->build_status;
+ src_size = sizeof(cl_build_status);
+ } else if (param_name == CL_PROGRAM_BUILD_OPTIONS) {
+ if (program->build_status != CL_BUILD_NONE && program->build_opts) {
+ ret_str = program->build_opts;
+ }
+ src_ptr = ret_str;
+ src_size = strlen(ret_str) + 1;
+ } else if (param_name == CL_PROGRAM_BUILD_LOG) {
+ src_ptr = pd->build_log;
+ src_size = pd->build_log_sz + 1;
+ } else if (param_name == CL_PROGRAM_BINARY_TYPE) {
+ src_ptr = &pd->binary_type;
+ src_size = sizeof(cl_uint);
+ } else if (param_name == CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE) {
+ if (program->build_status != CL_BUILD_NONE) {
+ err = device->api.program_get_info(device, program, param_name, &result);
+ } else {
+ result = 0;
+ }
+
+ if (err != CL_SUCCESS)
+ return result;
+
+ src_ptr = &result;
+ src_size = sizeof(result);
+ } else {
+ return CL_INVALID_VALUE;
+ }
+
+ return cl_get_info_helper(src_ptr, src_size,
+ param_value, param_value_size, param_value_size_ret);
+}
+
+cl_program
+clCreateProgramWithSource(cl_context context,
+ cl_uint count,
+ const char **strings,
+ const size_t *lengths,
+ cl_int *errcode_ret)
+{
+ cl_program program = NULL;
+ cl_int err = CL_SUCCESS;
+ cl_uint i;
+ cl_int *lens = NULL;
+ cl_int len_total = 0;
+ char *p = NULL;
+
+ do {
+ if (!CL_OBJECT_IS_CONTEXT(context)) {
+ err = CL_INVALID_CONTEXT;
+ break;
+ }
+
+ if (count == 0) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+ if (strings == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (strings[i] == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+ }
+ if (err != CL_SUCCESS)
+ break;
+
+ program = cl_program_new(context);
+ if (program == NULL) {
+ err = CL_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ lens = CL_CALLOC(count, sizeof(cl_int));
+ if (lens == NULL) {
+ err = CL_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ for (i = 0; i < (cl_int)count; ++i) {
+ size_t len;
+ if (lengths == NULL || lengths[i] == 0)
+ len = strlen(strings[i]);
+ else
+ len = lengths[i];
+ lens[i] = len;
+ len_total += len;
+ }
+
+ program->source = CL_CALLOC(len_total + 1, sizeof(char));
+ if (program->source == NULL) {
+ err = CL_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ p = program->source;
+ for (i = 0; i < (cl_int)count; ++i) {
+ memcpy(p, strings[i], lens[i]);
+ p += lens[i];
+ }
+ *p = '\0';
+
+ program->source_sz = len_total + 1;
+ } while (0);
+
+ if (err != CL_SUCCESS) {
+ if (program)
+ cl_program_delete(program);
+ }
+
+ CL_FREE(lens);
+
+ if (errcode_ret)
+ *errcode_ret = err;
+ return program;
+}
+
+cl_program
+clCreateProgramWithBinary(cl_context context,
+ cl_uint num_devices,
+ const cl_device_id *devices,
+ const size_t *lengths,
+ const unsigned char **binaries,
+ cl_int *binary_status,
+ cl_int *errcode_ret)
+{
+ cl_program program = NULL;
+ cl_int err = CL_SUCCESS;
+ cl_int i;
+
+ do {
+ if (!CL_OBJECT_IS_CONTEXT(context)) {
+ err = CL_INVALID_CONTEXT;
+ break;
+ }
+
+ if (devices == NULL || num_devices == 0) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ err = cl_devices_list_check(num_devices, devices);
+ if (err != CL_SUCCESS)
+ break;
+
+ err = cl_devices_list_include_check(context->device_num, context->devices, num_devices, devices);
+ if (err != CL_SUCCESS)
+ break;
+
+ if (binaries == NULL || lengths == NULL) {
+ if (binary_status) {
+ for (i = 0; i < num_devices; i++)
+ binary_status[i] = CL_INVALID_VALUE;
+ }
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ for (i = 0; i < num_devices; i++) {
+ if (binaries[i] == NULL || lengths[i] == 0) {
+ if (binary_status)
+ binary_status[i] = CL_INVALID_VALUE;
+
+ err = CL_INVALID_VALUE;
+ } else {
+ if (binary_status)
+ binary_status[i] = CL_SUCCESS;
+ }
+ }
+ if (err != CL_SUCCESS)
+ break;
+
+ program = cl_program_create_from_binary(context, num_devices, devices, lengths,
+ binaries, binary_status, &err);
+ } while (0);
+
+ if (errcode_ret)
+ *errcode_ret = err;
+ return program;
+}
+
+cl_int
+clBuildProgram(cl_program program,
+ cl_uint num_devices,
+ const cl_device_id *device_list,
+ const char *options,
+ void(CL_CALLBACK *pfn_notify)(cl_program, void *),
+ void *user_data)
+{
+ cl_int err = CL_SUCCESS;
+
+ do {
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ err = CL_INVALID_PROGRAM;
+ break;
+ }
+
+ if ((num_devices == 0 && device_list != NULL) ||
+ (num_devices != 0 && device_list == NULL)) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (pfn_notify == NULL && user_data != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (device_list) {
+ err = cl_devices_list_check(num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+ }
+
+ if (device_list) {
+ assert(program->ctx);
+ err = cl_devices_list_check(num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ err = cl_devices_list_include_check(program->ctx->device_num,
+ program->ctx->devices, num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+ }
+
+ err = cl_program_build(program, options, num_devices, device_list);
+ } while (0);
+
+ if (pfn_notify)
+ pfn_notify(program, user_data);
+
+ return err;
+}
+
+cl_int
+clCompileProgram(cl_program program,
+ cl_uint num_devices,
+ const cl_device_id *device_list,
+ const char *options,
+ cl_uint num_input_headers,
+ const cl_program *input_headers,
+ const char **header_include_names,
+ void(CL_CALLBACK *pfn_notify)(cl_program, void *),
+ void *user_data)
+{
+ cl_int err = CL_SUCCESS;
+
+ do {
+ if (!CL_OBJECT_IS_PROGRAM(program)) {
+ err = CL_INVALID_PROGRAM;
+ break;
+ }
+
+ if (num_devices == 0 && device_list != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (num_devices != 0 && device_list == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (pfn_notify == 0 && user_data != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (num_input_headers == 0 && input_headers != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (num_input_headers != 0 && input_headers == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (device_list) {
+ assert(program->ctx);
+ err = cl_devices_list_check(num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ err = cl_devices_list_include_check(program->ctx->device_num,
+ program->ctx->devices, num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+ }
+
+ err = cl_program_compile(program, num_input_headers, input_headers,
+ header_include_names, options, num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ } while (0);
+
+ if (pfn_notify)
+ pfn_notify(program, user_data);
+ return err;
+}
+
+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)
+{
+ cl_int err = CL_SUCCESS;
+ cl_program program = NULL;
+ cl_uint i = 0;
+
+ do {
+ if (!CL_OBJECT_IS_CONTEXT(context)) {
+ err = CL_INVALID_CONTEXT;
+ break;
+ }
+
+ if (pfn_notify == 0 && user_data != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (num_input_programs == 0 && input_programs != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+ if (num_input_programs != 0 && input_programs == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+ if (num_input_programs == 0 && input_programs == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (num_devices == 0 && device_list != NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+ if (num_devices != 0 && device_list == NULL) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ if (device_list) {
+ err = cl_devices_list_check(num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ err = cl_devices_list_include_check(context->device_num,
+ context->devices, num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+ }
+
+ for (i = 0; i < num_input_programs; i++) {
+ if (!CL_OBJECT_IS_PROGRAM(input_programs[i])) {
+ err = CL_INVALID_PROGRAM;
+ break;
+ }
+ }
+ if (err != CL_SUCCESS)
+ break;
+
+ program = cl_program_link(context, num_devices, device_list,
+ num_input_programs, input_programs, options, &err);
+
+ } while (0);
+
+ if (pfn_notify)
+ pfn_notify(program, user_data);
+
+ if (errcode_ret)
+ *errcode_ret = err;
+ return program;
+}
+
+cl_int
+clCreateKernelsInProgram(cl_program program,
+ cl_uint num_kernels,
+ cl_kernel *kernels,
+ cl_uint *num_kernels_ret)
+{
+ cl_int err = CL_SUCCESS;
+
+ if (!CL_OBJECT_IS_PROGRAM(program))
+ return CL_INVALID_PROGRAM;
+
+ if (kernels == NULL && num_kernels_ret == 0)
+ return CL_INVALID_VALUE;
+
+ err = cl_program_create_kernels_in_program(program, num_kernels, kernels, num_kernels_ret);
+
+ return err;
+}
+
+cl_program
+clCreateProgramWithBuiltInKernels(cl_context context,
+ cl_uint num_devices,
+ const cl_device_id *device_list,
+ const char *kernel_names,
+ cl_int *errcode_ret)
+{
+ cl_program program = NULL;
+ cl_int err = CL_SUCCESS;
+
+ do {
+ if (!CL_OBJECT_IS_CONTEXT(context)) {
+ err = CL_INVALID_CONTEXT;
+ break;
+ }
+
+ if (kernel_names == NULL || kernel_names[0] == 0) {
+ err = CL_INVALID_VALUE;
+ break;
+ }
+
+ err = cl_devices_list_check(num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ err = cl_devices_list_include_check(context->device_num,
+ context->devices, num_devices, device_list);
+ if (err != CL_SUCCESS)
+ break;
+
+ program = cl_program_create_with_built_in_kernles(context, num_devices, device_list,
+ kernel_names, &err);
+ } while (0);
+
+ if (errcode_ret)
+ *errcode_ret = err;
+ return program;
+}
--
2.7.4
More information about the Beignet
mailing list