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