ocl: memory corruption check
This commit is contained in:
parent
d3bcf609f1
commit
447c052e59
@ -109,6 +109,31 @@ cl_mem openCLCreateBuffer(Context *ctx, size_t flag , size_t size)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//#define CHECK_MEMORY_CORRUPTION
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
//#define CHECK_MEMORY_CORRUPTION_PRINT_ERROR
|
||||
#define CHECK_MEMORY_CORRUPTION_RAISE_ERROR
|
||||
static const int __memory_corruption_check_bytes = 1024*1024;
|
||||
static const int __memory_corruption_check_pattern = 0x14326547; // change pattern for sizeof(int)==8
|
||||
struct CheckBuffers
|
||||
{
|
||||
cl_mem mainBuffer;
|
||||
size_t size;
|
||||
size_t widthInBytes, height;
|
||||
CheckBuffers()
|
||||
: mainBuffer(NULL), size(0), widthInBytes(0), height(0)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
CheckBuffers(cl_mem _mainBuffer, size_t _size, size_t _widthInBytes, size_t _height)
|
||||
: mainBuffer(_mainBuffer), size(_size), widthInBytes(_widthInBytes), height(_height)
|
||||
{
|
||||
// notihng
|
||||
}
|
||||
};
|
||||
static std::map<cl_mem, CheckBuffers> __check_buffers;
|
||||
#endif
|
||||
|
||||
void openCLMallocPitch(Context *ctx, void **dev_ptr, size_t *pitch,
|
||||
size_t widthInBytes, size_t height)
|
||||
{
|
||||
@ -119,9 +144,34 @@ void openCLMallocPitchEx(Context *ctx, void **dev_ptr, size_t *pitch,
|
||||
size_t widthInBytes, size_t height, DevMemRW rw_type, DevMemType mem_type)
|
||||
{
|
||||
cl_int status;
|
||||
size_t size = widthInBytes * height;
|
||||
#ifndef CHECK_MEMORY_CORRUPTION
|
||||
*dev_ptr = clCreateBuffer(getClContext(ctx), gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
widthInBytes * height, 0, &status);
|
||||
size, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
#else
|
||||
size_t allocSize = size + __memory_corruption_check_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_check_bytes, size};
|
||||
*dev_ptr = clCreateSubBuffer(mainBuffer,
|
||||
gDevMemRWValueMap[rw_type]|gDevMemTypeValueMap[mem_type],
|
||||
CL_BUFFER_CREATE_TYPE_REGION, &r,
|
||||
&status);
|
||||
openCLVerifyCall(status);
|
||||
std::vector<int> tmp(__memory_corruption_check_bytes / sizeof(int),
|
||||
__memory_corruption_check_pattern);
|
||||
CV_Assert(tmp.size() * sizeof(int) == __memory_corruption_check_bytes);
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_TRUE, 0, __memory_corruption_check_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
openCLVerifyCall(clEnqueueWriteBuffer(getClCommandQueue(ctx),
|
||||
mainBuffer, CL_TRUE, __memory_corruption_check_bytes + size, __memory_corruption_check_bytes, &tmp[0],
|
||||
0, NULL, NULL));
|
||||
CheckBuffers data(mainBuffer, size, widthInBytes, height);
|
||||
__check_buffers.insert(std::pair<cl_mem, CheckBuffers>((cl_mem)*dev_ptr, data));
|
||||
#endif
|
||||
*pitch = widthInBytes;
|
||||
}
|
||||
|
||||
@ -174,7 +224,59 @@ void openCLCopyBuffer2D(Context *ctx, void *dst, size_t dpitch, int dst_offset,
|
||||
|
||||
void openCLFree(void *devPtr)
|
||||
{
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
bool failBefore = false, failAfter = false;
|
||||
CheckBuffers data;
|
||||
std::map<cl_mem, CheckBuffers>::iterator i = __check_buffers.find((cl_mem)devPtr);
|
||||
if (i != __check_buffers.end())
|
||||
{
|
||||
data = i->second;
|
||||
Context* ctx = Context::getContext();
|
||||
std::vector<uchar> checkBefore(__memory_corruption_check_bytes);
|
||||
std::vector<uchar> checkAfter(__memory_corruption_check_bytes);
|
||||
openCLVerifyCall(clEnqueueReadBuffer(getClCommandQueue(ctx),
|
||||
data.mainBuffer, CL_TRUE, 0, __memory_corruption_check_bytes, &checkBefore[0],
|
||||
0, NULL, NULL));
|
||||
openCLVerifyCall(clEnqueueReadBuffer(getClCommandQueue(ctx),
|
||||
data.mainBuffer, CL_TRUE, __memory_corruption_check_bytes + data.size, __memory_corruption_check_bytes, &checkAfter[0],
|
||||
0, NULL, NULL));
|
||||
|
||||
std::vector<int> tmp(__memory_corruption_check_bytes / sizeof(int),
|
||||
__memory_corruption_check_pattern);
|
||||
|
||||
if (memcmp(&checkBefore[0], &tmp[0], __memory_corruption_check_bytes) != 0)
|
||||
{
|
||||
failBefore = true;
|
||||
}
|
||||
if (memcmp(&checkAfter[0], &tmp[0], __memory_corruption_check_bytes) != 0)
|
||||
{
|
||||
failAfter = true;
|
||||
}
|
||||
openCLSafeCall(clReleaseMemObject(data.mainBuffer));
|
||||
__check_buffers.erase(i);
|
||||
}
|
||||
#endif
|
||||
openCLSafeCall(clReleaseMemObject((cl_mem)devPtr));
|
||||
#ifdef CHECK_MEMORY_CORRUPTION
|
||||
if (failBefore)
|
||||
{
|
||||
#ifdef CHECK_MEMORY_CORRUPTION_PRINT_ERROR
|
||||
std::cerr << "ERROR: Memory corruption detected: before buffer: " << cv::format("widthInBytes=%d height=%d", (int)data.widthInBytes, (int)data.height) << std::endl;
|
||||
#endif
|
||||
#ifdef CHECK_MEMORY_CORRUPTION_RAISE_ERROR
|
||||
CV_Error(CV_StsInternal, "Memory corruption detected: before buffer");
|
||||
#endif
|
||||
}
|
||||
if (failAfter)
|
||||
{
|
||||
#ifdef CHECK_MEMORY_CORRUPTION_PRINT_ERROR
|
||||
std::cerr << "ERROR: Memory corruption detected: after buffer: " << cv::format("widthInBytes=%d height=%d", (int)data.widthInBytes, (int)data.height) << std::endl;
|
||||
#endif
|
||||
#ifdef CHECK_MEMORY_CORRUPTION_RAISE_ERROR
|
||||
CV_Error(CV_StsInternal, "Memory corruption detected: after buffer");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cl_kernel openCLGetKernelFromSource(const Context *ctx, const cv::ocl::ProgramEntry* source, string kernelName)
|
||||
|
Loading…
x
Reference in New Issue
Block a user