Home | History | Annotate | Download | only in src
      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) 2010-2013, Advanced Micro Devices, Inc., 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 "precomp.hpp"
     43 
     44 #include "opencv2/ts/ocl_test.hpp"
     45 
     46 namespace cvtest {
     47 namespace ocl {
     48 
     49 using namespace cv;
     50 
     51 int test_loop_times = 1; // TODO Read from command line / environment
     52 
     53 #ifdef HAVE_OPENCL
     54 
     55 #define DUMP_PROPERTY_XML(propertyName, propertyValue) \
     56     do { \
     57         std::stringstream ssName, ssValue;\
     58         ssName << propertyName;\
     59         ssValue << (propertyValue); \
     60         ::testing::Test::RecordProperty(ssName.str(), ssValue.str()); \
     61     } while (false)
     62 
     63 #define DUMP_MESSAGE_STDOUT(msg) \
     64     do { \
     65         std::cout << msg << std::endl; \
     66     } while (false)
     67 
     68 static std::string bytesToStringRepr(size_t value)
     69 {
     70     size_t b = value % 1024;
     71     value /= 1024;
     72 
     73     size_t kb = value % 1024;
     74     value /= 1024;
     75 
     76     size_t mb = value % 1024;
     77     value /= 1024;
     78 
     79     size_t gb = value;
     80 
     81     std::ostringstream stream;
     82 
     83     if (gb > 0)
     84         stream << gb << " GB ";
     85     if (mb > 0)
     86         stream << mb << " MB ";
     87     if (kb > 0)
     88         stream << kb << " kB ";
     89     if (b > 0)
     90         stream << b << " B";
     91 
     92     return stream.str();
     93 }
     94 
     95 void dumpOpenCLDevice()
     96 {
     97     using namespace cv::ocl;
     98 
     99     try
    100     {
    101         if (!useOpenCL())
    102         {
    103             DUMP_MESSAGE_STDOUT("OpenCL is disabled");
    104             DUMP_PROPERTY_XML("cv_ocl", "disabled");
    105             return;
    106         }
    107 
    108         std::vector<PlatformInfo> platforms;
    109         cv::ocl::getPlatfomsInfo(platforms);
    110         if (platforms.size() > 0)
    111         {
    112             DUMP_MESSAGE_STDOUT("OpenCL Platforms: ");
    113             for (size_t i = 0; i < platforms.size(); i++)
    114             {
    115                 const PlatformInfo* platform = &platforms[i];
    116                 DUMP_MESSAGE_STDOUT("    " << platform->name().c_str());
    117                 Device current_device;
    118                 for (int j = 0; j < platform->deviceNumber(); j++)
    119                 {
    120                     platform->getDevice(current_device, j);
    121                     const char* deviceTypeStr = current_device.type() == Device::TYPE_CPU
    122                         ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? current_device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown");
    123                     DUMP_MESSAGE_STDOUT( "        " << deviceTypeStr << ": " << current_device.name().c_str() << " (" << current_device.version().c_str() << ")");
    124                     DUMP_PROPERTY_XML( cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j ),
    125                         cv::format("(Platform=%s)(Type=%s)(Name=%s)(Version=%s)",
    126                         platform->name().c_str(), deviceTypeStr, current_device.name().c_str(), current_device.version().c_str()) );
    127                 }
    128             }
    129         }
    130         else
    131         {
    132             DUMP_MESSAGE_STDOUT("OpenCL is not available");
    133             DUMP_PROPERTY_XML("cv_ocl", "not available");
    134             return;
    135         }
    136 
    137         const Device& device = Device::getDefault();
    138         if (!device.available())
    139             CV_ErrorNoReturn(CV_OpenCLInitError, "OpenCL device is not available");
    140 
    141         DUMP_MESSAGE_STDOUT("Current OpenCL device: ");
    142 
    143 #if 0
    144         DUMP_MESSAGE_STDOUT("    Platform = "<< device.getPlatform().name());
    145         DUMP_PROPERTY_XML("cv_ocl_current_platformName", device.getPlatform().name());
    146 #endif
    147 
    148         const char* deviceTypeStr = device.type() == Device::TYPE_CPU
    149             ? ("CPU") : (device.type() == Device::TYPE_GPU ? device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown");
    150         DUMP_MESSAGE_STDOUT("    Type = "<< deviceTypeStr);
    151         DUMP_PROPERTY_XML("cv_ocl_current_deviceType", deviceTypeStr);
    152 
    153         DUMP_MESSAGE_STDOUT("    Name = "<< device.name());
    154         DUMP_PROPERTY_XML("cv_ocl_current_deviceName", device.name());
    155 
    156         DUMP_MESSAGE_STDOUT("    Version = " << device.version());
    157         DUMP_PROPERTY_XML("cv_ocl_current_deviceVersion", device.version());
    158 
    159         DUMP_MESSAGE_STDOUT("    Compute units = "<< device.maxComputeUnits());
    160         DUMP_PROPERTY_XML("cv_ocl_current_maxComputeUnits", device.maxComputeUnits());
    161 
    162         DUMP_MESSAGE_STDOUT("    Max work group size = "<< device.maxWorkGroupSize());
    163         DUMP_PROPERTY_XML("cv_ocl_current_maxWorkGroupSize", device.maxWorkGroupSize());
    164 
    165         std::string localMemorySizeStr = bytesToStringRepr(device.localMemSize());
    166         DUMP_MESSAGE_STDOUT("    Local memory size = " << localMemorySizeStr);
    167         DUMP_PROPERTY_XML("cv_ocl_current_localMemSize", device.localMemSize());
    168 
    169         std::string maxMemAllocSizeStr = bytesToStringRepr(device.maxMemAllocSize());
    170         DUMP_MESSAGE_STDOUT("    Max memory allocation size = "<< maxMemAllocSizeStr);
    171         DUMP_PROPERTY_XML("cv_ocl_current_maxMemAllocSize", device.maxMemAllocSize());
    172 
    173         const char* doubleSupportStr = device.doubleFPConfig() > 0 ? "Yes" : "No";
    174         DUMP_MESSAGE_STDOUT("    Double support = "<< doubleSupportStr);
    175         DUMP_PROPERTY_XML("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0);
    176 
    177         const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No";
    178         DUMP_MESSAGE_STDOUT("    Host unified memory = "<< isUnifiedMemoryStr);
    179         DUMP_PROPERTY_XML("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory());
    180 
    181         const char* haveAmdBlasStr = haveAmdBlas() ? "Yes" : "No";
    182         DUMP_MESSAGE_STDOUT("    Has AMD Blas = "<< haveAmdBlasStr);
    183         DUMP_PROPERTY_XML("cv_ocl_current_AmdBlas", haveAmdBlas());
    184 
    185         const char* haveAmdFftStr = haveAmdFft() ? "Yes" : "No";
    186         DUMP_MESSAGE_STDOUT("    Has AMD Fft = "<< haveAmdFftStr);
    187         DUMP_PROPERTY_XML("cv_ocl_current_AmdFft", haveAmdFft());
    188 
    189 
    190         DUMP_MESSAGE_STDOUT("    Preferred vector width char = "<< device.preferredVectorWidthChar());
    191         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthChar", device.preferredVectorWidthChar());
    192 
    193         DUMP_MESSAGE_STDOUT("    Preferred vector width short = "<< device.preferredVectorWidthShort());
    194         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthShort", device.preferredVectorWidthShort());
    195 
    196         DUMP_MESSAGE_STDOUT("    Preferred vector width int = "<< device.preferredVectorWidthInt());
    197         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthInt", device.preferredVectorWidthInt());
    198 
    199         DUMP_MESSAGE_STDOUT("    Preferred vector width long = "<< device.preferredVectorWidthLong());
    200         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthLong", device.preferredVectorWidthLong());
    201 
    202         DUMP_MESSAGE_STDOUT("    Preferred vector width float = "<< device.preferredVectorWidthFloat());
    203         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthFloat", device.preferredVectorWidthFloat());
    204 
    205         DUMP_MESSAGE_STDOUT("    Preferred vector width double = "<< device.preferredVectorWidthDouble());
    206         DUMP_PROPERTY_XML("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble());
    207     }
    208     catch (...)
    209     {
    210         DUMP_MESSAGE_STDOUT("Exception. Can't dump OpenCL info");
    211         DUMP_MESSAGE_STDOUT("OpenCL device not available");
    212         DUMP_PROPERTY_XML("cv_ocl", "not available");
    213     }
    214 }
    215 #undef DUMP_MESSAGE_STDOUT
    216 #undef DUMP_PROPERTY_XML
    217 
    218 #endif
    219 
    220 Mat TestUtils::readImage(const String &fileName, int flags)
    221 {
    222     return cv::imread(cvtest::TS::ptr()->get_data_path() + fileName, flags);
    223 }
    224 
    225 Mat TestUtils::readImageType(const String &fname, int type)
    226 {
    227     Mat src = readImage(fname, CV_MAT_CN(type) == 1 ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
    228     if (CV_MAT_CN(type) == 4)
    229     {
    230         Mat temp;
    231         cv::cvtColor(src, temp, cv::COLOR_BGR2BGRA);
    232         swap(src, temp);
    233     }
    234     src.convertTo(src, CV_MAT_DEPTH(type));
    235     return src;
    236 }
    237 
    238 double TestUtils::checkNorm1(InputArray m, InputArray mask)
    239 {
    240     return cvtest::norm(m.getMat(), NORM_INF, mask.getMat());
    241 }
    242 
    243 double TestUtils::checkNorm2(InputArray m1, InputArray m2, InputArray mask)
    244 {
    245     return cvtest::norm(m1.getMat(), m2.getMat(), NORM_INF, mask.getMat());
    246 }
    247 
    248 double TestUtils::checkSimilarity(InputArray m1, InputArray m2)
    249 {
    250     Mat diff;
    251     matchTemplate(m1.getMat(), m2.getMat(), diff, CV_TM_CCORR_NORMED);
    252     return std::abs(diff.at<float>(0, 0) - 1.f);
    253 }
    254 
    255 double TestUtils::checkRectSimilarity(const Size & sz, std::vector<Rect>& ob1, std::vector<Rect>& ob2)
    256 {
    257     double final_test_result = 0.0;
    258     size_t sz1 = ob1.size();
    259     size_t sz2 = ob2.size();
    260 
    261     if (sz1 != sz2)
    262         return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1);
    263     else
    264     {
    265         if (sz1 == 0 && sz2 == 0)
    266             return 0;
    267         cv::Mat cpu_result(sz, CV_8UC1);
    268         cpu_result.setTo(0);
    269 
    270         for (vector<Rect>::const_iterator r = ob1.begin(); r != ob1.end(); r++)
    271         {
    272             cv::Mat cpu_result_roi(cpu_result, *r);
    273             cpu_result_roi.setTo(1);
    274             cpu_result.copyTo(cpu_result);
    275         }
    276         int cpu_area = cv::countNonZero(cpu_result > 0);
    277 
    278         cv::Mat gpu_result(sz, CV_8UC1);
    279         gpu_result.setTo(0);
    280         for(vector<Rect>::const_iterator r2 = ob2.begin(); r2 != ob2.end(); r2++)
    281         {
    282             cv::Mat gpu_result_roi(gpu_result, *r2);
    283             gpu_result_roi.setTo(1);
    284             gpu_result.copyTo(gpu_result);
    285         }
    286 
    287         cv::Mat result_;
    288         multiply(cpu_result, gpu_result, result_);
    289         int result = cv::countNonZero(result_ > 0);
    290         if (cpu_area!=0 && result!=0)
    291             final_test_result = 1.0 - (double)result/(double)cpu_area;
    292         else if(cpu_area==0 && result!=0)
    293             final_test_result = -1;
    294     }
    295     return final_test_result;
    296 }
    297 
    298 void TestUtils::showDiff(InputArray _src, InputArray _gold, InputArray _actual, double eps, bool alwaysShow)
    299 {
    300     Mat src = _src.getMat(), actual = _actual.getMat(), gold = _gold.getMat();
    301 
    302     Mat diff, diff_thresh;
    303     absdiff(gold, actual, diff);
    304     diff.convertTo(diff, CV_32F);
    305     threshold(diff, diff_thresh, eps, 255.0, cv::THRESH_BINARY);
    306 
    307     if (alwaysShow || cv::countNonZero(diff_thresh.reshape(1)) > 0)
    308     {
    309 #if 0
    310         std::cout << "Source: " << std::endl << src << std::endl;
    311         std::cout << "Expected: " << std::endl << gold << std::endl;
    312         std::cout << "Actual: " << std::endl << actual << std::endl;
    313 #endif
    314 
    315         namedWindow("src", WINDOW_NORMAL);
    316         namedWindow("gold", WINDOW_NORMAL);
    317         namedWindow("actual", WINDOW_NORMAL);
    318         namedWindow("diff", WINDOW_NORMAL);
    319 
    320         imshow("src", src);
    321         imshow("gold", gold);
    322         imshow("actual", actual);
    323         imshow("diff", diff);
    324 
    325         cv::waitKey();
    326     }
    327 }
    328 
    329 } } // namespace cvtest::ocl
    330