Publishing 2019 R3 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / test / common / gapi_tests_common.hpp
index 937587c..3d3141f 100644 (file)
@@ -2,13 +2,20 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 //
-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2019 Intel Corporation
 
+#ifndef OPENCV_GAPI_TESTS_COMMON_HPP
+#define OPENCV_GAPI_TESTS_COMMON_HPP
 
 #include <iostream>
+#include <tuple>
+#include <type_traits>
 
-#include "opencv2/ts.hpp"
-#include "opencv2/gapi.hpp"
+#include <opencv2/ts.hpp>
+#include <opencv2/gapi.hpp>
+#include <opencv2/gapi/util/util.hpp>
+
+#include "gapi_tests_helpers.hpp"
 
 namespace
 {
@@ -41,6 +48,15 @@ public:
         return cv::Scalar(s1, s2, s3, s4);
     }
 
+    void initOutMats(cv::Size sz_in, int dtype)
+    {
+        if (dtype != -1)
+        {
+            out_mat_gapi = cv::Mat(sz_in, dtype);
+            out_mat_ocv = cv::Mat(sz_in, dtype);
+        }
+    }
+
     void initMatsRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
     {
         in_mat1 = cv::Mat(sz_in, type);
@@ -50,10 +66,9 @@ public:
         cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
         cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
 
-        if (createOutputMatrices && dtype != -1)
+        if (createOutputMatrices)
         {
-            out_mat_gapi = cv::Mat (sz_in, dtype);
-            out_mat_ocv = cv::Mat (sz_in, dtype);
+            initOutMats(sz_in, dtype);
         }
     }
 
@@ -62,28 +77,28 @@ public:
         in_mat1 = cv::Mat(sz_in, type);
 
         sc = initScalarRandU(100);
-
         cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
 
-        if (createOutputMatrices && dtype != -1)
+        if (createOutputMatrices)
         {
-            out_mat_gapi = cv::Mat (sz_in, dtype);
-            out_mat_ocv = cv::Mat (sz_in, dtype);
+            initOutMats(sz_in, dtype);
         }
     }
 
-    void initMatsRandN(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
+    void initMatrixRandN(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
     {
-        in_mat1  = cv::Mat(sz_in, type);
+        in_mat1 = cv::Mat(sz_in, type);
         cv::randn(in_mat1, cv::Scalar::all(127), cv::Scalar::all(40.f));
 
-        if (createOutputMatrices  && dtype != -1)
+        if (createOutputMatrices)
         {
-            out_mat_gapi = cv::Mat(sz_in, dtype);
-            out_mat_ocv = cv::Mat(sz_in, dtype);
+            initOutMats(sz_in, dtype);
         }
     }
 
+    // empty function intended to show that nothing is to be initialized via TestFunctional methods
+    void initNothing(int, cv::Size, int, bool = true) {}
+
     static cv::Mat nonZeroPixels(const cv::Mat& mat)
     {
         int channels = mat.channels();
@@ -117,6 +132,134 @@ using compare_f = std::function<bool(const cv::Mat &a, const cv::Mat &b)>;
 
 using compare_scalar_f = std::function<bool(const cv::Scalar &a, const cv::Scalar &b)>;
 
+// FIXME: re-use MatType. current problem: "special values" interpreted incorrectly (-1 is printed
+//        as 16FC512)
+struct MatType2
+{
+public:
+    MatType2(int val = 0) : _value(val) {}
+    operator int() const { return _value; }
+    friend std::ostream& operator<<(std::ostream& os, const MatType2& t)
+    {
+        switch (t)
+        {
+            case -1: return os << "SAME_TYPE";
+            default: PrintTo(MatType(t), &os); return os;
+        }
+    }
+private:
+    int _value;
+};
+
+// Universal parameter wrapper for common (pre-defined) and specific (user-defined) parameters
+template<typename ...SpecificParams>
+struct Params
+{
+    using gcomp_args_function_t = cv::GCompileArgs(*)();
+    using common_params_t = std::tuple<MatType2, cv::Size, MatType2, gcomp_args_function_t>;
+    using specific_params_t = std::tuple<SpecificParams...>;
+    using params_t = std::tuple<MatType2, cv::Size, MatType2, gcomp_args_function_t, SpecificParams...>;
+    static constexpr const size_t common_params_size = std::tuple_size<common_params_t>::value;
+    static constexpr const size_t specific_params_size = std::tuple_size<specific_params_t>::value;
+
+    template<size_t I>
+    static const typename std::tuple_element<I, common_params_t>::type&
+    getCommon(const params_t& t)
+    {
+        static_assert(I < common_params_size, "Index out of range");
+        return std::get<I>(t);
+    }
+
+    template<size_t I>
+    static const typename std::tuple_element<I, specific_params_t>::type&
+    getSpecific(const params_t& t)
+    {
+        static_assert(specific_params_size > 0,
+            "Impossible to call this function: no specific parameters specified");
+        static_assert(I < specific_params_size, "Index out of range");
+        return std::get<common_params_size + I>(t);
+    }
+};
+
+// Base class for test fixtures
+template<typename ...SpecificParams>
+struct TestWithParamBase : TestFunctional,
+    TestWithParam<typename Params<SpecificParams...>::params_t>
+{
+    using AllParams = Params<SpecificParams...>;
+
+    MatType2 type = getCommonParam<0>();
+    cv::Size sz = getCommonParam<1>();
+    MatType2 dtype = getCommonParam<2>();
+
+    // Get common (pre-defined) parameter value by index
+    template<size_t I>
+    inline auto getCommonParam() const
+        -> decltype(AllParams::template getCommon<I>(this->GetParam()))
+    {
+        return AllParams::template getCommon<I>(this->GetParam());
+    }
+
+    // Get specific (user-defined) parameter value by index
+    template<size_t I>
+    inline auto getSpecificParam() const
+        -> decltype(AllParams::template getSpecific<I>(this->GetParam()))
+    {
+        return AllParams::template getSpecific<I>(this->GetParam());
+    }
+
+    // Return G-API compile arguments specified for test fixture
+    inline cv::GCompileArgs getCompileArgs() const
+    {
+        return getCommonParam<3>()();
+    }
+};
+
+/**
+ * @private
+ * @brief Create G-API test fixture with TestWithParamBase base class
+ * @param Fixture   test fixture name
+ * @param InitF     callable that will initialize default available members (from TestFunctional)
+ * @param API       base class API. Specifies types of user-defined parameters. If there are no such
+ *                  parameters, empty angle brackets ("<>") must be specified.
+ * @param Number    number of user-defined parameters (corresponds to the number of types in API).
+ *                  if there are no such parameters, 0 must be specified.
+ * @param ...       list of names of user-defined parameters. if there are no parameters, the list
+ *                  must be empty.
+ */
+#define GAPI_TEST_FIXTURE(Fixture, InitF, API, Number, ...) \
+    struct Fixture : public TestWithParamBase API { \
+        static_assert(Number == AllParams::specific_params_size, \
+            "Number of user-defined parameters doesn't match size of __VA_ARGS__"); \
+        __WRAP_VAARGS(DEFINE_SPECIFIC_PARAMS_##Number(__VA_ARGS__)) \
+        Fixture() { InitF(type, sz, dtype); } \
+    };
+
+// Wrapper for test fixture API. Use to specify multiple types.
+// Example: FIXTURE_API(int, bool) expands to <int, bool>
+#define FIXTURE_API(...) <__VA_ARGS__>
+
+template<typename T1, typename T2>
+struct CompareF
+{
+    using callable_t = std::function<bool(const T1& a, const T2& b)>;
+    CompareF(callable_t&& cmp, std::string&& cmp_name) :
+        _comparator(std::move(cmp)), _name(std::move(cmp_name)) {}
+    bool operator()(const T1& a, const T2& b) const
+    {
+        return _comparator(a, b);
+    }
+    friend std::ostream& operator<<(std::ostream& os, const CompareF<T1, T2>& obj)
+    {
+        return os << obj._name;
+    }
+private:
+    callable_t _comparator;
+    std::string _name;
+};
+
+using CompareMats = CompareF<cv::Mat, cv::Mat>;
+using CompareScalars = CompareF<cv::Scalar, cv::Scalar>;
 
 template<typename T>
 struct Wrappable
@@ -129,6 +272,14 @@ struct Wrappable
             return t(a, b);
         };
     }
+
+    CompareMats to_compare_obj()
+    {
+        T t = *static_cast<T*const>(this);
+        std::stringstream ss;
+        ss << t;
+        return CompareMats(to_compare_f(), ss.str());
+    }
 };
 
 template<typename T>
@@ -142,6 +293,14 @@ struct WrappableScalar
             return t(a, b);
         };
     }
+
+    CompareScalars to_compare_obj()
+    {
+        T t = *static_cast<T*const>(this);
+        std::stringstream ss;
+        ss << t;
+        return CompareScalars(to_compare_f(), ss.str());
+    }
 };
 
 
@@ -161,7 +320,10 @@ public:
             return true;
         }
     }
-private:
+    friend std::ostream& operator<<(std::ostream& os, const AbsExact&)
+    {
+        return os << "AbsExact()";
+    }
 };
 
 class AbsTolerance : public Wrappable<AbsTolerance>
@@ -181,6 +343,10 @@ public:
             return true;
         }
     }
+    friend std::ostream& operator<<(std::ostream& os, const AbsTolerance& obj)
+    {
+        return os << "AbsTolerance(" << std::to_string(obj._tol) << ")";
+    }
 private:
     double _tol;
 };
@@ -209,6 +375,10 @@ public:
             }
         }
     }
+    friend std::ostream& operator<<(std::ostream& os, const Tolerance_FloatRel_IntAbs& obj)
+    {
+        return os << "Tolerance_FloatRel_IntAbs(" << obj._tol << ", " << obj._tol8u << ")";
+    }
 private:
     double _tol;
     double _tol8u;
@@ -238,6 +408,10 @@ public:
             return true;
         }
     }
+    friend std::ostream& operator<<(std::ostream& os, const AbsSimilarPoints& obj)
+    {
+        return os << "AbsSimilarPoints(" << obj._tol << ", " << obj._percent << ")";
+    }
 private:
     double _tol;
     double _percent;
@@ -270,6 +444,11 @@ public:
         }
         return true;
     }
+    friend std::ostream& operator<<(std::ostream& os, const ToleranceFilter& obj)
+    {
+        return os << "ToleranceFilter(" << obj._tol << ", " << obj._tol8u << ", "
+                  << obj._inf_tol << ")";
+    }
 private:
     double _tol;
     double _tol8u;
@@ -298,6 +477,10 @@ public:
         }
         return true;
     }
+    friend std::ostream& operator<<(std::ostream& os, const ToleranceColor& obj)
+    {
+        return os << "ToleranceColor(" << obj._tol << ", " << obj._inf_tol << ")";
+    }
 private:
     double _tol;
     double _inf_tol;
@@ -320,24 +503,66 @@ public:
             return true;
         }
     }
+    friend std::ostream& operator<<(std::ostream& os, const AbsToleranceScalar& obj)
+    {
+        return os << "AbsToleranceScalar(" << std::to_string(obj._tol) << ")";
+    }
 private:
     double _tol;
 };
-
 } // namespace opencv_test
 
 namespace
 {
-    inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_f&)
+inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_f&)
+{
+    return os << "compare_f";
+}
+
+inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_scalar_f&)
+{
+    return os << "compare_scalar_f";
+}
+}  // anonymous namespace
+
+// Note: namespace must match the namespace of the type of the printed object
+namespace cv
+{
+inline std::ostream& operator<<(std::ostream& os, CmpTypes op)
+{
+#define CASE(v) case CmpTypes::v: os << #v; break
+    switch (op)
     {
-        return os << "compare_f";
+        CASE(CMP_EQ);
+        CASE(CMP_GT);
+        CASE(CMP_GE);
+        CASE(CMP_LT);
+        CASE(CMP_LE);
+        CASE(CMP_NE);
+        default: GAPI_Assert(false && "unknown CmpTypes value");
     }
+#undef CASE
+    return os;
 }
 
-namespace
+inline std::ostream& operator<<(std::ostream& os, NormTypes op)
 {
-    inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_scalar_f&)
+#define CASE(v) case NormTypes::v: os << #v; break
+    switch (op)
     {
-        return os << "compare_scalar_f";
+        CASE(NORM_INF);
+        CASE(NORM_L1);
+        CASE(NORM_L2);
+        CASE(NORM_L2SQR);
+        CASE(NORM_HAMMING);
+        CASE(NORM_HAMMING2);
+        CASE(NORM_RELATIVE);
+        CASE(NORM_MINMAX);
+        default: GAPI_Assert(false && "unknown NormTypes value");
     }
+#undef CASE
+    return os;
 }
+}  // namespace cv
+
+#endif //OPENCV_GAPI_TESTS_COMMON_HPP