<h5 dir="auto">System information (version)</h5>

<ul dir="auto">
<li>OpenCV =&gt; 4.1</li>
<li>Operating System / Platform =&gt; MacOS</li>
<li>Compiler =&gt; emsdk</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">I'm trying to use a freshly build opencv.js build with increased memory as I need a bit more as the default provides me. This leads me to having even less memory available on the go when compiled a build having a flag of '-s TOTAL_MEMORY=1342177280 '.<br>
I'm using the latest emsdk and latest opencv version.</p>
<h5 dir="auto">Steps to reproduce</h5>
<h5 dir="auto">System information (version)</h5>

<ul dir="auto">
<li>OpenCV =&gt; 3.3.1</li>
<li>Operating System / Platform =&gt; Windows 64 Bit</li>
<li>Compiler =&gt; Visual Studio 2017</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">Running multiple template matching operations in parallel on separate threads results in the following error from within the <code class="notranslate">pMatcher-&gt;match()</code> function:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="`OpenCV Error: Assertion failed (allocSize == allocations.back()) in`anonymous-namespace'
::MemoryStack::returnMemory, file C:\Users\derrickb\Documents\opencv\modules\core\src\cuda_stream.cpp, line 99"><pre class="notranslate"><code class="notranslate">`OpenCV Error: Assertion failed (allocSize == allocations.back()) in`anonymous-namespace'
::MemoryStack::returnMemory, file C:\Users\derrickb\Documents\opencv\modules\core\src\cuda_stream.cpp, line 99
</code></pre></div>
<p dir="auto">The error is not entirely repeatable.  It may happen with 4 threads and not with 16 threads, and is probably dependent on the performance of the test system.  But on my system the error is fairly easy to trigger.  Setting <code class="notranslate">N_THREADS = 1</code> never reproduces the problem.</p>
<h5 dir="auto">Steps to reproduce</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="void threadCallback(GpuMat &amp;imS, GpuMat &amp;imT, int count)
{
	std::vector&lt;GpuMat&gt; imR;
	Ptr&lt;TemplateMatching&gt; pMatcher = cuda::createTemplateMatching(CV_8U, TM_CCOEFF_NORMED);

	// Use a separate results array for each match
	for (int j = 0; j &lt; count; j++) {
		imR.push_back(GpuMat(imS.size().height - imT.size().height + 1,
			imS.size().width - imT.size().width + 1, CV_8UC1));
	}

	cuda::Stream stream;
	for (int j = 0; j &lt; count; j++) {
		pMatcher-&gt;match(imS, imT, imR[j], stream);  // ABORT HAPPENS ON THIS LINE
	}
	stream.waitForCompletion();
}


void TestTemplateMatchThreads()
{
	// Does threading improve performance for many matches?
	int IMG_SIZE = 300;
	int TEM_SIZE = 100;
	GpuMat imT = GpuMat(TEM_SIZE, TEM_SIZE, CV_8UC1);
	GpuMat imS = GpuMat(IMG_SIZE, IMG_SIZE, CV_8UC1);

	std::vector&lt; std::thread&gt; threads;

	int N_THREADS = 4;
	int count = 10;

	for (int j = 0; j &lt; N_THREADS; j++) {
		std::thread threadObj(threadCallback, imS, imT, count);
		threads.push_back(std::move(threadObj));
	}
	for (int j = 0; j &lt; N_THREADS; j++) {
		threads[j].join();
	}
}"><pre class="notranslate"><code class="notranslate">void threadCallback(GpuMat &amp;imS, GpuMat &amp;imT, int count)
{
	std::vector&lt;GpuMat&gt; imR;
	Ptr&lt;TemplateMatching&gt; pMatcher = cuda::createTemplateMatching(CV_8U, TM_CCOEFF_NORMED);

	// Use a separate results array for each match
	for (int j = 0; j &lt; count; j++) {
		imR.push_back(GpuMat(imS.size().height - imT.size().height + 1,
			imS.size().width - imT.size().width + 1, CV_8UC1));
	}

	cuda::Stream stream;
	for (int j = 0; j &lt; count; j++) {
		pMatcher-&gt;match(imS, imT, imR[j], stream);  // ABORT HAPPENS ON THIS LINE
	}
	stream.waitForCompletion();
}


void TestTemplateMatchThreads()
{
	// Does threading improve performance for many matches?
	int IMG_SIZE = 300;
	int TEM_SIZE = 100;
	GpuMat imT = GpuMat(TEM_SIZE, TEM_SIZE, CV_8UC1);
	GpuMat imS = GpuMat(IMG_SIZE, IMG_SIZE, CV_8UC1);

	std::vector&lt; std::thread&gt; threads;

	int N_THREADS = 4;
	int count = 10;

	for (int j = 0; j &lt; N_THREADS; j++) {
		std::thread threadObj(threadCallback, imS, imT, count);
		threads.push_back(std::move(threadObj));
	}
	for (int j = 0; j &lt; N_THREADS; j++) {
		threads[j].join();
	}
}
</code></pre></div>
<p dir="auto">One theory of why the match() function is not threadsafe is that it uses calls to non-stream based versions of:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="    Scalar templ_sum = cuda::sum(templ);
    Scalar templ_sqsum = cuda::sqrSum(templ);"><pre class="notranslate"><code class="notranslate">    Scalar templ_sum = cuda::sum(templ);
    Scalar templ_sqsum = cuda::sqrSum(templ);
</code></pre></div>
<p dir="auto">from: <a href="https://github.com/opencv/opencv_contrib/blob/master/modules/cudaimgproc/src/match_template.cpp">https://github.com/opencv/opencv_contrib/blob/master/modules/cudaimgproc/src/match_template.cpp</a>, line 549.</p>
<p dir="auto">Other similar bugs seem to have been resolved by using the corresponding stream based equivalent functions:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="    Scalar templ_sum = cuda::calcSum(templ, stream);
    Scalar templ_sqsum = cuda::calcSqrSum(templ, stream);"><pre class="notranslate"><code class="notranslate">    Scalar templ_sum = cuda::calcSum(templ, stream);
    Scalar templ_sqsum = cuda::calcSqrSum(templ, stream);
</code></pre></div>
<p dir="auto">Such as <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="164409280" data-permission-text="Title is private" data-url="https://github.com/opencv/opencv/issues/6788" data-hovercard-type="issue" data-hovercard-url="/opencv/opencv/issues/6788/hovercard?comment_id=231290564&amp;comment_type=issue_comment" href="https://github.com/opencv/opencv/issues/6788#issuecomment-231290564">#6788 (comment)</a><br>
So this "fix" is purely speculative.  If it is indeed the problem, it exists in a similar form in ~10 places in the same file (<a href="https://github.com/opencv/opencv_contrib/blob/master/modules/cudaimgproc/src/match_template.cpp">https://github.com/opencv/opencv_contrib/blob/master/modules/cudaimgproc/src/match_template.cpp</a>) .</p>
<p dir="auto">The problem has been reproduced using: <code class="notranslate">TM_CCOEFF_NORMED</code>, <code class="notranslate">TM_CCORR</code>, <code class="notranslate">TM_CCORR_NORMED</code>, and <code class="notranslate">TM_CCOEFF</code>.</p>