test_umat.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  22. // * Redistribution's in binary form must reproduce the above copyright notice,
  23. // this list of conditions and the following disclaimer in the documentation
  24. // and/or other materials provided with the distribution.
  25. //
  26. // * The name of the copyright holders may not be used to endorse or promote products
  27. // derived from this software without specific prior written permission.
  28. //
  29. // This software is provided by the copyright holders and contributors "as is" and
  30. // any express or implied warranties, including, but not limited to, the implied
  31. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  32. // In no event shall the OpenCV Foundation or contributors be liable for any direct,
  33. // indirect, incidental, special, exemplary, or consequential damages
  34. // (including, but not limited to, procurement of substitute goods or services;
  35. // loss of use, data, or profits; or business interruption) however caused
  36. // and on any theory of liability, whether in contract, strict liability,
  37. // or tort (including negligence or otherwise) arising in any way out of
  38. // the use of this software, even if advised of the possibility of such damage.
  39. //
  40. //M*/
  41. #include "test_precomp.hpp"
  42. #include "opencv2/ts/ocl_test.hpp"
  43. using namespace opencv_test;
  44. using namespace testing;
  45. using namespace cv;
  46. namespace opencv_test {
  47. namespace ocl {
  48. #define UMAT_TEST_SIZES testing::Values(cv::Size(1, 1), cv::Size(1,128), cv::Size(128, 1), \
  49. cv::Size(128, 128), cv::Size(640, 480), cv::Size(751, 373), cv::Size(1200, 1200))
  50. /////////////////////////////// Basic Tests ////////////////////////////////
  51. PARAM_TEST_CASE(UMatBasicTests, int, int, Size, bool)
  52. {
  53. Mat a;
  54. UMat ua;
  55. int type;
  56. int depth;
  57. int cn;
  58. Size size;
  59. bool useRoi;
  60. Size roi_size;
  61. Rect roi;
  62. virtual void SetUp()
  63. {
  64. depth = GET_PARAM(0);
  65. cn = GET_PARAM(1);
  66. size = GET_PARAM(2);
  67. useRoi = GET_PARAM(3);
  68. type = CV_MAKE_TYPE(depth, cn);
  69. a = randomMat(size, type, -100, 100);
  70. a.copyTo(ua);
  71. int roi_shift_x = randomInt(0, size.width-1);
  72. int roi_shift_y = randomInt(0, size.height-1);
  73. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  74. roi = Rect(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  75. }
  76. };
  77. TEST_P(UMatBasicTests, createUMat)
  78. {
  79. if(useRoi)
  80. {
  81. ua = UMat(ua, roi);
  82. }
  83. int dims = randomInt(2,6);
  84. int _sz[CV_MAX_DIM];
  85. for( int i = 0; i<dims; i++)
  86. {
  87. _sz[i] = randomInt(1,50);
  88. }
  89. int *sz = _sz;
  90. int new_depth = randomInt(CV_8S, CV_64F);
  91. int new_cn = randomInt(1,4);
  92. ua.create(dims, sz, CV_MAKE_TYPE(new_depth, new_cn));
  93. for(int i = 0; i<dims; i++)
  94. {
  95. ASSERT_EQ(ua.size[i], sz[i]);
  96. }
  97. ASSERT_EQ(ua.dims, dims);
  98. ASSERT_EQ(ua.type(), CV_MAKE_TYPE(new_depth, new_cn) );
  99. Size new_size = randomSize(1, 1000);
  100. ua.create(new_size, CV_MAKE_TYPE(new_depth, new_cn) );
  101. ASSERT_EQ( ua.size(), new_size);
  102. ASSERT_EQ(ua.type(), CV_MAKE_TYPE(new_depth, new_cn) );
  103. ASSERT_EQ( ua.dims, 2);
  104. }
  105. TEST_P(UMatBasicTests, swap)
  106. {
  107. Mat b = randomMat(size, type, -100, 100);
  108. UMat ub;
  109. b.copyTo(ub);
  110. if(useRoi)
  111. {
  112. ua = UMat(ua,roi);
  113. ub = UMat(ub,roi);
  114. }
  115. UMat uc = ua, ud = ub;
  116. swap(ua,ub);
  117. EXPECT_MAT_NEAR(ub,uc, 0);
  118. EXPECT_MAT_NEAR(ud, ua, 0);
  119. }
  120. TEST_P(UMatBasicTests, base)
  121. {
  122. const int align_mask = 3;
  123. roi.x &= ~align_mask;
  124. roi.y &= ~align_mask;
  125. roi.width = (roi.width + align_mask) & ~align_mask;
  126. roi &= Rect(0, 0, ua.cols, ua.rows);
  127. if(useRoi)
  128. {
  129. ua = UMat(ua,roi);
  130. }
  131. UMat ub = ua.clone();
  132. EXPECT_MAT_NEAR(ub,ua,0);
  133. ASSERT_EQ(ua.channels(), cn);
  134. ASSERT_EQ(ua.depth(), depth);
  135. ASSERT_EQ(ua.type(), type);
  136. ASSERT_EQ(ua.elemSize(), a.elemSize());
  137. ASSERT_EQ(ua.elemSize1(), a.elemSize1());
  138. ASSERT_EQ(ub.empty(), ub.cols*ub.rows == 0);
  139. ub.release();
  140. ASSERT_TRUE( ub.empty() );
  141. if(useRoi && a.size() != ua.size())
  142. {
  143. ASSERT_EQ(ua.isSubmatrix(), true);
  144. }
  145. else
  146. {
  147. ASSERT_EQ(ua.isSubmatrix(), false);
  148. }
  149. int dims = randomInt(2,6);
  150. int sz[CV_MAX_DIM];
  151. size_t total = 1;
  152. for(int i = 0; i<dims; i++)
  153. {
  154. sz[i] = randomInt(1,45);
  155. total *= (size_t)sz[i];
  156. }
  157. int new_type = CV_MAKE_TYPE(randomInt(CV_8S,CV_64F),randomInt(1,4));
  158. ub = UMat(dims, sz, new_type);
  159. ASSERT_EQ(ub.total(), total);
  160. }
  161. TEST_P(UMatBasicTests, copyTo)
  162. {
  163. int i;
  164. if(useRoi)
  165. {
  166. UMat roi_ua;
  167. Mat roi_a;
  168. roi_ua = UMat(ua, roi);
  169. roi_a = Mat(a, roi);
  170. roi_a.copyTo(roi_ua);
  171. EXPECT_MAT_NEAR(roi_a, roi_ua, 0);
  172. roi_ua.copyTo(roi_a);
  173. EXPECT_MAT_NEAR(roi_ua, roi_a, 0);
  174. roi_ua.copyTo(ua);
  175. EXPECT_MAT_NEAR(roi_ua, ua, 0);
  176. ua.copyTo(a);
  177. EXPECT_MAT_NEAR(ua, a, 0);
  178. }
  179. {
  180. UMat ub;
  181. ua.copyTo(ub);
  182. EXPECT_MAT_NEAR(ua, ub, 0);
  183. }
  184. {
  185. UMat ub;
  186. i = randomInt(0, ua.cols-1);
  187. a.col(i).copyTo(ub);
  188. EXPECT_MAT_NEAR(a.col(i), ub, 0);
  189. }
  190. {
  191. UMat ub;
  192. ua.col(i).copyTo(ub);
  193. EXPECT_MAT_NEAR(ua.col(i), ub, 0);
  194. }
  195. {
  196. Mat b;
  197. ua.col(i).copyTo(b);
  198. EXPECT_MAT_NEAR(ua.col(i), b, 0);
  199. }
  200. {
  201. UMat ub;
  202. i = randomInt(0, a.rows-1);
  203. ua.row(i).copyTo(ub);
  204. EXPECT_MAT_NEAR(ua.row(i), ub, 0);
  205. }
  206. {
  207. UMat ub;
  208. a.row(i).copyTo(ub);
  209. EXPECT_MAT_NEAR(a.row(i), ub, 0);
  210. }
  211. {
  212. Mat b;
  213. ua.row(i).copyTo(b);
  214. EXPECT_MAT_NEAR(ua.row(i), b, 0);
  215. }
  216. }
  217. TEST_P(UMatBasicTests, GetUMat)
  218. {
  219. if(useRoi)
  220. {
  221. a = Mat(a, roi);
  222. ua = UMat(ua,roi);
  223. }
  224. {
  225. UMat ub;
  226. ub = a.getUMat(ACCESS_RW);
  227. EXPECT_MAT_NEAR(ub, ua, 0);
  228. }
  229. {
  230. UMat u = a.getUMat(ACCESS_RW);
  231. {
  232. Mat b = u.getMat(ACCESS_RW);
  233. EXPECT_MAT_NEAR(b, a, 0);
  234. }
  235. }
  236. {
  237. Mat b;
  238. b = ua.getMat(ACCESS_RW);
  239. EXPECT_MAT_NEAR(b, a, 0);
  240. }
  241. {
  242. Mat m = ua.getMat(ACCESS_RW);
  243. {
  244. UMat ub = m.getUMat(ACCESS_RW);
  245. EXPECT_MAT_NEAR(ub, ua, 0);
  246. }
  247. }
  248. }
  249. INSTANTIATE_TEST_CASE_P(UMat, UMatBasicTests, Combine(testing::Values(CV_8U, CV_64F), testing::Values(1, 2),
  250. testing::Values(cv::Size(1, 1), cv::Size(1, 128), cv::Size(128, 1), cv::Size(128, 128), cv::Size(640, 480)), Bool()));
  251. //////////////////////////////////////////////////////////////// Reshape ////////////////////////////////////////////////////////////////////////
  252. PARAM_TEST_CASE(UMatTestReshape, int, int, Size, bool)
  253. {
  254. Mat a;
  255. UMat ua, ub;
  256. int type;
  257. int depth;
  258. int cn;
  259. Size size;
  260. bool useRoi;
  261. Size roi_size;
  262. virtual void SetUp()
  263. {
  264. depth = GET_PARAM(0);
  265. cn = GET_PARAM(1);
  266. size = GET_PARAM(2);
  267. useRoi = GET_PARAM(3);
  268. type = CV_MAKE_TYPE(depth, cn);
  269. }
  270. };
  271. TEST_P(UMatTestReshape, reshape)
  272. {
  273. a = randomMat(size,type, -100, 100);
  274. a.copyTo(ua);
  275. if(useRoi)
  276. {
  277. int roi_shift_x = randomInt(0, size.width-1);
  278. int roi_shift_y = randomInt(0, size.height-1);
  279. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  280. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  281. ua = UMat(ua, roi).clone();
  282. a = Mat(a, roi).clone();
  283. }
  284. int nChannels = randomInt(1,4);
  285. if ((ua.cols*ua.channels()*ua.rows)%nChannels != 0)
  286. {
  287. EXPECT_ANY_THROW(ua.reshape(nChannels));
  288. }
  289. else
  290. {
  291. ub = ua.reshape(nChannels);
  292. ASSERT_EQ(ub.channels(),nChannels);
  293. ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
  294. EXPECT_MAT_NEAR(ua.reshape(nChannels), a.reshape(nChannels), 0);
  295. int new_rows = randomInt(1, INT_MAX);
  296. if ( ((int)ua.total()*ua.channels())%(new_rows*nChannels) != 0)
  297. {
  298. EXPECT_ANY_THROW (ua.reshape(nChannels, new_rows) );
  299. }
  300. else
  301. {
  302. EXPECT_NO_THROW ( ub = ua.reshape(nChannels, new_rows) );
  303. ASSERT_EQ(ub.channels(),nChannels);
  304. ASSERT_EQ(ub.rows, new_rows);
  305. ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
  306. EXPECT_MAT_NEAR(ua.reshape(nChannels,new_rows), a.reshape(nChannels,new_rows), 0);
  307. }
  308. new_rows = (int)ua.total()*ua.channels()/(nChannels*randomInt(1, size.width*size.height));
  309. if (new_rows == 0) new_rows = 1;
  310. int new_cols = (int)ua.total()*ua.channels()/(new_rows*nChannels);
  311. int sz[] = {new_rows, new_cols};
  312. if( ((int)ua.total()*ua.channels()) % (new_rows*new_cols) != 0 )
  313. {
  314. EXPECT_ANY_THROW( ua.reshape(nChannels, ua.dims, sz) );
  315. }
  316. else
  317. {
  318. EXPECT_NO_THROW ( ub = ua.reshape(nChannels, ua.dims, sz) );
  319. ASSERT_EQ(ub.channels(),nChannels);
  320. ASSERT_EQ(ub.rows, new_rows);
  321. ASSERT_EQ(ub.cols, new_cols);
  322. ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
  323. EXPECT_MAT_NEAR(ua.reshape(nChannels, ua.dims, sz), a.reshape(nChannels, a.dims, sz), 0);
  324. }
  325. }
  326. }
  327. INSTANTIATE_TEST_CASE_P(UMat, UMatTestReshape, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool() ));
  328. static void check_ndim_shape(const cv::UMat &mat, int cn, int ndims, const int *sizes)
  329. {
  330. EXPECT_EQ(mat.channels(), cn);
  331. EXPECT_EQ(mat.dims, ndims);
  332. if (mat.dims != ndims)
  333. return;
  334. for (int i = 0; i < ndims; i++)
  335. EXPECT_EQ(mat.size[i], sizes[i]);
  336. }
  337. TEST(UMatTestReshape, reshape_ndims_2)
  338. {
  339. const cv::UMat A(8, 16, CV_8UC3);
  340. cv::UMat B;
  341. {
  342. int new_sizes_mask[] = { 0, 3, 4, 4 };
  343. int new_sizes_real[] = { 8, 3, 4, 4 };
  344. ASSERT_NO_THROW(B = A.reshape(1, 4, new_sizes_mask));
  345. check_ndim_shape(B, 1, 4, new_sizes_real);
  346. }
  347. {
  348. int new_sizes[] = { 16, 8 };
  349. ASSERT_NO_THROW(B = A.reshape(0, 2, new_sizes));
  350. check_ndim_shape(B, 3, 2, new_sizes);
  351. EXPECT_EQ(B.rows, new_sizes[0]);
  352. EXPECT_EQ(B.cols, new_sizes[1]);
  353. }
  354. {
  355. int new_sizes[] = { 2, 5, 1, 3 };
  356. cv::UMat A_sliced = A(cv::Range::all(), cv::Range(0, 15));
  357. ASSERT_ANY_THROW(A_sliced.reshape(4, 4, new_sizes));
  358. }
  359. }
  360. TEST(UMatTestReshape, reshape_ndims_4)
  361. {
  362. const int sizes[] = { 2, 6, 4, 12 };
  363. const cv::UMat A(4, sizes, CV_8UC3);
  364. cv::UMat B;
  365. {
  366. int new_sizes_mask[] = { 0, 864 };
  367. int new_sizes_real[] = { 2, 864 };
  368. ASSERT_NO_THROW(B = A.reshape(1, 2, new_sizes_mask));
  369. check_ndim_shape(B, 1, 2, new_sizes_real);
  370. EXPECT_EQ(B.rows, new_sizes_real[0]);
  371. EXPECT_EQ(B.cols, new_sizes_real[1]);
  372. }
  373. {
  374. int new_sizes_mask[] = { 4, 0, 0, 2, 3 };
  375. int new_sizes_real[] = { 4, 6, 4, 2, 3 };
  376. ASSERT_NO_THROW(B = A.reshape(0, 5, new_sizes_mask));
  377. check_ndim_shape(B, 3, 5, new_sizes_real);
  378. }
  379. {
  380. int new_sizes_mask[] = { 1, 1 };
  381. ASSERT_ANY_THROW(A.reshape(0, 2, new_sizes_mask));
  382. }
  383. {
  384. int new_sizes_mask[] = { 4, 6, 3, 3, 0 };
  385. ASSERT_ANY_THROW(A.reshape(0, 5, new_sizes_mask));
  386. }
  387. }
  388. ////////////////////////////////////////////////////////////////// ROI testing ///////////////////////////////////////////////////////////////
  389. PARAM_TEST_CASE(UMatTestRoi, int, int, Size)
  390. {
  391. Mat a, roi_a;
  392. UMat ua, roi_ua;
  393. int type;
  394. int depth;
  395. int cn;
  396. Size size;
  397. Size roi_size;
  398. virtual void SetUp()
  399. {
  400. depth = GET_PARAM(0);
  401. cn = GET_PARAM(1);
  402. size = GET_PARAM(2);
  403. type = CV_MAKE_TYPE(depth, cn);
  404. }
  405. };
  406. TEST_P(UMatTestRoi, createRoi)
  407. {
  408. int roi_shift_x = randomInt(0, size.width-1);
  409. int roi_shift_y = randomInt(0, size.height-1);
  410. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  411. a = randomMat(size, type, -100, 100);
  412. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  413. roi_a = Mat(a, roi);
  414. a.copyTo(ua);
  415. roi_ua = UMat(ua, roi);
  416. EXPECT_MAT_NEAR(roi_a, roi_ua, 0);
  417. }
  418. TEST_P(UMatTestRoi, locateRoi)
  419. {
  420. int roi_shift_x = randomInt(0, size.width-1);
  421. int roi_shift_y = randomInt(0, size.height-1);
  422. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  423. a = randomMat(size, type, -100, 100);
  424. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  425. roi_a = Mat(a, roi);
  426. a.copyTo(ua);
  427. roi_ua = UMat(ua,roi);
  428. Size sz, usz;
  429. Point p, up;
  430. roi_a.locateROI(sz, p);
  431. roi_ua.locateROI(usz, up);
  432. ASSERT_EQ(sz, usz);
  433. ASSERT_EQ(p, up);
  434. }
  435. TEST_P(UMatTestRoi, adjustRoi)
  436. {
  437. int roi_shift_x = randomInt(0, size.width-1);
  438. int roi_shift_y = randomInt(0, size.height-1);
  439. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  440. a = randomMat(size, type, -100, 100);
  441. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  442. a.copyTo(ua);
  443. roi_ua = UMat( ua, roi);
  444. int adjLeft = randomInt(-(roi_ua.cols/2), (size.width-1)/2);
  445. int adjRight = randomInt(-(roi_ua.cols/2), (size.width-1)/2);
  446. int adjTop = randomInt(-(roi_ua.rows/2), (size.height-1)/2);
  447. int adjBot = randomInt(-(roi_ua.rows/2), (size.height-1)/2);
  448. roi_ua.adjustROI(adjTop, adjBot, adjLeft, adjRight);
  449. roi_shift_x = std::max(0, roi.x-adjLeft);
  450. roi_shift_y = std::max(0, roi.y-adjTop);
  451. Rect new_roi( roi_shift_x, roi_shift_y, std::min(roi.width+adjRight+adjLeft, size.width-roi_shift_x), std::min(roi.height+adjBot+adjTop, size.height-roi_shift_y) );
  452. UMat test_roi = UMat(ua, new_roi);
  453. EXPECT_MAT_NEAR(roi_ua, test_roi, 0);
  454. }
  455. INSTANTIATE_TEST_CASE_P(UMat, UMatTestRoi, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES ));
  456. TEST(UMatTestRoi, adjustRoiOverflow)
  457. {
  458. UMat m(15, 10, CV_32S);
  459. UMat roi(m, cv::Range(2, 10), cv::Range(3,6));
  460. int rowsInROI = roi.rows;
  461. roi.adjustROI(1, 0, 0, 0);
  462. ASSERT_EQ(roi.rows, rowsInROI + 1);
  463. roi.adjustROI(-m.rows, -m.rows, 0, 0);
  464. ASSERT_EQ(roi.rows, m.rows);
  465. }
  466. /////////////////////////////////////////////////////////////// Size ////////////////////////////////////////////////////////////////////
  467. PARAM_TEST_CASE(UMatTestSizeOperations, int, int, Size, bool)
  468. {
  469. Mat a, b, roi_a, roi_b;
  470. UMat ua, ub, roi_ua, roi_ub;
  471. int type;
  472. int depth;
  473. int cn;
  474. Size size;
  475. Size roi_size;
  476. bool useRoi;
  477. virtual void SetUp()
  478. {
  479. depth = GET_PARAM(0);
  480. cn = GET_PARAM(1);
  481. size = GET_PARAM(2);
  482. useRoi = GET_PARAM(3);
  483. type = CV_MAKE_TYPE(depth, cn);
  484. }
  485. };
  486. TEST_P(UMatTestSizeOperations, copySize)
  487. {
  488. Size s = randomSize(1,300);
  489. a = randomMat(size, type, -100, 100);
  490. b = randomMat(s, type, -100, 100);
  491. a.copyTo(ua);
  492. b.copyTo(ub);
  493. if(useRoi)
  494. {
  495. int roi_shift_x = randomInt(0, size.width-1);
  496. int roi_shift_y = randomInt(0, size.height-1);
  497. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  498. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  499. ua = UMat(ua,roi);
  500. roi_shift_x = randomInt(0, s.width-1);
  501. roi_shift_y = randomInt(0, s.height-1);
  502. roi_size = Size(s.width - roi_shift_x, s.height - roi_shift_y);
  503. roi = Rect(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  504. ub = UMat(ub, roi);
  505. }
  506. ua.copySize(ub);
  507. ASSERT_EQ(ua.size, ub.size);
  508. }
  509. INSTANTIATE_TEST_CASE_P(UMat, UMatTestSizeOperations, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool() ));
  510. ///////////////////////////////////////////////////////////////// UMat operations ////////////////////////////////////////////////////////////////////////////
  511. PARAM_TEST_CASE(UMatTestUMatOperations, int, int, Size, bool)
  512. {
  513. Mat a, b;
  514. UMat ua, ub;
  515. int type;
  516. int depth;
  517. int cn;
  518. Size size;
  519. Size roi_size;
  520. bool useRoi;
  521. virtual void SetUp()
  522. {
  523. depth = GET_PARAM(0);
  524. cn = GET_PARAM(1);
  525. size = GET_PARAM(2);
  526. useRoi = GET_PARAM(3);
  527. type = CV_MAKE_TYPE(depth, cn);
  528. }
  529. };
  530. TEST_P(UMatTestUMatOperations, diag)
  531. {
  532. a = randomMat(size, type, -100, 100);
  533. a.copyTo(ua);
  534. Mat new_diag;
  535. if(useRoi)
  536. {
  537. int roi_shift_x = randomInt(0, size.width-1);
  538. int roi_shift_y = randomInt(0, size.height-1);
  539. roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
  540. Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
  541. ua = UMat(ua,roi);
  542. a = Mat(a, roi);
  543. }
  544. int n = randomInt(0, ua.cols-1);
  545. ub = ua.diag(n);
  546. b = a.diag(n);
  547. EXPECT_MAT_NEAR(b, ub, 0);
  548. new_diag = randomMat(Size(ua.rows, 1), type, -100, 100);
  549. new_diag.copyTo(ub);
  550. ua = cv::UMat::diag(ub);
  551. EXPECT_MAT_NEAR(ua.diag(), new_diag.t(), 0);
  552. }
  553. INSTANTIATE_TEST_CASE_P(UMat, UMatTestUMatOperations, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool()));
  554. /////////////////////////////////////////////////////////////// getUMat -> GetMat ///////////////////////////////////////////////////////////////////
  555. PARAM_TEST_CASE(getUMat, int, int, Size, bool)
  556. {
  557. int type;
  558. Size size;
  559. virtual void SetUp()
  560. {
  561. int depth = GET_PARAM(0);
  562. int cn = GET_PARAM(1);
  563. size = GET_PARAM(2);
  564. useOpenCL = GET_PARAM(3);
  565. type = CV_MAKE_TYPE(depth, cn);
  566. isOpenCL_enabled = cv::ocl::useOpenCL();
  567. cv::ocl::setUseOpenCL(useOpenCL);
  568. }
  569. virtual void TearDown()
  570. {
  571. cv::ocl::setUseOpenCL(isOpenCL_enabled);
  572. }
  573. // UMat created from user allocated host memory (USE_HOST_PTR)
  574. void custom_ptr_test(size_t align_base, size_t align_offset)
  575. {
  576. void* pData_allocated = new unsigned char [size.area() * CV_ELEM_SIZE(type) + (align_base + align_offset)];
  577. void* pData = (char*)alignPtr(pData_allocated, (int)align_base) + align_offset;
  578. size_t step = size.width * CV_ELEM_SIZE(type);
  579. {
  580. Mat m = Mat(size, type, pData, step);
  581. m.setTo(cv::Scalar::all(2));
  582. UMat u = m.getUMat(ACCESS_RW);
  583. cv::add(u, cv::Scalar::all(2), u);
  584. Mat d = u.getMat(ACCESS_READ);
  585. Mat expected(m.size(), m.type(), cv::Scalar::all(4));
  586. double norm = cvtest::norm(d, expected, NORM_INF);
  587. EXPECT_EQ(0, norm);
  588. }
  589. delete[] (unsigned char*)pData_allocated;
  590. }
  591. private:
  592. bool useOpenCL;
  593. bool isOpenCL_enabled;
  594. };
  595. TEST_P(getUMat, custom_ptr_align_4Kb)
  596. {
  597. custom_ptr_test(4096, 0);
  598. }
  599. TEST_P(getUMat, custom_ptr_align_64b)
  600. {
  601. custom_ptr_test(4096, 64);
  602. }
  603. TEST_P(getUMat, custom_ptr_align_none)
  604. {
  605. custom_ptr_test(4096, cv::alignSize(CV_ELEM_SIZE(type), 4));
  606. }
  607. TEST_P(getUMat, self_allocated)
  608. {
  609. Mat m = Mat(size, type);
  610. m.setTo(cv::Scalar::all(2));
  611. UMat u = m.getUMat(ACCESS_RW);
  612. cv::add(u, cv::Scalar::all(2), u);
  613. Mat d = u.getMat(ACCESS_READ);
  614. Mat expected(m.size(), m.type(), cv::Scalar::all(4));
  615. double norm = cvtest::norm(d, expected, NORM_INF);
  616. EXPECT_EQ(0, norm);
  617. }
  618. INSTANTIATE_TEST_CASE_P(UMat, getUMat, Combine(
  619. Values(CV_8U, CV_64F), // depth
  620. Values(1, 3), // channels
  621. Values(cv::Size(1, 1), cv::Size(255, 255), cv::Size(256, 256)), // Size
  622. Bool() // useOpenCL
  623. ));
  624. ///////////////////////////////////////////////////////////////// OpenCL ////////////////////////////////////////////////////////////////////////////
  625. #ifdef HAVE_OPENCL
  626. TEST(UMat, BufferPoolGrowing)
  627. {
  628. #ifdef _DEBUG
  629. const int ITERATIONS = 100;
  630. #else
  631. const int ITERATIONS = 200;
  632. #endif
  633. const Size sz(1920, 1080);
  634. BufferPoolController* c = cv::ocl::getOpenCLAllocator()->getBufferPoolController();
  635. if (c)
  636. {
  637. size_t oldMaxReservedSize = c->getMaxReservedSize();
  638. c->freeAllReservedBuffers();
  639. c->setMaxReservedSize(sz.area() * 10);
  640. for (int i = 0; i < ITERATIONS; i++)
  641. {
  642. UMat um(Size(sz.width + i, sz.height + i), CV_8UC1);
  643. UMat um2(Size(sz.width + 2 * i, sz.height + 2 * i), CV_8UC1);
  644. }
  645. c->setMaxReservedSize(oldMaxReservedSize);
  646. c->freeAllReservedBuffers();
  647. }
  648. else
  649. std::cout << "Skipped, no OpenCL" << std::endl;
  650. }
  651. #endif
  652. class CV_UMatTest :
  653. public cvtest::BaseTest
  654. {
  655. public:
  656. CV_UMatTest() {}
  657. ~CV_UMatTest() {}
  658. protected:
  659. void run(int);
  660. struct test_excep
  661. {
  662. test_excep(const string& _s=string("")) : s(_s) { }
  663. string s;
  664. };
  665. bool TestUMat();
  666. void checkDiff(const Mat& m1, const Mat& m2, const string& s)
  667. {
  668. if (cvtest::norm(m1, m2, NORM_INF) != 0)
  669. throw test_excep(s);
  670. }
  671. void checkDiffF(const Mat& m1, const Mat& m2, const string& s)
  672. {
  673. if (cvtest::norm(m1, m2, NORM_INF) > 1e-5)
  674. throw test_excep(s);
  675. }
  676. };
  677. #define STR(a) STR2(a)
  678. #define STR2(a) #a
  679. #define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ") != (" #b ") at l." STR(__LINE__))
  680. #define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ") !=(eps) (" #b ") at l." STR(__LINE__))
  681. bool CV_UMatTest::TestUMat()
  682. {
  683. try
  684. {
  685. Mat a(100, 100, CV_16SC2), b, c;
  686. randu(a, Scalar::all(-100), Scalar::all(100));
  687. Rect roi(1, 3, 5, 4);
  688. Mat ra(a, roi), rb, rc, rc0;
  689. UMat ua, ura, ub, urb, uc, urc;
  690. a.copyTo(ua);
  691. ua.copyTo(b);
  692. CHECK_DIFF(a, b);
  693. ura = ua(roi);
  694. ura.copyTo(rb);
  695. CHECK_DIFF(ra, rb);
  696. ra += Scalar::all(1.f);
  697. {
  698. Mat temp = ura.getMat(ACCESS_RW);
  699. temp += Scalar::all(1.f);
  700. }
  701. ra.copyTo(rb);
  702. CHECK_DIFF(ra, rb);
  703. b = a.clone();
  704. ra = a(roi);
  705. rb = b(roi);
  706. randu(b, Scalar::all(-100), Scalar::all(100));
  707. b.copyTo(ub);
  708. urb = ub(roi);
  709. /*std::cout << "==============================================\nbefore op (CPU):\n";
  710. std::cout << "ra: " << ra << std::endl;
  711. std::cout << "rb: " << rb << std::endl;*/
  712. ra.copyTo(ura);
  713. rb.copyTo(urb);
  714. ra.release();
  715. rb.release();
  716. ura.copyTo(ra);
  717. urb.copyTo(rb);
  718. /*std::cout << "==============================================\nbefore op (GPU):\n";
  719. std::cout << "ra: " << ra << std::endl;
  720. std::cout << "rb: " << rb << std::endl;*/
  721. cv::max(ra, rb, rc);
  722. cv::max(ura, urb, urc);
  723. urc.copyTo(rc0);
  724. /*std::cout << "==============================================\nafter op:\n";
  725. std::cout << "rc: " << rc << std::endl;
  726. std::cout << "rc0: " << rc0 << std::endl;*/
  727. CHECK_DIFF(rc0, rc);
  728. {
  729. UMat tmp = rc0.getUMat(ACCESS_WRITE);
  730. cv::max(ura, urb, tmp);
  731. }
  732. CHECK_DIFF(rc0, rc);
  733. ura.copyTo(urc);
  734. cv::max(urc, urb, urc);
  735. urc.copyTo(rc0);
  736. CHECK_DIFF(rc0, rc);
  737. rc = ra ^ rb;
  738. cv::bitwise_xor(ura, urb, urc);
  739. urc.copyTo(rc0);
  740. /*std::cout << "==============================================\nafter op:\n";
  741. std::cout << "ra: " << rc0 << std::endl;
  742. std::cout << "rc: " << rc << std::endl;*/
  743. CHECK_DIFF(rc0, rc);
  744. rc = ra + rb;
  745. cv::add(ura, urb, urc);
  746. urc.copyTo(rc0);
  747. CHECK_DIFF(rc0, rc);
  748. cv::subtract(ra, Scalar::all(5), rc);
  749. cv::subtract(ura, Scalar::all(5), urc);
  750. urc.copyTo(rc0);
  751. CHECK_DIFF(rc0, rc);
  752. }
  753. catch (const test_excep& e)
  754. {
  755. ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
  756. ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
  757. return false;
  758. }
  759. return true;
  760. }
  761. void CV_UMatTest::run( int /* start_from */)
  762. {
  763. printf("Use OpenCL: %s\nHave OpenCL: %s\n",
  764. cv::ocl::useOpenCL() ? "TRUE" : "FALSE",
  765. cv::ocl::haveOpenCL() ? "TRUE" : "FALSE" );
  766. if (!TestUMat())
  767. return;
  768. ts->set_failed_test_info(cvtest::TS::OK);
  769. }
  770. TEST(Core_UMat, base) { CV_UMatTest test; test.safe_run(); }
  771. TEST(Core_UMat, getUMat)
  772. {
  773. {
  774. int a[3] = { 1, 2, 3 };
  775. Mat m = Mat(1, 1, CV_32SC3, a);
  776. UMat u = m.getUMat(ACCESS_READ);
  777. EXPECT_NE((void*)NULL, u.u);
  778. }
  779. {
  780. Mat m(10, 10, CV_8UC1), ref;
  781. for (int y = 0; y < m.rows; ++y)
  782. {
  783. uchar * const ptr = m.ptr<uchar>(y);
  784. for (int x = 0; x < m.cols; ++x)
  785. ptr[x] = (uchar)(x + y * 2);
  786. }
  787. ref = m.clone();
  788. Rect r(1, 1, 8, 8);
  789. ref(r).setTo(17);
  790. {
  791. UMat um = m(r).getUMat(ACCESS_WRITE);
  792. um.setTo(17);
  793. }
  794. double err = cvtest::norm(m, ref, NORM_INF);
  795. if (err > 0)
  796. {
  797. std::cout << "m: " << std::endl << m << std::endl;
  798. std::cout << "ref: " << std::endl << ref << std::endl;
  799. }
  800. EXPECT_EQ(0., err);
  801. }
  802. }
  803. TEST(UMat, Sync)
  804. {
  805. UMat um(10, 10, CV_8UC1);
  806. {
  807. Mat m = um.getMat(ACCESS_WRITE);
  808. m.setTo(cv::Scalar::all(17));
  809. }
  810. um.setTo(cv::Scalar::all(19));
  811. EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), cv::Mat(um.size(), um.type(), 19), NORM_INF));
  812. }
  813. TEST(UMat, SyncTemp)
  814. {
  815. Mat m(10, 10, CV_8UC1);
  816. {
  817. UMat um = m.getUMat(ACCESS_WRITE);
  818. {
  819. Mat m2 = um.getMat(ACCESS_WRITE);
  820. m2.setTo(cv::Scalar::all(17));
  821. }
  822. um.setTo(cv::Scalar::all(19));
  823. EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), cv::Mat(um.size(), um.type(), 19), NORM_INF));
  824. }
  825. }
  826. TEST(UMat, CopyToIfDeviceCopyIsObsolete)
  827. {
  828. UMat um(7, 2, CV_8UC1);
  829. Mat m(um.size(), um.type());
  830. m.setTo(Scalar::all(0));
  831. {
  832. // make obsolete device copy of UMat
  833. Mat temp = um.getMat(ACCESS_WRITE);
  834. temp.setTo(Scalar::all(10));
  835. }
  836. m.copyTo(um);
  837. um.setTo(Scalar::all(17));
  838. EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), Mat(um.size(), um.type(), 17), NORM_INF));
  839. }
  840. TEST(UMat, setOpenCL)
  841. {
  842. #ifndef HAVE_OPENCL
  843. return; // test skipped
  844. #else
  845. // save the current state
  846. bool useOCL = cv::ocl::useOpenCL();
  847. Mat m = (Mat_<uchar>(3,3)<<0,1,2,3,4,5,6,7,8);
  848. cv::ocl::setUseOpenCL(true);
  849. UMat um1;
  850. m.copyTo(um1);
  851. cv::ocl::setUseOpenCL(false);
  852. UMat um2;
  853. m.copyTo(um2);
  854. cv::ocl::setUseOpenCL(true);
  855. countNonZero(um1);
  856. countNonZero(um2);
  857. um1.copyTo(um2);
  858. EXPECT_MAT_NEAR(um1, um2, 0);
  859. EXPECT_MAT_NEAR(um1, m, 0);
  860. um2.copyTo(um1);
  861. EXPECT_MAT_NEAR(um1, m, 0);
  862. EXPECT_MAT_NEAR(um1, um2, 0);
  863. cv::ocl::setUseOpenCL(false);
  864. countNonZero(um1);
  865. countNonZero(um2);
  866. um1.copyTo(um2);
  867. EXPECT_MAT_NEAR(um1, um2, 0);
  868. EXPECT_MAT_NEAR(um1, m, 0);
  869. um2.copyTo(um1);
  870. EXPECT_MAT_NEAR(um1, um2, 0);
  871. EXPECT_MAT_NEAR(um1, m, 0);
  872. // reset state to the previous one
  873. cv::ocl::setUseOpenCL(useOCL);
  874. #endif
  875. }
  876. TEST(UMat, ReadBufferRect)
  877. {
  878. UMat m(1, 10000, CV_32FC2, Scalar::all(-1));
  879. Mat t(1, 9000, CV_32FC2, Scalar::all(-200)), t2(1, 9000, CV_32FC2, Scalar::all(-1));
  880. m.colRange(0, 9000).copyTo(t);
  881. EXPECT_MAT_NEAR(t, t2, 0);
  882. }
  883. // Use iGPU or OPENCV_OPENCL_DEVICE=:CPU: to catch problem
  884. TEST(UMat, synchronization_map_unmap)
  885. {
  886. class TestParallelLoopBody : public cv::ParallelLoopBody
  887. {
  888. UMat u_;
  889. public:
  890. TestParallelLoopBody(const UMat& u) : u_(u) { }
  891. void operator() (const cv::Range& range) const
  892. {
  893. printf("range: %d, %d -- begin\n", range.start, range.end);
  894. for (int i = 0; i < 10; i++)
  895. {
  896. printf("%d: %d map...\n", range.start, i);
  897. Mat m = u_.getMat(cv::ACCESS_READ);
  898. printf("%d: %d unmap...\n", range.start, i);
  899. m.release();
  900. }
  901. printf("range: %d, %d -- end\n", range.start, range.end);
  902. }
  903. };
  904. try
  905. {
  906. UMat u(1000, 1000, CV_32FC1, Scalar::all(0));
  907. parallel_for_(cv::Range(0, 2), TestParallelLoopBody(u));
  908. }
  909. catch (const cv::Exception& e)
  910. {
  911. FAIL() << "Exception: " << e.what();
  912. ADD_FAILURE();
  913. }
  914. catch (...)
  915. {
  916. FAIL() << "Exception!";
  917. }
  918. }
  919. TEST(UMat, async_unmap)
  920. {
  921. for (int i = 0; i < 20; i++)
  922. {
  923. try
  924. {
  925. Mat m = Mat(1000, 1000, CV_8UC1, Scalar::all(0));
  926. UMat u = m.getUMat(ACCESS_READ);
  927. UMat dst;
  928. cv::add(u, Scalar::all(0), dst); // start async operation
  929. u.release();
  930. m.release();
  931. }
  932. catch (const cv::Exception& e)
  933. {
  934. printf("i = %d... %s\n", i, e.what());
  935. ADD_FAILURE();
  936. }
  937. catch (...)
  938. {
  939. printf("i = %d...\n", i);
  940. ADD_FAILURE();
  941. }
  942. }
  943. }
  944. TEST(UMat, unmap_in_class)
  945. {
  946. class Logic
  947. {
  948. public:
  949. Logic() {}
  950. void processData(InputArray input)
  951. {
  952. Mat m = input.getMat();
  953. {
  954. Mat dst;
  955. m.convertTo(dst, CV_32FC1);
  956. // some additional CPU-based per-pixel processing into dst
  957. intermediateResult = dst.getUMat(ACCESS_READ); // this violates lifetime of base(dst) / derived (intermediateResult) objects. Use copyTo?
  958. std::cout << "data processed..." << std::endl;
  959. } // problem is here: dst::~Mat()
  960. std::cout << "leave ProcessData()" << std::endl;
  961. }
  962. UMat getResult() const { return intermediateResult; }
  963. protected:
  964. UMat intermediateResult;
  965. };
  966. try
  967. {
  968. Mat m = Mat(1000, 1000, CV_8UC1, Scalar::all(0));
  969. Logic l;
  970. l.processData(m);
  971. UMat result = l.getResult();
  972. }
  973. catch (const cv::Exception& e)
  974. {
  975. printf("exception... %s\n", e.what());
  976. ADD_FAILURE();
  977. }
  978. catch (...)
  979. {
  980. printf("exception... \n");
  981. ADD_FAILURE();
  982. }
  983. }
  984. TEST(UMat, map_unmap_counting)
  985. {
  986. if (!cv::ocl::useOpenCL())
  987. {
  988. std::cout << "OpenCL is not enabled. Skip test" << std::endl;
  989. return;
  990. }
  991. std::cout << "Host memory: " << cv::ocl::Device::getDefault().hostUnifiedMemory() << std::endl;
  992. Mat m(Size(10, 10), CV_8UC1, Scalar::all(0));
  993. UMat um = m.getUMat(ACCESS_RW);
  994. {
  995. Mat d1 = um.getMat(ACCESS_RW);
  996. Mat d2 = um.getMat(ACCESS_RW);
  997. d1.release();
  998. }
  999. void* h = NULL;
  1000. EXPECT_NO_THROW(h = um.handle(ACCESS_RW));
  1001. std::cout << "Handle: " << h << std::endl;
  1002. }
  1003. static void process_with_async_cleanup(Mat& frame)
  1004. {
  1005. UMat blurResult;
  1006. {
  1007. UMat umat_buffer = frame.getUMat(ACCESS_READ);
  1008. cv::blur(umat_buffer, blurResult, Size(3, 3)); // UMat doesn't support inplace, this call is not synchronized
  1009. }
  1010. Mat result;
  1011. blurResult.copyTo(result);
  1012. swap(result, frame);
  1013. // umat_buffer cleanup is done asynchronously, silence warning about original 'frame' cleanup here (through 'result')
  1014. // - release input 'frame' (as 'result')
  1015. // - release 'umat_buffer' asynchronously and silence warning about "parent" buffer (in debug builds)
  1016. }
  1017. TEST(UMat, async_cleanup_without_call_chain_warning)
  1018. {
  1019. Mat frame(Size(640, 480), CV_8UC1, Scalar::all(128));
  1020. for (int i = 0; i < 10; i++)
  1021. {
  1022. process_with_async_cleanup(frame);
  1023. }
  1024. }
  1025. ///////////// oclCleanupCallback threadsafe check (#5062) /////////////////////
  1026. // Case 1: reuse of old src Mat in OCL pipe. Hard to catch!
  1027. OCL_TEST(UMat, DISABLED_OCL_ThreadSafe_CleanupCallback_1_VeryLongTest)
  1028. {
  1029. if (!cv::ocl::useOpenCL())
  1030. {
  1031. std::cout << "OpenCL is not enabled. Skip test" << std::endl;
  1032. return;
  1033. }
  1034. for (int j = 0; j < 100; j++)
  1035. {
  1036. const Size srcSize(320, 240);
  1037. const int type = CV_8UC1;
  1038. const int dtype = CV_16UC1;
  1039. Mat src(srcSize, type, Scalar::all(0));
  1040. Mat dst_ref(srcSize, dtype);
  1041. // Generate reference data as additional check
  1042. OCL_OFF(src.convertTo(dst_ref, dtype));
  1043. cv::ocl::setUseOpenCL(true); // restore OpenCL state
  1044. UMat dst(srcSize, dtype);
  1045. // Use multiple iterations to increase chance of data race catching
  1046. for(int k = 0; k < 10000; k++)
  1047. {
  1048. UMat tmpUMat = src.getUMat(ACCESS_RW);
  1049. tmpUMat.convertTo(dst, dtype);
  1050. ::cv::ocl::finish(); // force kernel to complete to start cleanup sooner
  1051. }
  1052. EXPECT_MAT_NEAR(dst_ref, dst, 1);
  1053. printf(".\n"); fflush(stdout);
  1054. }
  1055. }
  1056. // Case 2: concurrent deallocation of UMatData between UMat and Mat deallocators. Hard to catch!
  1057. OCL_TEST(UMat, DISABLED_OCL_ThreadSafe_CleanupCallback_2_VeryLongTest)
  1058. {
  1059. if (!cv::ocl::useOpenCL())
  1060. {
  1061. std::cout << "OpenCL is not enabled. Skip test" << std::endl;
  1062. return;
  1063. }
  1064. for (int j = 0; j < 100; j++)
  1065. {
  1066. const Size srcSize(320, 240);
  1067. const int type = CV_8UC1;
  1068. const int dtype = CV_16UC1;
  1069. // This test is only relevant for OCL
  1070. UMat dst(srcSize, dtype);
  1071. // Use multiple iterations to increase chance of data race catching
  1072. for(int k = 0; k < 10000; k++)
  1073. {
  1074. Mat src(srcSize, type, Scalar::all(0)); // Declare src inside loop now to catch its destruction on stack
  1075. {
  1076. UMat tmpUMat = src.getUMat(ACCESS_RW);
  1077. tmpUMat.convertTo(dst, dtype);
  1078. }
  1079. ::cv::ocl::finish(); // force kernel to complete to start cleanup sooner
  1080. }
  1081. printf(".\n"); fflush(stdout);
  1082. }
  1083. }
  1084. TEST(UMat, DISABLED_Test_same_behaviour_read_and_read)
  1085. {
  1086. bool exceptionDetected = false;
  1087. try
  1088. {
  1089. UMat u(Size(10, 10), CV_8UC1, Scalar::all(0));
  1090. Mat m = u.getMat(ACCESS_READ);
  1091. UMat dst;
  1092. cv::add(u, Scalar::all(1), dst);
  1093. }
  1094. catch (...)
  1095. {
  1096. exceptionDetected = true;
  1097. }
  1098. ASSERT_FALSE(exceptionDetected); // no data race, 2+ reads are valid
  1099. }
  1100. // VP: this test (and probably others from same_behaviour series) is not valid in my opinion.
  1101. TEST(UMat, DISABLED_Test_same_behaviour_read_and_write)
  1102. {
  1103. bool exceptionDetected = false;
  1104. try
  1105. {
  1106. UMat u(Size(10, 10), CV_8UC1, Scalar::all(0));
  1107. Mat m = u.getMat(ACCESS_READ);
  1108. cv::add(u, Scalar::all(1), u);
  1109. }
  1110. catch (...)
  1111. {
  1112. exceptionDetected = true;
  1113. }
  1114. ASSERT_TRUE(exceptionDetected); // data race
  1115. }
  1116. TEST(UMat, DISABLED_Test_same_behaviour_write_and_read)
  1117. {
  1118. bool exceptionDetected = false;
  1119. try
  1120. {
  1121. UMat u(Size(10, 10), CV_8UC1, Scalar::all(0));
  1122. Mat m = u.getMat(ACCESS_WRITE);
  1123. UMat dst;
  1124. cv::add(u, Scalar::all(1), dst);
  1125. }
  1126. catch (...)
  1127. {
  1128. exceptionDetected = true;
  1129. }
  1130. ASSERT_TRUE(exceptionDetected); // data race
  1131. }
  1132. TEST(UMat, DISABLED_Test_same_behaviour_write_and_write)
  1133. {
  1134. bool exceptionDetected = false;
  1135. try
  1136. {
  1137. UMat u(Size(10, 10), CV_8UC1, Scalar::all(0));
  1138. Mat m = u.getMat(ACCESS_WRITE);
  1139. cv::add(u, Scalar::all(1), u);
  1140. }
  1141. catch (...)
  1142. {
  1143. exceptionDetected = true;
  1144. }
  1145. ASSERT_TRUE(exceptionDetected); // data race
  1146. }
  1147. TEST(UMat, mat_umat_sync)
  1148. {
  1149. UMat u(10, 10, CV_8UC1, Scalar(1));
  1150. {
  1151. Mat m = u.getMat(ACCESS_RW).reshape(1);
  1152. m.setTo(Scalar(255));
  1153. }
  1154. UMat uDiff;
  1155. cv::compare(u, 255, uDiff, CMP_NE);
  1156. ASSERT_EQ(0, countNonZero(uDiff));
  1157. }
  1158. TEST(UMat, testTempObjects_UMat)
  1159. {
  1160. UMat u(10, 10, CV_8UC1, Scalar(1));
  1161. {
  1162. UMat u2 = u.getMat(ACCESS_RW).getUMat(ACCESS_RW);
  1163. u2.setTo(Scalar(255));
  1164. }
  1165. UMat uDiff;
  1166. cv::compare(u, 255, uDiff, CMP_NE);
  1167. ASSERT_EQ(0, countNonZero(uDiff));
  1168. }
  1169. TEST(UMat, testTempObjects_Mat)
  1170. {
  1171. Mat m(10, 10, CV_8UC1, Scalar(1));
  1172. {
  1173. Mat m2;
  1174. ASSERT_ANY_THROW({
  1175. // Below is unwrapped version of this invalid expression:
  1176. // m2 = m.getUMat(ACCESS_RW).getMat(ACCESS_RW)
  1177. UMat u = m.getUMat(ACCESS_RW);
  1178. m2 = u.getMat(ACCESS_RW);
  1179. u.release();
  1180. });
  1181. }
  1182. }
  1183. TEST(UMat, testWrongLifetime_UMat)
  1184. {
  1185. UMat u(10, 10, CV_8UC1, Scalar(1));
  1186. {
  1187. UMat u2 = u.getMat(ACCESS_RW).getUMat(ACCESS_RW);
  1188. u.release(); // base object
  1189. u2.release(); // derived object, should show warning message
  1190. }
  1191. }
  1192. TEST(UMat, testWrongLifetime_Mat)
  1193. {
  1194. Mat m(10, 10, CV_8UC1, Scalar(1));
  1195. {
  1196. UMat u = m.getUMat(ACCESS_RW);
  1197. Mat m2 = u.getMat(ACCESS_RW);
  1198. m.release(); // base object
  1199. m2.release(); // map of derived object
  1200. u.release(); // derived object, should show warning message
  1201. }
  1202. }
  1203. TEST(UMat, DISABLED_regression_5991)
  1204. {
  1205. int sz[] = {2,3,2};
  1206. UMat mat(3, sz, CV_32F, Scalar(1));
  1207. ASSERT_NO_THROW(mat.convertTo(mat, CV_8U));
  1208. EXPECT_EQ(sz[0], mat.size[0]);
  1209. EXPECT_EQ(sz[1], mat.size[1]);
  1210. EXPECT_EQ(sz[2], mat.size[2]);
  1211. EXPECT_EQ(0, cvtest::norm(mat.getMat(ACCESS_READ), Mat(3, sz, CV_8U, Scalar(1)), NORM_INF));
  1212. }
  1213. TEST(UMat, testTempObjects_Mat_issue_8693)
  1214. {
  1215. UMat srcUMat(3, 4, CV_32FC1);
  1216. Mat srcMat;
  1217. randu(srcUMat, -1.f, 1.f);
  1218. srcUMat.copyTo(srcMat);
  1219. reduce(srcUMat, srcUMat, 0, REDUCE_SUM);
  1220. reduce(srcMat, srcMat, 0, REDUCE_SUM);
  1221. srcUMat.convertTo(srcUMat, CV_64FC1);
  1222. srcMat.convertTo(srcMat, CV_64FC1);
  1223. EXPECT_EQ(0, cvtest::norm(srcUMat.getMat(ACCESS_READ), srcMat, NORM_INF));
  1224. }
  1225. TEST(UMat, resize_Mat_issue_13577)
  1226. {
  1227. // save the current state
  1228. bool useOCL = cv::ocl::useOpenCL();
  1229. cv::ocl::setUseOpenCL(false);
  1230. UMat foo(10, 10, CV_32FC1);
  1231. cv::resize(foo, foo, cv::Size(), .5, .5);
  1232. cv::ocl::setUseOpenCL(useOCL); // restore state
  1233. }
  1234. TEST(UMat, exceptions_refcounts_issue_20594)
  1235. {
  1236. if (!cv::ocl::useOpenCL())
  1237. {
  1238. // skip test, difficult to create exception scenario without OpenCL
  1239. std::cout << "OpenCL is not enabled. Skip test" << std::endl;
  1240. return;
  1241. }
  1242. UMat umat1(10, 10, CV_8UC1);
  1243. EXPECT_EQ(0, umat1.u->refcount);
  1244. // cause exception in underlying allocator
  1245. void* const original_handle = umat1.u->handle;
  1246. umat1.u->handle = NULL;
  1247. try
  1248. {
  1249. Mat mat1 = umat1.getMat(ACCESS_RW);
  1250. }
  1251. catch (...)
  1252. {
  1253. // nothing
  1254. }
  1255. // check for correct refcount, and no change of intentional bad handle
  1256. EXPECT_EQ(0, umat1.u->refcount);
  1257. EXPECT_EQ(NULL, umat1.u->handle);
  1258. // reset UMat to good state
  1259. umat1.u->refcount = 0;
  1260. umat1.u->handle = original_handle;
  1261. }
  1262. } } // namespace opencv_test::ocl