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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With