You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

pooling.cpp 9.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "test/common/pooling.h"
  2. #include "test/common/benchmarker.h"
  3. #include "test/common/checker.h"
  4. #include "test/common/task_record_check.h"
  5. #include "test/x86/fixture.h"
  6. namespace megdnn {
  7. namespace test {
  8. TEST_F(X86, POOLING) {
  9. auto args = pooling::get_args();
  10. for (auto&& arg : args) {
  11. Checker<Pooling> checker(handle());
  12. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  13. }
  14. }
  15. TEST_F(X86, POOLING_RECORD) {
  16. auto args = pooling::get_args();
  17. for (auto&& arg : args) {
  18. TaskRecordChecker<Pooling> checker(0);
  19. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  20. }
  21. }
  22. TEST_F(X86, S1POOLING88) {
  23. Checker<Pooling> checker(handle());
  24. auto run = [&](size_t WH, size_t WW, size_t PH, size_t PW, size_t SH, size_t SW,
  25. size_t N, size_t C, size_t H, size_t W) {
  26. Pooling::Param param;
  27. param.format = param::Pooling::Format::NCHW88;
  28. param.window_h = WH;
  29. param.window_w = WW;
  30. param.pad_h = PH;
  31. param.pad_w = PW;
  32. param.stride_w = SW;
  33. param.stride_h = SH;
  34. param.mode = param::Pooling::Mode::MAX;
  35. checker.set_param(param);
  36. checker.execs({{N, C, H, W, 8}, {}});
  37. };
  38. for (size_t wh = 10; wh < 15; ++wh) {
  39. for (size_t ww = 10; ww < 15; ++ww) {
  40. for (size_t n : {1, 2, 4}) {
  41. for (size_t c : {1, 4}) {
  42. for (size_t h : {10, 13, 20}) {
  43. for (size_t w : {10, 13, 20}) {
  44. run(wh, ww, wh / 2, ww / 2, 1, 1, n, c, h, w);
  45. }
  46. }
  47. }
  48. }
  49. }
  50. }
  51. }
  52. TEST_F(X86_MULTI_THREADS, S1POOLING88) {
  53. Checker<Pooling> checker(handle());
  54. auto run = [&](size_t WH, size_t WW, size_t PH, size_t PW, size_t SH, size_t SW,
  55. size_t N, size_t C, size_t H, size_t W) {
  56. Pooling::Param param;
  57. param.format = param::Pooling::Format::NCHW88;
  58. param.window_h = WH;
  59. param.window_w = WW;
  60. param.pad_h = PH;
  61. param.pad_w = PW;
  62. param.stride_w = SW;
  63. param.stride_h = SH;
  64. param.mode = param::Pooling::Mode::MAX;
  65. checker.set_param(param);
  66. checker.execs({{N, C, H, W, 8}, {}});
  67. };
  68. for (size_t wh = 10; wh < 15; ++wh) {
  69. for (size_t ww = 10; ww < 15; ++ww) {
  70. for (size_t n : {1, 2, 4}) {
  71. for (size_t c : {1, 4}) {
  72. for (size_t h : {10, 13, 20}) {
  73. for (size_t w : {10, 13, 20}) {
  74. run(wh, ww, wh / 2, ww / 2, 1, 1, n, c, h, w);
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. }
  82. #if MEGDNN_X86_WITH_MKL_DNN
  83. TEST_F(X86, POOLING88) {
  84. Checker<Pooling> checker(handle());
  85. auto args = pooling::get_args();
  86. for (auto&& arg : args) {
  87. arg.ishape.ndim = 5;
  88. arg.ishape[1] = (arg.ishape[1] + 7) / 8;
  89. arg.ishape[4] = 8;
  90. arg.param.format = param::Pooling::Format::NCHW88;
  91. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  92. }
  93. }
  94. TEST_F(X86, POOLING88_RECORD) {
  95. TaskRecordChecker<Pooling> checker(0);
  96. auto args = pooling::get_args();
  97. for (auto&& arg : args) {
  98. arg.ishape.ndim = 5;
  99. arg.ishape[1] = (arg.ishape[1] + 7) / 8;
  100. arg.ishape[4] = 8;
  101. arg.param.format = param::Pooling::Format::NCHW88;
  102. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  103. }
  104. }
  105. TEST_F(X86_MULTI_THREADS, POOLING88) {
  106. Checker<Pooling> checker(handle());
  107. auto args = pooling::get_args();
  108. for (auto&& arg : args) {
  109. arg.ishape.ndim = 5;
  110. arg.ishape[1] = (arg.ishape[1] + 7) / 8;
  111. arg.ishape[4] = 8;
  112. arg.param.format = param::Pooling::Format::NCHW88;
  113. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  114. }
  115. }
  116. #endif
  117. #if MEGDNN_WITH_BENCHMARK
  118. static void test_x86_megdnn_pooling(Handle* handle) {
  119. constexpr size_t RUNS = 50;
  120. auto rng = std::make_unique<UniformIntRNG>(-127, 127);
  121. Benchmarker<Pooling> benchmarker_pooling(handle);
  122. benchmarker_pooling.set_times(RUNS)
  123. .set_dtype(0, dtype::QuantizedS8(1.2))
  124. .set_display(false)
  125. .set_rng(0, rng.get());
  126. auto run = [&](uint32_t pad, uint32_t stride, uint32_t window_size,
  127. size_t in_number, size_t in_channel, size_t in_height,
  128. size_t in_width) {
  129. TensorLayout dst_layout;
  130. auto opr = handle->create_operator<Pooling>();
  131. opr->param() = {param::Pooling::Mode::MAX,
  132. pad,
  133. pad,
  134. stride,
  135. stride,
  136. window_size,
  137. window_size};
  138. TensorShape shape{in_number, in_channel, in_height, in_width};
  139. opr->deduce_layout({shape, dtype::Int8{}}, dst_layout);
  140. float computation =
  141. dst_layout.total_nr_elems() * window_size * window_size * 1e-9;
  142. auto pooling_used = benchmarker_pooling
  143. .set_param(
  144. {param::Pooling::Mode::MAX, pad, pad,
  145. stride, stride, window_size, window_size})
  146. .exec(TensorShapeArray{shape, {}}) /
  147. RUNS;
  148. float through_put = computation / pooling_used * 1e3;
  149. std::cout << "{" << pad << "," << stride << "," << window_size << ","
  150. << in_number << "," << in_channel << "," << in_height << ","
  151. << in_width << "} "
  152. << "use time " << pooling_used << "ms, "
  153. << "through_put " << through_put << "Gops, " << std::endl;
  154. };
  155. for (auto widows_size : {2, 3})
  156. for (auto stride : {2})
  157. for (auto pad : {2})
  158. for (auto n : {1, 3, 4})
  159. for (auto c : {1, 32, 64})
  160. for (auto h_w : {12, 32, 64}) {
  161. run(pad, stride, widows_size, n, c, h_w, h_w);
  162. }
  163. }
  164. TEST_F(X86, BENCHMARK_POOLING) {
  165. test_x86_megdnn_pooling(handle());
  166. }
  167. TEST_F(X86_MULTI_THREADS, BENCHMARK_POOLING) {
  168. test_x86_megdnn_pooling(handle());
  169. }
  170. TEST_F(X86, BENCHMARK_POOLING_MAX_S1_NCHW88) {
  171. constexpr size_t RUNS = 50;
  172. auto x86_handle = handle();
  173. Benchmarker<Pooling> benchmarker_pooling(x86_handle);
  174. benchmarker_pooling.set_times(RUNS);
  175. auto run = [&](uint32_t pad, uint32_t stride, uint32_t window_size,
  176. size_t in_number, size_t in_channel, size_t in_height,
  177. size_t in_width) {
  178. auto opr = x86_handle->create_operator<Pooling>();
  179. opr->param() = {param::Pooling::Mode::MAX,
  180. pad,
  181. pad,
  182. stride,
  183. stride,
  184. window_size,
  185. window_size};
  186. opr->param().format = param::Pooling::Format::NCHW88;
  187. TensorShape shape{in_number, in_channel / 8, in_height, in_width, 8};
  188. TensorLayout dst_layout;
  189. opr->deduce_layout({shape, dtype::Float32()}, dst_layout);
  190. float computation =
  191. dst_layout.total_nr_elems() * window_size * window_size * 1e-9;
  192. auto pooling_used = benchmarker_pooling.set_param(opr->param())
  193. .exec(TensorShapeArray{shape, {}}) /
  194. RUNS;
  195. float through_put = computation / pooling_used * 1e3;
  196. printf("profiling max pooling NCHW88 {%zu,%zu,%zu,%zu,8}\nuse time : "
  197. "%f ms\nthrough_put : %f Gflops\n",
  198. in_number, in_channel / 8, in_height, in_width, pooling_used,
  199. through_put);
  200. };
  201. run(6, 1, 13, 1, 32 * 8, 20, 20);
  202. }
  203. #endif
  204. #if MEGDNN_X86_WITH_MKL_DNN
  205. TEST_F(X86, POOLING_INT8) {
  206. auto args = pooling::get_args();
  207. for (auto&& arg : args) {
  208. Checker<Pooling> checker(handle());
  209. auto rng = std::make_unique<UniformIntRNG>(-127, 127);
  210. checker.set_dtype(0, dtype::Int8()).set_rng(0, rng.get());
  211. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  212. }
  213. }
  214. TEST_F(X86, POOLING_INT8_RECORD) {
  215. auto args = pooling::get_args();
  216. for (auto&& arg : args) {
  217. Checker<Pooling> checker(handle());
  218. auto rng = std::make_unique<UniformIntRNG>(-127, 127);
  219. checker.set_dtype(0, dtype::Int8()).set_rng(0, rng.get());
  220. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  221. }
  222. }
  223. TEST_F(X86_MULTI_THREADS, POOLING_INT8) {
  224. auto args = pooling::get_args();
  225. for (auto&& arg : args) {
  226. Checker<Pooling> checker(handle());
  227. auto rng = std::make_unique<UniformIntRNG>(-127, 127);
  228. checker.set_dtype(0, dtype::Int8()).set_rng(0, rng.get());
  229. checker.set_param(arg.param).exec(TensorShapeArray{arg.ishape, {}});
  230. }
  231. }
  232. #endif
  233. } // namespace test
  234. } // namespace megdnn
  235. // vim: syntax=cpp.doxygen