mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 13:10:12 +08:00
Merge pull request #1756 from alalek:ocl_workaround_memory_leaks_with_subbuffer
This commit is contained in:
commit
296f76a135
@ -148,35 +148,52 @@ void openCLMallocPitchEx(Context *ctx, void **dev_ptr, size_t *pitch,
|
||||
{
|
||||
cl_int status;
|
||||
size_t size = widthInBytes * height;
|
||||
bool useSubBuffers =
|
||||
#ifndef MEMORY_CORRUPTION_GUARD
|
||||
*dev_ptr = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
size, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
false;
|
||||
#else
|
||||
size_t allocSize = size + __memory_corruption_guard_bytes * 2;
|
||||
cl_mem mainBuffer = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
allocSize, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
cl_buffer_region r = {__memory_corruption_guard_bytes, size};
|
||||
*dev_ptr = clCreateSubBuffer(mainBuffer,
|
||||
gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
CL_BUFFER_CREATE_TYPE_REGION, &r,
|
||||
&status);
|
||||
openCLVerifyCall(status);
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
std::vector<int> tmp(__memory_corruption_guard_bytes / sizeof(int),
|
||||
__memory_corruption_check_pattern);
|
||||
CV_Assert(tmp.size() * sizeof(int) == __memory_corruption_guard_bytes);
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_FALSE, 0, __memory_corruption_guard_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_FALSE, __memory_corruption_guard_bytes + size, __memory_corruption_guard_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
clFinish(getClCommandQueue(ctx));
|
||||
true;
|
||||
#endif
|
||||
CheckBuffers data(mainBuffer, size, widthInBytes, height);
|
||||
__check_buffers.insert(std::pair<cl_mem, CheckBuffers>((cl_mem)*dev_ptr, data));
|
||||
const DeviceInfo& devInfo = ctx->getDeviceInfo();
|
||||
if (useSubBuffers && devInfo.isIntelDevice)
|
||||
{
|
||||
useSubBuffers = false; // TODO FIXIT We observe memory leaks then we working with sub-buffers
|
||||
// on the CPU device of Intel OpenCL SDK (Linux). We will investigate this later.
|
||||
}
|
||||
if (!useSubBuffers)
|
||||
{
|
||||
*dev_ptr = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
size, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
}
|
||||
#ifdef MEMORY_CORRUPTION_GUARD
|
||||
else
|
||||
{
|
||||
size_t allocSize = size + __memory_corruption_guard_bytes * 2;
|
||||
cl_mem mainBuffer = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
allocSize, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
cl_buffer_region r = {__memory_corruption_guard_bytes, size};
|
||||
*dev_ptr = clCreateSubBuffer(mainBuffer,
|
||||
gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
CL_BUFFER_CREATE_TYPE_REGION, &r,
|
||||
&status);
|
||||
openCLVerifyCall(status);
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
std::vector<int> tmp(__memory_corruption_guard_bytes / sizeof(int),
|
||||
__memory_corruption_check_pattern);
|
||||
CV_Assert(tmp.size() * sizeof(int) == __memory_corruption_guard_bytes);
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_FALSE, 0, __memory_corruption_guard_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_FALSE, __memory_corruption_guard_bytes + size, __memory_corruption_guard_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
clFinish(getClCommandQueue(ctx));
|
||||
#endif
|
||||
CheckBuffers data(mainBuffer, size, widthInBytes, height);
|
||||
__check_buffers.insert(std::pair<cl_mem, CheckBuffers>((cl_mem)*dev_ptr, data));
|
||||
}
|
||||
#endif
|
||||
*pitch = widthInBytes;
|
||||
}
|
||||
@ -230,6 +247,7 @@ void openCLCopyBuffer2D(Context *ctx, void *dst, size_t dpitch, int dst_offset,
|
||||
|
||||
void openCLFree(void *devPtr)
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
|
||||
#ifdef MEMORY_CORRUPTION_GUARD
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
bool failBefore = false, failAfter = false;
|
||||
@ -270,9 +288,7 @@ void openCLFree(void *devPtr)
|
||||
openCLSafeCall(clReleaseMemObject(data.mainBuffer));
|
||||
__check_buffers.erase(i);
|
||||
}
|
||||
#endif
|
||||
openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
|
||||
#if defined(MEMORY_CORRUPTION_GUARD) && defined(CHECK_MEMORY_CORRUPTION)
|
||||
#if defined(CHECK_MEMORY_CORRUPTION)
|
||||
if (failBefore)
|
||||
{
|
||||
#ifdef CHECK_MEMORY_CORRUPTION_PRINT_ERROR
|
||||
@ -291,7 +307,8 @@ void openCLFree(void *devPtr)
|
||||
CV_Error(CV_StsInternal, "Memory corruption detected: after buffer");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif // CHECK_MEMORY_CORRUPTION
|
||||
#endif // MEMORY_CORRUPTION_GUARD
|
||||
}
|
||||
|
||||
cl_kernel openCLGetKernelFromSource(const Context *ctx, const cv::ocl::ProgramEntry* source, string kernelName)
|
||||
|
Loading…
Reference in New Issue
Block a user