Home | History | Annotate | Download | only in test
      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 
     42 #include "test_precomp.hpp"
     43 #include "opencv2/ts/ocl_test.hpp"
     44 
     45 using namespace cvtest;
     46 using namespace testing;
     47 using namespace cv;
     48 
     49 namespace cvtest {
     50 namespace ocl {
     51 
     52 #define UMAT_TEST_SIZES testing::Values(cv::Size(1, 1), cv::Size(1,128), cv::Size(128, 1), \
     53     cv::Size(128, 128), cv::Size(640, 480), cv::Size(751, 373), cv::Size(1200, 1200))
     54 
     55 /////////////////////////////// Basic Tests ////////////////////////////////
     56 
     57 PARAM_TEST_CASE(UMatBasicTests, int, int, Size, bool)
     58 {
     59     Mat a;
     60     UMat ua;
     61     int type;
     62     int depth;
     63     int cn;
     64     Size size;
     65     bool useRoi;
     66     Size roi_size;
     67     Rect roi;
     68 
     69     virtual void SetUp()
     70     {
     71         depth = GET_PARAM(0);
     72         cn = GET_PARAM(1);
     73         size = GET_PARAM(2);
     74         useRoi = GET_PARAM(3);
     75         type = CV_MAKE_TYPE(depth, cn);
     76         a = randomMat(size, type, -100, 100);
     77         a.copyTo(ua);
     78         int roi_shift_x = randomInt(0, size.width-1);
     79         int roi_shift_y = randomInt(0, size.height-1);
     80         roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
     81         roi = Rect(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
     82     }
     83 };
     84 
     85 TEST_P(UMatBasicTests, createUMat)
     86 {
     87     if(useRoi)
     88     {
     89         ua = UMat(ua, roi);
     90     }
     91     int dims = randomInt(2,6);
     92     int _sz[CV_MAX_DIM];
     93     for( int i = 0; i<dims; i++)
     94     {
     95         _sz[i] = randomInt(1,50);
     96     }
     97     int *sz = _sz;
     98     int new_depth = randomInt(CV_8S, CV_64F);
     99     int new_cn = randomInt(1,4);
    100     ua.create(dims, sz, CV_MAKE_TYPE(new_depth, new_cn));
    101 
    102     for(int i = 0; i<dims; i++)
    103     {
    104         ASSERT_EQ(ua.size[i], sz[i]);
    105     }
    106     ASSERT_EQ(ua.dims, dims);
    107     ASSERT_EQ(ua.type(), CV_MAKE_TYPE(new_depth, new_cn) );
    108     Size new_size = randomSize(1, 1000);
    109     ua.create(new_size, CV_MAKE_TYPE(new_depth, new_cn) );
    110     ASSERT_EQ( ua.size(), new_size);
    111     ASSERT_EQ(ua.type(), CV_MAKE_TYPE(new_depth, new_cn) );
    112     ASSERT_EQ( ua.dims, 2);
    113 }
    114 
    115 TEST_P(UMatBasicTests, swap)
    116 {
    117     Mat b = randomMat(size, type, -100, 100);
    118     UMat ub;
    119     b.copyTo(ub);
    120     if(useRoi)
    121     {
    122         ua = UMat(ua,roi);
    123         ub = UMat(ub,roi);
    124     }
    125     UMat uc = ua, ud = ub;
    126     swap(ua,ub);
    127     EXPECT_MAT_NEAR(ub,uc, 0);
    128     EXPECT_MAT_NEAR(ud, ua, 0);
    129 }
    130 
    131 TEST_P(UMatBasicTests, base)
    132 {
    133     const int align_mask = 3;
    134     roi.x &= ~align_mask;
    135     roi.y &= ~align_mask;
    136     roi.width = (roi.width + align_mask) & ~align_mask;
    137     roi &= Rect(0, 0, ua.cols, ua.rows);
    138 
    139     if(useRoi)
    140     {
    141         ua = UMat(ua,roi);
    142     }
    143     UMat ub = ua.clone();
    144     EXPECT_MAT_NEAR(ub,ua,0);
    145 
    146     ASSERT_EQ(ua.channels(), cn);
    147     ASSERT_EQ(ua.depth(), depth);
    148     ASSERT_EQ(ua.type(), type);
    149     ASSERT_EQ(ua.elemSize(), a.elemSize());
    150     ASSERT_EQ(ua.elemSize1(), a.elemSize1());
    151     ASSERT_EQ(ub.empty(), ub.cols*ub.rows == 0);
    152     ub.release();
    153     ASSERT_TRUE( ub.empty() );
    154     if(useRoi && a.size() != ua.size())
    155     {
    156         ASSERT_EQ(ua.isSubmatrix(), true);
    157     }
    158     else
    159     {
    160         ASSERT_EQ(ua.isSubmatrix(), false);
    161     }
    162 
    163     int dims = randomInt(2,6);
    164     int sz[CV_MAX_DIM];
    165     size_t total = 1;
    166     for(int i = 0; i<dims; i++)
    167     {
    168         sz[i] = randomInt(1,45);
    169         total *= (size_t)sz[i];
    170     }
    171     int new_type = CV_MAKE_TYPE(randomInt(CV_8S,CV_64F),randomInt(1,4));
    172     ub = UMat(dims, sz, new_type);
    173     ASSERT_EQ(ub.total(), total);
    174 }
    175 
    176 TEST_P(UMatBasicTests, DISABLED_copyTo)
    177 {
    178     UMat roi_ua;
    179     Mat roi_a;
    180     int i;
    181     if(useRoi)
    182     {
    183         roi_ua = UMat(ua, roi);
    184         roi_a = Mat(a, roi);
    185         roi_a.copyTo(roi_ua);
    186         EXPECT_MAT_NEAR(roi_a, roi_ua, 0);
    187         roi_ua.copyTo(roi_a);
    188         EXPECT_MAT_NEAR(roi_ua, roi_a, 0);
    189         roi_ua.copyTo(ua);
    190         EXPECT_MAT_NEAR(roi_ua, ua, 0);
    191         ua.copyTo(a);
    192         EXPECT_MAT_NEAR(ua, a, 0);
    193     }
    194     {
    195         UMat ub;
    196         ua.copyTo(ub);
    197         EXPECT_MAT_NEAR(ua, ub, 0);
    198     }
    199     {
    200         UMat ub;
    201         i = randomInt(0, ua.cols-1);
    202         a.col(i).copyTo(ub);
    203         EXPECT_MAT_NEAR(a.col(i), ub, 0);
    204     }
    205     {
    206         UMat ub;
    207         ua.col(i).copyTo(ub);
    208         EXPECT_MAT_NEAR(ua.col(i), ub, 0);
    209     }
    210     {
    211         Mat b;
    212         ua.col(i).copyTo(b);
    213         EXPECT_MAT_NEAR(ua.col(i), b, 0);
    214     }
    215     {
    216         UMat ub;
    217         i = randomInt(0, a.rows-1);
    218         ua.row(i).copyTo(ub);
    219         EXPECT_MAT_NEAR(ua.row(i), ub, 0);
    220     }
    221     {
    222         UMat ub;
    223         a.row(i).copyTo(ub);
    224         EXPECT_MAT_NEAR(a.row(i), ub, 0);
    225     }
    226     {
    227         Mat b;
    228         ua.row(i).copyTo(b);
    229         EXPECT_MAT_NEAR(ua.row(i), b, 0);
    230     }
    231 }
    232 
    233 TEST_P(UMatBasicTests, DISABLED_GetUMat)
    234 {
    235     if(useRoi)
    236     {
    237         a = Mat(a, roi);
    238         ua = UMat(ua,roi);
    239     }
    240     {
    241         UMat ub;
    242         ub = a.getUMat(ACCESS_RW);
    243         EXPECT_MAT_NEAR(ub, ua, 0);
    244     }
    245     {
    246         Mat b;
    247         b = a.getUMat(ACCESS_RW).getMat(ACCESS_RW);
    248         EXPECT_MAT_NEAR(b, a, 0);
    249     }
    250     {
    251         Mat b;
    252         b = ua.getMat(ACCESS_RW);
    253         EXPECT_MAT_NEAR(b, a, 0);
    254     }
    255     {
    256         UMat ub;
    257         ub = ua.getMat(ACCESS_RW).getUMat(ACCESS_RW);
    258         EXPECT_MAT_NEAR(ub, ua, 0);
    259     }
    260 }
    261 
    262 INSTANTIATE_TEST_CASE_P(UMat, UMatBasicTests, Combine(testing::Values(CV_8U), testing::Values(1, 2),
    263     testing::Values(cv::Size(1, 1), cv::Size(1, 128), cv::Size(128, 1), cv::Size(128, 128), cv::Size(640, 480)), Bool()));
    264 
    265 //////////////////////////////////////////////////////////////// Reshape ////////////////////////////////////////////////////////////////////////
    266 
    267 PARAM_TEST_CASE(UMatTestReshape,  int, int, Size, bool)
    268 {
    269     Mat a;
    270     UMat ua, ub;
    271     int type;
    272     int depth;
    273     int cn;
    274     Size size;
    275     bool useRoi;
    276     Size roi_size;
    277     virtual void SetUp()
    278     {
    279         depth = GET_PARAM(0);
    280         cn = GET_PARAM(1);
    281         size = GET_PARAM(2);
    282         useRoi = GET_PARAM(3);
    283         type = CV_MAKE_TYPE(depth, cn);
    284     }
    285 };
    286 
    287 TEST_P(UMatTestReshape, DISABLED_reshape)
    288 {
    289     a = randomMat(size,type, -100, 100);
    290     a.copyTo(ua);
    291     if(useRoi)
    292     {
    293         int roi_shift_x = randomInt(0, size.width-1);
    294         int roi_shift_y = randomInt(0, size.height-1);
    295         roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    296         Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    297         ua = UMat(ua, roi).clone();
    298         a = Mat(a, roi).clone();
    299     }
    300 
    301     int nChannels = randomInt(1,4);
    302 
    303     if ((ua.cols*ua.channels()*ua.rows)%nChannels != 0)
    304     {
    305         EXPECT_ANY_THROW(ua.reshape(nChannels));
    306     }
    307     else
    308     {
    309         ub = ua.reshape(nChannels);
    310         ASSERT_EQ(ub.channels(),nChannels);
    311         ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
    312 
    313         EXPECT_MAT_NEAR(ua.reshape(nChannels), a.reshape(nChannels), 0);
    314 
    315         int new_rows = randomInt(1, INT_MAX);
    316         if ( ((int)ua.total()*ua.channels())%(new_rows*nChannels) != 0)
    317         {
    318             EXPECT_ANY_THROW (ua.reshape(nChannels, new_rows) );
    319         }
    320         else
    321         {
    322             EXPECT_NO_THROW ( ub = ua.reshape(nChannels, new_rows) );
    323             ASSERT_EQ(ub.channels(),nChannels);
    324             ASSERT_EQ(ub.rows, new_rows);
    325             ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
    326 
    327             EXPECT_MAT_NEAR(ua.reshape(nChannels,new_rows), a.reshape(nChannels,new_rows), 0);
    328         }
    329 
    330         new_rows = (int)ua.total()*ua.channels()/(nChannels*randomInt(1, size.width*size.height));
    331         if (new_rows == 0) new_rows = 1;
    332         int new_cols = (int)ua.total()*ua.channels()/(new_rows*nChannels);
    333         int sz[] = {new_rows, new_cols};
    334         if( ((int)ua.total()*ua.channels()) % (new_rows*new_cols) != 0 )
    335         {
    336             EXPECT_ANY_THROW( ua.reshape(nChannels, ua.dims, sz) );
    337         }
    338         else
    339         {
    340             EXPECT_NO_THROW ( ub = ua.reshape(nChannels, ua.dims, sz) );
    341             ASSERT_EQ(ub.channels(),nChannels);
    342             ASSERT_EQ(ub.rows, new_rows);
    343             ASSERT_EQ(ub.cols, new_cols);
    344             ASSERT_EQ(ub.channels()*ub.cols*ub.rows, ua.channels()*ua.cols*ua.rows);
    345 
    346             EXPECT_MAT_NEAR(ua.reshape(nChannels, ua.dims, sz), a.reshape(nChannels, a.dims, sz), 0);
    347         }
    348     }
    349 }
    350 
    351 INSTANTIATE_TEST_CASE_P(UMat, UMatTestReshape, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool() ));
    352 
    353 ////////////////////////////////////////////////////////////////// ROI testing ///////////////////////////////////////////////////////////////
    354 
    355 PARAM_TEST_CASE(UMatTestRoi, int, int, Size)
    356 {
    357     Mat a, roi_a;
    358     UMat ua, roi_ua;
    359     int type;
    360     int depth;
    361     int cn;
    362     Size size;
    363     Size roi_size;
    364     virtual void SetUp()
    365     {
    366         depth = GET_PARAM(0);
    367         cn = GET_PARAM(1);
    368         size = GET_PARAM(2);
    369         type = CV_MAKE_TYPE(depth, cn);
    370     }
    371 };
    372 
    373 TEST_P(UMatTestRoi, createRoi)
    374 {
    375     int roi_shift_x = randomInt(0, size.width-1);
    376     int roi_shift_y = randomInt(0, size.height-1);
    377     roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    378     a = randomMat(size, type, -100, 100);
    379     Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    380     roi_a = Mat(a, roi);
    381     a.copyTo(ua);
    382     roi_ua = UMat(ua, roi);
    383 
    384     EXPECT_MAT_NEAR(roi_a, roi_ua, 0);
    385 }
    386 
    387 TEST_P(UMatTestRoi, locateRoi)
    388 {
    389     int roi_shift_x = randomInt(0, size.width-1);
    390     int roi_shift_y = randomInt(0, size.height-1);
    391     roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    392     a = randomMat(size, type, -100, 100);
    393     Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    394     roi_a = Mat(a, roi);
    395     a.copyTo(ua);
    396     roi_ua = UMat(ua,roi);
    397     Size sz, usz;
    398     Point p, up;
    399     roi_a.locateROI(sz, p);
    400     roi_ua.locateROI(usz, up);
    401     ASSERT_EQ(sz, usz);
    402     ASSERT_EQ(p, up);
    403 }
    404 
    405 TEST_P(UMatTestRoi, adjustRoi)
    406 {
    407     int roi_shift_x = randomInt(0, size.width-1);
    408     int roi_shift_y = randomInt(0, size.height-1);
    409     roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    410     a = randomMat(size, type, -100, 100);
    411     Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    412     a.copyTo(ua);
    413     roi_ua = UMat( ua, roi);
    414     int adjLeft = randomInt(-(roi_ua.cols/2), (size.width-1)/2);
    415     int adjRight = randomInt(-(roi_ua.cols/2), (size.width-1)/2);
    416     int adjTop = randomInt(-(roi_ua.rows/2), (size.height-1)/2);
    417     int adjBot = randomInt(-(roi_ua.rows/2), (size.height-1)/2);
    418     roi_ua.adjustROI(adjTop, adjBot, adjLeft, adjRight);
    419     roi_shift_x = std::max(0, roi.x-adjLeft);
    420     roi_shift_y = std::max(0, roi.y-adjTop);
    421     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) );
    422     UMat test_roi = UMat(ua, new_roi);
    423     EXPECT_MAT_NEAR(roi_ua, test_roi, 0);
    424 }
    425 
    426 INSTANTIATE_TEST_CASE_P(UMat, UMatTestRoi, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES ));
    427 
    428 /////////////////////////////////////////////////////////////// Size ////////////////////////////////////////////////////////////////////
    429 
    430 PARAM_TEST_CASE(UMatTestSizeOperations, int, int, Size, bool)
    431 {
    432     Mat a, b, roi_a, roi_b;
    433     UMat ua, ub, roi_ua, roi_ub;
    434     int type;
    435     int depth;
    436     int cn;
    437     Size size;
    438     Size roi_size;
    439     bool useRoi;
    440     virtual void SetUp()
    441     {
    442         depth = GET_PARAM(0);
    443         cn = GET_PARAM(1);
    444         size = GET_PARAM(2);
    445         useRoi = GET_PARAM(3);
    446         type = CV_MAKE_TYPE(depth, cn);
    447     }
    448 };
    449 
    450 TEST_P(UMatTestSizeOperations, copySize)
    451 {
    452     Size s = randomSize(1,300);
    453     a = randomMat(size, type, -100, 100);
    454     b = randomMat(s, type, -100, 100);
    455     a.copyTo(ua);
    456     b.copyTo(ub);
    457     if(useRoi)
    458     {
    459         int roi_shift_x = randomInt(0, size.width-1);
    460         int roi_shift_y = randomInt(0, size.height-1);
    461         roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    462         Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    463         ua = UMat(ua,roi);
    464 
    465         roi_shift_x = randomInt(0, s.width-1);
    466         roi_shift_y = randomInt(0, s.height-1);
    467         roi_size = Size(s.width - roi_shift_x, s.height - roi_shift_y);
    468         roi = Rect(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    469         ub = UMat(ub, roi);
    470     }
    471     ua.copySize(ub);
    472     ASSERT_EQ(ua.size, ub.size);
    473 }
    474 
    475 INSTANTIATE_TEST_CASE_P(UMat, UMatTestSizeOperations, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool() ));
    476 
    477 ///////////////////////////////////////////////////////////////// UMat operations ////////////////////////////////////////////////////////////////////////////
    478 
    479 PARAM_TEST_CASE(UMatTestUMatOperations, int, int, Size, bool)
    480 {
    481     Mat a, b;
    482     UMat ua, ub;
    483     int type;
    484     int depth;
    485     int cn;
    486     Size size;
    487     Size roi_size;
    488     bool useRoi;
    489     virtual void SetUp()
    490     {
    491         depth = GET_PARAM(0);
    492         cn = GET_PARAM(1);
    493         size = GET_PARAM(2);
    494         useRoi = GET_PARAM(3);
    495         type = CV_MAKE_TYPE(depth, cn);
    496     }
    497 };
    498 
    499 TEST_P(UMatTestUMatOperations, diag)
    500 {
    501     a = randomMat(size, type, -100, 100);
    502     a.copyTo(ua);
    503     Mat new_diag;
    504     if(useRoi)
    505     {
    506         int roi_shift_x = randomInt(0, size.width-1);
    507         int roi_shift_y = randomInt(0, size.height-1);
    508         roi_size = Size(size.width - roi_shift_x, size.height - roi_shift_y);
    509         Rect roi(roi_shift_x, roi_shift_y, roi_size.width, roi_size.height);
    510         ua = UMat(ua,roi);
    511         a = Mat(a, roi);
    512     }
    513     int n = randomInt(0, ua.cols-1);
    514     ub = ua.diag(n);
    515     b = a.diag(n);
    516     EXPECT_MAT_NEAR(b, ub, 0);
    517     new_diag = randomMat(Size(ua.rows, 1), type, -100, 100);
    518     new_diag.copyTo(ub);
    519     ua = cv::UMat::diag(ub);
    520     EXPECT_MAT_NEAR(ua.diag(), new_diag.t(), 0);
    521 }
    522 
    523 INSTANTIATE_TEST_CASE_P(UMat, UMatTestUMatOperations, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, UMAT_TEST_SIZES, Bool()));
    524 
    525 ///////////////////////////////////////////////////////////////// OpenCL ////////////////////////////////////////////////////////////////////////////
    526 
    527 TEST(UMat, BufferPoolGrowing)
    528 {
    529 #ifdef _DEBUG
    530     const int ITERATIONS = 100;
    531 #else
    532     const int ITERATIONS = 200;
    533 #endif
    534     const Size sz(1920, 1080);
    535     BufferPoolController* c = cv::ocl::getOpenCLAllocator()->getBufferPoolController();
    536     if (c)
    537     {
    538         size_t oldMaxReservedSize = c->getMaxReservedSize();
    539         c->freeAllReservedBuffers();
    540         c->setMaxReservedSize(sz.area() * 10);
    541         for (int i = 0; i < ITERATIONS; i++)
    542         {
    543             UMat um(Size(sz.width + i, sz.height + i), CV_8UC1);
    544             UMat um2(Size(sz.width + 2 * i, sz.height + 2 * i), CV_8UC1);
    545         }
    546         c->setMaxReservedSize(oldMaxReservedSize);
    547         c->freeAllReservedBuffers();
    548     }
    549     else
    550         std::cout << "Skipped, no OpenCL" << std::endl;
    551 }
    552 
    553 class CV_UMatTest :
    554         public cvtest::BaseTest
    555 {
    556 public:
    557     CV_UMatTest() {}
    558     ~CV_UMatTest() {}
    559 protected:
    560     void run(int);
    561 
    562     struct test_excep
    563     {
    564         test_excep(const string& _s=string("")) : s(_s) { }
    565         string s;
    566     };
    567 
    568     bool TestUMat();
    569 
    570     void checkDiff(const Mat& m1, const Mat& m2, const string& s)
    571     {
    572         if (cvtest::norm(m1, m2, NORM_INF) != 0)
    573             throw test_excep(s);
    574     }
    575     void checkDiffF(const Mat& m1, const Mat& m2, const string& s)
    576     {
    577         if (cvtest::norm(m1, m2, NORM_INF) > 1e-5)
    578             throw test_excep(s);
    579     }
    580 };
    581 
    582 #define STR(a) STR2(a)
    583 #define STR2(a) #a
    584 
    585 #define CHECK_DIFF(a, b) checkDiff(a, b, "(" #a ")  !=  (" #b ")  at l." STR(__LINE__))
    586 #define CHECK_DIFF_FLT(a, b) checkDiffF(a, b, "(" #a ")  !=(eps)  (" #b ")  at l." STR(__LINE__))
    587 
    588 
    589 bool CV_UMatTest::TestUMat()
    590 {
    591     try
    592     {
    593         Mat a(100, 100, CV_16SC2), b, c;
    594         randu(a, Scalar::all(-100), Scalar::all(100));
    595         Rect roi(1, 3, 5, 4);
    596         Mat ra(a, roi), rb, rc, rc0;
    597         UMat ua, ura, ub, urb, uc, urc;
    598         a.copyTo(ua);
    599         ua.copyTo(b);
    600         CHECK_DIFF(a, b);
    601 
    602         ura = ua(roi);
    603         ura.copyTo(rb);
    604 
    605         CHECK_DIFF(ra, rb);
    606 
    607         ra += Scalar::all(1.f);
    608         {
    609             Mat temp = ura.getMat(ACCESS_RW);
    610             temp += Scalar::all(1.f);
    611         }
    612         ra.copyTo(rb);
    613         CHECK_DIFF(ra, rb);
    614 
    615         b = a.clone();
    616         ra = a(roi);
    617         rb = b(roi);
    618         randu(b, Scalar::all(-100), Scalar::all(100));
    619         b.copyTo(ub);
    620         urb = ub(roi);
    621 
    622         /*std::cout << "==============================================\nbefore op (CPU):\n";
    623         std::cout << "ra: " << ra << std::endl;
    624         std::cout << "rb: " << rb << std::endl;*/
    625 
    626         ra.copyTo(ura);
    627         rb.copyTo(urb);
    628         ra.release();
    629         rb.release();
    630         ura.copyTo(ra);
    631         urb.copyTo(rb);
    632 
    633         /*std::cout << "==============================================\nbefore op (GPU):\n";
    634         std::cout << "ra: " << ra << std::endl;
    635         std::cout << "rb: " << rb << std::endl;*/
    636 
    637         cv::max(ra, rb, rc);
    638         cv::max(ura, urb, urc);
    639         urc.copyTo(rc0);
    640 
    641         /*std::cout << "==============================================\nafter op:\n";
    642         std::cout << "rc: " << rc << std::endl;
    643         std::cout << "rc0: " << rc0 << std::endl;*/
    644 
    645         CHECK_DIFF(rc0, rc);
    646 
    647         {
    648             UMat tmp = rc0.getUMat(ACCESS_WRITE);
    649             cv::max(ura, urb, tmp);
    650         }
    651         CHECK_DIFF(rc0, rc);
    652 
    653         ura.copyTo(urc);
    654         cv::max(urc, urb, urc);
    655         urc.copyTo(rc0);
    656         CHECK_DIFF(rc0, rc);
    657 
    658         rc = ra ^ rb;
    659         cv::bitwise_xor(ura, urb, urc);
    660         urc.copyTo(rc0);
    661 
    662         /*std::cout << "==============================================\nafter op:\n";
    663         std::cout << "ra: " << rc0 << std::endl;
    664         std::cout << "rc: " << rc << std::endl;*/
    665 
    666         CHECK_DIFF(rc0, rc);
    667 
    668         rc = ra + rb;
    669         cv::add(ura, urb, urc);
    670         urc.copyTo(rc0);
    671 
    672         CHECK_DIFF(rc0, rc);
    673 
    674         cv::subtract(ra, Scalar::all(5), rc);
    675         cv::subtract(ura, Scalar::all(5), urc);
    676         urc.copyTo(rc0);
    677 
    678         CHECK_DIFF(rc0, rc);
    679     }
    680     catch (const test_excep& e)
    681     {
    682         ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
    683         ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
    684         return false;
    685     }
    686     return true;
    687 }
    688 
    689 void CV_UMatTest::run( int /* start_from */)
    690 {
    691     printf("Use OpenCL: %s\nHave OpenCL: %s\n",
    692            cv::ocl::useOpenCL() ? "TRUE" : "FALSE",
    693            cv::ocl::haveOpenCL() ? "TRUE" : "FALSE" );
    694 
    695     if (!TestUMat())
    696         return;
    697 
    698     ts->set_failed_test_info(cvtest::TS::OK);
    699 }
    700 
    701 TEST(Core_UMat, base) { CV_UMatTest test; test.safe_run(); }
    702 
    703 TEST(Core_UMat, getUMat)
    704 {
    705     {
    706         int a[3] = { 1, 2, 3 };
    707         Mat m = Mat(1, 1, CV_32SC3, a);
    708         UMat u = m.getUMat(ACCESS_READ);
    709         EXPECT_NE((void*)NULL, u.u);
    710     }
    711 
    712     {
    713         Mat m(10, 10, CV_8UC1), ref;
    714         for (int y = 0; y < m.rows; ++y)
    715         {
    716             uchar * const ptr = m.ptr<uchar>(y);
    717             for (int x = 0; x < m.cols; ++x)
    718                 ptr[x] = (uchar)(x + y * 2);
    719         }
    720 
    721         ref = m.clone();
    722         Rect r(1, 1, 8, 8);
    723         ref(r).setTo(17);
    724 
    725         {
    726             UMat um = m(r).getUMat(ACCESS_WRITE);
    727             um.setTo(17);
    728         }
    729 
    730         double err = cvtest::norm(m, ref, NORM_INF);
    731         if (err > 0)
    732         {
    733             std::cout << "m: " << std::endl << m << std::endl;
    734             std::cout << "ref: " << std::endl << ref << std::endl;
    735         }
    736         EXPECT_EQ(0., err);
    737     }
    738 }
    739 
    740 TEST(UMat, Sync)
    741 {
    742     UMat um(10, 10, CV_8UC1);
    743 
    744     {
    745         Mat m = um.getMat(ACCESS_WRITE);
    746         m.setTo(cv::Scalar::all(17));
    747     }
    748 
    749     um.setTo(cv::Scalar::all(19));
    750 
    751     EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), cv::Mat(um.size(), um.type(), 19), NORM_INF));
    752 }
    753 
    754 TEST(UMat, CopyToIfDeviceCopyIsObsolete)
    755 {
    756     UMat um(7, 2, CV_8UC1);
    757     Mat m(um.size(), um.type());
    758     m.setTo(Scalar::all(0));
    759 
    760     {
    761         // make obsolete device copy of UMat
    762         Mat temp = um.getMat(ACCESS_WRITE);
    763         temp.setTo(Scalar::all(10));
    764     }
    765 
    766     m.copyTo(um);
    767     um.setTo(Scalar::all(17));
    768 
    769     EXPECT_EQ(0, cvtest::norm(um.getMat(ACCESS_READ), Mat(um.size(), um.type(), 17), NORM_INF));
    770 }
    771 
    772 TEST(UMat, setOpenCL)
    773 {
    774     // save the current state
    775     bool useOCL = cv::ocl::useOpenCL();
    776 
    777     Mat m = (Mat_<uchar>(3,3)<<0,1,2,3,4,5,6,7,8);
    778 
    779     cv::ocl::setUseOpenCL(true);
    780     UMat um1;
    781     m.copyTo(um1);
    782 
    783     cv::ocl::setUseOpenCL(false);
    784     UMat um2;
    785     m.copyTo(um2);
    786 
    787     cv::ocl::setUseOpenCL(true);
    788     countNonZero(um1);
    789     countNonZero(um2);
    790 
    791     um1.copyTo(um2);
    792     EXPECT_MAT_NEAR(um1, um2, 0);
    793     EXPECT_MAT_NEAR(um1, m, 0);
    794     um2.copyTo(um1);
    795     EXPECT_MAT_NEAR(um1, m, 0);
    796     EXPECT_MAT_NEAR(um1, um2, 0);
    797 
    798     cv::ocl::setUseOpenCL(false);
    799     countNonZero(um1);
    800     countNonZero(um2);
    801 
    802     um1.copyTo(um2);
    803     EXPECT_MAT_NEAR(um1, um2, 0);
    804     EXPECT_MAT_NEAR(um1, m, 0);
    805     um2.copyTo(um1);
    806     EXPECT_MAT_NEAR(um1, um2, 0);
    807     EXPECT_MAT_NEAR(um1, m, 0);
    808 
    809     // reset state to the previous one
    810     cv::ocl::setUseOpenCL(useOCL);
    811 }
    812 
    813 TEST(UMat, ReadBufferRect)
    814 {
    815     UMat m(1, 10000, CV_32FC2, Scalar::all(-1));
    816     Mat t(1, 9000, CV_32FC2, Scalar::all(-200)), t2(1, 9000, CV_32FC2, Scalar::all(-1));
    817     m.colRange(0, 9000).copyTo(t);
    818 
    819     EXPECT_MAT_NEAR(t, t2, 0);
    820 }
    821 
    822 // Use iGPU or OPENCV_OPENCL_DEVICE=:CPU: to catch problem
    823 TEST(UMat, DISABLED_synchronization_map_unmap)
    824 {
    825     class TestParallelLoopBody : public cv::ParallelLoopBody
    826     {
    827         UMat u_;
    828     public:
    829         TestParallelLoopBody(const UMat& u) : u_(u) { }
    830         void operator() (const cv::Range& range) const
    831         {
    832             printf("range: %d, %d -- begin\n", range.start, range.end);
    833             for (int i = 0; i < 10; i++)
    834             {
    835                 printf("%d: %d map...\n", range.start, i);
    836                 Mat m = u_.getMat(cv::ACCESS_READ);
    837 
    838                 printf("%d: %d unmap...\n", range.start, i);
    839                 m.release();
    840             }
    841             printf("range: %d, %d -- end\n", range.start, range.end);
    842         }
    843     };
    844     try
    845     {
    846         UMat u(1000, 1000, CV_32FC1);
    847         parallel_for_(cv::Range(0, 2), TestParallelLoopBody(u));
    848     }
    849     catch (const cv::Exception& e)
    850     {
    851         FAIL() << "Exception: " << e.what();
    852         ADD_FAILURE();
    853     }
    854     catch (...)
    855     {
    856         FAIL() << "Exception!";
    857     }
    858 }
    859 
    860 } } // namespace cvtest::ocl
    861 
    862 TEST(UMat, DISABLED_bug_with_unmap)
    863 {
    864     for (int i = 0; i < 20; i++)
    865     {
    866         try
    867         {
    868             Mat m = Mat(1000, 1000, CV_8UC1);
    869             UMat u = m.getUMat(ACCESS_READ);
    870             UMat dst;
    871             add(u, Scalar::all(0), dst); // start async operation
    872             u.release();
    873             m.release();
    874         }
    875         catch (const cv::Exception& e)
    876         {
    877             printf("i = %d... %s\n", i, e.what());
    878             ADD_FAILURE();
    879         }
    880         catch (...)
    881         {
    882             printf("i = %d...\n", i);
    883             ADD_FAILURE();
    884         }
    885     }
    886 }
    887 
    888 TEST(UMat, DISABLED_bug_with_unmap_in_class)
    889 {
    890     class Logic
    891     {
    892     public:
    893         Logic() {}
    894         void processData(InputArray input)
    895         {
    896             Mat m = input.getMat();
    897             {
    898                 Mat dst;
    899                 m.convertTo(dst, CV_32FC1);
    900                 // some additional CPU-based per-pixel processing into dst
    901                 intermediateResult = dst.getUMat(ACCESS_READ);
    902                 std::cout << "data processed..." << std::endl;
    903             } // problem is here: dst::~Mat()
    904             std::cout << "leave ProcessData()" << std::endl;
    905         }
    906         UMat getResult() const { return intermediateResult; }
    907     protected:
    908         UMat intermediateResult;
    909     };
    910     try
    911     {
    912         Mat m = Mat(1000, 1000, CV_8UC1);
    913         Logic l;
    914         l.processData(m);
    915         UMat result = l.getResult();
    916     }
    917     catch (const cv::Exception& e)
    918     {
    919         printf("exception... %s\n", e.what());
    920         ADD_FAILURE();
    921     }
    922     catch (...)
    923     {
    924         printf("exception... \n");
    925         ADD_FAILURE();
    926     }
    927 }
    928 
    929 TEST(UMat, Test_same_behaviour_read_and_read)
    930 {
    931     bool exceptionDetected = false;
    932     try
    933     {
    934         UMat u(Size(10, 10), CV_8UC1);
    935         Mat m = u.getMat(ACCESS_READ);
    936         UMat dst;
    937         add(u, Scalar::all(1), dst);
    938     }
    939     catch (...)
    940     {
    941         exceptionDetected = true;
    942     }
    943     ASSERT_FALSE(exceptionDetected); // no data race, 2+ reads are valid
    944 }
    945 
    946 // VP: this test (and probably others from same_behaviour series) is not valid in my opinion.
    947 TEST(UMat, DISABLED_Test_same_behaviour_read_and_write)
    948 {
    949     bool exceptionDetected = false;
    950     try
    951     {
    952         UMat u(Size(10, 10), CV_8UC1);
    953         Mat m = u.getMat(ACCESS_READ);
    954         add(u, Scalar::all(1), u);
    955     }
    956     catch (...)
    957     {
    958         exceptionDetected = true;
    959     }
    960     ASSERT_TRUE(exceptionDetected); // data race
    961 }
    962 
    963 TEST(UMat, DISABLED_Test_same_behaviour_write_and_read)
    964 {
    965     bool exceptionDetected = false;
    966     try
    967     {
    968         UMat u(Size(10, 10), CV_8UC1);
    969         Mat m = u.getMat(ACCESS_WRITE);
    970         UMat dst;
    971         add(u, Scalar::all(1), dst);
    972     }
    973     catch (...)
    974     {
    975         exceptionDetected = true;
    976     }
    977     ASSERT_TRUE(exceptionDetected); // data race
    978 }
    979 
    980 TEST(UMat, DISABLED_Test_same_behaviour_write_and_write)
    981 {
    982     bool exceptionDetected = false;
    983     try
    984     {
    985         UMat u(Size(10, 10), CV_8UC1);
    986         Mat m = u.getMat(ACCESS_WRITE);
    987         add(u, Scalar::all(1), u);
    988     }
    989     catch (...)
    990     {
    991         exceptionDetected = true;
    992     }
    993     ASSERT_TRUE(exceptionDetected); // data race
    994 }
    995