summaryrefslogtreecommitdiff
path: root/libmeltopengpu/meltopengpu-runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmeltopengpu/meltopengpu-runtime.c')
-rw-r--r--libmeltopengpu/meltopengpu-runtime.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/libmeltopengpu/meltopengpu-runtime.c b/libmeltopengpu/meltopengpu-runtime.c
new file mode 100644
index 00000000000..8b454a6d8d3
--- /dev/null
+++ b/libmeltopengpu/meltopengpu-runtime.c
@@ -0,0 +1,196 @@
+/* MELTOPENGPU: runtime support for calls to OpenCL code generated by
+ GCC MELT
+
+ Copyright (C) 2010
+ Free Software Foundation, Inc.
+ Contributed by Basile Starynkevitch <basile@starynkevitch.net>
+ [funded within OpenGPU french project: http://opengpu.net/ ]
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/***
+ This runtime wraps OpenCL runtime library calls into something
+ simpler. Every variable or function defined here has the
+ meltopengpu_ prefix. Variables with meltopengpu_ are read only
+ from the application, unless specified otherwise. Most of them
+ are internal to this runtime, and need not to be queried at all by
+ explicit user code.
+
+ I am compiling this with
+ gcc -O -Wall -fPIC -shared meltopengpu-runtime.c -lOpenCL -o libmeltopengpu.so
+****/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* this is the usual opencl header, provided by the OpenCL
+ vendor... */
+#include <CL/cl.h>
+
+
+/* Set to one if the library has been initialized. Read-only for user application code. */
+int meltopengpu_is_initialized;
+
+
+/* Signature of the error routine. */
+typedef void (meltopengpu_error_routine_t) (const char*);
+
+/* The OpenCL plateform identifier, and the number of them (0 or
+ 1)! */
+static cl_platform_id meltopengpu_platform;
+static cl_uint meltopengpu_num_platforms;
+
+/* The OpenCL GPU device. */
+static cl_device_id meltopengpu_device;
+static cl_uint meltopengpu_num_devices;
+
+/* The OpenCL context. */
+static cl_context meltopengpu_context;
+
+/* The OpenCL command queue. */
+static cl_command_queue meltopengpu_command_queue;
+
+/* The pointer to the error routine. */
+static meltopengpu_error_routine_t* meltopengpu_error_fun;
+
+/* Our internal fatal error routine. */
+static void meltopengpu_fatal_printf (const char*fmt, ...)
+ __attribute__((format(printf,1,2)))
+ __attribute__((noreturn));
+
+static void meltopengpu_fatal_printf (const char*fmt, ...)
+{
+ static char errbuf[512];
+ va_list args;
+ memset (errbuf, 0, sizeof(errbuf));
+ va_start(args, fmt);
+ vsnprintf(errbuf, sizeof(errbuf)-1, fmt, args);
+ va_end (args);
+ if (meltopengpu_error_fun)
+ meltopengpu_error_fun (errbuf);
+ else {
+ fputs (errbuf, stderr);
+ putc('\n', stderr);
+ fflush (stderr);
+ }
+ abort ();
+}
+
+/* This initialization code should be called by the user application,
+ at the very beginning. If the user did not call that function
+ explicitly, nothing specific to MELT OPENGPU happens, and no code
+ runs on the GPU. The argument is a fatal error routine function
+ pointer or null; if null, any error spits a message to stderr and
+ abort()-s */
+void meltopengpu_initialize (meltopengpu_error_routine_t erh)
+{
+ cl_int got = CL_SUCCESS;
+ if (erh)
+ meltopengpu_error_fun = erh;
+
+ /* Get the platform */
+ got = clGetPlatformIDs(1, &meltopengpu_platform,
+ &meltopengpu_num_platforms);
+ if (got != CL_SUCCESS);
+ meltopengpu_fatal_printf ("MELTOPENGPU failed to get OpenCL PlateformIDs [%d]",
+ (int) got);
+
+ /* Get the GPU device */
+ got = clGetDeviceIDs (meltopengpu_platform,
+ CL_DEVICE_TYPE_GPU, /* perhaps CL_DEVICE_TYPE_DEFAULT? */
+ 1,
+ &meltopengpu_device,
+ &meltopengpu_num_devices);
+ if (got != CL_SUCCESS)
+ meltopengpu_fatal_printf ("MELTOPENGPU failed to get OpenCL device [%d]",
+ (int) got);
+
+ /* Create the context. */
+ got = CL_SUCCESS;
+ meltopengpu_context
+ = clCreateContext (NULL,
+ 1,
+ &meltopengpu_device,
+ NULL, NULL,
+ &got);
+ if (!meltopengpu_context)
+ meltopengpu_fatal_printf ("MELTOPENGPU failed to create OpenCL context [%d]",
+ (int) got);
+
+ /* Create the command queue. */
+ got = CL_SUCCESS;
+ meltopengpu_command_queue
+ = clCreateCommandQueue (meltopengpu_context,
+ meltopengpu_device,
+ 0,
+ &got);
+ if (!meltopengpu_command_queue)
+ meltopengpu_fatal_printf ("MELTOPENGPU failed to create OpenCL command queue [%d]",
+ (int) got);
+
+ /* at last, remember that we have been initialized correctly. */
+ meltopengpu_is_initialized = 1;
+}
+
+cl_program
+meltopengpu_compile_program (const char*src)
+{
+ cl_int got = CL_SUCCESS;
+ cl_program prog = NULL;
+ if (!src || !meltopengpu_is_initialized)
+ return NULL;
+ /* compile the program */
+ prog =
+ clCreateProgramWithSource (meltopengpu_context,
+ 1,
+ &src,
+ 0,
+ &got);
+ if (!prog)
+ meltopengpu_fatal_printf("MELTOPENGPU failed to compile OpenCL program [%d]",
+ (int) got);
+ /* build it */
+ got = clBuildProgram (prog, 1, &meltopengpu_device, NULL, NULL, NULL);
+ if (got != CL_SUCCESS)
+ meltopengpu_fatal_printf ("MELTOPNBPU failed to build OpenCL program [%d]",
+ (int) got);
+
+ return prog;
+}
+
+cl_kernel
+meltopengpu_create_kernel (cl_program prog, const char*kernam)
+{
+ cl_kernel kern = 0;
+ cl_int got = CL_SUCCESS;
+ kern = clCreateKernel (prog, kernam, &got);
+ if (!kern)
+ meltopengpu_fatal_printf ("MELTOPNBPU failed to create kernel %s [%d]",
+ kernam, (int) got);
+ return kern;
+}
+
+/* eof $Id$ */
+
+