1 #ifndef OPENCV_CUDA_SAMPLE_PERFORMANCE_H_
2 #define OPENCV_CUDA_SAMPLE_PERFORMANCE_H_
3 
4 #include <iostream>
5 #include <cstdio>
6 #include <vector>
7 #include <numeric>
8 #include <string>
9 #include <opencv2/core/utility.hpp>
10 
11 #define TAB "    "
12 
13 class Runnable
14 {
15 public:
Runnable(const std::string & nameStr)16     explicit Runnable(const std::string& nameStr): name_(nameStr) {}
~Runnable()17     virtual ~Runnable() {}
18 
name()19     const std::string& name() const { return name_; }
20 
21     virtual void run() = 0;
22 
23 private:
24     std::string name_;
25 };
26 
27 
28 class TestSystem
29 {
30 public:
instance()31     static TestSystem& instance()
32     {
33         static TestSystem me;
34         return me;
35     }
36 
setWorkingDir(const std::string & val)37     void setWorkingDir(const std::string& val) { working_dir_ = val; }
workingDir()38     const std::string& workingDir() const { return working_dir_; }
39 
setTestFilter(const std::string & val)40     void setTestFilter(const std::string& val) { test_filter_ = val; }
testFilter()41     const std::string& testFilter() const { return test_filter_; }
42 
setNumIters(int num_iters)43     void setNumIters(int num_iters) { num_iters_ = num_iters; }
44 
addInit(Runnable * init)45     void addInit(Runnable* init) { inits_.push_back(init); }
addTest(Runnable * test)46     void addTest(Runnable* test) { tests_.push_back(test); }
47     void run();
48 
49     // It's public because OpenCV callback uses it
50     void printError(const std::string& msg);
51 
startNewSubtest()52     std::stringstream& startNewSubtest()
53     {
54         finishCurrentSubtest();
55         return cur_subtest_description_;
56     }
57 
stop()58     bool stop() const { return cur_iter_idx_ >= num_iters_; }
59 
cpuOn()60     void cpuOn() { cpu_started_ = cv::getTickCount(); }
cpuOff()61     void cpuOff()
62     {
63         int64 delta = cv::getTickCount() - cpu_started_;
64         cpu_times_.push_back(delta);
65         ++cur_iter_idx_;
66     }
cpuComplete()67     void cpuComplete()
68     {
69         cpu_elapsed_ += meanTime(cpu_times_);
70         cur_subtest_is_empty_ = false;
71         cur_iter_idx_ = 0;
72     }
73 
gpuOn()74     void gpuOn() { gpu_started_ = cv::getTickCount(); }
gpuOff()75     void gpuOff()
76     {
77         int64 delta = cv::getTickCount() - gpu_started_;
78         gpu_times_.push_back(delta);
79         ++cur_iter_idx_;
80     }
gpuComplete()81     void gpuComplete()
82     {
83         gpu_elapsed_ += meanTime(gpu_times_);
84         cur_subtest_is_empty_ = false;
85         cur_iter_idx_ = 0;
86     }
87 
isListMode()88     bool isListMode() const { return is_list_mode_; }
setListMode(bool value)89     void setListMode(bool value) { is_list_mode_ = value; }
90 
91 private:
TestSystem()92     TestSystem():
93             cur_subtest_is_empty_(true), cpu_elapsed_(0),
94             gpu_elapsed_(0), speedup_total_(0.0),
95             num_subtests_called_(0), is_list_mode_(false),
96             num_iters_(10), cur_iter_idx_(0)
97     {
98         cpu_times_.reserve(num_iters_);
99         gpu_times_.reserve(num_iters_);
100     }
101 
102     void finishCurrentSubtest();
resetCurrentSubtest()103     void resetCurrentSubtest()
104     {
105         cpu_elapsed_ = 0;
106         gpu_elapsed_ = 0;
107         cur_subtest_description_.str("");
108         cur_subtest_is_empty_ = true;
109         cur_iter_idx_ = 0;
110         cpu_times_.clear();
111         gpu_times_.clear();
112     }
113 
114     double meanTime(const std::vector<int64> &samples);
115 
116     void printHeading();
117     void printSummary();
118     void printMetrics(double cpu_time, double gpu_time, double speedup);
119 
120     std::string working_dir_;
121     std::string test_filter_;
122 
123     std::vector<Runnable*> inits_;
124     std::vector<Runnable*> tests_;
125 
126     std::stringstream cur_subtest_description_;
127     bool cur_subtest_is_empty_;
128 
129     int64 cpu_started_;
130     int64 gpu_started_;
131     double cpu_elapsed_;
132     double gpu_elapsed_;
133 
134     double speedup_total_;
135     int num_subtests_called_;
136 
137     bool is_list_mode_;
138 
139     int num_iters_;
140     int cur_iter_idx_;
141     std::vector<int64> cpu_times_;
142     std::vector<int64> gpu_times_;
143 };
144 
145 
146 #define GLOBAL_INIT(name) \
147     struct name##_init: Runnable { \
148         name##_init(): Runnable(#name) { \
149             TestSystem::instance().addInit(this); \
150         } \
151         void run(); \
152     } name##_init_instance; \
153     void name##_init::run()
154 
155 
156 #define TEST(name) \
157     struct name##_test: Runnable { \
158         name##_test(): Runnable(#name) { \
159             TestSystem::instance().addTest(this); \
160         } \
161         void run(); \
162     } name##_test_instance; \
163     void name##_test::run()
164 
165 #define SUBTEST TestSystem::instance().startNewSubtest()
166 
167 #define CPU_ON \
168     while (!TestSystem::instance().stop()) { \
169         TestSystem::instance().cpuOn()
170 #define CPU_OFF \
171         TestSystem::instance().cpuOff(); \
172     } TestSystem::instance().cpuComplete()
173 
174 #define CUDA_ON \
175     while (!TestSystem::instance().stop()) { \
176         TestSystem::instance().gpuOn()
177 #define CUDA_OFF \
178         TestSystem::instance().gpuOff(); \
179     } TestSystem::instance().gpuComplete()
180 
181 // Generates a matrix
182 void gen(cv::Mat& mat, int rows, int cols, int type, cv::Scalar low,
183          cv::Scalar high);
184 
185 // Returns abs path taking into account test system working dir
186 std::string abspath(const std::string& relpath);
187 
188 #endif // OPENCV_CUDA_SAMPLE_PERFORMANCE_H_
189