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.

convolution3d.cpp 16 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /**
  2. * \file dnn/test/common/convolution3d.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "test/common/convolution3d.h"
  12. #include <chrono>
  13. #include <sstream>
  14. #include <unordered_set>
  15. #include "test/common/checker.h"
  16. using namespace megdnn;
  17. using namespace test;
  18. using namespace convolution3d;
  19. std::vector<TestArg> convolution3d::get_1x1x1_args() {
  20. std::vector<TestArg> args;
  21. param::Convolution3D param;
  22. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  23. // clang-format off
  24. for (size_t batch_size: {4, 8})
  25. for (size_t ic: {1, 4, 8})
  26. for (size_t oc: {ic})
  27. for (size_t id: {4, 16, 64})
  28. for (size_t ih : {id})
  29. for (size_t iw : {id}) {
  30. args.emplace_back(param, TensorShape{batch_size, ic, id, ih, iw},
  31. TensorShape{oc, ic, 1, 1, 1});
  32. }
  33. // clang-format on
  34. return args;
  35. }
  36. #if MEGDNN_WITH_BENCHMARK
  37. std::vector<TestArg> convolution3d::get_speed_test_args() {
  38. std::vector<TestArg> args;
  39. std::vector<std::pair<size_t, size_t>> range;
  40. range.push_back(std::pair<size_t, size_t>(10, 16));
  41. // clang-format off
  42. for (size_t n: {64})
  43. for (size_t id: {18, 32, 64})
  44. for (size_t ih: {id})
  45. for (size_t iw: {18, 64, 128})
  46. for (size_t oc: {16, 64})
  47. for (size_t ic: {oc})
  48. for (size_t fd: {1, 2, 3})
  49. for (size_t fh: {fd})
  50. for (size_t fw: {fh})
  51. for (size_t pd: {0, 1})
  52. for (size_t sd: {1, 2, 3})
  53. for (size_t dd: {1, 3})
  54. for (size_t cw: {false})
  55. for (bool xcorr: {false, true}) {
  56. param::Convolution3D param;
  57. param.mode = xcorr ? param::Convolution3D::Mode::CROSS_CORRELATION
  58. : param::Convolution3D::Mode::CONVOLUTION;
  59. param.stride_d = param.stride_h = param.stride_w = sd;
  60. param.pad_d = param.pad_h = param.pad_w = pd;
  61. param.dilate_d = param.dilate_h = param.dilate_w = dd;
  62. if (cw)
  63. param.sparse = param::Convolution3D::Sparse::GROUP;
  64. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  65. !cw ? TensorShape{oc, ic, fd, fh, fw}
  66. : TensorShape{ic, oc, 1, fd, fh, fw});
  67. }
  68. // clang-format on
  69. return args;
  70. }
  71. #endif
  72. std::vector<TestArg> convolution3d::get_args() {
  73. std::vector<TestArg> args;
  74. std::vector<std::pair<size_t, size_t>> range;
  75. range.push_back(std::pair<size_t, size_t>(11, 13));
  76. // clang-format off
  77. #if 1
  78. for (size_t n: {4})
  79. for (size_t id: {12, 16})
  80. for (size_t ih: {id})
  81. for (size_t iw: {16})
  82. for (size_t ic: {5, 10})
  83. for (size_t oc: {ic})
  84. for (size_t fd: {1,2,3})
  85. for (size_t fh: {fd})
  86. for (size_t fw: {fh})
  87. for (size_t pd: {0, 4})
  88. for (size_t sd: {2})
  89. #if CUDNN_MAJOR >= 6
  90. for (size_t dd: {1, 3, 4})
  91. #else
  92. for (size_t dd: {1})
  93. #endif
  94. for (size_t cw: {false})
  95. for (bool xcorr: {false, true}) {
  96. param::Convolution3D param;
  97. param.mode = xcorr ? param::Convolution3D::Mode::CROSS_CORRELATION
  98. : param::Convolution3D::Mode::CONVOLUTION;
  99. param.stride_d = param.stride_h = param.stride_w = sd;
  100. param.pad_d = param.pad_h = param.pad_w = pd;
  101. param.dilate_d = param.dilate_h = param.dilate_w = dd;
  102. if (cw)
  103. param.sparse = param::Convolution3D::Sparse::GROUP;
  104. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  105. !cw ? TensorShape{oc, ic, fd, fh, fw}
  106. : TensorShape{ic, oc, 1, fd, fh, fw});
  107. }
  108. return args;
  109. #endif
  110. // clang-format on
  111. // clang-format off
  112. for (size_t n: {8})
  113. for (size_t id: {20})
  114. for (size_t ih: {id})
  115. for (size_t iw: {id})
  116. for (size_t ic: {1})
  117. for (size_t oc: {ic})
  118. for (size_t fd: {3})
  119. for (size_t fh: {fd})
  120. for (size_t fw: {fh})
  121. for (size_t pd: {1, 2, 3})
  122. for (size_t sd: {2})
  123. for (size_t dd: {1, 2})
  124. for (size_t cw: {false})
  125. for (bool xcorr: {false, true}) {
  126. param::Convolution3D param;
  127. param.mode = xcorr ? param::Convolution3D::Mode::CROSS_CORRELATION
  128. : param::Convolution3D::Mode::CONVOLUTION;
  129. param.stride_d = param.stride_h = param.stride_w = sd;
  130. param.pad_d = param.pad_h = param.pad_w = pd;
  131. param.dilate_d = param.dilate_h = param.dilate_w = dd;
  132. if (cw)
  133. param.sparse = param::Convolution3D::Sparse::GROUP;
  134. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  135. !cw ? TensorShape{oc, ic, fd, fh, fw}
  136. : TensorShape{ic, oc, 1, fd, fh, fw});
  137. }
  138. // clang-format on
  139. return args;
  140. for (size_t i = range[0].first; i < range[0].second; ++i) {
  141. param::Convolution3D param;
  142. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  143. args.emplace_back(
  144. param, TensorShape{4, 10, i, i + 1, i + 2},
  145. TensorShape{10, 10, 1, 1, 1});
  146. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  147. args.emplace_back(
  148. param, TensorShape{4, 10, i, i + 1, i + 2},
  149. TensorShape{4, 10, 1, 1, 1});
  150. }
  151. for (size_t i = 2; i < 6; ++i) {
  152. param::Convolution3D param;
  153. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  154. args.emplace_back(
  155. param, TensorShape{1, 1, i, i + 1, i + 2}, TensorShape{1, 1, 1, 2, 3});
  156. }
  157. for (size_t i = 2; i < 6; ++i) {
  158. param::Convolution3D param;
  159. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  160. args.emplace_back(
  161. param, TensorShape{1, 1, i, i + 1, i + 2}, TensorShape{1, 1, 1, 2, 3});
  162. }
  163. for (size_t i = 2; i < 5; ++i) {
  164. param::Convolution3D param;
  165. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  166. args.emplace_back(
  167. param, TensorShape{1, 1, i, i + 1, i + 2}, TensorShape{1, 1, 2, 2, 2});
  168. }
  169. for (size_t i = range[0].first; i < range[0].second; ++i) {
  170. param::Convolution3D param;
  171. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  172. args.emplace_back(
  173. param, TensorShape{5, 2, i, i + 1, i + 2}, TensorShape{3, 2, 3, 4, 5});
  174. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  175. args.emplace_back(
  176. param, TensorShape{5, 2, i, i + 1, i + 2}, TensorShape{3, 2, 3, 4, 5});
  177. }
  178. // padding case
  179. for (size_t i = range[0].first; i < range[0].second; ++i) {
  180. param::Convolution3D param;
  181. param.pad_d = 1;
  182. param.pad_h = 2;
  183. param.pad_w = 3;
  184. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  185. args.emplace_back(
  186. param, TensorShape{5, 2, i, i + 1, i + 2}, TensorShape{3, 2, 3, 4, 5});
  187. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  188. args.emplace_back(
  189. param, TensorShape{5, 2, i, i + 1, i + 2}, TensorShape{3, 2, 3, 4, 5});
  190. }
  191. // large channel
  192. for (size_t i = range[0].first; i < range[0].second; ++i) {
  193. param::Convolution3D param;
  194. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  195. args.emplace_back(
  196. param, TensorShape{2, 20, i, i + 1, i + 2},
  197. TensorShape{30, 20, 3, 4, 5});
  198. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  199. args.emplace_back(
  200. param, TensorShape{2, 20, i, i + 1, i + 2},
  201. TensorShape{30, 20, 3, 4, 5});
  202. }
  203. for (size_t i = range[0].first; i < range[0].second; ++i) {
  204. param::Convolution3D param;
  205. param.pad_d = 1;
  206. param.pad_h = 2;
  207. param.pad_w = 3;
  208. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  209. args.emplace_back(
  210. param, TensorShape{2, 20, i, i + 1, i + 2},
  211. TensorShape{30, 20, 3, 4, 5});
  212. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  213. args.emplace_back(
  214. param, TensorShape{2, 20, i, i + 1, i + 2},
  215. TensorShape{30, 20, 3, 4, 5});
  216. }
  217. // 1x1x1
  218. for (size_t i = range[0].first; i < range[0].second; ++i) {
  219. param::Convolution3D param;
  220. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  221. args.emplace_back(
  222. param, TensorShape{2, 20, i, i + 1, i + 2},
  223. TensorShape{30, 20, 1, 1, 1});
  224. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  225. args.emplace_back(
  226. param, TensorShape{2, 20, i, i + 1, i + 2},
  227. TensorShape{30, 20, 1, 1, 1});
  228. }
  229. // large filter
  230. for (size_t i = range[0].first; i < range[0].second; ++i) {
  231. param::Convolution3D param;
  232. param.mode = param::Convolution3D::Mode::CONVOLUTION;
  233. args.emplace_back(
  234. param, TensorShape{2, 2, i, i + 1, i + 2}, TensorShape{3, 2, 7, 8, 9});
  235. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  236. args.emplace_back(
  237. param, TensorShape{2, 2, i, i + 1, i + 2}, TensorShape{3, 2, 7, 8, 9});
  238. }
  239. // exhaustive search
  240. // clang-format off
  241. for (size_t n: {1, 2})
  242. for (size_t id: {7, 8})
  243. for (size_t ih: {id+1})
  244. for (size_t iw: {ih+1})
  245. for (size_t ic: {3})
  246. for (size_t oc: {4})
  247. for (size_t fd: {2, 4})
  248. for (size_t fh: {fd+1})
  249. for (size_t fw: {fh+1})
  250. for (size_t ph: {0, 1})
  251. for (size_t sh: {1, 2})
  252. for (bool xcorr: {false, true})
  253. {
  254. param::Convolution3D param;
  255. param.mode = xcorr ? param::Convolution3D::Mode::CROSS_CORRELATION
  256. : param::Convolution3D::Mode::CONVOLUTION;
  257. param.stride_d = param.stride_h = param.stride_w = sh;
  258. param.pad_d = param.pad_h = param.pad_w = ph;
  259. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  260. TensorShape{oc, ic, fd, fh, fw});
  261. }
  262. // clang-format on
  263. // 4x4x4
  264. for (size_t oh = 1; oh < 10; ++oh) {
  265. param::Convolution3D param;
  266. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  267. args.emplace_back(
  268. param, TensorShape{4, 3, oh + 3, oh + 4, oh + 5},
  269. TensorShape{2, 3, 4, 4, 4});
  270. }
  271. // large channels
  272. // clang-format off
  273. for (size_t n: {2})
  274. for (size_t id: {8})
  275. for (size_t ih: {id+1})
  276. for (size_t iw: {ih+1})
  277. for (size_t ic: {16})
  278. for (size_t oc: {16})
  279. for (size_t fd: {3, 6})
  280. for (size_t fh: {fd+1})
  281. for (size_t fw: {fh+1})
  282. for (size_t ph: {0, 1})
  283. for (size_t sh: {1, 2})
  284. for (bool xcorr: {false, true})
  285. {
  286. param::Convolution3D param;
  287. param.mode = xcorr ? param::Convolution3D::Mode::CROSS_CORRELATION
  288. : param::Convolution3D::Mode::CONVOLUTION;
  289. param.stride_d = param.stride_h = param.stride_w = sh;
  290. param.pad_d = param.pad_h = param.pad_w = ph;
  291. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  292. TensorShape{oc, ic, fd, fh, fw});
  293. }
  294. // clang-format on
  295. #if 0
  296. // x86 direct case 2
  297. for (size_t stride: {1, 2})
  298. for (size_t ker_size: {3, 5, 7})
  299. {
  300. param::Convolution3D param;
  301. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  302. param.stride_d = param.stride_h = param.stride_w = stride;
  303. param.pad_d = param.pad_h = param.pad_w = ker_size/2;
  304. args.emplace_back(param,
  305. TensorShape{2, 2, 20, 19, 18},
  306. TensorShape{3, 2, ker_size, ker_size, ker_size});
  307. args.emplace_back(param,
  308. TensorShape{2, 2, 20, 19, 18},
  309. TensorShape{1, 2, ker_size, ker_size, ker_size});
  310. }
  311. for (size_t sd: {1, 2})
  312. for (size_t sh: {1, 2})
  313. for (size_t sw: {1, 2})
  314. for (size_t pd: {0, 1, 2})
  315. for (size_t ph: {0, 1, 2})
  316. for (size_t pw: {0, 1, 2})
  317. for (size_t ker_size: {3, 4, 5, 7})
  318. for (size_t xcorr : {false, true})
  319. {
  320. param::Convolution3D param;
  321. param.mode = xcorr ?
  322. param::Convolution3D::Mode::CROSS_CORRELATION :
  323. param::Convolution3D::Mode::CONVOLUTION;
  324. param.stride_d = sd;
  325. param.stride_h = sh;
  326. param.stride_w = sw;
  327. param.pad_d = pd;
  328. param.pad_h = ph;
  329. param.pad_w = pw;
  330. args.emplace_back(param,
  331. TensorShape{2, 2, 10, 15, 20},
  332. TensorShape{3, 2, ker_size, ker_size, ker_size});
  333. args.emplace_back(param,
  334. TensorShape{2, 2, 10, 15, 20},
  335. TensorShape{1, 2, ker_size, ker_size, ker_size});
  336. }
  337. // fallback non-templated impl
  338. for (size_t sd: {1, 2})
  339. for (size_t sh: {1, 2})
  340. for (size_t sw: {1, 2})
  341. for (size_t pd: {0, 1, 2})
  342. for (size_t ph: {0, 1, 2})
  343. for (size_t pw: {0, 1, 2})
  344. for (size_t ker_size: {3, 4, 5})
  345. for (size_t xcorr : {false, true})
  346. {
  347. param::Convolution3D param;
  348. param.mode = xcorr ?
  349. param::Convolution3D::Mode::CROSS_CORRELATION :
  350. param::Convolution3D::Mode::CONVOLUTION;
  351. param.stride_d = sd;
  352. param.stride_h = sh;
  353. param.stride_w = sw;
  354. param.pad_d = pd;
  355. param.pad_h = ph;
  356. param.pad_w = pw;
  357. args.emplace_back(param,
  358. TensorShape{2, 2, 5, 15, 20}, TensorShape{3, 2, ker_size, ker_size+1, ker_size+2});
  359. args.emplace_back(param,
  360. TensorShape{2, 2, 5, 15, 20},
  361. TensorShape{1, 2, ker_size, ker_size+1, ker_size+2});
  362. }
  363. // x86 winograd algorithm
  364. for (size_t ic_size: {8, 16})
  365. {
  366. param::Convolution3D param;
  367. param.mode = param::Convolution3D::Mode::CROSS_CORRELATION;
  368. param.stride_d = param.stride_h = param.stride_w = 1;
  369. param.pad_d = param.pad_h = param.pad_w = 0;
  370. args.emplace_back(param,
  371. TensorShape{2, ic_size, 20, 18, 19},
  372. TensorShape{8, ic_size, 3, 3, 3});
  373. }
  374. #endif
  375. return args;
  376. }
  377. std::vector<TestArg> convolution3d::get_chanwise_args() {
  378. std::vector<TestArg> args;
  379. // clang-format off
  380. for (size_t n : {4})
  381. for (size_t id : {35})
  382. for (size_t ih : {id + 1})
  383. for (size_t iw : {ih + 1})
  384. for (size_t c : {4, 8, 16})
  385. for (size_t fd : {3, 4, 7})
  386. for (size_t fh : {fd + 1})
  387. for (size_t fw : {fh + 1})
  388. for (size_t ph : {0, 1})
  389. for (size_t sh : {1, 2})
  390. for (size_t dh : {1}) {
  391. param::Convolution3D param;
  392. param.sparse = param::Convolution3D::Sparse::GROUP;
  393. param.stride_d = param.stride_h = param.stride_w = sh;
  394. param.pad_d = param.pad_h = param.pad_w = ph;
  395. param.dilate_d = param.dilate_h = param.dilate_w = dh;
  396. args.emplace_back(param, TensorShape{n, c, id, ih, iw},
  397. TensorShape{c, 1, 1, fd, fh, fw});
  398. }
  399. // clang-format on
  400. return args;
  401. }
  402. std::vector<TestArg> convolution3d::get_dilated_args() {
  403. std::vector<TestArg> args;
  404. param::Convolution3D param;
  405. {
  406. param.pad_d = param.pad_h = param.pad_w = 2;
  407. param.dilate_d = param.dilate_h = param.dilate_w = 3;
  408. size_t n = 1, ic = 5, id = 24, ih = 24, iw = 24, fd = 3, fh = 3, fw = 3, oc = 6;
  409. args.emplace_back(
  410. param, TensorShape{n, ic, id, ih, iw}, TensorShape{oc, ic, fd, fh, fw});
  411. }
  412. // exhaustive search
  413. // clang-format off
  414. for (size_t n : {2})
  415. for (size_t id : {32})
  416. for (size_t ih : {id + 1})
  417. for (size_t iw : {ih + 1})
  418. for (size_t ic : {3})
  419. for (size_t oc : {4})
  420. for (size_t fd : {2, 3, 4})
  421. for (size_t fh : {fd + 1})
  422. for (size_t fw : {fh + 1})
  423. for (size_t ph : {0, 1})
  424. for (size_t sh : {2, 3})
  425. for (size_t dh : {2, 3, 4}) {
  426. param::Convolution3D param;
  427. param.stride_d = param.stride_h = param.stride_w = sh;
  428. param.pad_d = param.pad_h = param.pad_w = ph;
  429. param.dilate_d = param.dilate_h = param.dilate_w = dh;
  430. args.emplace_back(param, TensorShape{n, ic, id, ih, iw},
  431. TensorShape{oc, ic, fd, fh, fw});
  432. }
  433. // clang-format on
  434. return args;
  435. }
  436. // vim: syntax=cpp.doxygen