Commit 6674a024 authored by Alexander Alekhin's avatar Alexander Alekhin

dnn: add OPENCV_DNN_DISABLE_MEMORY_OPTIMIZATIONS runtime option

replaces REUSE_DNN_MEMORY compile-time option
parent ee35263e
...@@ -97,8 +97,3 @@ if(BUILD_PERF_TESTS) ...@@ -97,8 +97,3 @@ if(BUILD_PERF_TESTS)
endif() endif()
endif() endif()
endif() endif()
ocv_option(${the_module}_REUSE_MEMORY "Enable reusing strategy of memory management" ON)
if (${the_module}_REUSE_MEMORY)
add_definitions(-DREUSE_DNN_MEMORY=1)
endif()
...@@ -51,10 +51,15 @@ ...@@ -51,10 +51,15 @@
#include <opencv2/dnn/shape_utils.hpp> #include <opencv2/dnn/shape_utils.hpp>
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
#include <opencv2/core/utils/configuration.private.hpp>
namespace cv { namespace cv {
namespace dnn { namespace dnn {
CV__DNN_EXPERIMENTAL_NS_BEGIN CV__DNN_EXPERIMENTAL_NS_BEGIN
// this option is usefull to run valgrind memory errors detection
static bool DNN_DISABLE_MEMORY_OPTIMIZATIONS = utils::getConfigurationParameterBool("OPENCV_DNN_DISABLE_MEMORY_OPTIMIZATIONS", false);
using std::vector; using std::vector;
using std::map; using std::map;
using std::make_pair; using std::make_pair;
...@@ -369,40 +374,42 @@ public: ...@@ -369,40 +374,42 @@ public:
void reuseOrCreate(const MatShape& shape, const LayerPin& lp, Mat& dst) void reuseOrCreate(const MatShape& shape, const LayerPin& lp, Mat& dst)
{ {
#ifdef REUSE_DNN_MEMORY if (!DNN_DISABLE_MEMORY_OPTIMIZATIONS)
Mat bestBlob; {
LayerPin bestBlobPin; Mat bestBlob;
LayerPin bestBlobPin;
std::map<LayerPin, Mat>::iterator hostIt; std::map<LayerPin, Mat>::iterator hostIt;
std::map<LayerPin, int>::iterator refIt; std::map<LayerPin, int>::iterator refIt;
const int targetTotal = total(shape); const int targetTotal = total(shape);
int bestBlobTotal = INT_MAX; int bestBlobTotal = INT_MAX;
for (hostIt = memHosts.begin(); hostIt != memHosts.end(); ++hostIt) for (hostIt = memHosts.begin(); hostIt != memHosts.end(); ++hostIt)
{
refIt = refCounter.find(hostIt->first);
// Use only blobs that had references before because if not,
// it might be used as output.
if (refIt != refCounter.end() && refIt->second == 0)
{ {
Mat& unusedBlob = hostIt->second; refIt = refCounter.find(hostIt->first);
if (unusedBlob.total() >= targetTotal && // Use only blobs that had references before because if not,
unusedBlob.total() < bestBlobTotal) // it might be used as output.
if (refIt != refCounter.end() && refIt->second == 0)
{ {
bestBlobPin = hostIt->first; Mat& unusedBlob = hostIt->second;
bestBlob = unusedBlob; if (unusedBlob.total() >= targetTotal &&
bestBlobTotal = unusedBlob.total(); unusedBlob.total() < bestBlobTotal)
{
bestBlobPin = hostIt->first;
bestBlob = unusedBlob;
bestBlobTotal = unusedBlob.total();
}
} }
} }
if (!bestBlob.empty())
{
reuse(bestBlobPin, lp);
dst = bestBlob.reshape(1, 1).colRange(0, targetTotal).reshape(1, shape);
return;
}
} }
if (!bestBlob.empty())
{
reuse(bestBlobPin, lp);
dst = bestBlob.reshape(1, 1).colRange(0, targetTotal).reshape(1, shape);
}
else
#endif // REUSE_DNN_MEMORY
{ {
// if dst already has been allocated with total(shape) elements, // if dst already has been allocated with total(shape) elements,
// it won't be recrreated and pointer of dst.data remains the same. // it won't be recrreated and pointer of dst.data remains the same.
...@@ -413,40 +420,42 @@ public: ...@@ -413,40 +420,42 @@ public:
void reuseOrCreate(const MatShape& shape, const LayerPin& lp, UMat &umat_dst) void reuseOrCreate(const MatShape& shape, const LayerPin& lp, UMat &umat_dst)
{ {
#ifdef REUSE_DNN_MEMORY if (!DNN_DISABLE_MEMORY_OPTIMIZATIONS)
UMat bestBlob; {
LayerPin bestBlobPin; UMat bestBlob;
LayerPin bestBlobPin;
std::map<LayerPin, UMat>::iterator hostIt; std::map<LayerPin, UMat>::iterator hostIt;
std::map<LayerPin, int>::iterator refIt; std::map<LayerPin, int>::iterator refIt;
const int targetTotal = total(shape); const int targetTotal = total(shape);
int bestBlobTotal = INT_MAX; int bestBlobTotal = INT_MAX;
for (hostIt = umat_memHosts.begin(); hostIt != umat_memHosts.end(); ++hostIt) for (hostIt = umat_memHosts.begin(); hostIt != umat_memHosts.end(); ++hostIt)
{
refIt = refCounter.find(hostIt->first);
// Use only blobs that had references before because if not,
// it might be used as output.
if (refIt != refCounter.end() && refIt->second == 0)
{ {
UMat& unusedBlob = hostIt->second; refIt = refCounter.find(hostIt->first);
if (unusedBlob.total() >= targetTotal && // Use only blobs that had references before because if not,
unusedBlob.total() < bestBlobTotal) // it might be used as output.
if (refIt != refCounter.end() && refIt->second == 0)
{ {
bestBlobPin = hostIt->first; UMat& unusedBlob = hostIt->second;
bestBlob = unusedBlob; if (unusedBlob.total() >= targetTotal &&
bestBlobTotal = unusedBlob.total(); unusedBlob.total() < bestBlobTotal)
{
bestBlobPin = hostIt->first;
bestBlob = unusedBlob;
bestBlobTotal = unusedBlob.total();
}
} }
} }
if (!bestBlob.empty())
{
reuse(bestBlobPin, lp);
umat_dst.create(shape, CV_32F);
return;
}
} }
if (!bestBlob.empty())
{
reuse(bestBlobPin, lp);
umat_dst.create(shape, CV_32F);
}
else
#endif // REUSE_DNN_MEMORY
{ {
// if dst already has been allocated with total(shape) elements, // if dst already has been allocated with total(shape) elements,
// it won't be recrreated and pointer of dst.data remains the same. // it won't be recrreated and pointer of dst.data remains the same.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment