我以为我在某个地方读过,(但是,对于我的生活,我找不到源代码),使用C ++ API,你不必释放设备/内核/内存,就像使用C一样API作为cl :: Kernel,cl :: Buffer,cl :: Device的析构函数,当类对象超出范围(程序结束等)时执行此操作。但是,仔细研究cl.hpp(最新版本,1.1 rev 04)后,我根本没有看到任何析构函数。例如,这是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, ¶m);
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
};
有人对此有所了解吗?我应该关心这件事吗?在C ++包装器文档中,他们甚至没有提到类似于releaseClMemObject或free(cl_devices)等的任何内容。
感谢。
答案 0 :(得分:12)
如果你进一步观察,那么你将看到所有这些类都继承自模板detail::Wrapper<T>
,而这又是专门为每个类型确实在其析构函数中调用相应的clRelease...
函数如你所知,类的析构函数将始终调用其基类析构函数,因此cl::Buffer
,cl::Kernel
和朋友不需要用户定义的析构函数。 (好吧,为了正确Wrapper<T>
不是专门的,而是使用一些名为ReferenceHandler<T>
的专业特征类来带来retain
和release
函数。)
因为所有这些OpenCL对象都使用某种引用计数语义,并且所有这些C ++包装器在其构造函数和析构函数中包含相应的clRetain/clRelease
调用,所以您确实不必担心在正确释放OpenCL资源时使用C ++,就像它应该的那样。
(但就像 DarkZeros 已经说过的那样,设备可能是一个不好的例子,因为设备通常不被保留或释放(并且detail::Wrapper<cl_device_id>
的con /析构函数可能什么都不做他们可能会使用OpenCL 1.2的设备分裂,但C ++包装器无论如何都不支持1.2。)
答案 1 :(得分:3)
OpenCL中唯一需要发布的东西是抽象结构。像:
您无法释放设备,因为无法“销毁”或取消分配设备。当您调用getDevice时,您会收到设备的ID,而不是新创建的设备。
注意:在OCL 1.2中,设备可以构建为上层设备(子设备)的分区。所以,它应该有一个删除案例。也许CL API应该处理新verisons的这个特定情况......我不知道
答案 2 :(得分:1)
只需使用
clReleaseMemObject(your_buffer());
使用cl :: Buffer或其他类时,秘密位于your_buffer名称后的()
中。
对其他使用相同的逻辑/语法。