diff options
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | clSimple.txt | 17 | ||||
-rw-r--r-- | cl_simple.c | 306 | ||||
-rw-r--r-- | cl_simple.h | 27 | ||||
-rw-r--r-- | get_global_id.c | 12 | ||||
-rw-r--r-- | get_global_id_2d.c | 7 | ||||
-rw-r--r-- | hello_world.c | 22 | ||||
-rw-r--r-- | loop.c | 7 | ||||
-rw-r--r-- | math-int.c | 20 | ||||
-rw-r--r-- | util.c | 292 | ||||
-rw-r--r-- | util.h | 27 |
11 files changed, 404 insertions, 357 deletions
@@ -1,18 +1,22 @@ CFLAGS=-g +COMMON_OBJECTS = cl_simple.o util.o +LDFLAGS = -L/usr/local/lib -lOpenCL + + all: hello_world math-int get-global-id get-global-id-2d loop -hello_world: hello_world.o util.o - gcc -o hello_world $^ -L/usr/local/lib/ -lOpenCL +hello_world: hello_world.o $(COMMON_OBJECTS) + gcc -o $@ $^ $(LDFLAGS) -math-int: math-int.o util.o - gcc -o math-int $^ -L/usr/local/lib/ -lOpenCL +math-int: math-int.o $(COMMON_OBJECTS) + gcc -o $@ $^ $(LDFLAGS) -get-global-id: get_global_id.o util.o - gcc -o get-global-id $^ -L/usr/local/lib/ -lOpenCL +get-global-id: get_global_id.o $(COMMON_OBJECTS) + gcc -o $@ $^ $(LDFLAGS) -get-global-id-2d: get_global_id_2d.o util.o - gcc -o $@ $^ -L/usr/local/lib/ -lOpenCL +get-global-id-2d: get_global_id_2d.o $(COMMON_OBJECTS) + gcc -o $@ $^ $(LDFLAGS) -loop: loop.o util.o - gcc -o $@ $^ -L/usr/local/lib/ -lOpenCL +loop: loop.o $(COMMON_OBJECTS) + gcc -o $@ $^ $(LDFLAGS) diff --git a/clSimple.txt b/clSimple.txt new file mode 100644 index 0000000..98f118b --- /dev/null +++ b/clSimple.txt @@ -0,0 +1,17 @@ +clSimple is set of wrappers around the OpenCL API that make writing simple +OpenCL programs easier. clSimple consists of two different types of functions: + ++ Direct wrappers: + These functions map directly to an OpenCL API call and will always have the + same name as an OpenCL API call except with the 'cl' prefix replaced by + 'clSimple'. These functions take a subset of the arguments that the wrapped + OpenCL function would take. + ++ Convenience wrappers: + These functions wrap around multiple clSimple calls and always take + struct cl_simple_context as their first argument. + +It is easy to mix clSimple and OpenCL API calls in the same program, so if you +want more functionality than the clSimple wrappers provided, you can always +replace one of the direct wrappers its wrapped OpenCL function. + diff --git a/cl_simple.c b/cl_simple.c new file mode 100644 index 0000000..82572ef --- /dev/null +++ b/cl_simple.c @@ -0,0 +1,306 @@ +#include <CL/cl.h> + +#include <fcntl.h> +#include <stdio.h> +#include <string.h> + +#include "cl_simple.h" +#include "util.h" + +/*============================================================================*/ +/*========== DIRECT WRAPPERS =================================================*/ +/*============================================================================*/ + +unsigned clSimpleCreateContext(cl_context * context, cl_device_id device_id) +{ + cl_int error; + *context = clCreateContext(NULL, /* Properties */ + 1, /* Number of devices */ + &device_id, /* Device pointer */ + NULL, /* Callback for reporting errors */ + NULL, /* User data to pass to error callback */ + &error); /* Error code */ + + if (error != CL_SUCCESS) { + fprintf(stderr, "clCreateContext() failed: %s\n", + clCheckErrorString(error)); + return 0; + } + return 1; +} + +unsigned clSimpleCreateCommandQueue(cl_command_queue * command_queue, + cl_context context, cl_device_id device_id) +{ + cl_int error; + *command_queue = clCreateCommandQueue(context, + device_id, + 0, /* Command queue properties */ + &error); /* Error code */ + + if (error != CL_SUCCESS) { + fprintf(stderr, "clCreateCommandQueue() failed: %s\n", + clCheckErrorString(error)); + return 0; + } + return 1; +} + +unsigned clSimpleKernelSetArg(cl_kernel kernel, cl_uint index, size_t size, + const void * value) +{ + cl_int error; + + error = clSetKernelArg(kernel, index, size, value); + + if (error != CL_SUCCESS) { + fprintf(stderr, "clSetKernelArg failed: %s\n", clCheckErrorString(error)); + return 0; + } + + fprintf(stderr, "clSetKernelArg() succeeded.\n"); + + return 1; +} + +unsigned clSimpleEnqueueNDRangeKernel(cl_command_queue command_queue, + cl_kernel kernel, cl_uint work_dim, const size_t * global_work_size, + const size_t * local_work_size) +{ + cl_int error = clEnqueueNDRangeKernel(command_queue, + kernel, + work_dim, /* Number of dimensions */ + NULL, /* Global work offset */ + global_work_size, + local_work_size, /* local work size */ + 0, /* Events in wait list */ + NULL, /* Wait list */ + NULL); /* Event object for this event */ + if (error != CL_SUCCESS) { + fprintf(stderr, "clEnqueueNDRangeKernel() failed: %s\n", + clCheckErrorString(error)); + return 0; + } + + return 1; +} + +/*============================================================================*/ +/*========== CONVENIENCE WRAPPERS=============================================*/ +/*============================================================================*/ + +unsigned clSimpleInitGpuDevice(cl_device_id * device_id) +{ + cl_int error; + + cl_uint total_platforms; + cl_platform_id platform_id; + + cl_uint total_gpu_devices; + + error = clGetPlatformIDs( + 1, /* Max number of platform IDs to return */ + &platform_id, /* Pointer to platform_id */ + &total_platforms); /* Total number of platforms + * found on the system */ + + if (error != CL_SUCCESS) { + fprintf(stderr, "clGetPlatformIDs() failed: %s\n", clCheckErrorString(error)); + return 0; + } + + fprintf(stderr, "There are %u platforms.\n", total_platforms); + + error = clGetDeviceIDs(platform_id, + CL_DEVICE_TYPE_GPU, + 1, + device_id, + &total_gpu_devices); + + if (error != CL_SUCCESS) { + fprintf(stderr, "clGetDeviceIDs() failed: %s\n", clCheckErrorString(error)); + return 0; + } + + fprintf(stderr, "There are %u GPU devices.\n", total_gpu_devices); + + return 1; +} + +#define CODE_CHUNK 64 + +unsigned clSimpleCreateKernel(cl_context context, cl_device_id device_id, + cl_kernel * kernel, const char * kernel_name) +{ + char * filename; + char * code = NULL; + size_t code_len = 0; + int fd; + int bytes_read; + + /* +3 .cl + * +1 NULL byte + * -- + * +4 + */ + unsigned filename_len = strlen(kernel_name) + 4; + + cl_int error; + cl_program program; + + /* Determine file name */ + filename = malloc (filename_len + 4); + if (!filename) { + fprintf(stderr, "Failed to malloc filename.\n"); + return 0; + } + + snprintf(filename, filename_len, "%s.cl", kernel_name); + + /* Open file */ + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Failed to open file: %s\n", filename); + return 0; + } + + /* Read code */ + do { + code = realloc(code, (code_len + CODE_CHUNK) * sizeof(unsigned char)); + if (!code) { + fprintf(stderr, "Failed to realloc code.\n"); + return 0; + } + + bytes_read = read(fd, code + code_len, CODE_CHUNK); + if (bytes_read < 0) { + fprintf(stderr, "Failed to read code.\n"); + return 0; + } + code_len += bytes_read; + } while(bytes_read == CODE_CHUNK); + + /* Create program */ + program = clCreateProgramWithSource(context, + 1, /* Number of strings */ + &code, + &code_len, /* String lengths, 0 means all the + * strings are NULL terminated. */ + &error); + + if (error != CL_SUCCESS) { + fprintf(stderr, "clCreateProgramWithSource() failed: %s\n", + clCheckErrorString(error)); + return 0; + } + + fprintf(stderr, "clCreateProgramWithSource() suceeded.\n"); + + /* Build program */ + error = clBuildProgram(program, + 1, /* Number of devices */ + &device_id, + NULL, /* options */ + NULL, /* callback function when compile is complete */ + NULL); /* user data for callback */ + + + if (error != CL_SUCCESS) { + char build_str[10000]; + error = clGetProgramBuildInfo(program, + device_id, + CL_PROGRAM_BUILD_LOG, + 10000, /* Size of output string */ + build_str, /* pointer to write the log to */ + NULL); /* Number of bytes written to the log */ + if (error != CL_SUCCESS) { + fprintf(stderr, "clGetProgramBuildInfo() failed: %s\n", + clCheckErrorString(error)); + } else { + fprintf(stderr, "Build Log: \n%s\n\n", build_str); + } + return 0; + } + + fprintf(stderr, "clBuildProgram() suceeded.\n"); + + *kernel = clCreateKernel(program, kernel_name, &error); + + if (error != CL_SUCCESS) { + fprintf(stderr, "clCreateKernel() failed: %s\n", clCheckErrorString(error)); + return 0; + } + + fprintf(stderr, "clCreateKernel() suceeded.\n"); + + return 1; +} + +unsigned clSimpleSimpleInit(struct cl_simple_context * context, const char * kernel_name) +{ + if (!clSimpleInitGpuDevice(&context->device_id)) { + return 0; + } + + if (!clSimpleCreateContext(&context->cl_ctx, context->device_id)) { + return 0; + } + + if (!clSimpleCreateCommandQueue(&context->command_queue, context->cl_ctx, + context->device_id)) { + return 0; + } + + if (!clSimpleCreateKernel(context->cl_ctx, context->device_id, &context->kernel, + kernel_name)) { + return 0; + } + + return 1; +} + +unsigned clSimpleSetOutputBuffer(struct cl_simple_context * context, + unsigned buffer_size) +{ + cl_int error; + + context->out_buffer = clCreateBuffer(context->cl_ctx, + CL_MEM_WRITE_ONLY, /* Flags */ + buffer_size, /* Size of buffer */ + NULL, /* Pointer to the data */ + &error); /* error code */ + + if (error != CL_SUCCESS) { + fprintf(stderr, "clCreateBuffer() failed: %s\n", clCheckErrorString(error)); + return 0; + } + + if (!clSimpleKernelSetArg(context->kernel, 0, sizeof(cl_mem), + &context->out_buffer)) { + return 0; + } + + return 1; +} + +unsigned clSimpleReadOutput(struct cl_simple_context * context, void * data, + size_t data_bytes) +{ + cl_int error = clEnqueueReadBuffer(context->command_queue, + context->out_buffer, + CL_TRUE, /* TRUE means it is a blocking read. */ + 0, /* Buffer offset to read from. */ + data_bytes, /* Bytes to read */ + data, /* Pointer to store the data */ + 0, /* Events in wait list */ + NULL, /* Wait list */ + NULL); /* Event object */ + + if (error != CL_SUCCESS) { + fprintf(stderr, "clEnqueueReadBuffer() failed: %s\n", + clCheckErrorString(error)); + return 0; + } + + return 1; +} diff --git a/cl_simple.h b/cl_simple.h new file mode 100644 index 0000000..44a8b16 --- /dev/null +++ b/cl_simple.h @@ -0,0 +1,27 @@ + +struct cl_simple_context { + cl_device_id device_id; + cl_context cl_ctx; + cl_command_queue command_queue; + cl_mem out_buffer; + cl_kernel kernel; +}; + +unsigned clSimpleCreateContext(cl_context * context, cl_device_id device_id); +unsigned clSimpleCreateCommandQueue(cl_command_queue * command_queue, + cl_context context, cl_device_id device_id); +unsigned clSimpleKernelSetArg(cl_kernel kernel, cl_uint index, size_t size, + const void * value); +unsigned clSimpleEnqueueNDRangeKernel(cl_command_queue command_queue, + cl_kernel kernel, cl_uint work_dim, const size_t * global_work_size, + const size_t * local_work_size); + +unsigned clSimpleInitGpuDevice(cl_device_id * device_id); +unsigned clSimpleCreateKernel(cl_context context, cl_device_id device_id, + cl_kernel * kernel, const char * kernel_name); +unsigned clSimpleSimpleInit(struct cl_simple_context * context, + const char * kernel_name); +unsigned clSimpleSetOutputBuffer(struct cl_simple_context * context, + unsigned buffer_size); +unsigned clSimpleReadOutput(struct cl_simple_context * context, void * data, + size_t data_bytes); diff --git a/get_global_id.c b/get_global_id.c index 84e6fb9..f9a5170 100644 --- a/get_global_id.c +++ b/get_global_id.c @@ -3,27 +3,27 @@ #include <CL/cl.h> -#include "util.h" +#include "cl_simple.h" int main(int argc, char ** argv) { cl_int error; - struct cltest_context context; + struct cl_simple_context context; unsigned i; int out_data[10]; size_t global_work_size = 10; - clTestSimpleInit(&context, "global_id"); + clSimpleSimpleInit(&context, "global_id"); - clTestSetOutputBuffer(&context, sizeof(out_data)); + clSimpleSetOutputBuffer(&context, sizeof(out_data)); - clTestEnqueueNDRangeKernel(context.command_queue, + clSimpleEnqueueNDRangeKernel(context.command_queue, context.kernel, 1, &global_work_size, &global_work_size); - clTestReadOutput(&context, out_data, sizeof(out_data)); + clSimpleReadOutput(&context, out_data, sizeof(out_data)); for (i = 0; i < 10; i++) { diff --git a/get_global_id_2d.c b/get_global_id_2d.c index f256b71..50b7db2 100644 --- a/get_global_id_2d.c +++ b/get_global_id_2d.c @@ -4,6 +4,7 @@ #include <CL/cl.h> +#include "cl_simple.h" #include "util.h" #define GLOBAL_DIM_X 10 @@ -19,9 +20,9 @@ int main (int argc, char ** argv) size_t global_work_size[2] = {GLOBAL_DIM_X, GLOBAL_DIM_Y}; size_t local_work_size[2] = {5, 5}; - struct cltest_context context; + struct cl_simple_context context; - clTestSimpleInit(&context, "global_id2d"); + clSimpleSimpleInit(&context, "global_id2d"); /* XXX: Delete this to see a missing error path */ out_buffer = clCreateBuffer(context.cl_ctx, @@ -31,7 +32,7 @@ int main (int argc, char ** argv) assert(error == CL_SUCCESS); - if (!clTestKernelSetArg(context.kernel, 0, sizeof(cl_mem), &out_buffer)) { + if (!clSimpleKernelSetArg(context.kernel, 0, sizeof(cl_mem), &out_buffer)) { return EXIT_FAILURE; } diff --git a/hello_world.c b/hello_world.c index 1daf653..c6247b6 100644 --- a/hello_world.c +++ b/hello_world.c @@ -42,7 +42,7 @@ int main(int argc, char ** argv) * found on the system */ if (error != CL_SUCCESS) { - fprintf(stderr, "clGetPlatformIDs() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clGetPlatformIDs() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -57,7 +57,7 @@ int main(int argc, char ** argv) &total_gpu_devices); if (error != CL_SUCCESS) { - fprintf(stderr, "clGetDeviceIDs() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clGetDeviceIDs() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -71,7 +71,7 @@ int main(int argc, char ** argv) &error); /* Error code */ if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateContext() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clCreateContext() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -84,7 +84,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clCreateCommandQueue() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -99,7 +99,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clCreateProgramWithSource() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -123,7 +123,7 @@ int main(int argc, char ** argv) NULL); /* Number of bytes written to the log */ if (error != CL_SUCCESS) { fprintf(stderr, "clGetProgramBuildInfo() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); } else { fprintf(stderr, "Build Log: \n%s\n\n", build_str); } @@ -135,7 +135,7 @@ int main(int argc, char ** argv) kernel = clCreateKernel(program, "pi", &error); if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateKernel() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clCreateKernel() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -148,7 +148,7 @@ int main(int argc, char ** argv) &error); /* error code */ if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateBuffer() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clCreateBuffer() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -160,7 +160,7 @@ int main(int argc, char ** argv) &out_buffer); if (error != CL_SUCCESS) { - fprintf(stderr, "clSetKernelArg failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clSetKernelArg failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -179,7 +179,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueNDRangeKernel() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -198,7 +198,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueReadBuffer() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -4,13 +4,14 @@ #include <CL/cl.h> +#include "cl_simple.h" #include "util.h" int main (int argc, char ** argv) { int i,j; - struct cltest_context context; + struct cl_simple_context context; cl_int error; @@ -18,7 +19,7 @@ int main (int argc, char ** argv) int out_data[100]; size_t global_work_size = 10; - if (!clTestSimpleInit(&context, "loop")) { + if (!clSimpleSimpleInit(&context, "loop")) { return EXIT_FAILURE; } @@ -29,7 +30,7 @@ int main (int argc, char ** argv) assert(error == CL_SUCCESS); - if (!clTestKernelSetArg(context.kernel, 0, sizeof(cl_mem), &out_buffer)) { + if (!clSimpleKernelSetArg(context.kernel, 0, sizeof(cl_mem), &out_buffer)) { return EXIT_FAILURE; } @@ -26,7 +26,7 @@ int main(int argc, char ** argv) arg1 = atoi(argv[3]); expected = atoi(argv[4]); - if (!clTestInitGpuDevice(&device_id)) { + if (!clSimpleInitGpuDevice(&device_id)) { return EXIT_FAILURE; } @@ -38,7 +38,7 @@ int main(int argc, char ** argv) &error); /* Error code */ if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateContext() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clCreateContext() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } @@ -51,13 +51,13 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clCreateCommandQueue() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateCommandQueue() succeeded.\n"); - if (!clTestCreateKernel(context, device_id, &kernel, kernel_name)) { + if (!clSimpleCreateKernel(context, device_id, &kernel, kernel_name)) { return EXIT_FAILURE; } @@ -68,15 +68,15 @@ int main(int argc, char ** argv) &error); /* error code */ if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateBuffer() failed: %s\n", clTestErrorString(error)); + fprintf(stderr, "clCreateBuffer() failed: %s\n", clCheckErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateBuffer() succeeded.\n"); - if ( !clTestKernelSetArg(kernel, 0, sizeof(cl_mem), &out_buffer) - || !clTestKernelSetArg(kernel, 1, sizeof(int), &arg0) - || !clTestKernelSetArg(kernel, 2, sizeof(int), &arg1)) { + if ( !clSimpleKernelSetArg(kernel, 0, sizeof(cl_mem), &out_buffer) + || !clSimpleKernelSetArg(kernel, 1, sizeof(int), &arg0) + || !clSimpleKernelSetArg(kernel, 2, sizeof(int), &arg1)) { return EXIT_FAILURE; } @@ -92,7 +92,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueNDRangeKernel() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -111,7 +111,7 @@ int main(int argc, char ** argv) if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueReadBuffer() failed: %s\n", - clTestErrorString(error)); + clCheckErrorString(error)); return EXIT_FAILURE; } @@ -8,7 +8,7 @@ #define CASE_ERR(ec) case ec: return #ec; -const char * clTestErrorString(cl_int error) +const char * clCheckErrorString(cl_int error) { switch(error) { @@ -49,293 +49,3 @@ const char * clTestErrorString(cl_int error) } } - -unsigned clTestInitGpuDevice(cl_device_id * device_id) -{ - cl_int error; - - cl_uint total_platforms; - cl_platform_id platform_id; - - cl_uint total_gpu_devices; - - error = clGetPlatformIDs( - 1, /* Max number of platform IDs to return */ - &platform_id, /* Pointer to platform_id */ - &total_platforms); /* Total number of platforms - * found on the system */ - - if (error != CL_SUCCESS) { - fprintf(stderr, "clGetPlatformIDs() failed: %s\n", clTestErrorString(error)); - return 0; - } - - fprintf(stderr, "There are %u platforms.\n", total_platforms); - - error = clGetDeviceIDs(platform_id, - CL_DEVICE_TYPE_GPU, - 1, - device_id, - &total_gpu_devices); - - if (error != CL_SUCCESS) { - fprintf(stderr, "clGetDeviceIDs() failed: %s\n", clTestErrorString(error)); - return 0; - } - - fprintf(stderr, "There are %u GPU devices.\n", total_gpu_devices); - - return 1; -} - -unsigned clTestCreateContext(cl_context * context, cl_device_id device_id) -{ - cl_int error; - *context = clCreateContext(NULL, /* Properties */ - 1, /* Number of devices */ - &device_id, /* Device pointer */ - NULL, /* Callback for reporting errors */ - NULL, /* User data to pass to error callback */ - &error); /* Error code */ - - if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateContext() failed: %s\n", - clTestErrorString(error)); - return 0; - } - return 1; -} - -unsigned clTestCreateCommandQueue(cl_command_queue * command_queue, - cl_context context, cl_device_id device_id) -{ - cl_int error; - *command_queue = clCreateCommandQueue(context, - device_id, - 0, /* Command queue properties */ - &error); /* Error code */ - - if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateCommandQueue() failed: %s\n", - clTestErrorString(error)); - return 0; - } - return 1; -} - -#define CODE_CHUNK 64 - -unsigned clTestCreateKernel(cl_context context, cl_device_id device_id, - cl_kernel * kernel, const char * kernel_name) -{ - char * filename; - char * code = NULL; - size_t code_len = 0; - int fd; - int bytes_read; - - /* +3 .cl - * +1 NULL byte - * -- - * +4 - */ - unsigned filename_len = strlen(kernel_name) + 4; - - cl_int error; - cl_program program; - - /* Determine file name */ - filename = malloc (filename_len + 4); - if (!filename) { - fprintf(stderr, "Failed to malloc filename.\n"); - return 0; - } - - snprintf(filename, filename_len, "%s.cl", kernel_name); - - /* Open file */ - fd = open(filename, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Failed to open file: %s\n", filename); - return 0; - } - - /* Read code */ - do { - code = realloc(code, (code_len + CODE_CHUNK) * sizeof(unsigned char)); - if (!code) { - fprintf(stderr, "Failed to realloc code.\n"); - return 0; - } - - bytes_read = read(fd, code + code_len, CODE_CHUNK); - if (bytes_read < 0) { - fprintf(stderr, "Failed to read code.\n"); - return 0; - } - code_len += bytes_read; - } while(bytes_read == CODE_CHUNK); - - /* Create program */ - program = clCreateProgramWithSource(context, - 1, /* Number of strings */ - &code, - &code_len, /* String lengths, 0 means all the - * strings are NULL terminated. */ - &error); - - if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateProgramWithSource() failed: %s\n", - clTestErrorString(error)); - return 0; - } - - fprintf(stderr, "clCreateProgramWithSource() suceeded.\n"); - - /* Build program */ - error = clBuildProgram(program, - 1, /* Number of devices */ - &device_id, - NULL, /* options */ - NULL, /* callback function when compile is complete */ - NULL); /* user data for callback */ - - - if (error != CL_SUCCESS) { - char build_str[10000]; - error = clGetProgramBuildInfo(program, - device_id, - CL_PROGRAM_BUILD_LOG, - 10000, /* Size of output string */ - build_str, /* pointer to write the log to */ - NULL); /* Number of bytes written to the log */ - if (error != CL_SUCCESS) { - fprintf(stderr, "clGetProgramBuildInfo() failed: %s\n", - clTestErrorString(error)); - } else { - fprintf(stderr, "Build Log: \n%s\n\n", build_str); - } - return 0; - } - - fprintf(stderr, "clBuildProgram() suceeded.\n"); - - *kernel = clCreateKernel(program, kernel_name, &error); - - if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateKernel() failed: %s\n", clTestErrorString(error)); - return 0; - } - - fprintf(stderr, "clCreateKernel() suceeded.\n"); - - return 1; -} - -unsigned clTestSimpleInit(struct cltest_context * context, const char * kernel_name) -{ - if (!clTestInitGpuDevice(&context->device_id)) { - return 0; - } - - if (!clTestCreateContext(&context->cl_ctx, context->device_id)) { - return 0; - } - - if (!clTestCreateCommandQueue(&context->command_queue, context->cl_ctx, - context->device_id)) { - return 0; - } - - if (!clTestCreateKernel(context->cl_ctx, context->device_id, &context->kernel, - kernel_name)) { - return 0; - } - - return 1; -} - -unsigned clTestSetOutputBuffer(struct cltest_context * context, - unsigned buffer_size) -{ - cl_int error; - - context->out_buffer = clCreateBuffer(context->cl_ctx, - CL_MEM_WRITE_ONLY, /* Flags */ - buffer_size, /* Size of buffer */ - NULL, /* Pointer to the data */ - &error); /* error code */ - - if (error != CL_SUCCESS) { - fprintf(stderr, "clCreateBuffer() failed: %s\n", clTestErrorString(error)); - return 0; - } - - if (!clTestKernelSetArg(context->kernel, 0, sizeof(cl_mem), - &context->out_buffer)) { - return 0; - } - - return 1; -} - -unsigned clTestKernelSetArg(cl_kernel kernel, cl_uint index, size_t size, - const void * value) -{ - cl_int error; - - error = clSetKernelArg(kernel, index, size, value); - - if (error != CL_SUCCESS) { - fprintf(stderr, "clSetKernelArg failed: %s\n", clTestErrorString(error)); - return 0; - } - - fprintf(stderr, "clSetKernelArg() succeeded.\n"); - - return 1; -} - -unsigned clTestEnqueueNDRangeKernel(cl_command_queue command_queue, - cl_kernel kernel, cl_uint work_dim, const size_t * global_work_size, - const size_t * local_work_size) -{ - cl_int error = clEnqueueNDRangeKernel(command_queue, - kernel, - work_dim, /* Number of dimensions */ - NULL, /* Global work offset */ - global_work_size, - local_work_size, /* local work size */ - 0, /* Events in wait list */ - NULL, /* Wait list */ - NULL); /* Event object for this event */ - if (error != CL_SUCCESS) { - fprintf(stderr, "clEnqueueNDRangeKernel() failed: %s\n", - clTestErrorString(error)); - return 0; - } - - return 1; -} - -unsigned clTestReadOutput(struct cltest_context * context, void * data, - size_t data_bytes) -{ - cl_int error = clEnqueueReadBuffer(context->command_queue, - context->out_buffer, - CL_TRUE, /* TRUE means it is a blocking read. */ - 0, /* Buffer offset to read from. */ - data_bytes, /* Bytes to read */ - data, /* Pointer to store the data */ - 0, /* Events in wait list */ - NULL, /* Wait list */ - NULL); /* Event object */ - - if (error != CL_SUCCESS) { - fprintf(stderr, "clEnqueueReadBuffer() failed: %s\n", - clTestErrorString(error)); - return 0; - } - - return 1; -} @@ -1,25 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H -struct cltest_context { - cl_device_id device_id; - cl_context cl_ctx; - cl_command_queue command_queue; - cl_mem out_buffer; - cl_kernel kernel; -}; +const char * clCheckErrorString(cl_int error); -const char * clTestErrorString(cl_int error); -unsigned clTestInitGpuDevice(cl_device_id * device_id); -unsigned clTestCreateContext(cl_context * context, cl_device_id device_id); -unsigned clTestCreateCommandQueue(cl_command_queue * command_queue, - cl_context context, cl_device_id device_id); -unsigned clTestCreateKernel(cl_context context, cl_device_id device_id, - cl_kernel * kernel, const char * kernel_name); -unsigned clTestSimpleInit(struct cltest_context * context, const char * kernel_name); -unsigned clTestSetOutputBuffer(struct cltest_context * context, unsigned buffer_size); -unsigned clTestKernelSetArg(cl_kernel kernel, cl_uint index, size_t size, - const void * value); -unsigned clTestEnqueueNDRangeKernel(cl_command_queue command_queue, - cl_kernel kernel, cl_uint work_dim, const size_t * global_work_size, - const size_t * local_work_size); -unsigned clTestReadOutput(struct cltest_context * context, void * data, - size_t data_bytes); +#endif /* UTIL_H */ |