[gegl] OpenCl kernel cache
- From: Ãyvind KolÃs <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] OpenCl kernel cache
- Date: Tue, 20 Mar 2012 13:49:53 +0000 (UTC)
commit 4c9274b524f3e16612fba54932b3b74cf2cf362f
Author: Victor Oliveira <victormatheus gmail com>
Date: Mon Nov 14 20:56:43 2011 -0200
OpenCl kernel cache
With this we avoid compiling the same kernel twice.
gegl/opencl/gegl-cl-init.c | 55 +++++++++++++++++++++++++++++++++++++------
gegl/opencl/gegl-cl-init.h | 12 ++++++++-
2 files changed, 57 insertions(+), 10 deletions(-)
---
diff --git a/gegl/opencl/gegl-cl-init.c b/gegl/opencl/gegl-cl-init.c
index dde1af0..a8283b6 100644
--- a/gegl/opencl/gegl-cl-init.c
+++ b/gegl/opencl/gegl-cl-init.c
@@ -6,14 +6,6 @@
#include <string.h>
#include <stdio.h>
-guint
-gegl_cl_count_lines(const char* kernel_source[])
-{
- guint count = 0;
- while (kernel_source[count++] != NULL);
- return count-1;
-}
-
/* http://forums.amd.com/forum/messageview.cfm?catid=390&threadid=128536 */
char *gegl_cl_errstring(cl_int err) {
switch (err) {
@@ -220,3 +212,50 @@ gegl_cl_init (GError **error)
}
#undef CL_LOAD_FUNCTION
+
+/* XXX: same program_source with different kernel_name[], context or device
+ * will retrieve the same key
+ */
+gegl_cl_run_data *
+gegl_cl_compile_and_build (const char *program_source, const char *kernel_name[])
+{
+ gint errcode;
+ gegl_cl_run_data *cl_data = NULL;
+
+ if ((cl_data = (gegl_cl_run_data *)g_hash_table_lookup(cl_program_hash, program_source)) == NULL)
+ {
+ size_t length = strlen(program_source);
+
+ gint i;
+ guint kernel_n = 0;
+ while (kernel_name[++kernel_n] != NULL);
+
+ cl_data = (gegl_cl_run_data *) g_malloc(sizeof(gegl_cl_run_data)+sizeof(cl_kernel)*kernel_n);
+
+ CL_SAFE_CALL( cl_data->program = gegl_clCreateProgramWithSource(gegl_cl_get_context(), 1, &program_source,
+ &length, &errcode) );
+
+ errcode = gegl_clBuildProgram(cl_data->program, 0, NULL, NULL, NULL, NULL);
+ if (errcode != CL_SUCCESS)
+ {
+ char buffer[2000];
+ char *err_msg;
+ CL_SAFE_CALL( errcode = gegl_clGetProgramBuildInfo(cl_data->program,
+ gegl_cl_get_device(),
+ CL_PROGRAM_BUILD_LOG,
+ sizeof(buffer), buffer, NULL) );
+ g_warning("OpenCL Build Error:%s\n%s",
+ err_msg = gegl_cl_errstring(errcode), buffer);
+ free(err_msg);
+ return NULL;
+ }
+
+ for (i=0; i<kernel_n; i++)
+ CL_SAFE_CALL( cl_data->kernel[i] =
+ gegl_clCreateKernel(cl_data->program, kernel_name[i], &errcode) );
+
+ g_hash_table_insert(cl_program_hash, g_strdup (program_source), (void*)cl_data);
+ }
+
+ return cl_data;
+}
diff --git a/gegl/opencl/gegl-cl-init.h b/gegl/opencl/gegl-cl-init.h
index 44822dd..d348a1d 100644
--- a/gegl/opencl/gegl-cl-init.h
+++ b/gegl/opencl/gegl-cl-init.h
@@ -31,8 +31,6 @@ typedef struct
}
gegl_cl_state;
-guint gegl_cl_count_lines(const char* kernel_source[]);
-
char *gegl_cl_errstring(cl_int err);
gboolean gegl_cl_init (GError **error);
@@ -47,6 +45,15 @@ cl_context gegl_cl_get_context (void);
cl_command_queue gegl_cl_get_command_queue (void);
+typedef struct
+{
+ cl_program program;
+ cl_kernel kernel[];
+} gegl_cl_run_data;
+
+gegl_cl_run_data *gegl_cl_compile_and_build (const char *program_source,
+ const char *kernel_name[]);
+
#ifdef __GEGL_CL_INIT_MAIN__
gegl_cl_state cl_state = {FALSE, NULL, NULL, NULL, NULL, FALSE, 0, 0, 0, "", "", "", ""};
@@ -93,6 +100,7 @@ t_clReleaseMemObject gegl_clReleaseMemObject = NULL;
#else
extern gegl_cl_state cl_state;
+extern GHashTable *cl_program_hash;
extern t_clGetPlatformIDs gegl_clGetPlatformIDs;
extern t_clGetPlatformInfo gegl_clGetPlatformInfo;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]