Free up Opencl memory, cores, devices, etc.

I thought that somewhere I read somewhere (although, for the life of me, I can’t find the source), that using the C ++ API you do not need to release devices / kernels / memory, for example w / C API like destructors for cl :: Kernel, cl :: Buffer, cl :: Device do this when class objects go out of scope (end of program, etc.). However, upon closer inspection of cl.hpp (the latter, 1.1 rev 04), I do not see any destructors at all. For example, here cl :: Device -

/*! \class Device * \brief Device interface for cl_device_id. */ class Device : public detail::Wrapper<cl_device_id> { public: Device(cl_device_id device) { object_ = device; } Device() : detail::Wrapper<cl_type>() { } Device(const Device& device) : detail::Wrapper<cl_type>(device) { } Device& operator = (const Device& rhs) { if (this != &rhs) { detail::Wrapper<cl_type>::operator=(rhs); } return *this; } template <typename T> cl_int getInfo(cl_device_info name, T* param) const { return detail::errHandler( detail::getInfo(&::clGetDeviceInfo, object_, name, param), __GET_DEVICE_INFO_ERR); } template <cl_int name> typename detail::param_traits<detail::cl_device_info, name>::param_type getInfo(cl_int* err = NULL) const { typename detail::param_traits< detail::cl_device_info, name>::param_type param; cl_int result = getInfo(name, &param); if (err != NULL) { *err = result; } return param; } #if defined(USE_CL_DEVICE_FISSION) cl_int createSubDevices( const cl_device_partition_property_ext * properties, VECTOR_CLASS<Device>* devices) { typedef CL_API_ENTRY cl_int ( CL_API_CALL * PFN_clCreateSubDevicesEXT)( cl_device_id /*in_device*/, const cl_device_partition_property_ext * /* properties */, cl_uint /*num_entries*/, cl_device_id * /*out_devices*/, cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; static PFN_clCreateSubDevicesEXT pfn_clCreateSubDevicesEXT = NULL; __INIT_CL_EXT_FCN_PTR(clCreateSubDevicesEXT); cl_uint n = 0; cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, NULL, &n); if (err != CL_SUCCESS) { return detail::errHandler(err, __CREATE_SUB_DEVICES); } cl_device_id* ids = (cl_device_id*) alloca(n * sizeof(cl_device_id)); err = pfn_clCreateSubDevicesEXT(object_, properties, n, ids, NULL); if (err != CL_SUCCESS) { return detail::errHandler(err, __CREATE_SUB_DEVICES); } devices->assign(&ids[0], &ids[n]); return CL_SUCCESS; } #endif }; 

Does anyone know about this? Should I take care of this? In the documentation for the C ++ shell, they do not even mention anything similar to releaseClMemObject or free (cl_devices), etc.

Thanks.

+6
source share
3 answers

If you look further, you will see that all these classes are inherited from the template detail::Wrapper<T> and which, in turn, is specialized for each type to really call the corresponding function clRelease... in its destructor and, as you know, a class destructor will always call destructors of its base class, so there is no need for a user-defined destructor in cl::Buffer , cl::Kernel and friends. (Well, to be correct, Wrapper<T> unspecialized, but uses another class of specialized features called ReferenceHandler<T> , which brings the retain and release functions.)

So, since all these OpenCL objects use some semantics of reference counting, and all these C ++ shells wrap the corresponding calls to clRetain/clRelease in their constructors and destructors, you really don't need to worry about the correct release of OpenCL resources when working with C ++, just RAII the way it should be.

(But, as DarkZeros already said, the device is probably a bad example, since the devices are usually not saved or not released (and detail::Wrapper<cl_device_id> con / destructor will probably do nothing). When dividing an OpenCL 1.2 device, they can, but the Cube shell does not support 1.2 anyway)

+11
source

The only things needed for release in OpenCL are abstract constructs. How:

  • Memory objects
  • contexts
  • Team Queues
  • Programs
  • Kernels
  • Developments

You cannot release the device because the device cannot be “destroyed” or not allocated. When you call getDevice, you get the device identifier, not the newly created device.

NOTE. In OCL 1.2, a device can be created as a partition of a top device (sub-device). So he should have a deletion case. Perhaps the CL API should take care of this particular case with the new versions ... I don't know

+2
source

Just use

 clReleaseMemObject(your_buffer**()**); 

Secret in () after your_buffer. Use the same logic / syntax for others.

0
source

Source: https://habr.com/ru/post/1487584/


All Articles