I get the following assertion error when running several cv::cuda:: functions on multiple threads in debug:
OpenCV Error: Assertion failed (allocSize == allocations.back()) in `anonymo
us-namespace'::MemoryStack::returnMemory, file C:\ExternalPackages\OpenCV-3.1.0-
t1-VC12-CudaStreamDebug\src\opencv\modules\core\src\cuda_stream.cpp, line 110
My test jig is shown below:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void RunSum()
{
cv::cuda::GpuMat dIsMaximalMask(cv::Mat::ones(100, 1, CV_32S));
cv::cuda::sum(dIsMaximalMask);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void RunSqrSum()
{
cv::cuda::GpuMat Row1(cv::Mat::ones(1, 100, CV_8U));
cv::cuda::GpuMat Row2(cv::Mat::ones(1, 100, CV_8U));
cv::cuda::sqrSum(Row1, Row2);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void RunMinMax()
{
double MaxVal;
cv::cuda::minMax(
cv::cuda::GpuMat(cv::Mat::ones(100, 1, CV_32S)),
0,
&MaxVal);
}
//*****************************************************************************
//*****************************************************************************
int main(int argc, const char** argv)
{
thread Thread1(RunSqrSum);
thread Thread2(RunMinMax);
Thread1.join();
Thread2.join();
return 0;
}
The following functions fail this assertion when run on two or more threads:
cv::cuda::minMax
cv::cuda::sqrSum
cv::cuda::sum
The cv::cuda::Stream
documentation notes the following disclaimer:
http://docs.opencv.org/master/d9/df3/classcv_1_1cuda_1_1Stream.html#gsc.tab=0
Currently, you may face problems if an operation is enqueued twice with different data. Some functions use the constant GPU memory, and next call may update the memory before the previous one has been finished. But calling different operations asynchronously is safe because each operation has its own constant buffer. Memory copy/upload/download/set operations to the buffers you hold are also safe.
Does this mean it is safe to call different cv::cuda::
functions that contain cv::cuda::Stream
objects asynchronously? I am seeing that this appears to be untrue.
I rebuilt OpenCV 3.1.0 with cout
statements around the assert statement in cuda_stream.cpp
in the functions requestMemory
and returnMemory
(beginning on lines 75 and 93, respectively) to generate the following console output:
requestMemory: size: requestMemory: size: 6464
requestMemory: freeMem: 10485760
requestMemory: freeMem: 10485760
requestMemory: allocations.size() before: 0
requestMemory: allocations.size() before: 0
requestMemory: tid: 7436
requestMemory: tid: 5656
requestMemory: allocations.size() after: 1
requestMemory: allocations.size() after: 2
returnMemory: allocSize: 128
returnMemory: allocations.back(): 64
returnMemory: allocSize: 64
returnMemory: tid: 7436
retuOpenCV Error: Assertion failed (allocSize == allocations.back()) in `anonymo
us-namespace'::MemoryStack::returnMemory, file C:\ExternalPackages\OpenCV-3.1.0-
t1-VC12-CudaStreamDebug\src\opencv\modules\core\src\cuda_stream.cpp, line 110
rnMemory: allocations.back(): 64
returnMemory: tid: 5656
returnMemory: allocations.size() before: 2
returnMemory: allocations.size() after: 1
This output appears to demonstrate that multiple processes are asking for GPU memory at the same time, as shown by multiple requestMemory
calls back-to-back and in some cases jumbled together. Is it unsafe to call certain cv::cuda::
functions on multiple threads?
Note: I am using Windows 7 (also tested on Windows 10) Visual Studio 2013 with VC12 compiler and OpenCV 3.1.0 (also tested on 3.0.0).
Note: cv::cuda::SURF_CUDA
, cv::cuda::add
and multiple other cv::cuda::
functions do not cause this assertion to fail.