blob: c7a215674c12dd1f2f4660c40f256ca669665e8f [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include "ocl_utilities.h"
/* Return the OpenCL error string for a given error number.
*/
const char *opencl_error_string(cl_int error)
{
int errorCount;
int index;
static const char *errorString[] = {
[CL_SUCCESS] = "CL_SUCCESS",
[-CL_DEVICE_NOT_FOUND] = "CL_DEVICE_NOT_FOUND",
[-CL_DEVICE_NOT_AVAILABLE] = "CL_DEVICE_NOT_AVAILABLE",
[-CL_COMPILER_NOT_AVAILABLE] = "CL_COMPILER_NOT_AVAILABLE",
[-CL_MEM_OBJECT_ALLOCATION_FAILURE] =
"CL_MEM_OBJECT_ALLOCATION_FAILURE",
[-CL_OUT_OF_RESOURCES] = "CL_OUT_OF_RESOURCES",
[-CL_OUT_OF_HOST_MEMORY] = "CL_OUT_OF_HOST_MEMORY",
[-CL_PROFILING_INFO_NOT_AVAILABLE] =
"CL_PROFILING_INFO_NOT_AVAILABLE",
[-CL_MEM_COPY_OVERLAP] = "CL_MEM_COPY_OVERLAP",
[-CL_IMAGE_FORMAT_MISMATCH] = "CL_IMAGE_FORMAT_MISMATCH",
[-CL_IMAGE_FORMAT_NOT_SUPPORTED] =
"CL_IMAGE_FORMAT_NOT_SUPPORTED",
[-CL_BUILD_PROGRAM_FAILURE] = "CL_BUILD_PROGRAM_FAILURE",
[-CL_MAP_FAILURE] = "CL_MAP_FAILURE",
[-CL_INVALID_VALUE] = "CL_INVALID_VALUE",
[-CL_INVALID_DEVICE_TYPE] = "CL_INVALID_DEVICE_TYPE",
[-CL_INVALID_PLATFORM] = "CL_INVALID_PLATFORM",
[-CL_INVALID_DEVICE] = "CL_INVALID_DEVICE",
[-CL_INVALID_CONTEXT] = "CL_INVALID_CONTEXT",
[-CL_INVALID_QUEUE_PROPERTIES] = "CL_INVALID_QUEUE_PROPERTIES",
[-CL_INVALID_COMMAND_QUEUE] = "CL_INVALID_COMMAND_QUEUE",
[-CL_INVALID_HOST_PTR] = "CL_INVALID_HOST_PTR",
[-CL_INVALID_MEM_OBJECT] = "CL_INVALID_MEM_OBJECT",
[-CL_INVALID_IMAGE_FORMAT_DESCRIPTOR] =
"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR",
[-CL_INVALID_IMAGE_SIZE] = "CL_INVALID_IMAGE_SIZE",
[-CL_INVALID_SAMPLER] = "CL_INVALID_SAMPLER",
[-CL_INVALID_BINARY] = "CL_INVALID_BINARY",
[-CL_INVALID_BUILD_OPTIONS] = "CL_INVALID_BUILD_OPTIONS",
[-CL_INVALID_PROGRAM] = "CL_INVALID_PROGRAM",
[-CL_INVALID_PROGRAM_EXECUTABLE] =
"CL_INVALID_PROGRAM_EXECUTABLE",
[-CL_INVALID_KERNEL_NAME] = "CL_INVALID_KERNEL_NAME",
[-CL_INVALID_KERNEL_DEFINITION] =
"CL_INVALID_KERNEL_DEFINITION",
[-CL_INVALID_KERNEL] = "CL_INVALID_KERNEL",
[-CL_INVALID_ARG_INDEX] = "CL_INVALID_ARG_INDEX",
[-CL_INVALID_ARG_VALUE] = "CL_INVALID_ARG_VALUE",
[-CL_INVALID_ARG_SIZE] = "CL_INVALID_ARG_SIZE",
[-CL_INVALID_KERNEL_ARGS] = "CL_INVALID_KERNEL_ARGS",
[-CL_INVALID_WORK_DIMENSION] = "CL_INVALID_WORK_DIMENSION",
[-CL_INVALID_WORK_GROUP_SIZE] = "CL_INVALID_WORK_GROUP_SIZE",
[-CL_INVALID_WORK_ITEM_SIZE] = "CL_INVALID_WORK_ITEM_SIZE",
[-CL_INVALID_GLOBAL_OFFSET] = "CL_INVALID_GLOBAL_OFFSET",
[-CL_INVALID_EVENT_WAIT_LIST] = "CL_INVALID_EVENT_WAIT_LIST",
[-CL_INVALID_EVENT] = "CL_INVALID_EVENT",
[-CL_INVALID_OPERATION] = "CL_INVALID_OPERATION",
[-CL_INVALID_GL_OBJECT] = "CL_INVALID_GL_OBJECT",
[-CL_INVALID_BUFFER_SIZE] = "CL_INVALID_BUFFER_SIZE",
[-CL_INVALID_MIP_LEVEL] = "CL_INVALID_MIP_LEVEL",
[-CL_INVALID_GLOBAL_WORK_SIZE] = "CL_INVALID_GLOBAL_WORK_SIZE",
[-CL_INVALID_PROPERTY] = "CL_INVALID_PROPERTY"
};
errorCount = sizeof(errorString) / sizeof(errorString[0]);
index = -error;
return (index >= 0 && index < errorCount) ?
errorString[index] : "Unspecified Error";
}
/* Find a GPU or a CPU associated with the first available platform.
* If use_gpu is set, then this function first tries to look for a GPU
* in the first available platform.
* If this fails or if use_gpu is not set, then it tries to use the CPU.
*/
cl_device_id opencl_create_device(int use_gpu)
{
cl_platform_id platform;
cl_device_id dev;
int err;
err = clGetPlatformIDs(1, &platform, NULL);
if (err < 0) {
fprintf(stderr, "Error %s while looking for a platform.\n",
opencl_error_string(err));
exit(1);
}
err = CL_DEVICE_NOT_FOUND;
if (use_gpu)
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &dev,
NULL);
if (err == CL_DEVICE_NOT_FOUND)
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &dev,
NULL);
if (err < 0) {
fprintf(stderr, "Error %s while looking for a device.\n",
opencl_error_string(err));
exit(1);
}
return dev;
}
/* Create an OpenCL program from a string and compile it.
*/
cl_program opencl_build_program_from_string(cl_context ctx, cl_device_id dev,
const char *program_source, size_t program_size,
const char *opencl_options)
{
int err;
cl_program program;
char *program_log;
size_t log_size;
program = clCreateProgramWithSource(ctx, 1,
&program_source, &program_size, &err);
if (err < 0) {
fprintf(stderr, "Could not create the program\n");
exit(1);
}
err = clBuildProgram(program, 0, NULL, opencl_options, NULL, NULL);
if (err < 0) {
fprintf(stderr, "Could not build the program.\n");
clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG, 0,
NULL, &log_size);
program_log = (char *) malloc(log_size + 1);
program_log[log_size] = '\0';
clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
log_size + 1, program_log, NULL);
fprintf(stderr, "%s\n", program_log);
free(program_log);
exit(1);
}
return program;
}
/* Create an OpenCL program from a source file and compile it.
*/
cl_program opencl_build_program_from_file(cl_context ctx, cl_device_id dev,
const char* filename, const char* opencl_options)
{
cl_program program;
FILE *program_file;
char *program_source;
size_t program_size, read;
program_file = fopen(filename, "r");
if (program_file == NULL) {
fprintf(stderr, "Could not find the source file.\n");
exit(1);
}
fseek(program_file, 0, SEEK_END);
program_size = ftell(program_file);
rewind(program_file);
program_source = (char *) malloc(program_size + 1);
program_source[program_size] = '\0';
read = fread(program_source, sizeof(char), program_size, program_file);
if (read != program_size) {
fprintf(stderr, "Error while reading the kernel.\n");
exit(1);
}
fclose(program_file);
program = opencl_build_program_from_string(ctx, dev, program_source,
program_size, opencl_options);
free(program_source);
return program;
}