CLAHE Python bindings
[profile/ivi/opencv.git] / modules / ocl / perf / precomp.cpp
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-2012, Multicoreware, Inc., all rights reserved.
14 // Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other oclMaterials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors as is and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "precomp.hpp"
44 #if GTEST_OS_WINDOWS
45 #define NOMINMAX
46 # include <windows.h>
47 #endif
48
49 // This program test most of the functions in ocl module and generate data metrix of x-factor in .csv files
50 // All images needed in this test are in samples/gpu folder.
51 // For haar template, haarcascade_frontalface_alt.xml shouold be in working directory
52 void TestSystem::run()
53 {
54     if (is_list_mode_)
55     {
56         for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
57         {
58             cout << (*it)->name() << endl;
59         }
60
61         return;
62     }
63
64     // Run test initializers
65     for (vector<Runnable *>::iterator it = inits_.begin(); it != inits_.end(); ++it)
66     {
67         if ((*it)->name().find(test_filter_, 0) != string::npos)
68         {
69             (*it)->run();
70         }
71     }
72
73     printHeading();
74     writeHeading();
75
76     // Run tests
77     for (vector<Runnable *>::iterator it = tests_.begin(); it != tests_.end(); ++it)
78     {
79         try
80         {
81             if ((*it)->name().find(test_filter_, 0) != string::npos)
82             {
83                 cout << endl << (*it)->name() << ":\n";
84
85                 setCurrentTest((*it)->name());
86                 //fprintf(record_,"%s\n",(*it)->name().c_str());
87
88                 (*it)->run();
89                 finishCurrentSubtest();
90             }
91         }
92         catch (const Exception &)
93         {
94             // Message is printed via callback
95             resetCurrentSubtest();
96         }
97         catch (const runtime_error &e)
98         {
99             printError(e.what());
100             resetCurrentSubtest();
101         }
102     }
103
104     printSummary();
105     writeSummary();
106 }
107
108
109 void TestSystem::finishCurrentSubtest()
110 {
111     if (cur_subtest_is_empty_)
112         // There is no need to print subtest statistics
113     {
114         return;
115     }
116
117     double cpu_time = cpu_elapsed_ / getTickFrequency() * 1000.0;
118     double gpu_time = gpu_elapsed_ / getTickFrequency() * 1000.0;
119     double gpu_full_time = gpu_full_elapsed_ / getTickFrequency() * 1000.0;
120
121     double speedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_elapsed_);
122     speedup_total_ += speedup;
123
124     double fullspeedup = static_cast<double>(cpu_elapsed_) / std::max(1.0, gpu_full_elapsed_);
125     speedup_full_total_ += fullspeedup;
126
127     if (speedup > top_)
128     {
129         speedup_faster_count_++;
130     }
131     else if (speedup < bottom_)
132     {
133         speedup_slower_count_++;
134     }
135     else
136     {
137         speedup_equal_count_++;
138     }
139
140     if (fullspeedup > top_)
141     {
142         speedup_full_faster_count_++;
143     }
144     else if (fullspeedup < bottom_)
145     {
146         speedup_full_slower_count_++;
147     }
148     else
149     {
150         speedup_full_equal_count_++;
151     }
152
153     // compute min, max and
154     std::sort(gpu_times_.begin(), gpu_times_.end());
155     double gpu_min = gpu_times_.front() / getTickFrequency() * 1000.0;
156     double gpu_max = gpu_times_.back() / getTickFrequency() * 1000.0;
157     double deviation = 0;
158
159     if (gpu_times_.size() > 1)
160     {
161         double sum = 0;
162
163         for (size_t i = 0; i < gpu_times_.size(); i++)
164         {
165             int64 diff = gpu_times_[i] - static_cast<int64>(gpu_elapsed_);
166             double diff_time = diff * 1000 / getTickFrequency();
167             sum += diff_time * diff_time;
168         }
169
170         deviation = std::sqrt(sum / gpu_times_.size());
171     }
172
173     printMetrics(is_accurate_, cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup);
174     writeMetrics(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, gpu_min, gpu_max, deviation);
175
176     num_subtests_called_++;
177     resetCurrentSubtest();
178 }
179
180
181 double TestSystem::meanTime(const vector<int64> &samples)
182 {
183     double sum = accumulate(samples.begin(), samples.end(), 0.);
184     return sum / samples.size();
185 }
186
187
188 void TestSystem::printHeading()
189 {
190     cout << endl;
191     cout<< setiosflags(ios_base::left);
192
193 #if 0
194     cout<<TAB<<setw(7)<< "Accu." << setw(10) << "CPU (ms)" << setw(10) << "GPU, ms"
195         << setw(8) << "Speedup"<< setw(10)<<"GPUTotal" << setw(10) << "Total"
196         << "Description\n";
197     cout<<TAB<<setw(7)<<""<<setw(10)<<""<<setw(10)<<""<<setw(8)<<""<<setw(10)<<"(ms)"<<setw(10)<<"Speedup\n";
198 #endif
199
200     cout<<TAB<< setw(10) << "CPU (ms)" << setw(10) << "GPU, ms"
201         << setw(8) << "Speedup"<< setw(10)<<"GPUTotal" << setw(10) << "Total"
202         << "Description\n";
203     cout<<TAB<<setw(10)<<""<<setw(10)<<""<<setw(8)<<""<<setw(10)<<"(ms)"<<setw(10)<<"Speedup\n";
204
205     cout << resetiosflags(ios_base::left);
206 }
207
208 void TestSystem::writeHeading()
209 {
210     if (!record_)
211     {
212         recordname_ += "_OCL.csv";
213         record_ = fopen(recordname_.c_str(), "w");
214         if(record_ == NULL)
215         {
216             cout<<".csv file open failed.\n";
217             exit(0);
218         }
219     }
220
221     fprintf(record_, "NAME,DESCRIPTION,ACCURACY,DIFFERENCE,CPU (ms),GPU (ms),SPEEDUP,GPUTOTAL (ms),TOTALSPEEDUP,GPU Min (ms),GPU Max (ms), Standard deviation (ms)\n");
222
223     fflush(record_);
224 }
225
226 void TestSystem::printSummary()
227 {
228     cout << setiosflags(ios_base::fixed);
229     cout << "\naverage GPU speedup: x"
230         << setprecision(3) << speedup_total_ / std::max(1, num_subtests_called_)
231         << endl;
232     cout << "\nGPU exceeded: "
233         << setprecision(3) << speedup_faster_count_
234         << "\nGPU passed: "
235         << setprecision(3) << speedup_equal_count_
236         << "\nGPU failed: "
237         << setprecision(3) << speedup_slower_count_
238         << endl;
239     cout << "\nGPU exceeded rate: "
240         << setprecision(3) << (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100
241         << "%"
242         << "\nGPU passed rate: "
243         << setprecision(3) << (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100
244         << "%"
245         << "\nGPU failed rate: "
246         << setprecision(3) << (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100
247         << "%"
248         << endl;
249     cout << "\naverage GPUTOTAL speedup: x"
250         << setprecision(3) << speedup_full_total_ / std::max(1, num_subtests_called_)
251         << endl;
252     cout << "\nGPUTOTAL exceeded: "
253         << setprecision(3) << speedup_full_faster_count_
254         << "\nGPUTOTAL passed: "
255         << setprecision(3) << speedup_full_equal_count_
256         << "\nGPUTOTAL failed: "
257         << setprecision(3) << speedup_full_slower_count_
258         << endl;
259     cout << "\nGPUTOTAL exceeded rate: "
260         << setprecision(3) << (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100
261         << "%"
262         << "\nGPUTOTAL passed rate: "
263         << setprecision(3) << (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100
264         << "%"
265         << "\nGPUTOTAL failed rate: "
266         << setprecision(3) << (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
267         << "%"
268         << endl;
269     cout << resetiosflags(ios_base::fixed);
270 }
271
272
273 enum GTestColor {
274     COLOR_DEFAULT,
275     COLOR_RED,
276     COLOR_GREEN,
277     COLOR_YELLOW
278 };
279 #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
280 // Returns the character attribute for the given color.
281 WORD GetColorAttribute(GTestColor color) {
282     switch (color) {
283     case COLOR_RED:    return FOREGROUND_RED;
284     case COLOR_GREEN:  return FOREGROUND_GREEN;
285     case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
286     default:           return 0;
287     }
288 }
289 #else
290 static const char* GetAnsiColorCode(GTestColor color) {
291     switch (color) {
292     case COLOR_RED:     return "1";
293     case COLOR_GREEN:   return "2";
294     case COLOR_YELLOW:  return "3";
295     default:            return NULL;
296     };
297 }
298 #endif
299
300 static void printMetricsUti(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, std::stringstream& stream, std::stringstream& cur_subtest_description)
301 {
302     //cout <<TAB<< setw(7) << stream.str(); 
303     cout <<TAB; 
304
305     stream.str("");
306     stream << cpu_time;
307     cout << setw(10) << stream.str();
308
309     stream.str("");
310     stream << gpu_time;
311     cout << setw(10) << stream.str();
312
313     stream.str("");
314     stream << "x" << setprecision(3) << speedup;
315     cout << setw(8) << stream.str();
316
317     stream.str("");
318     stream << gpu_full_time;
319     cout << setw(10) << stream.str();
320
321     stream.str("");
322     stream << "x" << setprecision(3) << fullspeedup;
323     cout << setw(10) << stream.str();
324
325     cout << cur_subtest_description.str();
326     cout << resetiosflags(ios_base::left) << endl;
327 }
328
329 void TestSystem::printMetrics(int is_accurate, double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup)
330 {
331     cout << setiosflags(ios_base::left);
332     stringstream stream;
333
334 #if 0
335     if(is_accurate == 1)
336             stream << "Pass";
337     else if(is_accurate_ == 0)
338             stream << "Fail";
339     else if(is_accurate == -1)
340         stream << " ";
341     else
342     {
343         std::cout<<"is_accurate errer: "<<is_accurate<<"\n";
344         exit(-1);
345     }
346 #endif
347
348     std::stringstream &cur_subtest_description = getCurSubtestDescription();
349    
350 #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
351     
352     WORD color;
353     const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
354     // Gets the current text color.
355     CONSOLE_SCREEN_BUFFER_INFO buffer_info;
356     GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
357     const WORD old_color_attrs = buffer_info.wAttributes;
358     // We need to flush the stream buffers into the console before each
359     // SetConsoleTextAttribute call lest it affect the text that is already
360     // printed but has not yet reached the console.
361     fflush(stdout);
362
363     if(is_accurate == 1||is_accurate == -1)
364     {
365         color = old_color_attrs;
366         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
367
368     }else
369     {
370         color = GetColorAttribute(COLOR_RED);
371         SetConsoleTextAttribute(stdout_handle,
372             color| FOREGROUND_INTENSITY);
373
374         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
375         fflush(stdout);
376         // Restores the text color.
377         SetConsoleTextAttribute(stdout_handle, old_color_attrs);
378     }
379 #else
380     GTestColor color = COLOR_RED;
381     if(is_accurate == 1|| is_accurate == -1)
382     {
383         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
384
385     }else
386     {
387         printf("\033[0;3%sm", GetAnsiColorCode(color));
388         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
389         printf("\033[m");  // Resets the terminal to default.
390     }
391 #endif
392 }
393
394 void TestSystem::writeMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, double gpu_min, double gpu_max, double std_dev)
395 {
396     if (!record_)
397     {
398         recordname_ += ".csv";
399         record_ = fopen(recordname_.c_str(), "w");
400     }
401
402     string _is_accurate_;
403
404     if(is_accurate_ == 1)
405         _is_accurate_ = "Pass";
406     else if(is_accurate_ == 0)
407         _is_accurate_ = "Fail";
408     else if(is_accurate_ == -1)
409         _is_accurate_ = " ";
410     else
411     {
412         std::cout<<"is_accurate errer: "<<is_accurate_<<"\n";
413         exit(-1);
414     }
415
416     fprintf(record_, "%s,%s,%s,%.2f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", 
417         itname_changed_ ? itname_.c_str() : "",
418         cur_subtest_description_.str().c_str(),
419         _is_accurate_.c_str(), 
420         accurate_diff_,
421         cpu_time, gpu_time, speedup, gpu_full_time, fullspeedup,
422         gpu_min, gpu_max, std_dev);
423
424     if (itname_changed_)
425     {
426         itname_changed_ = false;
427     }
428
429     fflush(record_);
430 }
431
432 void TestSystem::writeSummary()
433 {
434     if (!record_)
435     {
436         recordname_ += ".csv";
437         record_ = fopen(recordname_.c_str(), "w");
438     }
439
440     fprintf(record_, "\nAverage GPU speedup: %.3f\n"
441         "exceeded: %d (%.3f%%)\n"
442         "passed: %d (%.3f%%)\n"
443         "failed: %d (%.3f%%)\n"
444         "\nAverage GPUTOTAL speedup: %.3f\n"
445         "exceeded: %d (%.3f%%)\n"
446         "passed: %d (%.3f%%)\n"
447         "failed: %d (%.3f%%)\n",
448         speedup_total_ / std::max(1, num_subtests_called_),
449         speedup_faster_count_, (float)speedup_faster_count_ / std::max(1, num_subtests_called_) * 100,
450         speedup_equal_count_, (float)speedup_equal_count_ / std::max(1, num_subtests_called_) * 100,
451         speedup_slower_count_, (float)speedup_slower_count_ / std::max(1, num_subtests_called_) * 100,
452         speedup_full_total_ / std::max(1, num_subtests_called_),
453         speedup_full_faster_count_, (float)speedup_full_faster_count_ / std::max(1, num_subtests_called_) * 100,
454         speedup_full_equal_count_, (float)speedup_full_equal_count_ / std::max(1, num_subtests_called_) * 100,
455         speedup_full_slower_count_, (float)speedup_full_slower_count_ / std::max(1, num_subtests_called_) * 100
456         );
457     fflush(record_);
458 }
459
460 void TestSystem::printError(const std::string &msg)
461 {
462     if(msg != "CL_INVALID_BUFFER_SIZE")
463     {
464         cout << TAB << "[error: " << msg << "] " << cur_subtest_description_.str() << endl;
465     }
466 }
467
468 void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high)
469 {
470     mat.create(rows, cols, type);
471     RNG rng(0);
472     rng.fill(mat, RNG::UNIFORM, low, high);
473 }
474
475 string abspath(const string &relpath)
476 {
477     return TestSystem::instance().workingDir() + relpath;
478 }
479
480
481 int CV_CDECL cvErrorCallback(int /*status*/, const char * /*func_name*/,
482     const char *err_msg, const char * /*file_name*/,
483     int /*line*/, void * /*userdata*/)
484 {
485     TestSystem::instance().printError(err_msg);
486     return 0;
487 }
488
489 double checkNorm(const Mat &m)
490 {
491     return norm(m, NORM_INF);
492 }
493
494 double checkNorm(const Mat &m1, const Mat &m2)
495 {
496     return norm(m1, m2, NORM_INF);
497 }
498
499 double checkSimilarity(const Mat &m1, const Mat &m2)
500 {
501     Mat diff;
502     matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);
503     return std::abs(diff.at<float>(0, 0) - 1.f);
504 }
505
506
507
508