Guest User

Untitled

a guest
May 26th, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.87 KB | None | 0 0
  1.  
  2.     class ParallelLoopBodyWrapperContext
  3.     {
  4.     public:
  5.         ParallelLoopBodyWrapperContext(const cv::ParallelLoopBody& _body, const cv::Range& _r, double _nstripes) :
  6.             is_rng_used(false), hasException(false)
  7.         {
  8.  
  9.             body = &_body;
  10.             wholeRange = _r;
  11.             double len = wholeRange.end - wholeRange.start;
  12.             nstripes = cvRound(_nstripes <= 0 ? len : MIN(MAX(_nstripes, 1.), len));
  13.  
  14.             // propagate main thread state
  15.             rng = cv::theRNG();
  16.  
  17. #ifdef OPENCV_TRACE
  18.             traceRootRegion = CV_TRACE_NS::details::getCurrentRegion();
  19.             traceRootContext = CV_TRACE_NS::details::getTraceManager().tls.get();
  20. #endif
  21.  
  22. #ifdef ENABLE_INSTRUMENTATION
  23.             pThreadRoot = cv::instr::getInstrumentTLSStruct().pCurrentNode;
  24. #endif
  25.         }
  26.         void finalize()
  27.         {
  28. #ifdef ENABLE_INSTRUMENTATION
  29.             for(size_t i = 0; i < pThreadRoot->m_childs.size(); i++)
  30.                 SyncNodes(pThreadRoot->m_childs[i]);
  31. #endif
  32.             if (is_rng_used)
  33.             {
  34.                 // Some parallel backends execute nested jobs in the main thread,
  35.                 // so we need to restore initial RNG state here.
  36.                 cv::theRNG() = rng;
  37.                 // We can't properly update RNG state based on RNG usage in worker threads,
  38.                 // so lets just change main thread RNG state to the next value.
  39.                 // Note: this behaviour is not equal to single-threaded mode.
  40.                 cv::theRNG().next();
  41.             }
  42. #ifdef OPENCV_TRACE
  43.             if (traceRootRegion)
  44.                 CV_TRACE_NS::details::parallelForFinalize(*traceRootRegion);
  45. #endif
  46.  
  47.             if (hasException)
  48.             {
  49. #if CV__EXCEPTION_PTR
  50.                 std::rethrow_exception(pException);
  51. #else
  52.                 CV_Error(Error::StsError, "Exception in parallel_for() body: " + exception_message);
  53. #endif
  54.             }
  55.         }
  56.         ~ParallelLoopBodyWrapperContext() {}
  57.  
  58.         const cv::ParallelLoopBody* body;
  59.         cv::Range wholeRange;
  60.         int nstripes;
  61.         cv::RNG rng;
  62.         mutable bool is_rng_used;
  63. #ifdef OPENCV_TRACE
  64.         CV_TRACE_NS::details::Region* traceRootRegion;
  65.         CV_TRACE_NS::details::TraceManagerThreadLocal* traceRootContext;
  66. #endif
  67. #ifdef ENABLE_INSTRUMENTATION
  68.         cv::instr::InstrNode *pThreadRoot;
  69. #endif
  70.         bool hasException;
  71. #if CV__EXCEPTION_PTR
  72.         std::exception_ptr pException;
  73. #else
  74.         cv::String exception_message;
  75. #endif
  76. #if CV__EXCEPTION_PTR
  77.         void recordException()
  78. #else
  79.         void recordException(const cv::String& msg)
  80. #endif
  81.         {
  82.             if (!hasException)
  83.             {
  84.                 cv::AutoLock lock(cv::getInitializationMutex());
  85.                 if (!hasException)
  86.                 {
  87.                     hasException = true;
  88. #if CV__EXCEPTION_PTR
  89.                     pException = std::current_exception();
  90. #else
  91.                     exception_message = msg;
  92. #endif
  93.                 }
  94.             }
  95.         }
  96.     private:
  97.         ParallelLoopBodyWrapperContext(const ParallelLoopBodyWrapperContext&); // disabled
  98.         ParallelLoopBodyWrapperContext& operator=(const ParallelLoopBodyWrapperContext&); // disabled
  99.     };
  100.  
  101.  
  102.     class ParallelLoopBodyWrapper : public cv::ParallelLoopBody
  103.     {
  104.     public:
  105.         ParallelLoopBodyWrapper(ParallelLoopBodyWrapperContext& ctx_) :
  106.             ctx(ctx_)
  107.         {
  108.         }
  109.         ~ParallelLoopBodyWrapper()
  110.         {
  111.         }
  112.         void operator()(const cv::Range& sr) const CV_OVERRIDE
  113.         {
  114. #ifdef OPENCV_TRACE
  115.             // TODO CV_TRACE_NS::details::setCurrentRegion(rootRegion);
  116.             if (ctx.traceRootRegion && ctx.traceRootContext)
  117.                 CV_TRACE_NS::details::parallelForSetRootRegion(*ctx.traceRootRegion, *ctx.traceRootContext);
  118.             CV__TRACE_OPENCV_FUNCTION_NAME("parallel_for_body");
  119.             if (ctx.traceRootRegion)
  120.                 CV_TRACE_NS::details::parallelForAttachNestedRegion(*ctx.traceRootRegion);
  121. #endif
  122.  
  123. #ifdef ENABLE_INSTRUMENTATION
  124.             {
  125.                 cv::instr::InstrTLSStruct *pInstrTLS = &cv::instr::getInstrumentTLSStruct();
  126.                 pInstrTLS->pCurrentNode = ctx.pThreadRoot; // Initialize TLS node for thread
  127.             }
  128.             CV_INSTRUMENT_REGION()
  129. #endif
  130.  
  131.             // propagate main thread state
  132.             cv::theRNG() = ctx.rng;
  133.  
  134.             cv::Range r;
  135.             cv::Range wholeRange = ctx.wholeRange;
  136.             int nstripes = ctx.nstripes;
  137.             r.start = (int)(wholeRange.start +
  138.                             ((uint64)sr.start*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes);
  139.             r.end = sr.end >= nstripes ? wholeRange.end : (int)(wholeRange.start +
  140.                             ((uint64)sr.end*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes);
  141.  
  142. #ifdef OPENCV_TRACE
  143.             CV_TRACE_ARG_VALUE(range_start, "range.start", (int64)r.start);
  144.             CV_TRACE_ARG_VALUE(range_end, "range.end", (int64)r.end);
  145. #endif
  146.  
  147.             try
  148.             {
  149.                 (*ctx.body)(r);
  150.             }
  151. #if CV__EXCEPTION_PTR
  152.             catch (...)
  153.             {
  154.                 ctx.recordException();
  155.             }
  156. #else
  157.             catch (const cv::Exception& e)
  158.             {
  159.                 ctx.recordException(e.what());
  160.             }
  161.             catch (const std::exception& e)
  162.             {
  163.                 ctx.recordException(e.what());
  164.             }
  165.             catch (...)
  166.             {
  167.                 ctx.recordException("Unknown exception");
  168.             }
  169. #endif
  170.  
  171.             if (!ctx.is_rng_used && !(cv::theRNG() == ctx.rng))
  172.                 ctx.is_rng_used = true;
  173.         }
  174.         cv::Range stripeRange() const { return cv::Range(0, ctx.nstripes); }
  175.  
  176.     protected:
  177.         ParallelLoopBodyWrapperContext& ctx;
  178.     };
Advertisement
Add Comment
Please, Sign In to add comment