]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/blobdiff - src/dynmem.hpp
Remove debug printf
[hercules2020/kcf.git] / src / dynmem.hpp
index 86ae874376d29991670d29fdedcef1698d19cd17..8e4964327899bbe0661ccc19d8b62c0bbb478181 100644 (file)
@@ -5,33 +5,66 @@
 #include <opencv2/opencv.hpp>
 #include <cassert>
 #include <numeric>
+#include <mutex>
+#include <stack>
 
 #if defined(CUFFT) || defined(CUFFTW)
 #include "cuda_runtime.h"
 #ifdef CUFFT
-#include "cuda/cuda_error_check.cuh"
+#include "cuda_error_check.hpp"
 #endif
 #endif
 
+class MemoryManager {
+    std::mutex mutex;
+    std::map<size_t, std::stack<void*> > map;
+
+public:
+    void *get(size_t size) {
+        std::lock_guard<std::mutex> guard(mutex);
+        auto &stack = map[size];
+        void *ptr = nullptr;
+        if (!stack.empty()) {
+            ptr = stack.top();
+            stack.pop();
+        }
+        return ptr;
+    }
+    void put(void *ptr, size_t size) {
+        std::lock_guard<std::mutex> guard(mutex);
+        map[size].push(ptr);
+    }
+};
+
 template <typename T> class DynMem_ {
   private:
     T *ptr_h = nullptr;
 #ifdef CUFFT
     T *ptr_d = nullptr;
+    static MemoryManager mmng;
 #endif
-    size_t num_elem;
   public:
-    typedef T type;
+    typedef T value_type;
+    const size_t num_elem;
+
     DynMem_(size_t num_elem) : num_elem(num_elem)
     {
 #ifdef CUFFT
-        CudaSafeCall(cudaHostAlloc(reinterpret_cast<void **>(&ptr_h), num_elem * sizeof(T), cudaHostAllocMapped));
+        ptr_h = reinterpret_cast<T*>(mmng.get(num_elem));
+        if (!ptr_h)
+            CudaSafeCall(cudaHostAlloc(reinterpret_cast<void **>(&ptr_h), num_elem * sizeof(T), cudaHostAllocMapped));
+
         CudaSafeCall(cudaHostGetDevicePointer(reinterpret_cast<void **>(&ptr_d), reinterpret_cast<void *>(ptr_h), 0));
 #else
         ptr_h = new T[num_elem];
 #endif
     }
-    DynMem_(DynMem_&& other) {
+    DynMem_(const DynMem_ &other) : DynMem_(other.num_elem)
+    {
+        memcpy(ptr_h, other.ptr_h, num_elem * sizeof(T));
+    }
+    DynMem_(DynMem_ &&other) : num_elem(other.num_elem)
+    {
         ptr_h = other.ptr_h;
         other.ptr_h = nullptr;
 #ifdef CUFFT
@@ -41,21 +74,22 @@ template <typename T> class DynMem_ {
     }
     ~DynMem_()
     {
-#ifdef CUFFT
-        CudaSafeCall(cudaFreeHost(ptr_h));
-#else
-        delete[] ptr_h;
-#endif
+        release();
     }
     T *hostMem() { return ptr_h; }
+    const T *hostMem() const { return ptr_h; }
 #ifdef CUFFT
     T *deviceMem() { return ptr_d; }
+    const T *deviceMem() const { return ptr_d; }
 #endif
     void operator=(DynMem_ &rhs) {
+        assert(num_elem == rhs.num_elem);
         memcpy(ptr_h, rhs.ptr_h, num_elem * sizeof(T));
     }
     void operator=(DynMem_ &&rhs)
     {
+        assert(num_elem == rhs.num_elem);
+        release();
         ptr_h = rhs.ptr_h;
         rhs.ptr_h = nullptr;
 #ifdef CUFFT
@@ -64,8 +98,24 @@ template <typename T> class DynMem_ {
 #endif
     }
     T operator[](uint i) const { return ptr_h[i]; }
+private:
+    void release()
+    {
+#ifdef CUFFT
+        if (ptr_h)
+            mmng.put(ptr_h, num_elem);
+        //CudaSafeCall(cudaFreeHost(ptr_h));
+#else
+        delete[] ptr_h;
+#endif
+    }
 };
 
+#ifdef CUFFT
+template <typename T>
+MemoryManager DynMem_<T>::mmng;
+#endif
+
 typedef DynMem_<float> DynMem;
 
 
@@ -119,6 +169,12 @@ public:
         assert(int(idx) < size[0]);
         return cv::Mat(size[1], size[2], cv::Mat::type(), ptr(idx));
     }
+    const cv::Mat plane(uint idx) const {
+        assert(dims == 3);
+        assert(int(idx) < size[0]);
+        return cv::Mat(size[1], size[2], cv::Mat::type(), const_cast<uchar*>(ptr(idx)));
+    }
+
 };
 
 class MatFeats : public Mat3d
@@ -144,7 +200,7 @@ public:
         assert(int(feature) < size[1]);
         return cv::Mat(size[2], size[3], cv::Mat::type(), ptr(scale, feature));
     }
-    cv::Mat features(uint scale) {
+    cv::Mat scale(uint scale) {
         assert(dims == 4);
         assert(int(scale) < size[0]);
         return cv::Mat(3, std::vector<int>({size[1], size[2], size[3]}).data(), cv::Mat::type(), ptr(scale));