[gegl/openmp: 3/4] add openmp support to point op base classes
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/openmp: 3/4] add openmp support to point op base classes
- Date: Tue, 3 Jun 2014 20:51:35 +0000 (UTC)
commit 125fee4bce4ffde7e81939a5f1d3014d09836198
Author: Øyvind Kolås <pippin gimp org>
Date: Tue Jun 3 22:47:28 2014 +0200
add openmp support to point op base classes
gegl/operation/gegl-operation-point-composer.c | 87 +++++++++++++---
gegl/operation/gegl-operation-point-composer3.c | 129 ++++++++++++++++-------
gegl/operation/gegl-operation-point-filter.c | 49 +++++++++
gegl/operation/gegl-operation-point-render.c | 49 +++++++++
4 files changed, 260 insertions(+), 54 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-point-composer.c b/gegl/operation/gegl-operation-point-composer.c
index ec99365..f441c21 100644
--- a/gegl/operation/gegl-operation-point-composer.c
+++ b/gegl/operation/gegl-operation-point-composer.c
@@ -22,6 +22,7 @@
#include <glib-object.h>
#include "gegl.h"
+#include "gegl-config.h"
#include "gegl/gegl-debug.h"
#include "gegl-operation-point-composer.h"
#include "gegl-operation-context.h"
@@ -224,6 +225,66 @@ error:
return FALSE;
}
+#ifdef HAVE_OPENMP
+
+#include <omp.h>
+
+static gboolean
+gegl_operation_point_composer_omp_process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *aux,
+ GeglBuffer *output,
+ const GeglRectangle *result,
+ gint level)
+{
+ GeglOperationPointComposerClass *point_composer_class = GEGL_OPERATION_POINT_COMPOSER_GET_CLASS
(operation);
+
+ if ((result->width > 0) && (result->height > 0))
+ {
+ const Babl *in_format = gegl_operation_get_format (operation, "input");
+ const Babl *aux_format = gegl_operation_get_format (operation, "aux");
+ const Babl *out_format = gegl_operation_get_format (operation, "output");
+ int in_bpp = babl_format_get_bytes_per_pixel (in_format);
+ int aux_bpp = babl_format_get_bytes_per_pixel (aux_format);
+ int out_bpp = babl_format_get_bytes_per_pixel (out_format);
+ {
+ /* using separate read and write iterators for in-place ideally a single
+ * readwrite indice would be sufficient
+ */
+ gint foo = 0;
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+ gint read = /*output == input ? 0 :*/ gegl_buffer_iterator_add (i, input, result, level, in_format,
GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ if (aux)
+ foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (i))
+ {
+#pragma omp parallel
+ {
+ int tid = omp_get_thread_num ();
+ int tnum = omp_get_num_threads ();
+
+ GeglRectangle roi = i->roi[0];
+ roi.y += (roi.height * tid /tnum);
+ roi.height = (roi.height * (tid + 1)/tnum) - (roi.height * tid / tnum);
+
+ point_composer_class->process (operation, (guchar*)i->data[read] + (roi.y-i->roi[0].y) *
roi.width * in_bpp,
+ aux?(guchar*)i->data[foo] + (roi.y-i->roi[0].y)
* roi.width * aux_bpp:NULL,
+ (guchar*)i->data[0] + (roi.y-i->roi[0].y) *
roi.width * out_bpp,
+ roi.width * roi.height,
+ &roi,
+ level);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+#endif
+
+
static gboolean
gegl_operation_point_composer_process (GeglOperation *operation,
GeglBuffer *input,
@@ -240,11 +301,15 @@ gegl_operation_point_composer_process (GeglOperation *operation,
if ((result->width > 0) && (result->height > 0))
{
+#ifdef HAVE_OPENMP
+ if (gegl_config()->use_openmp)
+ return gegl_operation_point_composer_omp_process (operation, input, aux, output, result, level);
+#endif
+
if (gegl_operation_use_opencl (operation) &&
(operation_class->cl_data || point_composer_class->cl_process))
{
- if (gegl_operation_point_composer_cl_process (operation, input, aux, output, result, level))
- return TRUE;
+ return gegl_operation_point_composer_cl_process (operation, input, aux, output, result, level);
}
{
@@ -253,23 +318,13 @@ gegl_operation_point_composer_process (GeglOperation *operation,
/* using separate read and write iterators for in-place ideally a single
* readwrite indice would be sufficient
*/
+ gint foo = 0;
if (aux)
- {
- gint foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
+ foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
- while (gegl_buffer_iterator_next (i))
- {
- point_composer_class->process (operation, i->data[read], i->data[foo], i->data[0],
i->length, &(i->roi[0]), level);
- }
- }
- else
- {
- while (gegl_buffer_iterator_next (i))
- {
- point_composer_class->process (operation, i->data[read], NULL, i->data[0], i->length,
&(i->roi[0]), level);
- }
- }
+ while (gegl_buffer_iterator_next (i))
+ point_composer_class->process (operation, i->data[read], aux?i->data[foo]:NULL, i->data[0],
i->length, &(i->roi[0]), level);
}
return TRUE;
}
diff --git a/gegl/operation/gegl-operation-point-composer3.c b/gegl/operation/gegl-operation-point-composer3.c
index fc77236..2d33795 100644
--- a/gegl/operation/gegl-operation-point-composer3.c
+++ b/gegl/operation/gegl-operation-point-composer3.c
@@ -22,6 +22,7 @@
#include <glib-object.h>
#include "gegl.h"
+#include "gegl-config.h"
#include "gegl-operation-point-composer3.h"
#include "gegl-operation-context.h"
#include <string.h>
@@ -131,6 +132,75 @@ gegl_operation_composer3_process2 (GeglOperation *operation,
return success;
}
+#ifdef HAVE_OPENMP
+
+#include <omp.h>
+
+static gboolean
+gegl_operation_point_composer3_omp_process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *aux,
+ GeglBuffer *aux2,
+ GeglBuffer *output,
+ const GeglRectangle *result,
+ gint level)
+{
+ //GeglOperationClass *operation_class = GEGL_OPERATION_GET_CLASS (operation);
+ GeglOperationPointComposer3Class *point_composer3_class = GEGL_OPERATION_POINT_COMPOSER3_GET_CLASS
(operation);
+
+ if ((result->width > 0) && (result->height > 0))
+ {
+ const Babl *in_format = gegl_operation_get_format (operation, "input");
+ const Babl *aux_format = gegl_operation_get_format (operation, "aux");
+ const Babl *aux2_format = gegl_operation_get_format (operation, "aux2");
+ const Babl *out_format = gegl_operation_get_format (operation, "output");
+ int in_bpp = babl_format_get_bytes_per_pixel (in_format);
+ int aux_bpp = babl_format_get_bytes_per_pixel (aux_format);
+ int aux2_bpp = babl_format_get_bytes_per_pixel (aux2_format);
+ int out_bpp = babl_format_get_bytes_per_pixel (out_format);
+
+ {
+ /* using separate read and write iterators for in-place ideally a single
+ * readwrite indice would be sufficient
+ */
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+ gint read = /*output == input ? 0 :*/ gegl_buffer_iterator_add (i, input, result, level, in_format,
GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ gint foo = 0;
+ gint bar = 0;
+
+ if (aux)
+ foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
+ if (aux2)
+ bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (i))
+ {
+#pragma omp parallel
+ {
+ int tid = omp_get_thread_num ();
+ int tnum = omp_get_num_threads ();
+
+ GeglRectangle roi = i->roi[0];
+ roi.y += (roi.height * tid /tnum);
+ roi.height = (roi.height * (tid + 1)/tnum) - (roi.height * tid / tnum);
+
+ point_composer3_class->process (operation,
+ (guchar*)i->data[read] + (roi.y-i->roi[0].y) * roi.width * in_bpp,
+ aux?(guchar*)i->data[foo] + (roi.y-i->roi[0].y) * roi.width * aux_bpp:NULL,
+ aux2?(guchar*)i->data[bar] + (roi.y-i->roi[0].y) * roi.width * aux2_bpp:NULL,
+ (guchar*)i->data[0] + (roi.y-i->roi[0].y) * roi.width * out_bpp,
+ roi.width * roi.height,
+ &roi,
+ level);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+#endif
static gboolean
gegl_operation_point_composer3_process (GeglOperation *operation,
GeglBuffer *input,
@@ -148,48 +218,31 @@ gegl_operation_point_composer3_process (GeglOperation *operation,
if ((result->width > 0) && (result->height > 0))
{
+#ifdef HAVE_OPENMP
+ if (gegl_config()->use_openmp)
+ return gegl_operation_point_composer3_omp_process (operation, input, aux, aux2, output, result,
level);
+#endif
+ {
+
+
GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
gint read = gegl_buffer_iterator_add (i, input, result, level, in_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
-
+ gint foo = 0;
+ gint bar = 0;
+
if (aux)
- {
- gint foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
- if (aux2)
- {
- gint bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
-
- while (gegl_buffer_iterator_next (i))
- {
- point_composer3_class->process (operation, i->data[read], i->data[foo], i->data[bar],
i->data[0], i->length, &(i->roi[0]), level);
- }
- }
- else
- {
- while (gegl_buffer_iterator_next (i))
- {
- point_composer3_class->process (operation, i->data[read], i->data[foo], NULL, i->data[0],
i->length, &(i->roi[0]), level);
- }
- }
- }
- else
- {
- if (aux2)
- {
- gint bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
- while (gegl_buffer_iterator_next (i))
- {
- point_composer3_class->process (operation, i->data[read], NULL, i->data[bar], i->data[0],
i->length, &(i->roi[0]), level);
- }
- }
- else
- {
- while (gegl_buffer_iterator_next (i))
- {
- point_composer3_class->process (operation, i->data[read], NULL, NULL, i->data[0],
i->length, &(i->roi[0]), level);
- }
- }
- }
+ foo = gegl_buffer_iterator_add (i, aux, result, level, aux_format, GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+ if (aux2)
+ bar = gegl_buffer_iterator_add (i, aux2, result, level, aux2_format, GEGL_BUFFER_READ,
GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (i))
+ {
+ point_composer3_class->process (operation,
+ i->data[read], aux?i->data[foo]:NULL, aux2?i->data[bar]:NULL,
+ i->data[0], i->length, &(i->roi[0]), level);
+ }
return TRUE;
+ }
}
return TRUE;
}
diff --git a/gegl/operation/gegl-operation-point-filter.c b/gegl/operation/gegl-operation-point-filter.c
index 886f8f9..0c534e6 100644
--- a/gegl/operation/gegl-operation-point-filter.c
+++ b/gegl/operation/gegl-operation-point-filter.c
@@ -23,6 +23,7 @@
#include <string.h>
#include "gegl.h"
+#include "gegl-config.h"
#include "gegl/gegl-debug.h"
#include "gegl-operation-point-filter.h"
#include "gegl-operation-context.h"
@@ -155,6 +156,50 @@ error:
return FALSE;
}
+#ifdef HAVE_OPENMP
+#include <omp.h>
+
+static gboolean
+gegl_operation_point_filter_omp_process (GeglOperation *operation,
+ GeglBuffer *input,
+ GeglBuffer *output,
+ const GeglRectangle *result,
+ gint level)
+{
+ GeglOperationPointFilterClass *point_filter_class = GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation);
+
+ if ((result->width > 0) && (result->height > 0))
+ {
+ const Babl *in_format = gegl_operation_get_format (operation, "input");
+ const Babl *out_format = gegl_operation_get_format (operation, "output");
+ int in_bpp = babl_format_get_bytes_per_pixel (in_format);
+ int out_bpp = babl_format_get_bytes_per_pixel (out_format);
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+ gint read = /*output == input ? 0 :*/ gegl_buffer_iterator_add (i, input, result, level, in_format,
GEGL_BUFFER_READ, GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (i))
+ {
+#pragma omp parallel
+ {
+ int tid = omp_get_thread_num ();
+ int tnum = omp_get_num_threads ();
+
+ GeglRectangle roi = i->roi[0];
+ roi.y += (roi.height * tid /tnum);
+ roi.height = (roi.height * (tid + 1)/tnum) - (roi.height * tid / tnum);
+
+ point_filter_class->process (operation, (guchar*)i->data[read] + (roi.y-i->roi[0].y) * roi.width
* in_bpp,
+ (guchar*)i->data[0] + (roi.y-i->roi[0].y) *
roi.width * out_bpp,
+ roi.height * roi.width,
+ &roi,
+ level);
+ }
+ }
+ }
+ return TRUE;
+}
+#endif
+
static gboolean
gegl_operation_point_filter_process (GeglOperation *operation,
GeglBuffer *input,
@@ -171,6 +216,10 @@ gegl_operation_point_filter_process (GeglOperation *operation,
if ((result->width > 0) && (result->height > 0))
{
+#ifdef HAVE_OPENMP
+ if (gegl_config()->use_openmp)
+ return gegl_operation_point_filter_omp_process (operation, input, output, result, level);
+#endif
if (gegl_operation_use_opencl (operation) &&
(operation_class->cl_data || point_filter_class->cl_process))
{
diff --git a/gegl/operation/gegl-operation-point-render.c b/gegl/operation/gegl-operation-point-render.c
index e46c2db..47712cc 100644
--- a/gegl/operation/gegl-operation-point-render.c
+++ b/gegl/operation/gegl-operation-point-render.c
@@ -22,6 +22,7 @@
#include <glib-object.h>
#include "gegl.h"
+#include "gegl-config.h"
#include "gegl-operation-point-render.h"
#include "gegl-operation-context.h"
@@ -68,6 +69,47 @@ gegl_operation_point_render_init (GeglOperationPointRender *self)
}
+#ifdef HAVE_OPENMP
+#include <omp.h>
+
+static gboolean
+gegl_operation_point_render_omp_process (GeglOperation *operation,
+ GeglBuffer *output,
+ const GeglRectangle *result,
+ gint level)
+{
+ GeglOperationPointRenderClass *point_render_class = GEGL_OPERATION_POINT_RENDER_GET_CLASS (operation);
+
+ if ((result->width > 0) && (result->height > 0))
+ {
+ const Babl *out_format = gegl_operation_get_format (operation, "output");
+ int out_bpp = babl_format_get_bytes_per_pixel (out_format);
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (i))
+ {
+#pragma omp parallel default(shared)
+ {
+ int tid = omp_get_thread_num ();
+ int tnum = omp_get_num_threads ();
+
+ GeglRectangle roi = i->roi[0];
+
+ roi.y += (roi.height * tid /tnum);
+ roi.height = (roi.height * (tid + 1)/tnum) - (roi.height * tid / tnum);
+
+ point_render_class->process (operation,
+ (guchar*)i->data[0] + (roi.y-i->roi[0].y) * roi.width * out_bpp,
+ roi.height * roi.width,
+ &roi,
+ level);
+ }
+ }
+ }
+ return TRUE;
+}
+#endif
+
static gboolean
gegl_operation_point_render_process (GeglOperation *operation,
GeglBuffer *output,
@@ -89,10 +131,17 @@ gegl_operation_point_render_process (GeglOperation *operation,
if ((result->width > 0) && (result->height > 0))
{
+#ifdef HAVE_OPENMP
+ if (gegl_config()->use_openmp)
+ return gegl_operation_point_render_omp_process (operation, output, result, level);
+#endif
+
+ {
GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format,
GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);
while (gegl_buffer_iterator_next (i))
point_render_class->process (operation, i->data[0], i->length, &i->roi[0], level);
+ }
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]