gpu: generate host code from schedule tree
[ppcg.git] / ocl_utilities.c
blobc7a215674c12dd1f2f4660c40f256ca669665e8f
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "ocl_utilities.h"
5 /* Return the OpenCL error string for a given error number.
6 */
7 const char *opencl_error_string(cl_int error)
9 int errorCount;
10 int index;
12 static const char *errorString[] = {
13 [CL_SUCCESS] = "CL_SUCCESS",
14 [-CL_DEVICE_NOT_FOUND] = "CL_DEVICE_NOT_FOUND",
15 [-CL_DEVICE_NOT_AVAILABLE] = "CL_DEVICE_NOT_AVAILABLE",
16 [-CL_COMPILER_NOT_AVAILABLE] = "CL_COMPILER_NOT_AVAILABLE",
17 [-CL_MEM_OBJECT_ALLOCATION_FAILURE] =
18 "CL_MEM_OBJECT_ALLOCATION_FAILURE",
19 [-CL_OUT_OF_RESOURCES] = "CL_OUT_OF_RESOURCES",
20 [-CL_OUT_OF_HOST_MEMORY] = "CL_OUT_OF_HOST_MEMORY",
21 [-CL_PROFILING_INFO_NOT_AVAILABLE] =
22 "CL_PROFILING_INFO_NOT_AVAILABLE",
23 [-CL_MEM_COPY_OVERLAP] = "CL_MEM_COPY_OVERLAP",
24 [-CL_IMAGE_FORMAT_MISMATCH] = "CL_IMAGE_FORMAT_MISMATCH",
25 [-CL_IMAGE_FORMAT_NOT_SUPPORTED] =
26 "CL_IMAGE_FORMAT_NOT_SUPPORTED",
27 [-CL_BUILD_PROGRAM_FAILURE] = "CL_BUILD_PROGRAM_FAILURE",
28 [-CL_MAP_FAILURE] = "CL_MAP_FAILURE",
29 [-CL_INVALID_VALUE] = "CL_INVALID_VALUE",
30 [-CL_INVALID_DEVICE_TYPE] = "CL_INVALID_DEVICE_TYPE",
31 [-CL_INVALID_PLATFORM] = "CL_INVALID_PLATFORM",
32 [-CL_INVALID_DEVICE] = "CL_INVALID_DEVICE",
33 [-CL_INVALID_CONTEXT] = "CL_INVALID_CONTEXT",
34 [-CL_INVALID_QUEUE_PROPERTIES] = "CL_INVALID_QUEUE_PROPERTIES",
35 [-CL_INVALID_COMMAND_QUEUE] = "CL_INVALID_COMMAND_QUEUE",
36 [-CL_INVALID_HOST_PTR] = "CL_INVALID_HOST_PTR",
37 [-CL_INVALID_MEM_OBJECT] = "CL_INVALID_MEM_OBJECT",
38 [-CL_INVALID_IMAGE_FORMAT_DESCRIPTOR] =
39 "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
40 [-CL_INVALID_IMAGE_SIZE] = "CL_INVALID_IMAGE_SIZE",
41 [-CL_INVALID_SAMPLER] = "CL_INVALID_SAMPLER",
42 [-CL_INVALID_BINARY] = "CL_INVALID_BINARY",
43 [-CL_INVALID_BUILD_OPTIONS] = "CL_INVALID_BUILD_OPTIONS",
44 [-CL_INVALID_PROGRAM] = "CL_INVALID_PROGRAM",
45 [-CL_INVALID_PROGRAM_EXECUTABLE] =
46 "CL_INVALID_PROGRAM_EXECUTABLE",
47 [-CL_INVALID_KERNEL_NAME] = "CL_INVALID_KERNEL_NAME",
48 [-CL_INVALID_KERNEL_DEFINITION] =
49 "CL_INVALID_KERNEL_DEFINITION",
50 [-CL_INVALID_KERNEL] = "CL_INVALID_KERNEL",
51 [-CL_INVALID_ARG_INDEX] = "CL_INVALID_ARG_INDEX",
52 [-CL_INVALID_ARG_VALUE] = "CL_INVALID_ARG_VALUE",
53 [-CL_INVALID_ARG_SIZE] = "CL_INVALID_ARG_SIZE",
54 [-CL_INVALID_KERNEL_ARGS] = "CL_INVALID_KERNEL_ARGS",
55 [-CL_INVALID_WORK_DIMENSION] = "CL_INVALID_WORK_DIMENSION",
56 [-CL_INVALID_WORK_GROUP_SIZE] = "CL_INVALID_WORK_GROUP_SIZE",
57 [-CL_INVALID_WORK_ITEM_SIZE] = "CL_INVALID_WORK_ITEM_SIZE",
58 [-CL_INVALID_GLOBAL_OFFSET] = "CL_INVALID_GLOBAL_OFFSET",
59 [-CL_INVALID_EVENT_WAIT_LIST] = "CL_INVALID_EVENT_WAIT_LIST",
60 [-CL_INVALID_EVENT] = "CL_INVALID_EVENT",
61 [-CL_INVALID_OPERATION] = "CL_INVALID_OPERATION",
62 [-CL_INVALID_GL_OBJECT] = "CL_INVALID_GL_OBJECT",
63 [-CL_INVALID_BUFFER_SIZE] = "CL_INVALID_BUFFER_SIZE",
64 [-CL_INVALID_MIP_LEVEL] = "CL_INVALID_MIP_LEVEL",
65 [-CL_INVALID_GLOBAL_WORK_SIZE] = "CL_INVALID_GLOBAL_WORK_SIZE",
66 [-CL_INVALID_PROPERTY] = "CL_INVALID_PROPERTY"
69 errorCount = sizeof(errorString) / sizeof(errorString[0]);
70 index = -error;
72 return (index >= 0 && index < errorCount) ?
73 errorString[index] : "Unspecified Error";
76 /* Find a GPU or a CPU associated with the first available platform.
77 * If use_gpu is set, then this function first tries to look for a GPU
78 * in the first available platform.
79 * If this fails or if use_gpu is not set, then it tries to use the CPU.
81 cl_device_id opencl_create_device(int use_gpu)
83 cl_platform_id platform;
84 cl_device_id dev;
85 int err;
87 err = clGetPlatformIDs(1, &platform, NULL);
88 if (err < 0) {
89 fprintf(stderr, "Error %s while looking for a platform.\n",
90 opencl_error_string(err));
91 exit(1);
94 err = CL_DEVICE_NOT_FOUND;
95 if (use_gpu)
96 err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &dev,
97 NULL);
98 if (err == CL_DEVICE_NOT_FOUND)
99 err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &dev,
100 NULL);
101 if (err < 0) {
102 fprintf(stderr, "Error %s while looking for a device.\n",
103 opencl_error_string(err));
104 exit(1);
106 return dev;
109 /* Create an OpenCL program from a string and compile it.
111 cl_program opencl_build_program_from_string(cl_context ctx, cl_device_id dev,
112 const char *program_source, size_t program_size,
113 const char *opencl_options)
115 int err;
116 cl_program program;
117 char *program_log;
118 size_t log_size;
120 program = clCreateProgramWithSource(ctx, 1,
121 &program_source, &program_size, &err);
122 if (err < 0) {
123 fprintf(stderr, "Could not create the program\n");
124 exit(1);
126 err = clBuildProgram(program, 0, NULL, opencl_options, NULL, NULL);
127 if (err < 0) {
128 fprintf(stderr, "Could not build the program.\n");
129 clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG, 0,
130 NULL, &log_size);
131 program_log = (char *) malloc(log_size + 1);
132 program_log[log_size] = '\0';
133 clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
134 log_size + 1, program_log, NULL);
135 fprintf(stderr, "%s\n", program_log);
136 free(program_log);
137 exit(1);
139 return program;
142 /* Create an OpenCL program from a source file and compile it.
144 cl_program opencl_build_program_from_file(cl_context ctx, cl_device_id dev,
145 const char* filename, const char* opencl_options)
147 cl_program program;
148 FILE *program_file;
149 char *program_source;
150 size_t program_size, read;
152 program_file = fopen(filename, "r");
153 if (program_file == NULL) {
154 fprintf(stderr, "Could not find the source file.\n");
155 exit(1);
157 fseek(program_file, 0, SEEK_END);
158 program_size = ftell(program_file);
159 rewind(program_file);
160 program_source = (char *) malloc(program_size + 1);
161 program_source[program_size] = '\0';
162 read = fread(program_source, sizeof(char), program_size, program_file);
163 if (read != program_size) {
164 fprintf(stderr, "Error while reading the kernel.\n");
165 exit(1);
167 fclose(program_file);
169 program = opencl_build_program_from_string(ctx, dev, program_source,
170 program_size, opencl_options);
171 free(program_source);
173 return program;