Merge remote-tracking branch 'upstream/3.4' into merge-3.4
[platform/upstream/opencv.git] / modules / dnn / test / test_common.hpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4
5 #ifndef __OPENCV_TEST_COMMON_HPP__
6 #define __OPENCV_TEST_COMMON_HPP__
7
8 #include "opencv2/dnn/utils/inference_engine.hpp"
9
10 #ifdef HAVE_OPENCL
11 #include "opencv2/core/ocl.hpp"
12 #endif
13
14
15 namespace cv { namespace dnn {
16 CV__DNN_INLINE_NS_BEGIN
17
18 void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
19 void PrintTo(const cv::dnn::Target& v, std::ostream* os);
20 using opencv_test::tuple;
21 using opencv_test::get;
22 void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
23
24 CV__DNN_INLINE_NS_END
25 }} // namespace cv::dnn
26
27
28
29 namespace opencv_test {
30
31 using namespace cv::dnn;
32
33 static inline const std::string &getOpenCVExtraDir()
34 {
35     return cvtest::TS::ptr()->get_data_path();
36 }
37
38 void normAssert(
39         cv::InputArray ref, cv::InputArray test, const char *comment = "",
40         double l1 = 0.00001, double lInf = 0.0001);
41
42 std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
43
44 void normAssertDetections(
45         const std::vector<int>& refClassIds,
46         const std::vector<float>& refScores,
47         const std::vector<cv::Rect2d>& refBoxes,
48         const std::vector<int>& testClassIds,
49         const std::vector<float>& testScores,
50         const std::vector<cv::Rect2d>& testBoxes,
51         const char *comment = "", double confThreshold = 0.0,
52         double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
53
54 // For SSD-based object detection networks which produce output of shape 1x1xNx7
55 // where N is a number of detections and an every detection is represented by
56 // a vector [batchId, classId, confidence, left, top, right, bottom].
57 void normAssertDetections(
58         cv::Mat ref, cv::Mat out, const char *comment = "",
59         double confThreshold = 0.0, double scores_diff = 1e-5,
60         double boxes_iou_diff = 1e-4);
61
62 void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content);
63
64 #ifdef HAVE_INF_ENGINE
65 bool validateVPUType();
66 #endif
67
68 testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
69         bool withInferenceEngine = true,
70         bool withHalide = false,
71         bool withCpuOCV = true,
72         bool withVkCom = true
73 );
74
75
76 class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
77 {
78 public:
79     dnn::Backend backend;
80     dnn::Target target;
81     double default_l1, default_lInf;
82
83     DNNTestLayer()
84     {
85         backend = (dnn::Backend)(int)get<0>(GetParam());
86         target = (dnn::Target)(int)get<1>(GetParam());
87         getDefaultThresholds(backend, target, &default_l1, &default_lInf);
88     }
89
90     static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
91     {
92         if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
93         {
94             *l1 = 4e-3;
95             *lInf = 2e-2;
96         }
97         else
98         {
99             *l1 = 1e-5;
100             *lInf = 1e-4;
101         }
102     }
103
104     static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
105     {
106         if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
107         {
108             if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
109                 inp->size[0] != 1 && inp->size[0] != ref->size[0])
110                 throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
111         }
112     }
113
114     void expectNoFallbacks(Net& net)
115     {
116         // Check if all the layers are supported with current backend and target.
117         // Some layers might be fused so their timings equal to zero.
118         std::vector<double> timings;
119         net.getPerfProfile(timings);
120         std::vector<String> names = net.getLayerNames();
121         CV_Assert(names.size() == timings.size());
122
123         for (int i = 0; i < names.size(); ++i)
124         {
125             Ptr<dnn::Layer> l = net.getLayer(net.getLayerId(names[i]));
126             bool fused = !timings[i];
127             if ((!l->supportBackend(backend) || l->preferableTarget != target) && !fused)
128                 CV_Error(Error::StsNotImplemented, "Layer [" + l->name + "] of type [" +
129                          l->type + "] is expected to has backend implementation");
130         }
131     }
132
133     void expectNoFallbacksFromIE(Net& net)
134     {
135         if (backend == DNN_BACKEND_INFERENCE_ENGINE)
136             expectNoFallbacks(net);
137     }
138
139 protected:
140     void checkBackend(Mat* inp = 0, Mat* ref = 0)
141     {
142         checkBackend(backend, target, inp, ref);
143     }
144 };
145
146 } // namespace
147
148
149 // src/op_inf_engine.hpp
150 #define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
151 #define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
152 #define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
153 #define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
154 #define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
155
156 #endif