我不知道为什么我会不断收到这个警告,因为我已经多次通过了这段代码而且我无法弄清楚这是来自哪里,因为我非常肯定(但很明显)不)释放所有的记忆。希望知道比我更多的人可以查看我的代码,并指出这种情况发生的地点和原因。
谢谢!
int runKernel( Image *anImage,
PixelPacket *imagePixels,
MagickSizeType imageSizeBytes,
const char *kernelSource )
{
cl_context myContext ;
cl_command_queue myQueue ;
cl_mem *outputImage ;
cl_event clEvent ;
int bitsPerChannel = anImage[0].depth ;
int width = anImage[0].columns ;
int height = anImage[0].rows ;
/****************************
Setup the Opencl environment
****************************/
// Use this to check the output of each API call
cl_int status ;
// Retrieve the number of platforms
cl_uint numPlatforms = 0 ;
status = clGetPlatformIDs( 0, NULL, &numPlatforms ) ;
// Allocate enough space for each platform
cl_platform_id *platforms = NULL ;
platforms = (cl_platform_id *) malloc( numPlatforms * sizeof(cl_platform_id) ) ;
// Fill in the platforms
status = clGetPlatformIDs( numPlatforms, platforms, NULL ) ;
// Retrieve the number of devices for the 1st platform
cl_uint numDevices = 0 ;
status = clGetDeviceIDs( platforms[0], CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices ) ;
// Allocate enough space for each device
cl_device_id *devices ;
devices = (cl_device_id *) malloc( numDevices * sizeof(cl_device_id) ) ;
// Fill in the devices
status = clGetDeviceIDs( platforms[0], CL_DEVICE_TYPE_ALL, numDevices,
devices, NULL ) ;
// Create the context
myContext = clCreateContext( NULL, numDevices, devices, NULL, NULL, &status ) ;
// Create the command queue with the 1st device
myQueue = clCreateCommandQueue( myContext, devices[0], 0, &status ) ;
/****************************
Create Images and Move Data
****************************/
// Set format and descriptor to proper values according to image type
cl_image_format *image_format = NULL ;
cl_image_desc *image_desc = NULL ;
get_cl_image_format( anImage, &image_desc, &image_format ) ;
// Create the image sampler
cl_sampler clSampler = clCreateSampler(
myContext,
CL_FALSE, //use pixel based addressing not normalized
CL_ADDRESS_CLAMP_TO_EDGE, // set equal to the pixel at the edge of the image
CL_FILTER_NEAREST,
&status);
// Set input Image region parameters
size_t origin[3] = {0, 0, 0} ; // Offset within the image to copy from
size_t region[3] = {width, height, 1} ; // Elements per dimension for 2d image
// Create cl memory object for the input image
cl_mem_flags flagsRead = CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR ;
cl_mem clInput = clCreateImage( myContext, flagsRead,
( const cl_image_format *)image_format,
( const cl_image_desc *)image_desc,
imagePixels,
&status ) ;
// Allocate space for output image and create cl memory object
float *outputPixels = (float *) malloc( imageSizeBytes ) ;
cl_mem_flags flagsWrite = CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR ;
cl_mem clOutput = clCreateImage( myContext, flagsWrite,
(const cl_image_format *)image_format,
( const cl_image_desc *)image_desc,
outputPixels,
&status ) ;
//Copy input image to the device
status = clEnqueueWriteImage( myQueue, clInput, CL_FALSE, origin, region,
0, 0, imagePixels, 0, NULL, NULL ) ;
/*****************************
Compile the kernel from source
*****************************/
// kernelSource stores the kernel code and must be NULL terminated
cl_program myProgram = clCreateProgramWithSource( myContext, 1,
&kernelSource,
NULL,
&status ) ;
// Compile the program
const char buildOptions[] = "-cl-std=CL1.2 -cl-mad-enable\0";
status = clBuildProgram( myProgram, 1, devices, buildOptions, NULL, NULL ) ;
// Create the kernel
cl_kernel myKernel = clCreateKernel( myProgram, "convolution", &status ) ;
/**********************************
Set kernel args and run the program
**********************************/
// Set the kernel arguments
clSetKernelArg( myKernel, 0, sizeof( cl_mem ), &clInput ) ;
clSetKernelArg( myKernel, 1, sizeof( cl_mem ), &clOutput ) ;
clSetKernelArg( myKernel, 2, sizeof( int ), &height ) ;
clSetKernelArg( myKernel, 3, sizeof( int ), &width ) ;
clSetKernelArg( myKernel, 4, sizeof( cl_sampler ), &clSampler ) ;
//Execute the kernel
status = clEnqueueTask( myQueue, myKernel, 0, NULL, NULL ) ;
//Read the output buffer back to the host
status = clEnqueueReadImage( myQueue, clOutput, CL_TRUE, origin, region, 0, 0,
(void *) outputPixels, 0, NULL, &clEvent ) ;
/**********************************
Free Resources
**********************************/
/* Wait for the kernel to finish */
clWaitForEvents( 1, &clEvent ) ;
free( refImage ) ;
free( platforms ) ;
free( devices ) ;
free( outputPixels ) ;
free( image_desc ) ;
free( image_format ) ;
clReleaseSampler( clSampler ) ;
clReleaseMemObject( clInput ) ;
clReleaseMemObject( clOutput ) ;
clReleaseProgram( myProgram ) ;
clReleaseCommandQueue( myQueue ) ;
clReleaseKernel( myKernel ) ;
clReleaseContext( myContext ) ;
clReleaseEvent( clEvent ) ;
return 0;
}
答案 0 :(得分:0)
在释放事件(clEvent
)之前销毁队列,内核,上下文或程序可能会导致警告。您可以尝试以下方法:
clReleaseEvent( clEvent ) ; // <<< THIS ONE FIRST
clReleaseSampler( clSampler ) ;
clReleaseMemObject( clInput ) ;
clReleaseMemObject( clOutput ) ;
clReleaseProgram( myProgram ) ;
clReleaseCommandQueue( myQueue ) ;
clReleaseKernel( myKernel ) ;
clReleaseContext( myContext ) ;
或者,逐行调试发布操作,直到收到警告为止。