Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Opencl for C++, buffer.release() is protected member

Tags:

c++

buffer

opencl

Im learning how to make simple opencl programs in C++ using Amd's app sdk and Khronos's header files for Opencl 1.2. I used the below example and it is working. But when I try to .release() the buffers in the end, I get an error message from compiler saying "cannot access protected member".

    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!!!

So I searched for the structure of wrapper class of buffer and found that:

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_);
    }
};

Question: How can I release the memory dedicated to buffers? Even the ~Wrapper() nor ~Memory() does not work because error says "invalid destructor name". Maybe it destroys itself when function exits? This is in a dll and from a C# wrapper, its being called repeatedly so I need it to be released only when needed. Thanks.

like image 791
huseyin tugrul buyukisik Avatar asked Feb 04 '26 01:02

huseyin tugrul buyukisik


1 Answers

It is good that the class Buffer handles itself the allocation and destruction.

If you want to allocate and destroy it manually just do this:

vector<cl::Buffer> mybuffer;

Then simply to create a memory zone:

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

To destroy it:

mybuffer.clear();

And the good thing is that if you forget to delete it, it will delete it automatically.

like image 145
DarkZeros Avatar answered Feb 07 '26 16:02

DarkZeros



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!