From ebdd74105a0c04ac16b1d6a9adc46d683cb44a07 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 28 Feb 2017 18:01:41 +0300 Subject: [PATCH] core(test): add regression test for RNG in parallel_for_() --- modules/core/test/test_rand.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/modules/core/test/test_rand.cpp b/modules/core/test/test_rand.cpp index 63b9094..b687a8f 100644 --- a/modules/core/test/test_rand.cpp +++ b/modules/core/test/test_rand.cpp @@ -382,3 +382,39 @@ TEST(Core_Rand, Regression_Stack_Corruption) ASSERT_EQ(param1, -9); ASSERT_EQ(param2, 2); } + +namespace { + +class RandRowFillParallelLoopBody : public cv::ParallelLoopBody +{ +public: + RandRowFillParallelLoopBody(Mat& dst) : dst_(dst) {} + ~RandRowFillParallelLoopBody() {} + void operator()(const cv::Range& r) const + { + cv::RNG rng = cv::theRNG(); // copy state + for (int y = r.start; y < r.end; y++) + { + cv::theRNG() = cv::RNG(rng.state + y); // seed is based on processed row + cv::randu(dst_.row(y), Scalar(-100), Scalar(100)); + } + // theRNG() state is changed here (but state collision has low probability, so we don't check this) + } +protected: + Mat& dst_; +}; + +TEST(Core_Rand, parallel_for_stable_results) +{ + cv::RNG rng = cv::theRNG(); // save rng state + Mat dst1(1000, 100, CV_8SC1); + parallel_for_(cv::Range(0, dst1.rows), RandRowFillParallelLoopBody(dst1)); + + cv::theRNG() = rng; // restore rng state + Mat dst2(1000, 100, CV_8SC1); + parallel_for_(cv::Range(0, dst2.rows), RandRowFillParallelLoopBody(dst2)); + + ASSERT_EQ(0, countNonZero(dst1 != dst2)); +} + +} // namespace -- 2.7.4