2013-06-22 66 views
4

我以爲我在某處讀過(儘管如此,對於我來說,我找不到源代碼),使用C++ API,您不必釋放設備/內核/內存像w/C API作爲cl :: Kernel,cl :: Buffer,cl :: Device的析構函數,當類對象超出作用域(程序結束等)時,它會執行此操作。然而,仔細研究cl.hpp(最新的1.1版本04)後,我根本沒有看到任何析構函數。例如,這裏是cl ::設備 -發佈Opencl內存,內核,設備等

/*! \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 
}; 

有沒有人知道這件事?我應該關心這個嗎?在C++包裝文檔中,他們甚至沒有提及任何類似releaseClMemObject或free(cl_devices)等的東西。

謝謝。

回答

8

如果你看得更遠,那麼你會看到,所有這些類繼承自模板detail::Wrapper<T>,並且反過來是專門爲每個並且每種類型的確在其析構函數中調用相應的函數,正如您所知,類的析構函數將始終調用其基類析構函數,因此cl::Buffer,cl::Kernel和朋友中不需要用戶定義的析構函數。 (好吧,是正確的Wrapper<T>不是專業,但使用名爲ReferenceHandler<T>其他一些特定特徵的類,它帶來的retainrelease功能。)

如此以來,所有這些OpenCL的對象使用某種形式的引用計數語義和所有的C++包裝在相應的構造函數和析構函數中調用相應的clRetain/clRelease調用,您確實不必擔心在使用C++時正確釋放OpenCL資源,只需按照它的方式使用RAII。

(但已經被DarkZeros說喜歡,一個設備可能是一個壞榜樣,因爲設備通常不會保留或釋放(和detail::Wrapper<cl_device_id>的CON /析構函數可能會什麼都不做)。隨着的OpenCL 1.2的設備裂變他們可能,但C++包裝不支持1.2無論如何。)

+0

華麗的迴應,謝謝。然而,我之前在源代碼文件中看過,並且在包裝器或內存/上下文的超類中沒有看到釋放調用或析構函數。您能否提供文件/行#請? W.r.t.該設備的東西,我只見過在C語法中,我不知道設備的分裂,這聽起來很酷。 –

+1

@SteveNovakov在'Wrapper '(行1103)的析構函數中,你會看到它調用'Wrapper :: release',那行(1133行)又調用'ReferenceHandler :: release',並在第1000-1087行'ReferenceHandler '及其針對所有不同OpenCL對象類型的各種專業化。 (我希望行數匹配,我有* Khronos *的正式頭文件,我認爲該文件當然是'cl.hpp',C++包裝的唯一文件,其他所有文件都是C接口。 ) –

+0

是的,我不知道第一次讀它時我是怎麼看的。非常感謝你。 –

1

在OpenCL中唯一需要發佈的東西是抽象結構。像:

  • 內存對象
  • 上下文
  • 命令隊列
  • 程序
  • 活動

您無法釋放的設備,因爲設備不能被「破壞「或未分配。當您調用getDevice時,您會收到設備的ID,而不是新創建的設備。

注意:在OCL 1.2中,設備可以構建爲上層設備(子設備)的分區。所以,它應該有一個刪除案例。也許CL API應該照顧這個新的verisons的具體情況...我不知道