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