summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile24
-rw-r--r--clSimple.txt17
-rw-r--r--cl_simple.c306
-rw-r--r--cl_simple.h27
-rw-r--r--get_global_id.c12
-rw-r--r--get_global_id_2d.c7
-rw-r--r--hello_world.c22
-rw-r--r--loop.c7
-rw-r--r--math-int.c20
-rw-r--r--util.c292
-rw-r--r--util.h27
11 files changed, 404 insertions, 357 deletions
diff --git a/Makefile b/Makefile
index 43862c1..3efe726 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
}
diff --git a/loop.c b/loop.c
index 6c60d6b..39f2db1 100644
--- a/loop.c
+++ b/loop.c
@@ -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;
}
diff --git a/math-int.c b/math-int.c
index 018e28f..56394b8 100644
--- a/math-int.c
+++ b/math-int.c
@@ -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;
}
diff --git a/util.c b/util.c
index 1bfd975..5ba3be9 100644
--- a/util.c
+++ b/util.c
@@ -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;
-}
diff --git a/util.h b/util.h
index 4d30690..1ebe991 100644
--- a/util.h
+++ b/util.h
@@ -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 */