From 03646e7e01899ecc96f196b5dd92f8dfc41f69a1 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 6 Nov 2013 13:20:02 +0400 Subject: [PATCH] ocl: workaround for subbuffer memory leaks --- modules/ocl/src/cl_operations.cpp | 75 ++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/modules/ocl/src/cl_operations.cpp b/modules/ocl/src/cl_operations.cpp index d96f347..7ed1a79 100644 --- a/modules/ocl/src/cl_operations.cpp +++ b/modules/ocl/src/cl_operations.cpp @@ -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); + true; +#endif + 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 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)); + std::vector 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)*dev_ptr, data)); + CheckBuffers data(mainBuffer, size, widthInBytes, height); + __check_buffers.insert(std::pair((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) -- 2.7.4