gapi_plaidml_pipelines.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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) 2019 Intel Corporation
  6. #include "test_precomp.hpp"
  7. #include <stdexcept>
  8. #include <ade/util/iota_range.hpp>
  9. #include "logger.hpp"
  10. #include <opencv2/gapi/plaidml/core.hpp>
  11. #include <opencv2/gapi/plaidml/plaidml.hpp>
  12. namespace opencv_test
  13. {
  14. #ifdef HAVE_PLAIDML
  15. inline cv::gapi::plaidml::config getConfig()
  16. {
  17. auto read_var_from_env = [](const char* env)
  18. {
  19. const char* raw = std::getenv(env);
  20. if (!raw)
  21. {
  22. cv::util::throw_error(std::runtime_error(std::string(env) + " is't set"));
  23. }
  24. return std::string(raw);
  25. };
  26. auto dev_id = read_var_from_env("PLAIDML_DEVICE");
  27. auto trg_id = read_var_from_env("PLAIDML_TARGET");
  28. return cv::gapi::plaidml::config{std::move(dev_id),
  29. std::move(trg_id)};
  30. }
  31. TEST(GAPI_PlaidML_Pipelines, SimpleArithmetic)
  32. {
  33. cv::Size size(1920, 1080);
  34. int type = CV_8UC1;
  35. cv::Mat in_mat1(size, type);
  36. cv::Mat in_mat2(size, type);
  37. // NB: What about overflow ? PlaidML doesn't handle it
  38. cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(127));
  39. cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(127));
  40. cv::Mat out_mat(size, type, cv::Scalar::all(0));
  41. cv::Mat ref_mat(size, type, cv::Scalar::all(0));
  42. ////////////////////////////// G-API //////////////////////////////////////
  43. cv::GMat in1, in2;
  44. auto out = in1 + in2;
  45. cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out));
  46. comp.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat),
  47. cv::compile_args(getConfig(),
  48. cv::gapi::use_only{cv::gapi::core::plaidml::kernels()}));
  49. ////////////////////////////// OpenCV /////////////////////////////////////
  50. cv::add(in_mat1, in_mat2, ref_mat, cv::noArray(), type);
  51. EXPECT_EQ(0, cv::norm(out_mat, ref_mat));
  52. }
  53. // FIXME PlaidML cpu backend does't support bitwise operations
  54. TEST(GAPI_PlaidML_Pipelines, DISABLED_ComplexArithmetic)
  55. {
  56. cv::Size size(1920, 1080);
  57. int type = CV_8UC1;
  58. cv::Mat in_mat1(size, type);
  59. cv::Mat in_mat2(size, type);
  60. cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
  61. cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
  62. cv::Mat out_mat(size, type, cv::Scalar::all(0));
  63. cv::Mat ref_mat(size, type, cv::Scalar::all(0));
  64. ////////////////////////////// G-API //////////////////////////////////////
  65. cv::GMat in1, in2;
  66. auto out = in1 | (in2 ^ (in1 & (in2 + (in1 - in2))));
  67. cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out));
  68. comp.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat),
  69. cv::compile_args(getConfig(),
  70. cv::gapi::use_only{cv::gapi::core::plaidml::kernels()}));
  71. ////////////////////////////// OpenCV /////////////////////////////////////
  72. cv::subtract(in_mat1, in_mat2, ref_mat, cv::noArray(), type);
  73. cv::add(in_mat2, ref_mat, ref_mat, cv::noArray(), type);
  74. cv::bitwise_and(in_mat1, ref_mat, ref_mat);
  75. cv::bitwise_xor(in_mat2, ref_mat, ref_mat);
  76. cv::bitwise_or(in_mat1, ref_mat, ref_mat);
  77. EXPECT_EQ(0, cv::norm(out_mat, ref_mat));
  78. }
  79. TEST(GAPI_PlaidML_Pipelines, TwoInputOperations)
  80. {
  81. cv::Size size(1920, 1080);
  82. int type = CV_8UC1;
  83. constexpr int kNumInputs = 4;
  84. std::vector<cv::Mat> in_mat(kNumInputs, cv::Mat(size, type));
  85. for (int i = 0; i < kNumInputs; ++i)
  86. {
  87. cv::randu(in_mat[i], cv::Scalar::all(0), cv::Scalar::all(60));
  88. }
  89. cv::Mat out_mat(size, type, cv::Scalar::all(0));
  90. cv::Mat ref_mat(size, type, cv::Scalar::all(0));
  91. ////////////////////////////// G-API //////////////////////////////////////
  92. cv::GMat in[4];
  93. auto out = (in[3] - in[0]) + (in[2] - in[1]);
  94. cv::GComputation comp(cv::GIn(in[0], in[1], in[2], in[3]), cv::GOut(out));
  95. // FIXME Doesn't work just apply(in_mat, out_mat, ...)
  96. comp.apply(cv::gin(in_mat[0], in_mat[1], in_mat[2], in_mat[3]), cv::gout(out_mat),
  97. cv::compile_args(getConfig(),
  98. cv::gapi::use_only{cv::gapi::core::plaidml::kernels()}));
  99. ////////////////////////////// OpenCV /////////////////////////////////////
  100. cv::subtract(in_mat[3], in_mat[0], ref_mat, cv::noArray(), type);
  101. cv::add(ref_mat, in_mat[2], ref_mat, cv::noArray(), type);
  102. cv::subtract(ref_mat, in_mat[1], ref_mat, cv::noArray(), type);
  103. EXPECT_EQ(0, cv::norm(out_mat, ref_mat));
  104. }
  105. TEST(GAPI_PlaidML_Pipelines, TwoOutputOperations)
  106. {
  107. cv::Size size(1920, 1080);
  108. int type = CV_8UC1;
  109. constexpr int kNumInputs = 4;
  110. std::vector<cv::Mat> in_mat(kNumInputs, cv::Mat(size, type));
  111. for (int i = 0; i < kNumInputs; ++i)
  112. {
  113. cv::randu(in_mat[i], cv::Scalar::all(0), cv::Scalar::all(60));
  114. }
  115. std::vector<cv::Mat> out_mat(kNumInputs, cv::Mat(size, type, cv::Scalar::all(0)));
  116. std::vector<cv::Mat> ref_mat(kNumInputs, cv::Mat(size, type, cv::Scalar::all(0)));
  117. ////////////////////////////// G-API //////////////////////////////////////
  118. cv::GMat in[4], out[2];
  119. out[0] = in[0] + in[3];
  120. out[1] = in[1] + in[2];
  121. cv::GComputation comp(cv::GIn(in[0], in[1], in[2], in[3]), cv::GOut(out[0], out[1]));
  122. // FIXME Doesn't work just apply(in_mat, out_mat, ...)
  123. comp.apply(cv::gin(in_mat[0], in_mat[1], in_mat[2], in_mat[3]),
  124. cv::gout(out_mat[0], out_mat[1]),
  125. cv::compile_args(getConfig(),
  126. cv::gapi::use_only{cv::gapi::core::plaidml::kernels()}));
  127. ////////////////////////////// OpenCV /////////////////////////////////////
  128. cv::add(in_mat[0], in_mat[3], ref_mat[0], cv::noArray(), type);
  129. cv::add(in_mat[1], in_mat[2], ref_mat[1], cv::noArray(), type);
  130. EXPECT_EQ(0, cv::norm(out_mat[0], ref_mat[0]));
  131. EXPECT_EQ(0, cv::norm(out_mat[1], ref_mat[1]));
  132. }
  133. #else // HAVE_PLAIDML
  134. TEST(GAPI_PlaidML_Pipelines, ThrowIfPlaidMLNotFound)
  135. {
  136. ASSERT_ANY_THROW(cv::gapi::core::plaidml::kernels());
  137. }
  138. #endif // HAVE_PLAIDML
  139. } // namespace opencv_test