added first version of gpu performance tests
authorAlexey Spizhevoy <no@email>
Mon, 24 Jan 2011 10:33:01 +0000 (10:33 +0000)
committerAlexey Spizhevoy <no@email>
Mon, 24 Jan 2011 10:33:01 +0000 (10:33 +0000)
modules/gpu/src/match_template.cpp
samples/gpu/CMakeLists.txt
samples/gpu/performance/CMakeLists.txt [new file with mode: 0644]
samples/gpu/performance/performance.cpp [new file with mode: 0644]
samples/gpu/performance/performance.h [new file with mode: 0644]
samples/gpu/performance/tests.cpp [new file with mode: 0644]

index 5f5807c..d534503 100644 (file)
@@ -178,7 +178,7 @@ namespace
             if (depth == CV_8U) return 300;\r
             break;\r
         case CV_TM_SQDIFF:\r
-            if (depth == CV_8U) return 500;\r
+            if (depth == CV_8U) return 300;\r
             break;\r
         }\r
         CV_Error(CV_StsBadArg, "getTemplateThreshold: unsupported match template mode");\r
index eb73fdd..c65c2e6 100644 (file)
@@ -47,7 +47,9 @@ if (BUILD_EXAMPLES)
     foreach(sample_filename ${gpu_samples})\r
         get_filename_component(sample ${sample_filename} NAME_WE)\r
         MY_DEFINE_EXAMPLE(${sample}  ${sample_filename})\r
-    endforeach()\r
+    endforeach()   \r
+    \r
+    include("performance/CMakeLists.txt")\r
 endif(BUILD_EXAMPLES)\r
 \r
 if (NOT WIN32)\r
diff --git a/samples/gpu/performance/CMakeLists.txt b/samples/gpu/performance/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3a17b28
--- /dev/null
@@ -0,0 +1,29 @@
+set(the_target "example_gpu_performance")\r
+\r
+file(GLOB sources "performance/*.cpp")\r
+file(GLOB headers "performance/*.h")\r
+\r
+add_executable(${the_target} ${sources} ${headers})\r
+\r
+set_target_properties(${the_target} PROPERTIES\r
+    OUTPUT_NAME "performance_gpu"\r
+    PROJECT_LABEL "(EXAMPLE_GPU) performance")\r
+    \r
+add_dependencies(${the_target} opencv_core opencv_flann opencv_imgproc opencv_highgui\r
+    opencv_ml opencv_video opencv_objdetect opencv_features2d\r
+    opencv_calib3d opencv_legacy opencv_contrib opencv_gpu)\r
+    \r
+target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} opencv_core\r
+    opencv_flann opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect\r
+    opencv_features2d opencv_calib3d opencv_legacy opencv_contrib opencv_gpu)\r
+\r
+if(WIN32)\r
+    install(TARGETS ${the_target} RUNTIME DESTINATION "samples/gpu" COMPONENT main)\r
+endif()\r
+\r
+if(NOT WIN32)\r
+    file(GLOB GPU_FILES performance/*.cpp performance/*.h)\r
+    install(FILES ${GPU_FILES}\r
+            DESTINATION share/opencv/samples/gpu/performance\r
+            PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)\r
+endif()
\ No newline at end of file
diff --git a/samples/gpu/performance/performance.cpp b/samples/gpu/performance/performance.cpp
new file mode 100644 (file)
index 0000000..035a123
--- /dev/null
@@ -0,0 +1,93 @@
+#include <iomanip>\r
+#include "performance.h"\r
+\r
+using namespace std;\r
+using namespace cv;\r
+\r
+\r
+void Test::gen(Mat& mat, int rows, int cols, int type, Scalar low, Scalar high)\r
+{   \r
+    mat.create(rows, cols, type);\r
+\r
+    RNG rng(0);\r
+    rng.fill(mat, RNG::UNIFORM, low, high);\r
+}\r
+\r
+\r
+void Test::gen(Mat& mat, int rows, int cols, int type)\r
+{   \r
+    mat.create(rows, cols, type);\r
+\r
+    Mat mat8u(rows, cols * mat.elemSize(), CV_8U, mat.data, mat.step);\r
+\r
+    RNG rng(0);\r
+    rng.fill(mat, RNG::UNIFORM, Scalar(0), Scalar(256));\r
+}\r
+\r
+\r
+void TestSystem::run()\r
+{\r
+    cout << setiosflags(ios_base::left);\r
+    cout << "    " << setw(10) << "CPU, ms" << setw(10) << "GPU, ms" \r
+        << setw(10) << "SPEEDUP" << "DESCRIPTION\n";\r
+    cout << resetiosflags(ios_base::left);\r
+\r
+    vector<Test*>::iterator it = tests_.begin();\r
+    for (; it != tests_.end(); ++it)\r
+    {\r
+        can_flush_ = false;\r
+        Test* test = *it;\r
+\r
+        cout << endl << test->name() << ":\n";\r
+        test->run();\r
+\r
+        flush();\r
+    }\r
+\r
+    cout << setiosflags(ios_base::fixed | ios_base::left);\r
+    cout << "\nCPU Total: " << setprecision(3) << cpu_total_ / getTickFrequency() << " sec\n";\r
+    cout << "GPU Total: " << setprecision(3) << gpu_total_ / getTickFrequency() << " sec (x" \r
+        << setprecision(3) << (double)cpu_total_ / gpu_total_ << ")\n";\r
+    cout << resetiosflags(ios_base::fixed | ios_base::left);\r
+}\r
+\r
+\r
+void TestSystem::flush()\r
+{\r
+    if (!can_flush_)\r
+        return;\r
+\r
+    int cpu_time = static_cast<int>(cpu_elapsed_ / getTickFrequency() * 1000.0);\r
+    int gpu_time = static_cast<int>(gpu_elapsed_ / getTickFrequency() * 1000.0);\r
+    double speedup = (double)cpu_time / gpu_time;\r
+\r
+    cpu_elapsed_ = 0;\r
+    gpu_elapsed_ = 0;\r
+\r
+    cout << "    " << setiosflags(ios_base::fixed | ios_base::left);\r
+\r
+    stringstream stream;\r
+    stream << cpu_time;\r
+    cout << setw(10) << stream.str();\r
+\r
+    stream.str("");\r
+    stream << gpu_time;\r
+    cout << setw(10) << stream.str();\r
+\r
+    stream.str("");\r
+    stream << "x" << setprecision(3) << speedup;\r
+    cout << setw(10) << stream.str();\r
+\r
+    cout << description_.str();\r
+    description_.str("");\r
+\r
+    cout << resetiosflags(ios_base::fixed | ios_base::left) << endl;\r
+    can_flush_ = false;\r
+}\r
+\r
+\r
+int main()\r
+{\r
+    TestSystem::instance()->run();\r
+    return 0;\r
+}
\ No newline at end of file
diff --git a/samples/gpu/performance/performance.h b/samples/gpu/performance/performance.h
new file mode 100644 (file)
index 0000000..ef0787c
--- /dev/null
@@ -0,0 +1,99 @@
+#include <iostream>\r
+#include <cstdio>\r
+#include <vector>\r
+#include <string>\r
+#include <opencv2/core/core.hpp>\r
+\r
+class Test\r
+{\r
+public:\r
+    Test(const std::string& name): name_(name) {}\r
+\r
+    const std::string& name() const { return name_; }\r
+\r
+    void gen(cv::Mat& mat, int rows, int cols, int type,\r
+             cv::Scalar low, cv::Scalar high);\r
+\r
+    void gen(cv::Mat& mat, int rows, int cols, int type);\r
+\r
+    virtual void run() = 0;\r
+\r
+private:\r
+    std::string name_;\r
+};\r
+\r
+\r
+class TestSystem\r
+{\r
+public:\r
+    static TestSystem* instance()\r
+    {\r
+        static TestSystem me;\r
+        return &me;\r
+    }\r
+\r
+    void add(Test* test) { tests_.push_back(test); }\r
+\r
+    void run();\r
+\r
+    void cpuOn() { cpu_started_ = cv::getTickCount(); }\r
+\r
+    void cpuOff() \r
+    {\r
+        int64 delta = cv::getTickCount() - cpu_started_;\r
+        cpu_elapsed_ += delta;\r
+        cpu_total_ += delta; \r
+        can_flush_ = true;\r
+    }  \r
+\r
+    void gpuOn() { gpu_started_ = cv::getTickCount(); }\r
+\r
+    void gpuOff() \r
+    {\r
+        int64 delta = cv::getTickCount() - gpu_started_;\r
+        gpu_elapsed_ += delta;\r
+        gpu_total_ += delta; \r
+        can_flush_ = true;\r
+    }\r
+\r
+    // Ends current subtest and starts new one\r
+    std::stringstream& subtest()\r
+    {\r
+        flush();\r
+        return description_;\r
+    }\r
+\r
+private:\r
+    TestSystem(): can_flush_(false),\r
+                  cpu_elapsed_(0), cpu_total_(0), \r
+                  gpu_elapsed_(0), gpu_total_(0) {};\r
+\r
+    void flush();\r
+\r
+    std::vector<Test*> tests_;\r
+\r
+    // Current test (subtest) description\r
+    std::stringstream description_;\r
+\r
+    bool can_flush_;\r
+\r
+    int64 cpu_started_, cpu_elapsed_, cpu_total_;\r
+    int64 gpu_started_, gpu_elapsed_, gpu_total_;\r
+};\r
+\r
+\r
+#define TEST(name) \\r
+    struct name##_test: public Test \\r
+    { \\r
+        name##_test(): Test(#name) { TestSystem::instance()->add(this); } \\r
+        void run(); \\r
+    } name##_test_instance; \\r
+    void name##_test::run()\r
+\r
+\r
+#define CPU_ON TestSystem::instance()->cpuOn()\r
+#define GPU_ON TestSystem::instance()->gpuOn()\r
+#define CPU_OFF TestSystem::instance()->cpuOff()\r
+#define GPU_OFF TestSystem::instance()->gpuOff()\r
+#define SUBTEST TestSystem::instance()->subtest()\r
+#define DESCRIPTION TestSystem::instance()->subtest()
\ No newline at end of file
diff --git a/samples/gpu/performance/tests.cpp b/samples/gpu/performance/tests.cpp
new file mode 100644 (file)
index 0000000..bd4957f
--- /dev/null
@@ -0,0 +1,30 @@
+#include <opencv2/imgproc/imgproc.hpp>\r
+#include <opencv2/gpu/gpu.hpp>\r
+#include "performance.h"\r
+\r
+using namespace std;\r
+using namespace cv;\r
+\r
+TEST(matchTemplate)\r
+{\r
+    for (int templ_size = 5; templ_size <= 1000; templ_size *= 2)\r
+    {\r
+        SUBTEST << "img 3000, templ " << templ_size << ", 8U, SQDIFF";\r
+\r
+        Mat image; gen(image, 3000, 3000, CV_8U);\r
+        Mat templ; gen(templ, templ_size, templ_size, CV_8U);\r
+        Mat result;\r
+\r
+        CPU_ON;\r
+        matchTemplate(image, templ, result, CV_TM_SQDIFF);\r
+        CPU_OFF;\r
+\r
+        gpu::GpuMat d_image(image);\r
+        gpu::GpuMat d_templ(templ);\r
+        gpu::GpuMat d_result;\r
+\r
+        GPU_ON;\r
+        gpu::matchTemplate(d_image, d_templ, d_result, CV_TM_SQDIFF);\r
+        GPU_OFF;\r
+    }\r
+}\r