Commit 296f76a1 authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by OpenCV Buildbot

Merge pull request #1756 from alalek:ocl_workaround_memory_leaks_with_subbuffer

parents 9afe65e5 03646e7e
...@@ -148,35 +148,52 @@ void openCLMallocPitchEx(Context *ctx, void **dev_ptr, size_t *pitch, ...@@ -148,35 +148,52 @@ void openCLMallocPitchEx(Context *ctx, void **dev_ptr, size_t *pitch,
{ {
cl_int status; cl_int status;
size_t size = widthInBytes * height; size_t size = widthInBytes * height;
bool useSubBuffers =
#ifndef MEMORY_CORRUPTION_GUARD #ifndef MEMORY_CORRUPTION_GUARD
*dev_ptr = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type], false;
size, 0, &status);
openCLVerifyCall(status);
#else #else
size_t allocSize = size + __memory_corruption_guard_bytes * 2; true;
cl_mem mainBuffer = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type], #endif
allocSize, 0, &status); const DeviceInfo& devInfo = ctx->getDeviceInfo();
openCLVerifyCall(status); if (useSubBuffers && devInfo.isIntelDevice)
cl_buffer_region r = {__memory_corruption_guard_bytes, size}; {
*dev_ptr = clCreateSubBuffer(mainBuffer, useSubBuffers = false; // TODO FIXIT We observe memory leaks then we working with sub-buffers
gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type], // on the CPU device of Intel OpenCL SDK (Linux). We will investigate this later.
CL_BUFFER_CREATE_TYPE_REGION, &r, }
&status); if (!useSubBuffers)
openCLVerifyCall(status); {
*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 #ifdef CHECK_MEMORY_CORRUPTION
std::vector<int> tmp(__memory_corruption_guard_bytes / sizeof(int), std::vector<int> tmp(__memory_corruption_guard_bytes / sizeof(int),
__memory_corruption_check_pattern); __memory_corruption_check_pattern);
CV_Assert(tmp.size() * sizeof(int) == __memory_corruption_guard_bytes); CV_Assert(tmp.size() * sizeof(int) == __memory_corruption_guard_bytes);
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx), openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
mainBuffer, CL_FALSE, 0, __memory_corruption_guard_bytes, &tmp[0], mainBuffer, CL_FALSE, 0, __memory_corruption_guard_bytes, &tmp[0],
0, NULL, NULL)); 0, NULL, NULL));
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx), openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
mainBuffer, CL_FALSE, __memory_corruption_guard_bytes + size, __memory_corruption_guard_bytes, &tmp[0], mainBuffer, CL_FALSE, __memory_corruption_guard_bytes + size, __memory_corruption_guard_bytes, &tmp[0],
0, NULL, NULL)); 0, NULL, NULL));
clFinish(getClCommandQueue(ctx)); clFinish(getClCommandQueue(ctx));
#endif #endif
CheckBuffers data(mainBuffer, size, widthInBytes, height); CheckBuffers data(mainBuffer, size, widthInBytes, height);
__check_buffers.insert(std::pair<cl_mem, CheckBuffers>((cl_mem)*dev_ptr, data)); __check_buffers.insert(std::pair<cl_mem, CheckBuffers>((cl_mem)*dev_ptr, data));
}
#endif #endif
*pitch = widthInBytes; *pitch = widthInBytes;
} }
...@@ -230,6 +247,7 @@ void openCLCopyBuffer2D(Context *ctx, void *dst, size_t dpitch, int dst_offset, ...@@ -230,6 +247,7 @@ void openCLCopyBuffer2D(Context *ctx, void *dst, size_t dpitch, int dst_offset,
void openCLFree(void *devPtr) void openCLFree(void *devPtr)
{ {
openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
#ifdef MEMORY_CORRUPTION_GUARD #ifdef MEMORY_CORRUPTION_GUARD
#ifdef CHECK_MEMORY_CORRUPTION #ifdef CHECK_MEMORY_CORRUPTION
bool failBefore = false, failAfter = false; bool failBefore = false, failAfter = false;
...@@ -270,9 +288,7 @@ void openCLFree(void *devPtr) ...@@ -270,9 +288,7 @@ void openCLFree(void *devPtr)
openCLSafeCall(clReleaseMemObject(data.mainBuffer)); openCLSafeCall(clReleaseMemObject(data.mainBuffer));
__check_buffers.erase(i); __check_buffers.erase(i);
} }
#endif #if defined(CHECK_MEMORY_CORRUPTION)
openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
#if defined(MEMORY_CORRUPTION_GUARD) && defined(CHECK_MEMORY_CORRUPTION)
if (failBefore) if (failBefore)
{ {
#ifdef CHECK_MEMORY_CORRUPTION_PRINT_ERROR #ifdef CHECK_MEMORY_CORRUPTION_PRINT_ERROR
...@@ -291,7 +307,8 @@ void openCLFree(void *devPtr) ...@@ -291,7 +307,8 @@ void openCLFree(void *devPtr)
CV_Error(CV_StsInternal, "Memory corruption detected: after buffer"); CV_Error(CV_StsInternal, "Memory corruption detected: after buffer");
#endif #endif
} }
#endif #endif // CHECK_MEMORY_CORRUPTION
#endif // MEMORY_CORRUPTION_GUARD
} }
cl_kernel openCLGetKernelFromSource(const Context *ctx, const cv::ocl::ProgramEntry* source, string kernelName) cl_kernel openCLGetKernelFromSource(const Context *ctx, const cv::ocl::ProgramEntry* source, string kernelName)
......
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