3

我正在学习如何使用 Amd 的 app sdk 和 Khronos 的 Opencl 1.2 头文件在 C++ 中制作简单的 opencl 程序。我使用了下面的示例,它正在工作。但是当我最后尝试.release()缓冲区时,我从编译器收到一条错误消息,说“无法访问受保护的成员”。

    int problemSize=1024;
    const char * kernelDerlenecek = 
    "__kernel void Toplam(__global float * v1, __global float * v2)"
    "{"
    "    int i = get_global_id(0);"
    "    v2[i]=v1[i];"
    "}";
cl::Context altYapi(CL_DEVICE_TYPE_GPU);
cl::Program::Sources kaynaklar;
kaynaklar.push_back(std::make_pair(kernelDerlenecek,strlen(kernelDerlenecek))); 
cl::Program program(altYapi,kaynaklar);
std::vector<cl::Device> aygitlar=altYapi.getInfo<CL_CONTEXT_DEVICES>();
program.build(aygitlar);
cl::Kernel kernel(program,"Toplam");
cl::CommandQueue cmdQ(altYapi,aygitlar[0]);
std::vector<cl_float> input;
std::generate_n (std::back_inserter ( input ) , problemSize , rand) ;
cl::Buffer inputBuffer(altYapi, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(cl_float) * input.size(), &input[0]);
cl::Buffer outputBuffer(altYapi ,CL_MEM_WRITE_ONLY , sizeof(cl_float )* input.size()) ;
kernel.setArg(0,inputBuffer);
kernel.setArg(1,outputBuffer);
cl::NDRange Global(1024);
cl::NDRange Local(64);
cmdQ.enqueueNDRangeKernel(kernel,cl::NullRange,Global,Local);
float * output = (float *)malloc(1024*sizeof(float));
cmdQ.enqueueReadBuffer(outputBuffer,CL_TRUE,0,1024 * sizeof(cl_float),output);
for(int i=0;i<1024;i++)
{
    printf(" %f \n ",output[i]);
}
free(output);

//inputBuffer.release(); <----- this is not accessible!!!
//inputBuffer.~Wrapper() <----- invalid destructor name!!!

于是我搜索了buffer的wrapper类的结构,发现:

class Wrapper
{
public:
    typedef T cl_type;

protected:
    cl_type object_;

public:
    Wrapper() : object_(NULL) { }

    ~Wrapper()
    {
        if (object_ != NULL) { release(); } //This is releasing, should I destroy myself?
    }

    Wrapper(const Wrapper<cl_type>& rhs)
    {
        object_ = rhs.object_;
        if (object_ != NULL) { retain(); }
    }

    Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
    {
        if (object_ != NULL) { release(); }
        object_ = rhs.object_;
        if (object_ != NULL) { retain(); }
        return *this;
    }

    cl_type operator ()() const { return object_; }

    cl_type& operator ()() { return object_; }

protected:

    cl_int retain() const
    {
        return ReferenceHandler<cl_type>::retain(object_);
    }

    cl_int release() const //<---yes, its true that I cannot access. Who can?
    {
        return ReferenceHandler<cl_type>::release(object_);
    }
};

问题:如何释放专用于缓冲区的内存?甚至 ~Wrapper() 和 ~Memory() 也不起作用,因为错误说“无效的析构函数名称”。也许它会在函数退出时自我毁灭?这是在一个 dll 和一个 C# 包装器中,它被重复调用,所以我需要它只在需要时才发布。谢谢。

4

2 回答 2

7

类 Buffer 自己处理分配和销毁是很好的。

如果您想手动分配和销毁它,只需执行以下操作:

vector<cl::Buffer> mybuffer;

然后简单地创建一个内存区域:

mybuffer.push_back(cl::Buffer(/*constructor parameters*/));

销毁它:

mybuffer.clear();

好在如果你忘记删除它,它会自动删除它。

于 2013-07-31T15:58:43.277 回答
2

您可以将其包装在一个指针中,最好是一个智能指针,如下所示:

std::unique_ptr<cl::Buffer> myBuffer(new cl::Buffer(...));

然后如果你想手动删除数据,或者用别的东西替换数据:

myBuffer.reset(new cl::Buffer(...));

这将删除旧数据并将其替换为新数据,如果您只想删除旧数据,请将“reset()”保留为空白。

于 2021-01-11T12:33:52.727 回答