gapi_gpu_test.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. // Copyright (C) 2018 Intel Corporation
  6. #include "test_precomp.hpp"
  7. #include "logger.hpp"
  8. #include "common/gapi_tests_common.hpp"
  9. #include <opencv2/gapi/gpu/ggpukernel.hpp>
  10. #include "opencl_kernels_test_gapi.hpp"
  11. namespace cv
  12. {
  13. #ifdef HAVE_OPENCL
  14. static void reference_symm7x7_CPU(const cv::Mat& in, const cv::Mat& kernel_coeff, int shift, cv::Mat &out)
  15. {
  16. cv::Point anchor = { -1, -1 };
  17. double delta = 0;
  18. const int* ci = kernel_coeff.ptr<int>();
  19. float c_float[10];
  20. float divisor = (float)(1 << shift);
  21. for (int i = 0; i < 10; i++)
  22. {
  23. c_float[i] = ci[i] / divisor;
  24. }
  25. // J & I & H & G & H & I & J
  26. // I & F & E & D & E & F & I
  27. // H & E & C & B & C & E & H
  28. // G & D & B & A & B & D & G
  29. // H & E & C & B & C & E & H
  30. // I & F & E & D & E & F & I
  31. // J & I & H & G & H & I & J
  32. // A & B & C & D & E & F & G & H & I & J
  33. // 9 & 8 & 7 & 6 & 7 & 8 & 9
  34. // 8 & 5 & 4 & 3 & 4 & 5 & 8
  35. // 7 & 4 & 2 & 1 & 2 & 4 & 7
  36. // 6 & 3 & 1 & 0 & 1 & 3 & 6
  37. // 7 & 4 & 2 & 1 & 2 & 4 & 7
  38. // 8 & 5 & 4 & 3 & 4 & 5 & 8
  39. // 9 & 8 & 7 & 6 & 7 & 8 & 9
  40. float coefficients[49] =
  41. {
  42. c_float[9], c_float[8], c_float[7], c_float[6], c_float[7], c_float[8], c_float[9],
  43. c_float[8], c_float[5], c_float[4], c_float[3], c_float[4], c_float[5], c_float[8],
  44. c_float[7], c_float[4], c_float[2], c_float[1], c_float[2], c_float[4], c_float[7],
  45. c_float[6], c_float[3], c_float[1], c_float[0], c_float[1], c_float[3], c_float[6],
  46. c_float[7], c_float[4], c_float[2], c_float[1], c_float[2], c_float[4], c_float[7],
  47. c_float[8], c_float[5], c_float[4], c_float[3], c_float[4], c_float[5], c_float[8],
  48. c_float[9], c_float[8], c_float[7], c_float[6], c_float[7], c_float[8], c_float[9]
  49. };
  50. cv::Mat kernel = cv::Mat(7, 7, CV_32FC1);
  51. float* cf = kernel.ptr<float>();
  52. for (int i = 0; i < 49; i++)
  53. {
  54. cf[i] = coefficients[i];
  55. }
  56. cv::filter2D(in, out, CV_8UC1, kernel, anchor, delta, cv::BORDER_REPLICATE);
  57. }
  58. namespace gapi_test_kernels
  59. {
  60. G_TYPED_KERNEL(TSymm7x7_test, <GMat(GMat, Mat, int)>, "org.opencv.imgproc.symm7x7_test") {
  61. static GMatDesc outMeta(GMatDesc in, Mat, int) {
  62. return in.withType(CV_8U, 1);
  63. }
  64. };
  65. GAPI_GPU_KERNEL(GGPUSymm7x7_test, TSymm7x7_test)
  66. {
  67. static void run(const cv::UMat& in, const cv::Mat& kernel_coeff, int shift, cv::UMat &out)
  68. {
  69. if (cv::ocl::isOpenCLActivated())
  70. {
  71. cv::Size size = in.size();
  72. size_t globalsize[2] = { (size_t)size.width, (size_t)size.height };
  73. const cv::String moduleName = "gapi";
  74. cv::ocl::ProgramSource source(moduleName, "symm7x7", opencl_symm7x7_src, "");
  75. static const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_UNDEFINED" };
  76. std::string build_options = " -D BORDER_CONSTANT_VALUE=" + std::to_string(0) +
  77. " -D " + borderMap[1] +
  78. " -D SCALE=1.f/" + std::to_string(1 << shift) + ".f";
  79. cv::String errmsg;
  80. cv::ocl::Program program(source, build_options, errmsg);
  81. if (program.ptr() == NULL)
  82. {
  83. CV_Error_(cv::Error::OpenCLInitError, ("symm_7x7_test Can't compile OpenCL program: = %s with build_options = %s\n", errmsg.c_str(), build_options.c_str()));
  84. }
  85. if (!errmsg.empty())
  86. {
  87. std::cout << "OpenCL program build log:" << std::endl << errmsg << std::endl;
  88. }
  89. cv::ocl::Kernel kernel("symm_7x7_test", program);
  90. if (kernel.empty())
  91. {
  92. CV_Error(cv::Error::OpenCLInitError, "symm_7x7_test Can't get OpenCL kernel\n");
  93. }
  94. cv::UMat gKer;
  95. kernel_coeff.copyTo(gKer);
  96. int tile_y = 0;
  97. int idxArg = kernel.set(0, cv::ocl::KernelArg::PtrReadOnly(in));
  98. idxArg = kernel.set(idxArg, (int)in.step);
  99. idxArg = kernel.set(idxArg, (int)size.width);
  100. idxArg = kernel.set(idxArg, (int)size.height);
  101. idxArg = kernel.set(idxArg, cv::ocl::KernelArg::PtrWriteOnly(out));
  102. idxArg = kernel.set(idxArg, (int)out.step);
  103. idxArg = kernel.set(idxArg, (int)size.height);
  104. idxArg = kernel.set(idxArg, (int)size.width);
  105. idxArg = kernel.set(idxArg, (int)tile_y);
  106. idxArg = kernel.set(idxArg, cv::ocl::KernelArg::PtrReadOnly(gKer));
  107. if (!kernel.run(2, globalsize, NULL, false))
  108. {
  109. CV_Error(cv::Error::OpenCLApiCallError, "symm_7x7_test OpenCL kernel run failed\n");
  110. }
  111. }
  112. else
  113. {
  114. //CPU fallback
  115. cv::Mat in_Mat, out_Mat;
  116. in_Mat = in.getMat(ACCESS_READ);
  117. out_Mat = out.getMat(ACCESS_WRITE);
  118. reference_symm7x7_CPU(in_Mat, kernel_coeff, shift, out_Mat);
  119. }
  120. }
  121. };
  122. cv::GKernelPackage gpuTestPackage = cv::gapi::kernels
  123. <GGPUSymm7x7_test
  124. >();
  125. } // namespace gapi_test_kernels
  126. #endif //HAVE_OPENCL
  127. } // namespace cv
  128. namespace opencv_test
  129. {
  130. #ifdef HAVE_OPENCL
  131. using namespace cv::gapi_test_kernels;
  132. TEST(GPU, Symm7x7_test)
  133. {
  134. const auto sz = cv::Size(1280, 720);
  135. cv::Mat in_mat = cv::Mat::eye(sz, CV_8UC1);
  136. cv::Mat out_mat_gapi(sz, CV_8UC1);
  137. cv::Mat out_mat_ocv(sz, CV_8UC1);
  138. cv::Scalar mean = cv::Scalar(127.0f);
  139. cv::Scalar stddev = cv::Scalar(40.f);
  140. cv::randn(in_mat, mean, stddev);
  141. //Symm7x7 coefficients and shift
  142. int coefficients_symm7x7[10] = { 1140, -118, 526, 290, -236, 64, -128, -5, -87, -7 };
  143. int shift = 10;
  144. cv::Mat kernel_coeff(10, 1, CV_32S);
  145. int* ci = kernel_coeff.ptr<int>();
  146. for (int i = 0; i < 10; i++)
  147. {
  148. ci[i] = coefficients_symm7x7[i];
  149. }
  150. // Run G-API
  151. cv::GMat in;
  152. auto out = TSymm7x7_test::on(in, kernel_coeff, shift);
  153. cv::GComputation comp(cv::GIn(in), cv::GOut(out));
  154. auto cc = comp.compile(cv::descr_of(in_mat), cv::compile_args(gpuTestPackage));
  155. cc(cv::gin(in_mat), cv::gout(out_mat_gapi));
  156. // Run OpenCV
  157. reference_symm7x7_CPU(in_mat, kernel_coeff, shift, out_mat_ocv);
  158. compare_f cmpF = AbsSimilarPoints(1, 0.05).to_compare_f();
  159. // Comparison //////////////////////////////////////////////////////////////
  160. {
  161. EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
  162. EXPECT_EQ(out_mat_gapi.size(), sz);
  163. }
  164. }
  165. #endif
  166. } // namespace opencv_test