[gegl/openmp: 3/4] add openmp support to point op base classes



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]