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

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