Skip to content

Commit 190d00e

Browse files
committed
Merge pull request opencv#5317 from alalek:workaround
2 parents 31fbe8c + ad70ab4 commit 190d00e

File tree

6 files changed

+239
-80
lines changed

6 files changed

+239
-80
lines changed

modules/core/include/opencv2/core/mat.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ struct CV_EXPORTS UMatData
496496
void* handle;
497497
void* userdata;
498498
int allocatorFlags_;
499+
int mapcount;
500+
UMatData* originalUMatData;
499501
};
500502

501503

modules/core/src/matrix.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,14 @@ class StdMatAllocator : public MatAllocator
208208
if(!u)
209209
return;
210210

211-
CV_Assert(u->urefcount >= 0);
212-
CV_Assert(u->refcount >= 0);
213-
if(u->refcount == 0)
211+
CV_Assert(u->urefcount == 0);
212+
CV_Assert(u->refcount == 0);
213+
if( !(u->flags & UMatData::USER_ALLOCATED) )
214214
{
215-
if( !(u->flags & UMatData::USER_ALLOCATED) )
216-
{
217-
fastFree(u->origdata);
218-
u->origdata = 0;
219-
}
220-
delete u;
215+
fastFree(u->origdata);
216+
u->origdata = 0;
221217
}
218+
delete u;
222219
}
223220
};
224221

modules/core/src/ocl.cpp

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,8 +4453,11 @@ class OpenCLAllocator : public MatAllocator
44534453
#endif
44544454
{
44554455
tempUMatFlags = UMatData::TEMP_UMAT;
4456-
handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|createFlags,
4457-
u->size, u->origdata, &retval);
4456+
if (u->origdata == cv::alignPtr(u->origdata, 4)) // There are OpenCL runtime issues for less aligned data
4457+
{
4458+
handle = clCreateBuffer(ctx_handle, CL_MEM_USE_HOST_PTR|createFlags,
4459+
u->size, u->origdata, &retval);
4460+
}
44584461
if((!handle || retval < 0) && !(accessFlags & ACCESS_FAST))
44594462
{
44604463
handle = clCreateBuffer(ctx_handle, CL_MEM_COPY_HOST_PTR|CL_MEM_READ_WRITE|createFlags,
@@ -4510,16 +4513,17 @@ class OpenCLAllocator : public MatAllocator
45104513
if(!u)
45114514
return;
45124515

4513-
CV_Assert(u->urefcount >= 0);
4514-
CV_Assert(u->refcount >= 0);
4516+
CV_Assert(u->urefcount == 0);
4517+
CV_Assert(u->refcount == 0 && "UMat deallocation error: some derived Mat is still alive");
45154518

4516-
CV_Assert(u->handle != 0 && u->urefcount == 0);
4519+
CV_Assert(u->handle != 0);
4520+
CV_Assert(u->mapcount == 0);
45174521
if(u->tempUMat())
45184522
{
45194523
CV_Assert(u->origdata);
45204524
// UMatDataAutoLock lock(u);
45214525

4522-
if( u->hostCopyObsolete() && u->refcount > 0 )
4526+
if (u->hostCopyObsolete())
45234527
{
45244528
#ifdef HAVE_OPENCL_SVM
45254529
if ((u->allocatorFlags_ & svm::OPENCL_SVM_BUFFER_MASK) != 0)
@@ -4572,16 +4576,29 @@ class OpenCLAllocator : public MatAllocator
45724576
else
45734577
{
45744578
cl_int retval = 0;
4575-
void* data = clEnqueueMapBuffer(q, (cl_mem)u->handle, CL_TRUE,
4576-
(CL_MAP_READ | CL_MAP_WRITE),
4577-
0, u->size, 0, 0, 0, &retval);
4578-
CV_OclDbgAssert(retval == CL_SUCCESS);
4579-
CV_OclDbgAssert(clEnqueueUnmapMemObject(q, (cl_mem)u->handle, data, 0, 0, 0) == CL_SUCCESS);
4580-
CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);
4579+
if (u->tempUMat())
4580+
{
4581+
CV_Assert(u->mapcount == 0);
4582+
void* data = clEnqueueMapBuffer(q, (cl_mem)u->handle, CL_TRUE,
4583+
(CL_MAP_READ | CL_MAP_WRITE),
4584+
0, u->size, 0, 0, 0, &retval);
4585+
CV_Assert(u->origdata == data);
4586+
CV_OclDbgAssert(retval == CL_SUCCESS);
4587+
if (u->originalUMatData)
4588+
{
4589+
CV_Assert(u->originalUMatData->data == data);
4590+
}
4591+
CV_OclDbgAssert(clEnqueueUnmapMemObject(q, (cl_mem)u->handle, data, 0, 0, 0) == CL_SUCCESS);
4592+
CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);
4593+
}
45814594
}
45824595
}
45834596
u->markHostCopyObsolete(false);
45844597
}
4598+
else
4599+
{
4600+
// nothing
4601+
}
45854602
#ifdef HAVE_OPENCL_SVM
45864603
if ((u->allocatorFlags_ & svm::OPENCL_SVM_BUFFER_MASK) != 0)
45874604
{
@@ -4607,16 +4624,12 @@ class OpenCLAllocator : public MatAllocator
46074624
if(u->data && u->copyOnMap() && u->data != u->origdata)
46084625
fastFree(u->data);
46094626
u->data = u->origdata;
4610-
if(u->refcount == 0)
4611-
{
4612-
u->currAllocator->deallocate(u);
4613-
u = NULL;
4614-
}
4627+
u->currAllocator->deallocate(u);
4628+
u = NULL;
46154629
}
46164630
else
46174631
{
46184632
CV_Assert(u->origdata == NULL);
4619-
CV_Assert(u->refcount == 0);
46204633
if(u->data && u->copyOnMap() && u->data != u->origdata)
46214634
{
46224635
fastFree(u->data);
@@ -4665,17 +4678,13 @@ class OpenCLAllocator : public MatAllocator
46654678
delete u;
46664679
u = NULL;
46674680
}
4668-
CV_Assert(u == NULL || u->refcount);
4681+
CV_Assert(u == NULL);
46694682
}
46704683

4684+
// synchronized call (external UMatDataAutoLock, see UMat::getMat)
46714685
void map(UMatData* u, int accessFlags) const
46724686
{
4673-
if(!u)
4674-
return;
4675-
4676-
CV_Assert( u->handle != 0 );
4677-
4678-
UMatDataAutoLock autolock(u);
4687+
CV_Assert(u && u->handle);
46794688

46804689
if(accessFlags & ACCESS_WRITE)
46814690
u->markDeviceCopyObsolete(true);
@@ -4715,11 +4724,16 @@ class OpenCLAllocator : public MatAllocator
47154724
}
47164725
#endif
47174726

4718-
cl_int retval = 0;
4719-
u->data = (uchar*)clEnqueueMapBuffer(q, (cl_mem)u->handle, CL_TRUE,
4720-
(CL_MAP_READ | CL_MAP_WRITE),
4721-
0, u->size, 0, 0, 0, &retval);
4722-
if(u->data && retval == CL_SUCCESS)
4727+
cl_int retval = CL_SUCCESS;
4728+
if (!u->deviceMemMapped())
4729+
{
4730+
CV_Assert(u->refcount == 1);
4731+
CV_Assert(u->mapcount++ == 0);
4732+
u->data = (uchar*)clEnqueueMapBuffer(q, (cl_mem)u->handle, CL_TRUE,
4733+
(CL_MAP_READ | CL_MAP_WRITE),
4734+
0, u->size, 0, 0, 0, &retval);
4735+
}
4736+
if (u->data && retval == CL_SUCCESS)
47234737
{
47244738
u->markHostCopyObsolete(false);
47254739
u->markDeviceMemMapped(true);
@@ -4765,7 +4779,6 @@ class OpenCLAllocator : public MatAllocator
47654779
if( !u->copyOnMap() && u->deviceMemMapped() )
47664780
{
47674781
CV_Assert(u->data != NULL);
4768-
u->markDeviceMemMapped(false);
47694782
#ifdef HAVE_OPENCL_SVM
47704783
if ((u->allocatorFlags_ & svm::OPENCL_SVM_BUFFER_MASK) != 0)
47714784
{
@@ -4792,16 +4805,21 @@ class OpenCLAllocator : public MatAllocator
47924805
return;
47934806
}
47944807
#endif
4795-
CV_Assert( (retval = clEnqueueUnmapMemObject(q,
4796-
(cl_mem)u->handle, u->data, 0, 0, 0)) == CL_SUCCESS );
4797-
if (Device::getDefault().isAMD())
4798-
{
4799-
// required for multithreaded applications (see stitching test)
4800-
CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);
4801-
}
4802-
48034808
if (u->refcount == 0)
4809+
{
4810+
CV_Assert(u->mapcount-- == 1);
4811+
CV_Assert((retval = clEnqueueUnmapMemObject(q,
4812+
(cl_mem)u->handle, u->data, 0, 0, 0)) == CL_SUCCESS);
4813+
if (Device::getDefault().isAMD())
4814+
{
4815+
// required for multithreaded applications (see stitching test)
4816+
CV_OclDbgAssert(clFinish(q) == CL_SUCCESS);
4817+
}
4818+
u->markDeviceMemMapped(false);
48044819
u->data = 0;
4820+
u->markDeviceCopyObsolete(false);
4821+
u->markHostCopyObsolete(true);
4822+
}
48054823
}
48064824
else if( u->copyOnMap() && u->deviceCopyObsolete() )
48074825
{
@@ -4811,9 +4829,9 @@ class OpenCLAllocator : public MatAllocator
48114829
#endif
48124830
CV_Assert( (retval = clEnqueueWriteBuffer(q, (cl_mem)u->handle, CL_TRUE, 0,
48134831
u->size, alignedPtr.getAlignedPtr(), 0, 0, 0)) == CL_SUCCESS );
4832+
u->markDeviceCopyObsolete(false);
4833+
u->markHostCopyObsolete(true);
48144834
}
4815-
u->markDeviceCopyObsolete(false);
4816-
u->markHostCopyObsolete(true);
48174835
}
48184836

48194837
bool checkContinuous(int dims, const size_t sz[],

0 commit comments

Comments
 (0)