test_common.hpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #ifndef __OPENCV_TEST_COMMON_HPP__
  5. #define __OPENCV_TEST_COMMON_HPP__
  6. #include "opencv2/dnn/utils/inference_engine.hpp"
  7. #ifdef HAVE_OPENCL
  8. #include "opencv2/core/ocl.hpp"
  9. #endif
  10. // src/op_inf_engine.hpp
  11. #define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
  12. #define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
  13. #define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
  14. #define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
  15. #define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
  16. #define CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND "dnn_skip_opencv_backend"
  17. #define CV_TEST_TAG_DNN_SKIP_HALIDE "dnn_skip_halide"
  18. #define CV_TEST_TAG_DNN_SKIP_CPU "dnn_skip_cpu"
  19. #define CV_TEST_TAG_DNN_SKIP_CPU_FP16 "dnn_skip_cpu_fp16"
  20. #define CV_TEST_TAG_DNN_SKIP_OPENCL "dnn_skip_ocl"
  21. #define CV_TEST_TAG_DNN_SKIP_OPENCL_FP16 "dnn_skip_ocl_fp16"
  22. #define CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER "dnn_skip_ie_nn_builder"
  23. #define CV_TEST_TAG_DNN_SKIP_IE_NGRAPH "dnn_skip_ie_ngraph"
  24. #define CV_TEST_TAG_DNN_SKIP_IE "dnn_skip_ie"
  25. #define CV_TEST_TAG_DNN_SKIP_IE_2018R5 "dnn_skip_ie_2018r5"
  26. #define CV_TEST_TAG_DNN_SKIP_IE_2019R1 "dnn_skip_ie_2019r1"
  27. #define CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 "dnn_skip_ie_2019r1_1"
  28. #define CV_TEST_TAG_DNN_SKIP_IE_2019R2 "dnn_skip_ie_2019r2"
  29. #define CV_TEST_TAG_DNN_SKIP_IE_2019R3 "dnn_skip_ie_2019r3"
  30. #define CV_TEST_TAG_DNN_SKIP_IE_CPU "dnn_skip_ie_cpu"
  31. #define CV_TEST_TAG_DNN_SKIP_IE_OPENCL "dnn_skip_ie_ocl"
  32. #define CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16 "dnn_skip_ie_ocl_fp16"
  33. #define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2 "dnn_skip_ie_myriad2"
  34. #define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X "dnn_skip_ie_myriadx"
  35. #define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X
  36. #define CV_TEST_TAG_DNN_SKIP_IE_ARM_CPU "dnn_skip_ie_arm_cpu"
  37. #define CV_TEST_TAG_DNN_SKIP_VULKAN "dnn_skip_vulkan"
  38. #define CV_TEST_TAG_DNN_SKIP_CUDA "dnn_skip_cuda"
  39. #define CV_TEST_TAG_DNN_SKIP_CUDA_FP16 "dnn_skip_cuda_fp16"
  40. #define CV_TEST_TAG_DNN_SKIP_CUDA_FP32 "dnn_skip_cuda_fp32"
  41. #define CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE "dnn_skip_onnx_conformance"
  42. #define CV_TEST_TAG_DNN_SKIP_PARSER "dnn_skip_parser"
  43. #define CV_TEST_TAG_DNN_SKIP_GLOBAL "dnn_skip_global"
  44. #define CV_TEST_TAG_DNN_SKIP_TIMVX "dnn_skip_timvx"
  45. #define CV_TEST_TAG_DNN_SKIP_CANN "dnn_skip_cann"
  46. #ifdef HAVE_INF_ENGINE
  47. #if INF_ENGINE_VER_MAJOR_EQ(2018050000)
  48. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2018R5
  49. #elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
  50. # if INF_ENGINE_RELEASE < 2019010100
  51. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1
  52. # else
  53. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R1_1
  54. # endif
  55. #elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
  56. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2
  57. #elif INF_ENGINE_VER_MAJOR_EQ(2019030000)
  58. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R3
  59. #endif
  60. #endif // HAVE_INF_ENGINE
  61. #ifndef CV_TEST_TAG_DNN_SKIP_IE_VERSION
  62. # define CV_TEST_TAG_DNN_SKIP_IE_VERSION CV_TEST_TAG_DNN_SKIP_IE
  63. #endif
  64. namespace cv { namespace dnn {
  65. CV__DNN_INLINE_NS_BEGIN
  66. void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
  67. void PrintTo(const cv::dnn::Target& v, std::ostream* os);
  68. using opencv_test::tuple;
  69. using opencv_test::get;
  70. void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
  71. CV__DNN_INLINE_NS_END
  72. }} // namespace cv::dnn
  73. namespace opencv_test {
  74. void initDNNTests();
  75. using namespace cv::dnn;
  76. static inline const std::string &getOpenCVExtraDir()
  77. {
  78. return cvtest::TS::ptr()->get_data_path();
  79. }
  80. void normAssert(
  81. cv::InputArray ref, cv::InputArray test, const char *comment = "",
  82. double l1 = 0.00001, double lInf = 0.0001);
  83. std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
  84. void normAssertDetections(
  85. const std::vector<int>& refClassIds,
  86. const std::vector<float>& refScores,
  87. const std::vector<cv::Rect2d>& refBoxes,
  88. const std::vector<int>& testClassIds,
  89. const std::vector<float>& testScores,
  90. const std::vector<cv::Rect2d>& testBoxes,
  91. const char *comment = "", double confThreshold = 0.0,
  92. double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
  93. // For SSD-based object detection networks which produce output of shape 1x1xNx7
  94. // where N is a number of detections and an every detection is represented by
  95. // a vector [batchId, classId, confidence, left, top, right, bottom].
  96. void normAssertDetections(
  97. cv::Mat ref, cv::Mat out, const char *comment = "",
  98. double confThreshold = 0.0, double scores_diff = 1e-5,
  99. double boxes_iou_diff = 1e-4);
  100. // For text detection networks
  101. // Curved text polygon is not supported in the current version.
  102. // (concave polygon is invalid input to intersectConvexConvex)
  103. void normAssertTextDetections(
  104. const std::vector<std::vector<Point>>& gtPolys,
  105. const std::vector<std::vector<Point>>& testPolys,
  106. const char *comment = "", double boxes_iou_diff = 1e-4);
  107. void readFileContent(const std::string& filename, CV_OUT std::vector<char>& content);
  108. bool validateVPUType();
  109. testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
  110. bool withInferenceEngine = true,
  111. bool withHalide = false,
  112. bool withCpuOCV = true,
  113. bool withVkCom = true,
  114. bool withCUDA = true,
  115. bool withNgraph = true,
  116. bool withWebnn = true,
  117. bool withCann = true
  118. );
  119. testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargetsIE();
  120. class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
  121. {
  122. public:
  123. dnn::Backend backend;
  124. dnn::Target target;
  125. double default_l1, default_lInf;
  126. DNNTestLayer()
  127. {
  128. backend = (dnn::Backend)(int)get<0>(GetParam());
  129. target = (dnn::Target)(int)get<1>(GetParam());
  130. getDefaultThresholds(backend, target, &default_l1, &default_lInf);
  131. }
  132. static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
  133. {
  134. if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
  135. {
  136. *l1 = 4e-3;
  137. *lInf = 2e-2;
  138. }
  139. else
  140. {
  141. *l1 = 1e-5;
  142. *lInf = 1e-4;
  143. }
  144. }
  145. static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
  146. {
  147. CV_UNUSED(backend); CV_UNUSED(target); CV_UNUSED(inp); CV_UNUSED(ref);
  148. #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021000000)
  149. if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
  150. && target == DNN_TARGET_MYRIAD)
  151. {
  152. if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
  153. inp->size[0] != 1 && inp->size[0] != ref->size[0])
  154. {
  155. std::cout << "Inconsistent batch size of input and output blobs for Myriad plugin" << std::endl;
  156. applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
  157. }
  158. }
  159. #endif
  160. }
  161. void expectNoFallbacks(Net& net, bool raiseError = true)
  162. {
  163. // Check if all the layers are supported with current backend and target.
  164. // Some layers might be fused so their timings equal to zero.
  165. std::vector<double> timings;
  166. net.getPerfProfile(timings);
  167. std::vector<String> names = net.getLayerNames();
  168. CV_Assert(names.size() == timings.size());
  169. bool hasFallbacks = false;
  170. for (int i = 0; i < names.size(); ++i)
  171. {
  172. Ptr<dnn::Layer> l = net.getLayer(net.getLayerId(names[i]));
  173. bool fused = !timings[i];
  174. if ((!l->supportBackend(backend) || l->preferableTarget != target) && !fused)
  175. {
  176. hasFallbacks = true;
  177. std::cout << "FALLBACK: Layer [" << l->type << "]:[" << l->name << "] is expected to have backend implementation" << endl;
  178. }
  179. }
  180. if (hasFallbacks && raiseError)
  181. CV_Error(Error::StsNotImplemented, "Implementation fallbacks are not expected in this test");
  182. }
  183. void expectNoFallbacksFromIE(Net& net)
  184. {
  185. if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
  186. expectNoFallbacks(net);
  187. if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
  188. expectNoFallbacks(net, false);
  189. }
  190. void expectNoFallbacksFromCUDA(Net& net)
  191. {
  192. if (backend == DNN_BACKEND_CUDA)
  193. expectNoFallbacks(net);
  194. }
  195. size_t getTopMemoryUsageMB();
  196. protected:
  197. void checkBackend(Mat* inp = 0, Mat* ref = 0)
  198. {
  199. checkBackend(backend, target, inp, ref);
  200. }
  201. };
  202. } // namespace
  203. #endif