From f937d68d60d8740a33f490b574da7a75607bcd0d Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Tue, 27 Dec 2011 16:37:24 +0000 Subject: [PATCH] Fixed build for x64 with sse2 disabled; several improvements in performance testing framework; enabled SANITY_CHECK() for performance tests --- modules/calib3d/perf/perf_pnp.cpp | 4 +- modules/core/include/opencv2/core/types_c.h | 10 ++-- modules/core/perf/perf_core_arithm.cpp | 4 +- modules/core/perf/perf_dft.cpp | 2 +- modules/core/perf/perf_math.cpp | 2 +- modules/core/perf/perf_stat.cpp | 34 +++++++------- .../perf/perf_geometric_transformations.cpp | 4 +- modules/ts/include/opencv2/ts/ts_perf.hpp | 3 +- modules/ts/src/ts_perf.cpp | 47 ++++++++++++------- 9 files changed, 63 insertions(+), 47 deletions(-) diff --git a/modules/calib3d/perf/perf_pnp.cpp b/modules/calib3d/perf/perf_pnp.cpp index 1fbe8f0bb5..78d22a4327 100644 --- a/modules/calib3d/perf/perf_pnp.cpp +++ b/modules/calib3d/perf/perf_pnp.cpp @@ -43,6 +43,6 @@ PERF_TEST_P(PointsNumber, solvePnP, testing::Values(4, 3*9, 7*13) solvePnP(points3d, points2d, intrinsics, distortion, rvec, tvec, false); } - SANITY_CHECK(rvec); - SANITY_CHECK(tvec); + SANITY_CHECK(rvec, 1e-6); + SANITY_CHECK(tvec, 1e-6); } diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index 1d097ad667..cf1d1d992b 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -72,9 +72,11 @@ #if (_MSC_VER >= 1400 && defined _M_X64) || (__GNUC__ >= 4 && defined __x86_64__) #if defined WIN32 - #include - #endif - #include + #include + #endif + #if __SSE2__ || !defined __GNUC__ + #include + #endif #endif #if defined __BORLANDC__ @@ -292,7 +294,7 @@ enum { CV_INLINE int cvRound( double value ) { -#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && !defined __APPLE__) +#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && __SSE2__ && !defined __APPLE__) __m128d t = _mm_set_sd( value ); return _mm_cvtsd_si32(t); #elif defined _MSC_VER && defined _M_IX86 diff --git a/modules/core/perf/perf_core_arithm.cpp b/modules/core/perf/perf_core_arithm.cpp index 695cad3832..849423d483 100644 --- a/modules/core/perf/perf_core_arithm.cpp +++ b/modules/core/perf/perf_core_arithm.cpp @@ -25,7 +25,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f, __testset) \ \ TEST_CYCLE(100) __f(a,b, c); \ \ - SANITY_CHECK(c); \ + SANITY_CHECK(c, 1e-8); \ } #define PERF_TEST_P__CORE_ARITHM_SCALAR(__f, __testset) \ @@ -42,7 +42,7 @@ PERF_TEST_P(Size_MatType, core_arithm__ ## __f ##__Scalar, __testset) \ \ TEST_CYCLE(100) __f(a,b, c); \ \ - SANITY_CHECK(c); \ + SANITY_CHECK(c, 1e-8); \ } PERF_TEST_P__CORE_ARITHM(bitwise_and, TYPICAL_MATS_BITW_ARITHM) diff --git a/modules/core/perf/perf_dft.cpp b/modules/core/perf/perf_dft.cpp index cb3aa566de..5cf4afb109 100644 --- a/modules/core/perf/perf_dft.cpp +++ b/modules/core/perf/perf_dft.cpp @@ -24,5 +24,5 @@ PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT) dft(src, dst); } - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1e-5); } diff --git a/modules/core/perf/perf_math.cpp b/modules/core/perf/perf_math.cpp index eb526c1a49..696be76c00 100644 --- a/modules/core/perf/perf_math.cpp +++ b/modules/core/perf/perf_math.cpp @@ -17,5 +17,5 @@ PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*102 TEST_CYCLE(200) cv::phase(X, Y, angle, true); - SANITY_CHECK(angle); + SANITY_CHECK(angle, 5e-5); } diff --git a/modules/core/perf/perf_stat.cpp b/modules/core/perf/perf_stat.cpp index 06883a730a..f5f7ff9843 100644 --- a/modules/core/perf/perf_stat.cpp +++ b/modules/core/perf/perf_stat.cpp @@ -21,7 +21,7 @@ PERF_TEST_P( Size_MatType, sum, TYPICAL_MATS ) TEST_CYCLE(100) { s = sum(arr); } - SANITY_CHECK(s); + SANITY_CHECK(s, 1e-6); } @@ -40,7 +40,7 @@ PERF_TEST_P( Size_MatType, mean, TYPICAL_MATS ) TEST_CYCLE(100) { s = mean(src); } - SANITY_CHECK(s); + SANITY_CHECK(s, 1e-6); } @@ -60,7 +60,7 @@ PERF_TEST_P( Size_MatType, mean_mask, TYPICAL_MATS ) TEST_CYCLE(100) { s = mean(src, mask); } - SANITY_CHECK(s); + SANITY_CHECK(s, 1e-6); } CV_FLAGS(NormType, NORM_INF, NORM_L1, NORM_L2, NORM_TYPE_MASK, NORM_RELATIVE, NORM_MINMAX) @@ -89,7 +89,7 @@ PERF_TEST_P( Size_MatType_NormType, norm, TEST_CYCLE(100) { n = norm(src1, normType); } - SANITY_CHECK(n); + SANITY_CHECK(n, 1e-5); } @@ -116,7 +116,7 @@ PERF_TEST_P( Size_MatType_NormType, norm_mask, TEST_CYCLE(100) { n = norm(src1, normType, mask); } - SANITY_CHECK(n); + SANITY_CHECK(n, 1e-5); } @@ -143,7 +143,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2, TEST_CYCLE(100) { n = norm(src1, src2, normType); } - SANITY_CHECK(n); + SANITY_CHECK(n, 1e-5); } @@ -171,7 +171,7 @@ PERF_TEST_P( Size_MatType_NormType, norm2_mask, TEST_CYCLE(100) { n = norm(src1, src2, normType, mask); } - SANITY_CHECK(n); + SANITY_CHECK(n, 1e-5); } @@ -200,7 +200,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize, TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType); } - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1e-6); } @@ -230,7 +230,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_mask, TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, -1, mask); } - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1e-6); } @@ -259,7 +259,7 @@ PERF_TEST_P( Size_MatType_NormType, normalize_32f, TEST_CYCLE(100) { normalize(src, dst, alpha, 0., normType, CV_32F); } - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1e-6); } @@ -279,7 +279,7 @@ PERF_TEST_P( Size_MatType, normalize_minmax, TYPICAL_MATS ) TEST_CYCLE(100) { normalize(src, dst, 20., 100., NORM_MINMAX); } - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1e-6); } @@ -298,8 +298,8 @@ PERF_TEST_P( Size_MatType, meanStdDev, TYPICAL_MATS ) TEST_CYCLE(100) { meanStdDev(src, mean, dev); } - SANITY_CHECK(mean); - SANITY_CHECK(dev); + SANITY_CHECK(mean, 1e-6); + SANITY_CHECK(dev, 1e-6); } @@ -319,8 +319,8 @@ PERF_TEST_P( Size_MatType, meanStdDev_mask, TYPICAL_MATS ) TEST_CYCLE(100) { meanStdDev(src, mean, dev, mask); } - SANITY_CHECK(mean); - SANITY_CHECK(dev); + SANITY_CHECK(mean, 1e-6); + SANITY_CHECK(dev, 1e-6); } @@ -368,8 +368,8 @@ PERF_TEST_P( Size_MatType, minMaxLoc, testing::Combine( TEST_CYCLE(100) { minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc); } - SANITY_CHECK(minVal); - SANITY_CHECK(maxVal); + SANITY_CHECK(minVal, 1e-12); + SANITY_CHECK(maxVal, 1e-12); } diff --git a/modules/imgproc/perf/perf_geometric_transformations.cpp b/modules/imgproc/perf/perf_geometric_transformations.cpp index a2961bb4fe..07a3701199 100644 --- a/modules/imgproc/perf/perf_geometric_transformations.cpp +++ b/modules/imgproc/perf/perf_geometric_transformations.cpp @@ -26,7 +26,7 @@ PERF_TEST_P(MatInfo_Size_Size, resizeUpLinear, TEST_CYCLE(100) cv::resize(src, dst, to); - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1 + 1e-6); } PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear, @@ -50,6 +50,6 @@ PERF_TEST_P(MatInfo_Size_Size, resizeDownLinear, TEST_CYCLE(100) cv::resize(src, dst, to); - SANITY_CHECK(dst); + SANITY_CHECK(dst, 1 + 1e-6); } diff --git a/modules/ts/include/opencv2/ts/ts_perf.hpp b/modules/ts/include/opencv2/ts/ts_perf.hpp index 0d5ef6347e..2e8f2bef2b 100644 --- a/modules/ts/include/opencv2/ts/ts_perf.hpp +++ b/modules/ts/include/opencv2/ts/ts_perf.hpp @@ -269,6 +269,7 @@ private: int64 totalTime; int64 timeLimit; static int64 timeLimitDefault; + static unsigned int iterationsLimitDefault; unsigned int nIters; unsigned int currentIter; @@ -297,7 +298,7 @@ private: _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, int wtype = WARMUP_WRITE); _declareHelper& out(cv::InputOutputArray a1, cv::InputOutputArray a2, cv::InputOutputArray a3, cv::InputOutputArray a4, int wtype = WARMUP_WRITE); - _declareHelper& iterations(int n); + _declareHelper& iterations(unsigned int n); _declareHelper& time(double timeLimitSecs); _declareHelper& tbb_threads(int n = -1); private: diff --git a/modules/ts/src/ts_perf.cpp b/modules/ts/src/ts_perf.cpp index b55a347f27..d1d41e80bc 100644 --- a/modules/ts/src/ts_perf.cpp +++ b/modules/ts/src/ts_perf.cpp @@ -204,12 +204,12 @@ void Regression::write(cv::Mat m) void Regression::verify(cv::FileNode node, cv::Mat actual, double eps, std::string argname) { - double actualmin, actualmax; - cv::minMaxLoc(actual, &actualmin, &actualmax); + double actual_min, actual_max; + cv::minMaxLoc(actual, &actual_min, &actual_max); - ASSERT_NEAR((double)node["min"], actualmin, eps) + ASSERT_NEAR((double)node["min"], actual_min, eps) << " " << argname << " has unexpected minimal value"; - ASSERT_NEAR((double)node["max"], actualmax, eps) + ASSERT_NEAR((double)node["max"], actual_max, eps) << " " << argname << " has unexpected maximal value"; cv::FileNode last = node["last"]; @@ -265,13 +265,13 @@ void Regression::write(cv::InputArray array) void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) { - ASSERT_EQ((int)node["kind"], array.kind()) << " Argument " << node.name() << " has unexpected kind"; - ASSERT_EQ((int)node["type"], array.type()) << " Argument " << node.name() << " has unexpected type"; + ASSERT_EQ((int)node["kind"], array.kind()) << " Argument \"" << node.name() << "\" has unexpected kind"; + ASSERT_EQ((int)node["type"], array.type()) << " Argument \"" << node.name() << "\" has unexpected type"; cv::FileNode valnode = node["val"]; if (isVector(array)) { - ASSERT_EQ((int)node["len"], (int)array.total()) << " Vector " << node.name() << " has unexpected length"; + ASSERT_EQ((int)node["len"], (int)array.total()) << " Vector \"" << node.name() << "\" has unexpected length"; int idx = node["idx"]; cv::Mat actual = array.getMat(idx); @@ -279,7 +279,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) if (valnode.isNone()) { ASSERT_LE((size_t)26, actual.total() * (size_t)actual.channels()) - << " " << node.name() << "[" << idx << "] has unexpected number of elements"; + << " \"" << node.name() << "[" << idx << "]\" has unexpected number of elements"; verify(node, actual, eps, cv::format("%s[%d]", node.name().c_str(), idx)); } else @@ -293,8 +293,12 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) cv::Mat diff; cv::absdiff(expected, actual, diff); if (!cv::checkRange(diff, true, 0, 0, eps)) - FAIL() << " Difference between argument " - << node.name() << "[" << idx << "] and expected value is bugger than " << eps; + { + double max; + cv::minMaxLoc(diff, 0, &max); + FAIL() << " Difference (=" << max << ") between argument \"" + << node.name() << "[" << idx << "]\" and expected value is bugger than " << eps; + } } } else @@ -302,7 +306,7 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) if (valnode.isNone()) { ASSERT_LE((size_t)26, array.total() * (size_t)array.channels()) - << " Argument " << node.name() << " has unexpected number of elements"; + << " Argument \"" << node.name() << "\" has unexpected number of elements"; verify(node, array.getMat(), eps, "Argument " + node.name()); } else @@ -312,13 +316,17 @@ void Regression::verify(cv::FileNode node, cv::InputArray array, double eps) cv::Mat actual = array.getMat(); ASSERT_EQ(expected.size(), actual.size()) - << " Argument " << node.name() << " has unexpected size"; + << " Argument \"" << node.name() << "\" has unexpected size"; cv::Mat diff; cv::absdiff(expected, actual, diff); if (!cv::checkRange(diff, true, 0, 0, eps)) - FAIL() << " Difference between argument " << node.name() - << " and expected value is bugger than " << eps; + { + double max; + cv::minMaxLoc(diff, 0, &max); + FAIL() << " Difference (=" << max << ") between argument \"" << node.name() + << "\" and expected value is bugger than " << eps; + } } } } @@ -378,12 +386,14 @@ performance_metrics::performance_metrics() * ::perf::TestBase \*****************************************************************************************/ int64 TestBase::timeLimitDefault = 0; +unsigned int TestBase::iterationsLimitDefault = (unsigned int)(-1); int64 TestBase::_timeadjustment = 0; const char *command_line_keys = { "{ |perf_max_outliers |8 |percent of allowed outliers}" "{ |perf_min_samples |10 |minimal required numer of samples}" + "{ |perf_force_samples |100 |force set maximum number of samples for all tests}" "{ |perf_seed |809564 |seed for random numbers generator}" "{ |perf_tbb_nthreads |-1 |if TBB is enabled, the number of TBB threads}" #if ANDROID @@ -399,6 +409,7 @@ const char *command_line_keys = double param_max_outliers; double param_max_deviation; unsigned int param_min_samples; +unsigned int perf_force_samples; uint64 param_seed; double param_time_limit; int param_tbb_nthreads; @@ -429,6 +440,7 @@ void TestBase::Init(int argc, const char* const argv[]) param_max_deviation = std::max(0., args.get("perf_max_deviation")); param_seed = args.get("perf_seed"); param_time_limit = std::max(0., args.get("perf_time_limit")); + perf_force_samples = args.get("perf_force_samples"); param_tbb_nthreads = args.get("perf_tbb_nthreads"); #if ANDROID @@ -443,6 +455,7 @@ void TestBase::Init(int argc, const char* const argv[]) } timeLimitDefault = param_time_limit == 0.0 ? 1 : (int64)(param_time_limit * cv::getTickFrequency()); + iterationsLimitDefault = perf_force_samples == 0 ? (unsigned)(-1) : perf_force_samples; _timeadjustment = _calibrate(); } @@ -785,7 +798,7 @@ void TestBase::SetUp() #endif lastTime = 0; totalTime = 0; - nIters = (unsigned int)-1; + nIters = iterationsLimitDefault; currentIter = (unsigned int)-1; timeLimit = timeLimitDefault; times.clear(); @@ -878,11 +891,11 @@ void TestBase::RunPerfTestBody() /*****************************************************************************************\ * ::perf::TestBase::_declareHelper \*****************************************************************************************/ -TestBase::_declareHelper& TestBase::_declareHelper::iterations(int n) +TestBase::_declareHelper& TestBase::_declareHelper::iterations(unsigned int n) { test->times.clear(); test->times.reserve(n); - test->nIters = n; + test->nIters = std::min(n, TestBase::iterationsLimitDefault); test->currentIter = (unsigned int)-1; return *this; }