perf_arithm.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. #include "perf_precomp.hpp"
  2. #include <numeric>
  3. #include "opencv2/core/softfloat.hpp"
  4. namespace opencv_test
  5. {
  6. using namespace perf;
  7. using BroadcastTest = perf::TestBaseWithParam<std::tuple<std::vector<int>, perf::MatType, std::vector<int>>>;
  8. typedef Size_MatType BinaryOpTest;
  9. PERF_TEST_P_(BroadcastTest, basic)
  10. {
  11. std::vector<int> shape_src = get<0>(GetParam());
  12. int dt_type = get<1>(GetParam());
  13. std::vector<int> shape_dst = get<2>(GetParam());
  14. cv::Mat src(static_cast<int>(shape_src.size()), shape_src.data(), dt_type);
  15. cv::Mat dst(static_cast<int>(shape_dst.size()), shape_dst.data(), dt_type);
  16. cv::randu(src, -1.f, 1.f);
  17. TEST_CYCLE() cv::broadcast(src, shape_dst, dst);
  18. SANITY_CHECK_NOTHING();
  19. }
  20. INSTANTIATE_TEST_CASE_P(/*nothing*/ , BroadcastTest,
  21. testing::Combine(
  22. testing::Values(std::vector<int>{1, 100, 800},
  23. std::vector<int>{10, 1, 800},
  24. std::vector<int>{10, 100, 1}),
  25. testing::Values(CV_32FC1),
  26. testing::Values(std::vector<int>{10, 100, 800})
  27. )
  28. );
  29. PERF_TEST_P_(BinaryOpTest, min)
  30. {
  31. Size sz = get<0>(GetParam());
  32. int type = get<1>(GetParam());
  33. cv::Mat a = Mat(sz, type);
  34. cv::Mat b = Mat(sz, type);
  35. cv::Mat c = Mat(sz, type);
  36. declare.in(a, b, WARMUP_RNG).out(c);
  37. TEST_CYCLE() cv::min(a, b, c);
  38. SANITY_CHECK_NOTHING();
  39. }
  40. PERF_TEST_P_(BinaryOpTest, minScalarDouble)
  41. {
  42. Size sz = get<0>(GetParam());
  43. int type = get<1>(GetParam());
  44. cv::Mat a = Mat(sz, type);
  45. cv::Scalar b;
  46. cv::Mat c = Mat(sz, type);
  47. declare.in(a, b, WARMUP_RNG).out(c);
  48. TEST_CYCLE() cv::min(a, b, c);
  49. SANITY_CHECK_NOTHING();
  50. }
  51. PERF_TEST_P_(BinaryOpTest, minScalarSameType)
  52. {
  53. Size sz = get<0>(GetParam());
  54. int type = get<1>(GetParam());
  55. cv::Mat a = Mat(sz, type);
  56. cv::Scalar b;
  57. cv::Mat c = Mat(sz, type);
  58. declare.in(a, b, WARMUP_RNG).out(c);
  59. if (CV_MAT_DEPTH(type) < CV_32S)
  60. {
  61. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  62. }
  63. else if (CV_MAT_DEPTH(type) == CV_32S)
  64. {
  65. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  66. }
  67. TEST_CYCLE() cv::min(a, b, c);
  68. SANITY_CHECK_NOTHING();
  69. }
  70. PERF_TEST_P_(BinaryOpTest, max)
  71. {
  72. Size sz = get<0>(GetParam());
  73. int type = get<1>(GetParam());
  74. cv::Mat a = Mat(sz, type);
  75. cv::Mat b = Mat(sz, type);
  76. cv::Mat c = Mat(sz, type);
  77. declare.in(a, b, WARMUP_RNG).out(c);
  78. TEST_CYCLE() cv::max(a, b, c);
  79. SANITY_CHECK_NOTHING();
  80. }
  81. PERF_TEST_P_(BinaryOpTest, maxScalarDouble)
  82. {
  83. Size sz = get<0>(GetParam());
  84. int type = get<1>(GetParam());
  85. cv::Mat a = Mat(sz, type);
  86. cv::Scalar b;
  87. cv::Mat c = Mat(sz, type);
  88. declare.in(a, b, WARMUP_RNG).out(c);
  89. TEST_CYCLE() cv::max(a, b, c);
  90. SANITY_CHECK_NOTHING();
  91. }
  92. PERF_TEST_P_(BinaryOpTest, maxScalarSameType)
  93. {
  94. Size sz = get<0>(GetParam());
  95. int type = get<1>(GetParam());
  96. cv::Mat a = Mat(sz, type);
  97. cv::Scalar b;
  98. cv::Mat c = Mat(sz, type);
  99. declare.in(a, b, WARMUP_RNG).out(c);
  100. if (CV_MAT_DEPTH(type) < CV_32S)
  101. {
  102. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  103. }
  104. else if (CV_MAT_DEPTH(type) == CV_32S)
  105. {
  106. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  107. }
  108. TEST_CYCLE() cv::max(a, b, c);
  109. SANITY_CHECK_NOTHING();
  110. }
  111. PERF_TEST_P_(BinaryOpTest, absdiff)
  112. {
  113. Size sz = get<0>(GetParam());
  114. int type = get<1>(GetParam());
  115. cv::Mat a = Mat(sz, type);
  116. cv::Mat b = Mat(sz, type);
  117. cv::Mat c = Mat(sz, type);
  118. declare.in(a, b, WARMUP_RNG).out(c);
  119. if (CV_MAT_DEPTH(type) == CV_32S)
  120. {
  121. //see ticket 1529: absdiff can be without saturation on 32S
  122. a /= 2;
  123. b /= 2;
  124. }
  125. TEST_CYCLE() cv::absdiff(a, b, c);
  126. SANITY_CHECK_NOTHING();
  127. }
  128. PERF_TEST_P_(BinaryOpTest, absdiffScalarDouble)
  129. {
  130. Size sz = get<0>(GetParam());
  131. int type = get<1>(GetParam());
  132. cv::Mat a = Mat(sz, type);
  133. cv::Scalar b;
  134. cv::Mat c = Mat(sz, type);
  135. declare.in(a, b, WARMUP_RNG).out(c);
  136. if (CV_MAT_DEPTH(type) == CV_32S)
  137. {
  138. //see ticket 1529: absdiff can be without saturation on 32S
  139. a /= 2;
  140. b /= 2;
  141. }
  142. TEST_CYCLE() cv::absdiff(a, b, c);
  143. SANITY_CHECK_NOTHING();
  144. }
  145. PERF_TEST_P_(BinaryOpTest, absdiffScalarSameType)
  146. {
  147. Size sz = get<0>(GetParam());
  148. int type = get<1>(GetParam());
  149. cv::Mat a = Mat(sz, type);
  150. cv::Scalar b;
  151. cv::Mat c = Mat(sz, type);
  152. declare.in(a, b, WARMUP_RNG).out(c);
  153. if (CV_MAT_DEPTH(type) < CV_32S)
  154. {
  155. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  156. }
  157. else if (CV_MAT_DEPTH(type) == CV_32S)
  158. {
  159. //see ticket 1529: absdiff can be without saturation on 32S
  160. a /= 2;
  161. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  162. }
  163. TEST_CYCLE() cv::absdiff(a, b, c);
  164. SANITY_CHECK_NOTHING();
  165. }
  166. PERF_TEST_P_(BinaryOpTest, add)
  167. {
  168. Size sz = get<0>(GetParam());
  169. int type = get<1>(GetParam());
  170. cv::Mat a = Mat(sz, type);
  171. cv::Mat b = Mat(sz, type);
  172. cv::Mat c = Mat(sz, type);
  173. declare.in(a, b, WARMUP_RNG).out(c);
  174. declare.time(50);
  175. if (CV_MAT_DEPTH(type) == CV_32S)
  176. {
  177. //see ticket 1529: add can be without saturation on 32S
  178. a /= 2;
  179. b /= 2;
  180. }
  181. TEST_CYCLE() cv::add(a, b, c);
  182. SANITY_CHECK_NOTHING();
  183. }
  184. PERF_TEST_P_(BinaryOpTest, addScalarDouble)
  185. {
  186. Size sz = get<0>(GetParam());
  187. int type = get<1>(GetParam());
  188. cv::Mat a = Mat(sz, type);
  189. cv::Scalar b;
  190. cv::Mat c = Mat(sz, type);
  191. declare.in(a, b, WARMUP_RNG).out(c);
  192. if (CV_MAT_DEPTH(type) == CV_32S)
  193. {
  194. //see ticket 1529: add can be without saturation on 32S
  195. a /= 2;
  196. b /= 2;
  197. }
  198. TEST_CYCLE() cv::add(a, b, c);
  199. SANITY_CHECK_NOTHING();
  200. }
  201. PERF_TEST_P_(BinaryOpTest, addScalarSameType)
  202. {
  203. Size sz = get<0>(GetParam());
  204. int type = get<1>(GetParam());
  205. cv::Mat a = Mat(sz, type);
  206. cv::Scalar b;
  207. cv::Mat c = Mat(sz, type);
  208. declare.in(a, b, WARMUP_RNG).out(c);
  209. if (CV_MAT_DEPTH(type) < CV_32S)
  210. {
  211. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  212. }
  213. else if (CV_MAT_DEPTH(type) == CV_32S)
  214. {
  215. //see ticket 1529: add can be without saturation on 32S
  216. a /= 2;
  217. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  218. }
  219. TEST_CYCLE() cv::add(a, b, c, noArray(), type);
  220. SANITY_CHECK_NOTHING();
  221. }
  222. PERF_TEST_P_(BinaryOpTest, subtract)
  223. {
  224. Size sz = get<0>(GetParam());
  225. int type = get<1>(GetParam());
  226. cv::Mat a = Mat(sz, type);
  227. cv::Mat b = Mat(sz, type);
  228. cv::Mat c = Mat(sz, type);
  229. declare.in(a, b, WARMUP_RNG).out(c);
  230. if (CV_MAT_DEPTH(type) == CV_32S)
  231. {
  232. //see ticket 1529: subtract can be without saturation on 32S
  233. a /= 2;
  234. b /= 2;
  235. }
  236. TEST_CYCLE() cv::subtract(a, b, c);
  237. SANITY_CHECK_NOTHING();
  238. }
  239. PERF_TEST_P_(BinaryOpTest, subtractScalarDouble)
  240. {
  241. Size sz = get<0>(GetParam());
  242. int type = get<1>(GetParam());
  243. cv::Mat a = Mat(sz, type);
  244. cv::Scalar b;
  245. cv::Mat c = Mat(sz, type);
  246. declare.in(a, b, WARMUP_RNG).out(c);
  247. if (CV_MAT_DEPTH(type) == CV_32S)
  248. {
  249. //see ticket 1529: subtract can be without saturation on 32S
  250. a /= 2;
  251. b /= 2;
  252. }
  253. TEST_CYCLE() cv::subtract(a, b, c);
  254. SANITY_CHECK_NOTHING();
  255. }
  256. PERF_TEST_P_(BinaryOpTest, subtractScalarSameType)
  257. {
  258. Size sz = get<0>(GetParam());
  259. int type = get<1>(GetParam());
  260. cv::Mat a = Mat(sz, type);
  261. cv::Scalar b;
  262. cv::Mat c = Mat(sz, type);
  263. declare.in(a, b, WARMUP_RNG).out(c);
  264. if (CV_MAT_DEPTH(type) < CV_32S)
  265. {
  266. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  267. }
  268. else if (CV_MAT_DEPTH(type) == CV_32S)
  269. {
  270. //see ticket 1529: subtract can be without saturation on 32S
  271. a /= 2;
  272. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  273. }
  274. TEST_CYCLE() cv::subtract(a, b, c, noArray(), type);
  275. SANITY_CHECK_NOTHING();
  276. }
  277. PERF_TEST_P_(BinaryOpTest, multiply)
  278. {
  279. Size sz = get<0>(GetParam());
  280. int type = get<1>(GetParam());
  281. cv::Mat a(sz, type), b(sz, type), c(sz, type);
  282. declare.in(a, b, WARMUP_RNG).out(c);
  283. if (CV_MAT_DEPTH(type) == CV_32S)
  284. {
  285. //According to docs, saturation is not applied when result is 32bit integer
  286. a /= (2 << 16);
  287. b /= (2 << 16);
  288. }
  289. TEST_CYCLE() cv::multiply(a, b, c);
  290. SANITY_CHECK_NOTHING();
  291. }
  292. PERF_TEST_P_(BinaryOpTest, multiplyScale)
  293. {
  294. Size sz = get<0>(GetParam());
  295. int type = get<1>(GetParam());
  296. cv::Mat a(sz, type), b(sz, type), c(sz, type);
  297. double scale = 0.5;
  298. declare.in(a, b, WARMUP_RNG).out(c);
  299. if (CV_MAT_DEPTH(type) == CV_32S)
  300. {
  301. //According to docs, saturation is not applied when result is 32bit integer
  302. a /= (2 << 16);
  303. b /= (2 << 16);
  304. }
  305. TEST_CYCLE() cv::multiply(a, b, c, scale);
  306. SANITY_CHECK_NOTHING();
  307. }
  308. PERF_TEST_P_(BinaryOpTest, divide)
  309. {
  310. Size sz = get<0>(GetParam());
  311. int type = get<1>(GetParam());
  312. cv::Mat a(sz, type), b(sz, type), c(sz, type);
  313. double scale = 0.5;
  314. declare.in(a, b, WARMUP_RNG).out(c);
  315. TEST_CYCLE() cv::divide(a, b, c, scale);
  316. SANITY_CHECK_NOTHING();
  317. }
  318. PERF_TEST_P_(BinaryOpTest, reciprocal)
  319. {
  320. Size sz = get<0>(GetParam());
  321. int type = get<1>(GetParam());
  322. cv::Mat b(sz, type), c(sz, type);
  323. double scale = 0.5;
  324. declare.in(b, WARMUP_RNG).out(c);
  325. TEST_CYCLE() cv::divide(scale, b, c);
  326. SANITY_CHECK_NOTHING();
  327. }
  328. PERF_TEST_P_(BinaryOpTest, transpose2d)
  329. {
  330. Size sz = get<0>(GetParam());
  331. int type = get<1>(GetParam());
  332. Size tsz = Size(sz.height, sz.width);
  333. cv::Mat a(sz, type), b(tsz, type);;
  334. declare.in(a, WARMUP_RNG).out(b);
  335. TEST_CYCLE() cv::transpose(a, b);
  336. SANITY_CHECK_NOTHING();
  337. }
  338. PERF_TEST_P_(BinaryOpTest, transposeND)
  339. {
  340. Size sz = get<0>(GetParam());
  341. int type = get<1>(GetParam());
  342. cv::Mat a = Mat(sz, type).reshape(1);
  343. std::vector<int> order(a.dims);
  344. std::iota(order.begin(), order.end(), 0);
  345. std::reverse(order.begin(), order.end());
  346. std::vector<int> new_sz(a.dims);
  347. std::copy(a.size.p, a.size.p + a.dims, new_sz.begin());
  348. std::reverse(new_sz.begin(), new_sz.end());
  349. cv::Mat b = Mat(new_sz, type);
  350. declare.in(a,WARMUP_RNG).out(b);
  351. TEST_CYCLE() cv::transposeND(a, order, b);
  352. SANITY_CHECK_NOTHING();
  353. }
  354. INSTANTIATE_TEST_CASE_P(/*nothing*/ , BinaryOpTest,
  355. testing::Combine(
  356. testing::Values(szVGA, sz720p, sz1080p),
  357. testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1)
  358. )
  359. );
  360. ///////////// Mixed type arithmetics ////////
  361. typedef perf::TestBaseWithParam<std::tuple<cv::Size, std::tuple<perf::MatType, perf::MatType>>> ArithmMixedTest;
  362. PERF_TEST_P_(ArithmMixedTest, add)
  363. {
  364. auto p = GetParam();
  365. Size sz = get<0>(p);
  366. int srcType = get<0>(get<1>(p));
  367. int dstType = get<1>(get<1>(p));
  368. cv::Mat a = Mat(sz, srcType);
  369. cv::Mat b = Mat(sz, srcType);
  370. cv::Mat c = Mat(sz, dstType);
  371. declare.in(a, b, WARMUP_RNG).out(c);
  372. declare.time(50);
  373. if (CV_MAT_DEPTH(dstType) == CV_32S)
  374. {
  375. //see ticket 1529: add can be without saturation on 32S
  376. a /= 2;
  377. b /= 2;
  378. }
  379. TEST_CYCLE() cv::add(a, b, c, /* mask */ noArray(), dstType);
  380. SANITY_CHECK_NOTHING();
  381. }
  382. PERF_TEST_P_(ArithmMixedTest, addScalarDouble)
  383. {
  384. auto p = GetParam();
  385. Size sz = get<0>(p);
  386. int srcType = get<0>(get<1>(p));
  387. int dstType = get<1>(get<1>(p));
  388. cv::Mat a = Mat(sz, srcType);
  389. cv::Scalar b;
  390. cv::Mat c = Mat(sz, dstType);
  391. declare.in(a, b, WARMUP_RNG).out(c);
  392. if (CV_MAT_DEPTH(dstType) == CV_32S)
  393. {
  394. //see ticket 1529: add can be without saturation on 32S
  395. a /= 2;
  396. b /= 2;
  397. }
  398. TEST_CYCLE() cv::add(a, b, c, /* mask */ noArray(), dstType);
  399. SANITY_CHECK_NOTHING();
  400. }
  401. PERF_TEST_P_(ArithmMixedTest, addScalarSameType)
  402. {
  403. auto p = GetParam();
  404. Size sz = get<0>(p);
  405. int srcType = get<0>(get<1>(p));
  406. int dstType = get<1>(get<1>(p));
  407. cv::Mat a = Mat(sz, srcType);
  408. cv::Scalar b;
  409. cv::Mat c = Mat(sz, dstType);
  410. declare.in(a, b, WARMUP_RNG).out(c);
  411. if (CV_MAT_DEPTH(dstType) < CV_32S)
  412. {
  413. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  414. }
  415. else if (CV_MAT_DEPTH(dstType) == CV_32S)
  416. {
  417. //see ticket 1529: add can be without saturation on 32S
  418. a /= 2;
  419. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  420. }
  421. TEST_CYCLE() cv::add(a, b, c, /* mask */ noArray(), dstType);
  422. SANITY_CHECK_NOTHING();
  423. }
  424. PERF_TEST_P_(ArithmMixedTest, subtract)
  425. {
  426. auto p = GetParam();
  427. Size sz = get<0>(p);
  428. int srcType = get<0>(get<1>(p));
  429. int dstType = get<1>(get<1>(p));
  430. cv::Mat a = Mat(sz, srcType);
  431. cv::Mat b = Mat(sz, srcType);
  432. cv::Mat c = Mat(sz, dstType);
  433. declare.in(a, b, WARMUP_RNG).out(c);
  434. if (CV_MAT_DEPTH(dstType) == CV_32S)
  435. {
  436. //see ticket 1529: subtract can be without saturation on 32S
  437. a /= 2;
  438. b /= 2;
  439. }
  440. TEST_CYCLE() cv::subtract(a, b, c, /* mask */ noArray(), dstType);
  441. SANITY_CHECK_NOTHING();
  442. }
  443. PERF_TEST_P_(ArithmMixedTest, subtractScalarDouble)
  444. {
  445. auto p = GetParam();
  446. Size sz = get<0>(p);
  447. int srcType = get<0>(get<1>(p));
  448. int dstType = get<1>(get<1>(p));
  449. cv::Mat a = Mat(sz, srcType);
  450. cv::Scalar b;
  451. cv::Mat c = Mat(sz, dstType);
  452. declare.in(a, b, WARMUP_RNG).out(c);
  453. if (CV_MAT_DEPTH(dstType) == CV_32S)
  454. {
  455. //see ticket 1529: subtract can be without saturation on 32S
  456. a /= 2;
  457. b /= 2;
  458. }
  459. TEST_CYCLE() cv::subtract(a, b, c, /* mask */ noArray(), dstType);
  460. SANITY_CHECK_NOTHING();
  461. }
  462. PERF_TEST_P_(ArithmMixedTest, subtractScalarSameType)
  463. {
  464. auto p = GetParam();
  465. Size sz = get<0>(p);
  466. int srcType = get<0>(get<1>(p));
  467. int dstType = get<1>(get<1>(p));
  468. cv::Mat a = Mat(sz, srcType);
  469. cv::Scalar b;
  470. cv::Mat c = Mat(sz, dstType);
  471. declare.in(a, b, WARMUP_RNG).out(c);
  472. if (CV_MAT_DEPTH(dstType) < CV_32S)
  473. {
  474. b = Scalar(1, 0, 3, 4); // don't pass non-integer values for 8U/8S/16U/16S processing
  475. }
  476. else if (CV_MAT_DEPTH(dstType) == CV_32S)
  477. {
  478. //see ticket 1529: subtract can be without saturation on 32S
  479. a /= 2;
  480. b = Scalar(1, 0, -3, 4); // don't pass non-integer values for 32S processing
  481. }
  482. TEST_CYCLE() cv::subtract(a, b, c, /* mask */ noArray(), dstType);
  483. SANITY_CHECK_NOTHING();
  484. }
  485. PERF_TEST_P_(ArithmMixedTest, multiply)
  486. {
  487. auto p = GetParam();
  488. Size sz = get<0>(p);
  489. int srcType = get<0>(get<1>(p));
  490. int dstType = get<1>(get<1>(p));
  491. cv::Mat a(sz, srcType), b(sz, srcType), c(sz, dstType);
  492. declare.in(a, b, WARMUP_RNG).out(c);
  493. if (CV_MAT_DEPTH(dstType) == CV_32S)
  494. {
  495. //According to docs, saturation is not applied when result is 32bit integer
  496. a /= (2 << 16);
  497. b /= (2 << 16);
  498. }
  499. TEST_CYCLE() cv::multiply(a, b, c, /* scale */ 1.0, dstType);
  500. SANITY_CHECK_NOTHING();
  501. }
  502. PERF_TEST_P_(ArithmMixedTest, multiplyScale)
  503. {
  504. auto p = GetParam();
  505. Size sz = get<0>(p);
  506. int srcType = get<0>(get<1>(p));
  507. int dstType = get<1>(get<1>(p));
  508. cv::Mat a(sz, srcType), b(sz, srcType), c(sz, dstType);
  509. double scale = 0.5;
  510. declare.in(a, b, WARMUP_RNG).out(c);
  511. if (CV_MAT_DEPTH(dstType) == CV_32S)
  512. {
  513. //According to docs, saturation is not applied when result is 32bit integer
  514. a /= (2 << 16);
  515. b /= (2 << 16);
  516. }
  517. TEST_CYCLE() cv::multiply(a, b, c, scale, dstType);
  518. SANITY_CHECK_NOTHING();
  519. }
  520. PERF_TEST_P_(ArithmMixedTest, divide)
  521. {
  522. auto p = GetParam();
  523. Size sz = get<0>(p);
  524. int srcType = get<0>(get<1>(p));
  525. int dstType = get<1>(get<1>(p));
  526. cv::Mat a(sz, srcType), b(sz, srcType), c(sz, dstType);
  527. double scale = 0.5;
  528. declare.in(a, b, WARMUP_RNG).out(c);
  529. TEST_CYCLE() cv::divide(a, b, c, scale, dstType);
  530. SANITY_CHECK_NOTHING();
  531. }
  532. PERF_TEST_P_(ArithmMixedTest, reciprocal)
  533. {
  534. auto p = GetParam();
  535. Size sz = get<0>(p);
  536. int srcType = get<0>(get<1>(p));
  537. int dstType = get<1>(get<1>(p));
  538. cv::Mat b(sz, srcType), c(sz, dstType);
  539. double scale = 0.5;
  540. declare.in(b, WARMUP_RNG).out(c);
  541. TEST_CYCLE() cv::divide(scale, b, c, dstType);
  542. SANITY_CHECK_NOTHING();
  543. }
  544. INSTANTIATE_TEST_CASE_P(/*nothing*/ , ArithmMixedTest,
  545. testing::Combine(
  546. testing::Values(szVGA, sz720p, sz1080p),
  547. testing::Values(std::tuple<perf::MatType, perf::MatType>{CV_8U, CV_16U},
  548. std::tuple<perf::MatType, perf::MatType>{CV_8S, CV_16S},
  549. std::tuple<perf::MatType, perf::MatType>{CV_8U, CV_32F},
  550. std::tuple<perf::MatType, perf::MatType>{CV_8S, CV_32F}
  551. )
  552. )
  553. );
  554. typedef perf::TestBaseWithParam<std::tuple<cv::Size, int, bool>> SqrtFixture;
  555. PERF_TEST_P_(SqrtFixture, Sqrt) {
  556. Size sz = get<0>(GetParam());
  557. int type = get<1>(GetParam());
  558. bool inverse = get<2>(GetParam());
  559. Mat src(sz, type), dst(sz, type);
  560. randu(src, FLT_EPSILON, 1000);
  561. declare.in(src).out(dst);
  562. TEST_CYCLE() cv::pow(src, inverse ? -0.5 : 0.5, dst);
  563. SANITY_CHECK_NOTHING();
  564. }
  565. INSTANTIATE_TEST_CASE_P(/*nothing*/ , SqrtFixture,
  566. testing::Combine(
  567. testing::Values(TYPICAL_MAT_SIZES),
  568. testing::Values(CV_32FC1, CV_64FC1),
  569. testing::Bool()
  570. )
  571. );
  572. ///////////// Rotate ////////////////////////
  573. typedef perf::TestBaseWithParam<std::tuple<cv::Size, int, perf::MatType>> RotateTest;
  574. PERF_TEST_P_(RotateTest, rotate)
  575. {
  576. Size sz = get<0>(GetParam());
  577. int rotatecode = get<1>(GetParam());
  578. int type = get<2>(GetParam());
  579. cv::Mat a(sz, type), b(sz, type);
  580. declare.in(a, WARMUP_RNG).out(b);
  581. TEST_CYCLE() cv::rotate(a, b, rotatecode);
  582. SANITY_CHECK_NOTHING();
  583. }
  584. INSTANTIATE_TEST_CASE_P(/*nothing*/ , RotateTest,
  585. testing::Combine(
  586. testing::Values(szVGA, sz720p, sz1080p),
  587. testing::Values(ROTATE_180, ROTATE_90_CLOCKWISE, ROTATE_90_COUNTERCLOCKWISE),
  588. testing::Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1)
  589. )
  590. );
  591. ///////////// PatchNaNs ////////////////////////
  592. template<typename _Tp>
  593. _Tp randomNan(RNG& rng);
  594. template<>
  595. float randomNan(RNG& rng)
  596. {
  597. uint32_t r = rng.next();
  598. Cv32suf v;
  599. v.u = r;
  600. // exp & set a bit to avoid zero mantissa
  601. v.u = v.u | 0x7f800001;
  602. return v.f;
  603. }
  604. template<>
  605. double randomNan(RNG& rng)
  606. {
  607. uint32_t r0 = rng.next();
  608. uint32_t r1 = rng.next();
  609. Cv64suf v;
  610. v.u = (uint64_t(r0) << 32) | uint64_t(r1);
  611. // exp &set a bit to avoid zero mantissa
  612. v.u = v.u | 0x7ff0000000000001;
  613. return v.f;
  614. }
  615. typedef Size_MatType PatchNaNsFixture;
  616. PERF_TEST_P_(PatchNaNsFixture, PatchNaNs)
  617. {
  618. const Size_MatType_t params = GetParam();
  619. Size srcSize = get<0>(params);
  620. const int type = get<1>(params), cn = CV_MAT_CN(type);
  621. Mat src(srcSize, type);
  622. declare.in(src, WARMUP_RNG).out(src);
  623. // generating NaNs
  624. {
  625. srcSize.width *= cn;
  626. RNG& rng = theRNG();
  627. for (int y = 0; y < srcSize.height; ++y)
  628. {
  629. float *const ptrf = src.ptr<float>(y);
  630. for (int x = 0; x < srcSize.width; ++x)
  631. {
  632. ptrf[x] = (x + y) % 2 == 0 ? randomNan<float >(rng) : ptrf[x];
  633. }
  634. }
  635. }
  636. TEST_CYCLE() cv::patchNaNs(src, 17.7);
  637. SANITY_CHECK(src);
  638. }
  639. INSTANTIATE_TEST_CASE_P(/*nothing*/ , PatchNaNsFixture,
  640. testing::Combine(
  641. testing::Values(szVGA, sz720p, sz1080p, sz2160p),
  642. testing::Values(CV_32FC1, CV_32FC2, CV_32FC3, CV_32FC4)
  643. )
  644. );
  645. //////////////EXP////////////
  646. typedef Size_MatType ExpFixture;
  647. PERF_TEST_P(ExpFixture, Exp,
  648. testing::Combine(testing::Values(TYPICAL_MAT_SIZES), testing::Values(CV_32F, CV_64F)))
  649. {
  650. cv::Size size = std::get<0>(GetParam());
  651. int type = std::get<1>(GetParam());
  652. cv::Mat src(size, type);
  653. cv::Mat dst(size, type);
  654. declare.in(src).out(dst);
  655. cv::randu(src, -5.0, 5.0);
  656. TEST_CYCLE()
  657. {
  658. cv::exp(src, dst);
  659. }
  660. SANITY_CHECK_NOTHING();
  661. }
  662. //////////////LOG////////////
  663. typedef Size_MatType LogFixture;
  664. PERF_TEST_P(LogFixture, Log,
  665. testing::Combine(testing::Values(TYPICAL_MAT_SIZES), testing::Values(CV_32F, CV_64F)))
  666. {
  667. cv::Size size = std::get<0>(GetParam());
  668. int type = std::get<1>(GetParam());
  669. cv::Mat src(size, type);
  670. cv::Mat dst(size, type);
  671. declare.in(src).out(dst);
  672. cv::randu(src, 1e-5, 1e5);
  673. TEST_CYCLE()
  674. {
  675. cv::log(src, dst);
  676. }
  677. SANITY_CHECK_NOTHING();
  678. }
  679. } // namespace