aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2017-01-21 16:59:29 +1300
committerDavid Phillips <david@sighup.nz>2017-01-21 16:59:29 +1300
commitff7e90e5db1c82cab7dc743dc2f8b7fd195754a5 (patch)
treebd912a942eef8f97a00059a5fb0317f1703378b8
parentdcba68a5a967967d87a04be9165715fd49ffae3e (diff)
downloadfractal-gen-opencl-ff7e90e5db1c82cab7dc743dc2f8b7fd195754a5.tar.xz
Add early-days source files
-rw-r--r--fractal-gen.c31
-rw-r--r--slurp.c30
-rw-r--r--slurp.h1
-rw-r--r--test.cl5
-rw-r--r--trampoline.c142
-rw-r--r--trampoline.h5
6 files changed, 214 insertions, 0 deletions
diff --git a/fractal-gen.c b/fractal-gen.c
new file mode 100644
index 0000000..117e2ca
--- /dev/null
+++ b/fractal-gen.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+#include "trampoline.h"
+
+int main() {
+ fprintf(stderr, "Building CL trampoline... ");
+ if (tramp_init()) {
+ fprintf(stderr, "Failed.\n");
+ return 1;
+ }
+ fprintf(stderr, "Done.\n");
+
+ fprintf(stderr, "Loading kernel source from file... ");
+ if (tramp_load_kernel("test.cl")) {
+ fprintf(stderr, "Failed.\n");
+ return 1;
+ }
+ fprintf(stderr, "Loaded.\n");
+
+ fprintf(stderr, "Compiling kernel source... ");
+ if (tramp_compile_kernel()) {
+ fprintf(stderr, "Failed:\n%s\n", tramp_get_build_log());
+ return 1;
+ }
+ fprintf(stderr, "Compiled.\n");
+
+ fprintf(stderr, "Destroying CL trampoline... ");
+ tramp_destroy();
+ fprintf(stderr, "Blown to smitherines.\n");
+ return 0;
+}
diff --git a/slurp.c b/slurp.c
new file mode 100644
index 0000000..1225806
--- /dev/null
+++ b/slurp.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFFER_STEP 1024
+
+char *slurp(FILE *f, size_t *size)
+{
+ char *buffer = NULL;
+ size_t nread = 0;
+
+ buffer = malloc(BUFFER_STEP);
+ if (!buffer) {
+ perror("malloc");
+ return NULL;
+ }
+
+ while (!feof(f)) {
+ nread = fread(&buffer[*size], 1, BUFFER_STEP, f);
+ *size += nread;
+ buffer = realloc(buffer, *size);
+ if (!buffer) {
+ perror("realloc");
+ return NULL;
+ }
+ }
+ if (ferror(f)) {
+ perror("slurp/fread");
+ }
+ return buffer;
+}
diff --git a/slurp.h b/slurp.h
new file mode 100644
index 0000000..114014b
--- /dev/null
+++ b/slurp.h
@@ -0,0 +1 @@
+char *slurp(FILE *f, size_t *size);
diff --git a/test.cl b/test.cl
new file mode 100644
index 0000000..cc587b4
--- /dev/null
+++ b/test.cl
@@ -0,0 +1,5 @@
+__kernel void test(__global float *a, __global float *b)
+{
+ unsigned int i = get_global_id(0);
+ b[i] = a[i] * 2.f;
+}
diff --git a/trampoline.c b/trampoline.c
new file mode 100644
index 0000000..b57311b
--- /dev/null
+++ b/trampoline.c
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <string.h>
+#include <CL/opencl.h>
+
+#include "slurp.h"
+
+static cl_platform_id platform;
+static cl_context context;
+static cl_device_id* devices;
+static cl_uint device_count;
+unsigned int device_in_use;
+static cl_command_queue command_queue;
+
+static cl_kernel kernel;
+static cl_program program;
+
+/* FIXME print cl error messages with oclErrorString */
+int tramp_init()
+{
+ cl_int res;
+
+ /* FIXME expose platform selection to user and flarg the blopple */
+// res = oclGetPlatformID(&platform);
+// if (res != CL_SUCCESS)
+// return 1;
+ platform=0;
+
+ /* FIXME expose device type to user */
+ res = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &device_count);
+ if (res != CL_SUCCESS)
+ return 1;
+
+ devices = malloc(device_count * sizeof(cl_device_id));
+ if (!devices) {
+ perror("device list malloc");
+ return 1;
+ }
+
+ /* FIXME expose device type to user */
+ res = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, device_count, devices, NULL);
+ if (res != CL_SUCCESS)
+ return 1;
+
+ context = clCreateContext(0, 1, devices, NULL, NULL, &res);
+ if (res != CL_SUCCESS)
+ return 1;
+
+ /* FIXME expose to user */
+ device_in_use = 0;
+ command_queue = clCreateCommandQueue(context, devices[device_in_use], 0, &res);
+ if (res != CL_SUCCESS)
+ return 1;
+
+ return 0;
+}
+
+void tramp_destroy()
+{
+ clReleaseKernel(kernel);
+ clReleaseProgram(program);
+ clReleaseCommandQueue(command_queue);
+ clReleaseContext(context);
+
+ if (devices) {
+ free(devices);
+ devices = NULL;
+ }
+}
+
+int tramp_load_kernel(const char *filename)
+{
+ cl_int res = 0;
+ size_t length = 0;
+ FILE *fin = fopen(filename, "r");
+ char *source = NULL;
+ if (!fin) {
+ perror("fopen");
+ return 1;
+ }
+ source = slurp(fin, &length);
+ if (!source)
+ return 1;
+
+ fclose(fin);
+
+ //fwrite(source, length, 1, stderr);
+
+ program = clCreateProgramWithSource(context, 1, (const char **)&source, &length, &res);
+
+ if (res != CL_SUCCESS)
+ return 1;
+
+ free(source);
+ source = NULL;
+
+ return 0;
+}
+
+char *tramp_get_build_log()
+{
+ cl_int ret = 0;
+ cl_build_status build_status;
+ char *build_log = NULL;
+ size_t log_size = 0;
+
+ ret = clGetProgramBuildInfo(program, devices[device_in_use],
+ CL_PROGRAM_BUILD_STATUS,
+ sizeof(cl_build_status),
+ &build_status, NULL);
+
+ /* FIXME check */
+
+ ret = clGetProgramBuildInfo(program, devices[device_in_use],
+ CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
+ /* FIXME check */
+
+ /* + 1 for null-terminator */
+ build_log = malloc(log_size + 1);
+ if (!build_log) {
+ perror("malloc");
+ return NULL;
+ }
+
+ ret = clGetProgramBuildInfo(program, devices[device_in_use],
+ CL_PROGRAM_BUILD_LOG,
+ log_size, build_log, NULL);
+
+ /* null-terminate log */
+ build_log[log_size] = '\0';
+
+ return build_log;
+}
+
+int tramp_compile_kernel()
+{
+ cl_int ret = 0;
+
+ ret = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
+
+ /* return non-zero on error */
+ return ret != CL_SUCCESS;
+}
diff --git a/trampoline.h b/trampoline.h
new file mode 100644
index 0000000..d5608b4
--- /dev/null
+++ b/trampoline.h
@@ -0,0 +1,5 @@
+int tramp_init();
+void tramp_destroy();
+int tramp_load_kernel(const char *filename);
+char *tramp_get_build_log();
+int tramp_compile_kernel();