Fluid Internal Parallelism:
authorAnton Potapov <anton.potapov@intel.com>
Tue, 3 Sep 2019 12:03:51 +0000 (15:03 +0300)
committerAnton Potapov <anton.potapov@intel.com>
Mon, 9 Sep 2019 14:37:52 +0000 (17:37 +0300)
  - add comments on signature of custom parallel_for
  - use cv::parallel_for_ by default

modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp
modules/gapi/src/backends/fluid/gfluidbackend.cpp

index b454e85..3235de7 100644 (file)
@@ -106,7 +106,10 @@ struct GFluidParallelOutputRois
 
 struct GFluidParallelFor
 {
-    std::function<void(std::size_t, std::function<void(std::size_t)>)> parallel_for;
+    //this function accepts:
+    // - size of the "parallel" range as the first argument
+    // - and a function to be called on the range items, designated by item index
+    std::function<void(std::size_t size, std::function<void(std::size_t index)>)> parallel_for;
 };
 
 namespace detail
index ab90973..78bc202 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <ade/util/algorithm.hpp>
 #include <ade/util/chain_range.hpp>
+#include <ade/util/iota_range.hpp>
 #include <ade/util/range.hpp>
 #include <ade/util/zip_range.hpp>
 
@@ -96,12 +97,31 @@ namespace
             const auto parallel_out_rois = cv::gimpl::getCompileArg<cv::GFluidParallelOutputRois>(args);
             const auto gpfor             = cv::gimpl::getCompileArg<cv::GFluidParallelFor>(args);
 
-            auto serial_for = [](std::size_t count, std::function<void(std::size_t)> f){
-                for (std::size_t i  = 0; i < count; ++i){
+#if !defined(GAPI_STANDALONE)
+            auto default_pfor = [](std::size_t count, std::function<void(std::size_t)> f){
+                struct Body : cv::ParallelLoopBody {
+                    decltype(f) func;
+                    Body( decltype(f) && _f) : func(_f){}
+                    virtual void operator() (const cv::Range& r) const CV_OVERRIDE
+                    {
+                        for (std::size_t i : ade::util::iota(r.start, r.end))
+                        {
+                            func(i);
+                        }
+                    }
+                };
+                cv::parallel_for_(cv::Range{0,static_cast<int>(count)}, Body{std::move(f)});
+            };
+#else
+            auto default_pfor = [](std::size_t count, std::function<void(std::size_t)> f){
+                for (auto i : ade::util::iota(count)){
                     f(i);
                 }
             };
-            auto pfor  = gpfor.has_value() ? gpfor.value().parallel_for : serial_for;
+#endif
+
+            auto pfor  = gpfor.has_value() ? gpfor.value().parallel_for : default_pfor;
+
             return parallel_out_rois.has_value() ?
                        EPtr{new cv::gimpl::GParallelFluidExecutable (graph, graph_data, std::move(parallel_out_rois.value().parallel_rois), pfor)}
                      : EPtr{new cv::gimpl::GFluidExecutable         (graph, graph_data, std::move(rois.rois))}