From fe01bc21c0f6346004c8d5392f94ec64b5cdfe09 Mon Sep 17 00:00:00 2001
From: Alexander Alekhin <alexander.alekhin@itseez.com>
Date: Mon, 2 Dec 2013 21:36:08 +0400
Subject: [PATCH 1/2] perf: test-based metrics collection strategy

---
 modules/ocl/perf/main.cpp                 |  2 +-
 modules/ts/include/opencv2/ts/ts_perf.hpp | 12 ++++--
 modules/ts/src/ts_perf.cpp                | 49 +++++++++++++++--------
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/modules/ocl/perf/main.cpp b/modules/ocl/perf/main.cpp
index 5a67d1cbf..c3b2f362f 100644
--- a/modules/ocl/perf/main.cpp
+++ b/modules/ocl/perf/main.cpp
@@ -70,7 +70,7 @@ static const char * impls[] =
 
 int main(int argc, char ** argv)
 {
-    ::perf::TestBase::setPerformanceStrategy(::perf::PERF_STRATEGY_SIMPLE);
+    ::perf::TestBase::setModulePerformanceStrategy(::perf::PERF_STRATEGY_SIMPLE);
 
     CV_PERF_TEST_MAIN_INTERNALS(ocl, impls, dumpOpenCLDevice())
 }
diff --git a/modules/ts/include/opencv2/ts/ts_perf.hpp b/modules/ts/include/opencv2/ts/ts_perf.hpp
index 40f3c951c..499b53cad 100644
--- a/modules/ts/include/opencv2/ts/ts_perf.hpp
+++ b/modules/ts/include/opencv2/ts/ts_perf.hpp
@@ -251,6 +251,7 @@ typedef struct CV_EXPORTS performance_metrics
 \*****************************************************************************************/
 enum PERF_STRATEGY
 {
+    PERF_STRATEGY_DEFAULT = -1,
     PERF_STRATEGY_BASE = 0,
     PERF_STRATEGY_SIMPLE = 1,
 };
@@ -271,8 +272,8 @@ public:
     static std::string getDataPath(const std::string& relativePath);
     static std::string getSelectedImpl();
 
-    static enum PERF_STRATEGY getPerformanceStrategy();
-    static enum PERF_STRATEGY setPerformanceStrategy(enum PERF_STRATEGY strategy);
+    static enum PERF_STRATEGY getCurrentModulePerformanceStrategy();
+    static enum PERF_STRATEGY setModulePerformanceStrategy(enum PERF_STRATEGY strategy);
 
     class PerfSkipTestException: public cv::Exception {};
 
@@ -286,7 +287,7 @@ protected:
     void stopTimer();
     bool next();
 
-    //_declareHelper declare;
+    PERF_STRATEGY getCurrentPerformanceStrategy() const;
 
     enum WarmUpType
     {
@@ -300,6 +301,7 @@ protected:
     static void warmup(cv::InputOutputArray a, WarmUpType wtype = WARMUP_READ);
 
     performance_metrics& calcMetrics();
+
     void RunPerfTestBody();
 private:
     typedef std::vector<std::pair<int, cv::Size> > SizeVector;
@@ -310,6 +312,8 @@ private:
     unsigned int getTotalInputSize() const;
     unsigned int getTotalOutputSize() const;
 
+    enum PERF_STRATEGY testStrategy;
+
     TimeVector times;
     int64 lastTime;
     int64 totalTime;
@@ -349,6 +353,8 @@ private:
         _declareHelper& time(double timeLimitSecs);
         _declareHelper& tbb_threads(int n = -1);
         _declareHelper& runs(unsigned int runsNumber);
+
+        _declareHelper& strategy(enum PERF_STRATEGY s);
     private:
         TestBase* test;
         _declareHelper(TestBase* t);
diff --git a/modules/ts/src/ts_perf.cpp b/modules/ts/src/ts_perf.cpp
index 1b95b1ac4..91f5e7fc7 100644
--- a/modules/ts/src/ts_perf.cpp
+++ b/modules/ts/src/ts_perf.cpp
@@ -19,7 +19,8 @@ static std::vector<std::string> available_impls;
 
 static std::string  param_impl;
 
-static enum PERF_STRATEGY param_strategy = PERF_STRATEGY_BASE;
+static enum PERF_STRATEGY strategyForce = PERF_STRATEGY_DEFAULT;
+static enum PERF_STRATEGY strategyModule = PERF_STRATEGY_BASE;
 
 static double       param_max_outliers;
 static double       param_max_deviation;
@@ -684,11 +685,11 @@ void TestBase::Init(const std::vector<std::string> & availableImpls,
     }
     else if (perf_strategy == "base")
     {
-        param_strategy = PERF_STRATEGY_BASE;
+        strategyForce = PERF_STRATEGY_BASE;
     }
     else if (perf_strategy == "simple")
     {
-        param_strategy = PERF_STRATEGY_SIMPLE;
+        strategyForce = PERF_STRATEGY_SIMPLE;
     }
     else
     {
@@ -788,16 +789,16 @@ std::string TestBase::getSelectedImpl()
     return param_impl;
 }
 
-enum PERF_STRATEGY TestBase::getPerformanceStrategy()
+enum PERF_STRATEGY TestBase::setModulePerformanceStrategy(enum PERF_STRATEGY strategy)
 {
-    return param_strategy;
+    enum PERF_STRATEGY ret = strategyModule;
+    strategyModule = strategy;
+    return ret;
 }
 
-enum PERF_STRATEGY TestBase::setPerformanceStrategy(enum PERF_STRATEGY strategy)
+enum PERF_STRATEGY TestBase::getCurrentModulePerformanceStrategy()
 {
-    enum PERF_STRATEGY ret = param_strategy;
-    param_strategy = strategy;
-    return ret;
+    return strategyForce == PERF_STRATEGY_DEFAULT ? strategyModule : strategyForce;
 }
 
 
@@ -830,7 +831,7 @@ int64 TestBase::_calibrate()
     _helper h;
     h.PerfTestBody();
     double compensation = h.getMetrics().min;
-    if (param_strategy == PERF_STRATEGY_SIMPLE)
+    if (getCurrentModulePerformanceStrategy() == PERF_STRATEGY_SIMPLE)
     {
         CV_Assert(compensation < 0.01 * cv::getTickFrequency());
         compensation = 0.0f; // simple strategy doesn't require any compensation
@@ -843,7 +844,7 @@ int64 TestBase::_calibrate()
 # pragma warning(push)
 # pragma warning(disable:4355)  // 'this' : used in base member initializer list
 #endif
-TestBase::TestBase(): declare(this)
+TestBase::TestBase(): testStrategy(PERF_STRATEGY_DEFAULT), declare(this)
 {
 }
 #ifdef _MSC_VER
@@ -896,6 +897,14 @@ cv::Size TestBase::getSize(cv::InputArray a)
     return cv::Size();
 }
 
+PERF_STRATEGY TestBase::getCurrentPerformanceStrategy() const
+{
+    if (strategyForce == PERF_STRATEGY_DEFAULT)
+        return (testStrategy == PERF_STRATEGY_DEFAULT) ? strategyModule : testStrategy;
+    else
+        return strategyForce;
+}
+
 bool TestBase::next()
 {
     static int64 lastActivityPrintTime = 0;
@@ -924,13 +933,13 @@ bool TestBase::next()
             break;
         }
 
-        if (param_strategy == PERF_STRATEGY_BASE)
+        if (getCurrentPerformanceStrategy() == PERF_STRATEGY_BASE)
         {
             has_next = currentIter < nIters && totalTime < timeLimit;
         }
         else
         {
-            assert(param_strategy == PERF_STRATEGY_SIMPLE);
+            assert(getCurrentPerformanceStrategy() == PERF_STRATEGY_SIMPLE);
             if (totalTime - lastActivityPrintTime >= cv::getTickFrequency() * 10)
             {
                 std::cout << '.' << std::endl;
@@ -1053,7 +1062,7 @@ performance_metrics& TestBase::calcMetrics()
     TimeVector::const_iterator start = times.begin();
     TimeVector::const_iterator end = times.end();
 
-    if (param_strategy == PERF_STRATEGY_BASE)
+    if (getCurrentPerformanceStrategy() == PERF_STRATEGY_BASE)
     {
         //estimate mean and stddev for log(time)
         double gmean = 0;
@@ -1084,7 +1093,7 @@ performance_metrics& TestBase::calcMetrics()
             ++end, --metrics.outliers;
         }
     }
-    else if (param_strategy == PERF_STRATEGY_SIMPLE)
+    else if (getCurrentPerformanceStrategy() == PERF_STRATEGY_SIMPLE)
     {
         metrics.outliers = static_cast<int>(times.size() * param_max_outliers / 100);
         for (unsigned int i = 0; i < metrics.outliers; i++)
@@ -1143,7 +1152,7 @@ void TestBase::validateMetrics()
     ASSERT_GE(m.samples, 1u)
       << "  No time measurements was performed.\nstartTimer() and stopTimer() commands are required for performance tests.";
 
-    if (param_strategy == PERF_STRATEGY_BASE)
+    if (getCurrentPerformanceStrategy() == PERF_STRATEGY_BASE)
     {
         EXPECT_GE(m.samples, param_min_samples)
           << "  Only a few samples are collected.\nPlease increase number of iterations or/and time limit to get reliable performance measurements.";
@@ -1157,7 +1166,7 @@ void TestBase::validateMetrics()
         EXPECT_LE(m.outliers, std::max((unsigned int)cvCeil(m.samples * param_max_outliers / 100.), 1u))
           << "  Test results are not reliable (too many outliers).";
     }
-    else if (param_strategy == PERF_STRATEGY_SIMPLE)
+    else if (getCurrentPerformanceStrategy() == PERF_STRATEGY_SIMPLE)
     {
         double mean = metrics.mean * 1000.0f / metrics.frequency;
         double stddev = metrics.stddev * 1000.0f / metrics.frequency;
@@ -1479,6 +1488,12 @@ TestBase::_declareHelper& TestBase::_declareHelper::out(cv::InputOutputArray a1,
     return *this;
 }
 
+TestBase::_declareHelper& TestBase::_declareHelper::strategy(enum PERF_STRATEGY s)
+{
+    test->testStrategy = s;
+    return *this;
+}
+
 TestBase::_declareHelper::_declareHelper(TestBase* t) : test(t)
 {
 }

From 7d9150460a7f4870b66a8b074bd861f7777333cb Mon Sep 17 00:00:00 2001
From: Alexander Alekhin <alexander.alekhin@itseez.com>
Date: Mon, 2 Dec 2013 21:37:32 +0400
Subject: [PATCH 2/2] core/ocl: added perf test infra + "Add" perf test

---
 modules/core/perf/opencl/perf_arithm.cpp   |  75 ++++++++++++++
 modules/imgproc/test/ocl/test_color.cpp    |   1 -
 modules/imgproc/test/ocl/test_warp.cpp     |   1 -
 modules/ts/include/opencv2/ts/ocl_perf.hpp | 111 +++++++++++++++++++++
 modules/ts/include/opencv2/ts/ocl_test.hpp |  10 +-
 modules/ts/src/ocl_perf.cpp                |  97 ++++++++++++++++++
 modules/ts/src/ts_perf.cpp                 |  13 ++-
 7 files changed, 299 insertions(+), 9 deletions(-)
 create mode 100644 modules/core/perf/opencl/perf_arithm.cpp
 create mode 100644 modules/ts/include/opencv2/ts/ocl_perf.hpp
 create mode 100644 modules/ts/src/ocl_perf.cpp

diff --git a/modules/core/perf/opencl/perf_arithm.cpp b/modules/core/perf/opencl/perf_arithm.cpp
new file mode 100644
index 000000000..8ee691a18
--- /dev/null
+++ b/modules/core/perf/opencl/perf_arithm.cpp
@@ -0,0 +1,75 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "perf_precomp.hpp"
+#include "opencv2/ts/ocl_perf.hpp"
+
+#ifdef HAVE_OPENCL
+
+namespace cvtest {
+namespace ocl {
+
+///////////// Add ////////////////////////
+
+typedef Size_MatType AddFixture;
+
+OCL_PERF_TEST_P(AddFixture, Add,
+            ::testing::Combine(OCL_TEST_SIZES,
+                               OCL_TEST_TYPES))
+{
+    const Size srcSize = GET_PARAM(0);
+    const int type = GET_PARAM(1);
+
+    checkDeviceMaxMemoryAllocSize(srcSize, type);
+
+    UMat src1(srcSize, type), src2(srcSize, type), dst(srcSize, type);
+    randu(src1);
+    randu(src2);
+    declare.in(src1, src2).out(dst);
+
+    OCL_TEST_CYCLE() cv::add(src1, src2, dst);
+
+    SANITY_CHECK(dst);
+}
+
+} } // namespace cvtest::ocl
+
+#endif // HAVE_OPENCL
diff --git a/modules/imgproc/test/ocl/test_color.cpp b/modules/imgproc/test/ocl/test_color.cpp
index 3a5046c79..5bcfa1bac 100644
--- a/modules/imgproc/test/ocl/test_color.cpp
+++ b/modules/imgproc/test/ocl/test_color.cpp
@@ -44,7 +44,6 @@
 //M*/
 
 #include "test_precomp.hpp"
-#include "cvconfig.h"
 #include "opencv2/ts/ocl_test.hpp"
 
 #ifdef HAVE_OPENCL
diff --git a/modules/imgproc/test/ocl/test_warp.cpp b/modules/imgproc/test/ocl/test_warp.cpp
index 6e549a4ec..0090655f2 100644
--- a/modules/imgproc/test/ocl/test_warp.cpp
+++ b/modules/imgproc/test/ocl/test_warp.cpp
@@ -52,7 +52,6 @@
 //M*/
 
 #include "test_precomp.hpp"
-#include "cvconfig.h"
 #include "opencv2/ts/ocl_test.hpp"
 
 #ifdef HAVE_OPENCL
diff --git a/modules/ts/include/opencv2/ts/ocl_perf.hpp b/modules/ts/include/opencv2/ts/ocl_perf.hpp
new file mode 100644
index 000000000..52f815d1c
--- /dev/null
+++ b/modules/ts/include/opencv2/ts/ocl_perf.hpp
@@ -0,0 +1,111 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_TS_OCL_PERF_HPP__
+#define __OPENCV_TS_OCL_PERF_HPP__
+
+#include "ocl_test.hpp"
+#include "ts_perf.hpp"
+
+#ifdef HAVE_OPENCL
+
+namespace cvtest {
+namespace ocl {
+
+using namespace perf;
+
+#define OCL_PERF_STRATEGY PERF_STRATEGY_SIMPLE
+
+#define OCL_PERF_TEST_P(fixture, name, params) SIMPLE_PERF_TEST_P(fixture, name, params)
+
+#define SIMPLE_PERF_TEST_P(fixture, name, params)\
+    class OCL##_##fixture##_##name : public fixture {\
+    public:\
+        OCL##_##fixture##_##name() {}\
+    protected:\
+        virtual void PerfTestBody();\
+    };\
+    TEST_P(OCL##_##fixture##_##name, name){ declare.strategy(OCL_PERF_STRATEGY); RunPerfTestBody(); }\
+    INSTANTIATE_TEST_CASE_P(/*none*/, OCL##_##fixture##_##name, params);\
+    void OCL##_##fixture##_##name::PerfTestBody()
+
+
+#define OCL_SIZE_1000 Size(1000, 1000)
+#define OCL_SIZE_2000 Size(2000, 2000)
+#define OCL_SIZE_4000 Size(4000, 4000)
+
+#define OCL_TEST_SIZES ::testing::Values(OCL_SIZE_1000, OCL_SIZE_2000, OCL_SIZE_4000)
+#define OCL_TEST_TYPES ::testing::Values(CV_8UC1, CV_32FC1, CV_8UC4, CV_32FC4)
+
+#define OCL_PERF_ENUM ::testing::Values
+
+// TODO Replace finish call to dstUMat.wait()
+#define OCL_TEST_CYCLE() \
+    for (; startTimer(), next(); cvtest::ocl::perf::safeFinish(), stopTimer())
+
+#define OCL_TEST_CYCLE_MULTIRUN(runsNum) \
+    for (declare.runs(runsNum); startTimer(), next(); cvtest::ocl::perf::safeFinish(), stopTimer()) \
+        for (int r = 0; r < runsNum; cvtest::ocl::perf::safeFinish(), ++r)
+
+namespace perf {
+
+// Check for current device limitation
+CV_EXPORTS void checkDeviceMaxMemoryAllocSize(const Size& size, int type, int factor = 1);
+
+// Initialize Mat with random numbers. Range is depends on the data type.
+// TODO Parameter type is actually OutputArray
+CV_EXPORTS void randu(InputOutputArray dst);
+
+inline void safeFinish()
+{
+    if (cv::ocl::useOpenCL())
+        cv::ocl::finish2();
+}
+
+} // namespace perf
+using namespace perf;
+
+} // namespace cvtest::ocl
+} // namespace cvtest
+
+#endif // HAVE_OPENCL
+
+#endif // __OPENCV_TS_OCL_PERF_HPP__
diff --git a/modules/ts/include/opencv2/ts/ocl_test.hpp b/modules/ts/include/opencv2/ts/ocl_test.hpp
index 33520b9b2..b4d28b64b 100644
--- a/modules/ts/include/opencv2/ts/ocl_test.hpp
+++ b/modules/ts/include/opencv2/ts/ocl_test.hpp
@@ -42,11 +42,11 @@
 #ifndef __OPENCV_TS_OCL_TEST_HPP__
 #define __OPENCV_TS_OCL_TEST_HPP__
 
-#ifdef HAVE_OPENCL
-
-#include "cvconfig.h"
+#include "cvconfig.h" // to get definition of HAVE_OPENCL
 #include "opencv2/opencv_modules.hpp"
 
+#ifdef HAVE_OPENCL
+
 #include "opencv2/ts.hpp"
 
 #include "opencv2/highgui.hpp"
@@ -123,7 +123,7 @@ using perf::MatType;
 
 #define OCL_RNG_SEED 123456
 
-struct TestUtils
+struct CV_EXPORTS TestUtils
 {
     cv::RNG rng;
 
@@ -270,7 +270,7 @@ struct TestUtils
 #define UMAT_UPLOAD_OUTPUT_PARAMETER(name) UMAT_UPLOAD_INPUT_PARAMETER(name)
 
 template <typename T>
-struct TSTestWithParam : public TestUtils, public ::testing::TestWithParam<T>
+struct CV_EXPORTS TSTestWithParam : public TestUtils, public ::testing::TestWithParam<T>
 {
 
 };
diff --git a/modules/ts/src/ocl_perf.cpp b/modules/ts/src/ocl_perf.cpp
new file mode 100644
index 000000000..9151f8889
--- /dev/null
+++ b/modules/ts/src/ocl_perf.cpp
@@ -0,0 +1,97 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the OpenCV Foundation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "precomp.hpp"
+
+#include "opencv2/ts/ocl_perf.hpp"
+
+#ifdef HAVE_OPENCL
+
+namespace cvtest {
+namespace ocl {
+
+namespace perf {
+
+void checkDeviceMaxMemoryAllocSize(const Size& size, int type, int factor)
+{
+    assert(factor > 0);
+    if (!cv::ocl::useOpenCL())
+        return;
+    int cn = CV_MAT_CN(type);
+    int cn_ocl = cn == 3 ? 4 : cn;
+    int type_ocl = CV_MAKE_TYPE(CV_MAT_DEPTH(type), cn_ocl);
+    size_t memSize = size.area() * CV_ELEM_SIZE(type_ocl);
+    const cv::ocl::Device& dev = cv::ocl::Device::getDefault();
+    if (memSize * factor >= dev.maxMemAllocSize())
+    {
+        throw ::perf::TestBase::PerfSkipTestException();
+    }
+}
+
+void randu(InputOutputArray dst)
+{
+    if (dst.depth() == CV_8U)
+    {
+        cv::randu(dst, 0, 256);
+    }
+    else if (dst.depth() == CV_8S)
+    {
+        cv::randu(dst, -128, 128);
+    }
+    else if (dst.depth() == CV_16U)
+    {
+        cv::randu(dst, 0, 1024);
+    }
+    else if (dst.depth() == CV_32F || dst.depth() == CV_64F)
+    {
+        cv::randu(dst, -1.0, 1.0);
+    }
+    else // (dst.depth() == CV_16S || dst.depth() == CV_32S)
+    {
+        cv::randu(dst, -4096, 4096);
+    }
+}
+
+} // namespace perf
+
+}} // namespace cvtest::ocl
+
+#endif // HAVE_OPENCL
diff --git a/modules/ts/src/ts_perf.cpp b/modules/ts/src/ts_perf.cpp
index 91f5e7fc7..08f2ed5c7 100644
--- a/modules/ts/src/ts_perf.cpp
+++ b/modules/ts/src/ts_perf.cpp
@@ -865,9 +865,18 @@ void TestBase::declareArray(SizeVector& sizes, cv::InputOutputArray a, WarmUpTyp
 
 void TestBase::warmup(cv::InputOutputArray a, WarmUpType wtype)
 {
-    if (a.empty()) return;
-    if (a.kind() != cv::_InputArray::STD_VECTOR_MAT && a.kind() != cv::_InputArray::STD_VECTOR_VECTOR)
+    if (a.empty())
+    {
+        return;
+    }
+    else if (a.isUMat())
+    {
+        return; // TODO current warmup_impl is not useful for GPU-based data
+    }
+    else if (a.kind() != cv::_InputArray::STD_VECTOR_MAT && a.kind() != cv::_InputArray::STD_VECTOR_VECTOR)
+    {
         warmup_impl(a.getMat(), wtype);
+    }
     else
     {
         size_t total = a.total();