forked from OSchip/llvm-project
175 lines
5.8 KiB
C
175 lines
5.8 KiB
C
#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;
|
|
}
|