message: core(test): add regression test for RNG in parallel_for_()
diff: @@ -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
  