Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ParallelLoopBodyWrapperContext
- {
- public:
- ParallelLoopBodyWrapperContext(const cv::ParallelLoopBody& _body, const cv::Range& _r, double _nstripes) :
- is_rng_used(false), hasException(false)
- {
- body = &_body;
- wholeRange = _r;
- double len = wholeRange.end - wholeRange.start;
- nstripes = cvRound(_nstripes <= 0 ? len : MIN(MAX(_nstripes, 1.), len));
- // propagate main thread state
- rng = cv::theRNG();
- #ifdef OPENCV_TRACE
- traceRootRegion = CV_TRACE_NS::details::getCurrentRegion();
- traceRootContext = CV_TRACE_NS::details::getTraceManager().tls.get();
- #endif
- #ifdef ENABLE_INSTRUMENTATION
- pThreadRoot = cv::instr::getInstrumentTLSStruct().pCurrentNode;
- #endif
- }
- void finalize()
- {
- #ifdef ENABLE_INSTRUMENTATION
- for(size_t i = 0; i < pThreadRoot->m_childs.size(); i++)
- SyncNodes(pThreadRoot->m_childs[i]);
- #endif
- if (is_rng_used)
- {
- // Some parallel backends execute nested jobs in the main thread,
- // so we need to restore initial RNG state here.
- cv::theRNG() = rng;
- // We can't properly update RNG state based on RNG usage in worker threads,
- // so lets just change main thread RNG state to the next value.
- // Note: this behaviour is not equal to single-threaded mode.
- cv::theRNG().next();
- }
- #ifdef OPENCV_TRACE
- if (traceRootRegion)
- CV_TRACE_NS::details::parallelForFinalize(*traceRootRegion);
- #endif
- if (hasException)
- {
- #if CV__EXCEPTION_PTR
- std::rethrow_exception(pException);
- #else
- CV_Error(Error::StsError, "Exception in parallel_for() body: " + exception_message);
- #endif
- }
- }
- ~ParallelLoopBodyWrapperContext() {}
- const cv::ParallelLoopBody* body;
- cv::Range wholeRange;
- int nstripes;
- cv::RNG rng;
- mutable bool is_rng_used;
- #ifdef OPENCV_TRACE
- CV_TRACE_NS::details::Region* traceRootRegion;
- CV_TRACE_NS::details::TraceManagerThreadLocal* traceRootContext;
- #endif
- #ifdef ENABLE_INSTRUMENTATION
- cv::instr::InstrNode *pThreadRoot;
- #endif
- bool hasException;
- #if CV__EXCEPTION_PTR
- std::exception_ptr pException;
- #else
- cv::String exception_message;
- #endif
- #if CV__EXCEPTION_PTR
- void recordException()
- #else
- void recordException(const cv::String& msg)
- #endif
- {
- if (!hasException)
- {
- cv::AutoLock lock(cv::getInitializationMutex());
- if (!hasException)
- {
- hasException = true;
- #if CV__EXCEPTION_PTR
- pException = std::current_exception();
- #else
- exception_message = msg;
- #endif
- }
- }
- }
- private:
- ParallelLoopBodyWrapperContext(const ParallelLoopBodyWrapperContext&); // disabled
- ParallelLoopBodyWrapperContext& operator=(const ParallelLoopBodyWrapperContext&); // disabled
- };
- class ParallelLoopBodyWrapper : public cv::ParallelLoopBody
- {
- public:
- ParallelLoopBodyWrapper(ParallelLoopBodyWrapperContext& ctx_) :
- ctx(ctx_)
- {
- }
- ~ParallelLoopBodyWrapper()
- {
- }
- void operator()(const cv::Range& sr) const CV_OVERRIDE
- {
- #ifdef OPENCV_TRACE
- // TODO CV_TRACE_NS::details::setCurrentRegion(rootRegion);
- if (ctx.traceRootRegion && ctx.traceRootContext)
- CV_TRACE_NS::details::parallelForSetRootRegion(*ctx.traceRootRegion, *ctx.traceRootContext);
- CV__TRACE_OPENCV_FUNCTION_NAME("parallel_for_body");
- if (ctx.traceRootRegion)
- CV_TRACE_NS::details::parallelForAttachNestedRegion(*ctx.traceRootRegion);
- #endif
- #ifdef ENABLE_INSTRUMENTATION
- {
- cv::instr::InstrTLSStruct *pInstrTLS = &cv::instr::getInstrumentTLSStruct();
- pInstrTLS->pCurrentNode = ctx.pThreadRoot; // Initialize TLS node for thread
- }
- CV_INSTRUMENT_REGION()
- #endif
- // propagate main thread state
- cv::theRNG() = ctx.rng;
- cv::Range r;
- cv::Range wholeRange = ctx.wholeRange;
- int nstripes = ctx.nstripes;
- r.start = (int)(wholeRange.start +
- ((uint64)sr.start*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes);
- r.end = sr.end >= nstripes ? wholeRange.end : (int)(wholeRange.start +
- ((uint64)sr.end*(wholeRange.end - wholeRange.start) + nstripes/2)/nstripes);
- #ifdef OPENCV_TRACE
- CV_TRACE_ARG_VALUE(range_start, "range.start", (int64)r.start);
- CV_TRACE_ARG_VALUE(range_end, "range.end", (int64)r.end);
- #endif
- try
- {
- (*ctx.body)(r);
- }
- #if CV__EXCEPTION_PTR
- catch (...)
- {
- ctx.recordException();
- }
- #else
- catch (const cv::Exception& e)
- {
- ctx.recordException(e.what());
- }
- catch (const std::exception& e)
- {
- ctx.recordException(e.what());
- }
- catch (...)
- {
- ctx.recordException("Unknown exception");
- }
- #endif
- if (!ctx.is_rng_used && !(cv::theRNG() == ctx.rng))
- ctx.is_rng_used = true;
- }
- cv::Range stripeRange() const { return cv::Range(0, ctx.nstripes); }
- protected:
- ParallelLoopBodyWrapperContext& ctx;
- };
Advertisement
Add Comment
Please, Sign In to add comment