cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

dravisher
Journeyman III

How to release resources (buffers, queues etc.)?

Using C++ bindings

Hello. I am having trouble releasing resources in my host application using the C++ bindings. Using for instance Buffer_Settings.release() yields an error message like what is attached. This is using Visual Studio 2008 with latest drivers and SDK.

Am I doing it wrong? Is there a different syntax for releasing resources in the C++ bindings? The samples never do this (at least not the C++ samples), so I haven't been able to find any example code.

1>.\4411p1aOCL.cpp(335) : error C2248: 'cl::detail::Wrapper<T>::release' : cannot access protected member declared in class 'cl::detail::Wrapper<T>' 1> with 1> [ 1> T=cl_mem 1> ] 1> C:\Program Files (x86)\ATI Stream\include\CL/cl.hpp(1128) : see declaration of 'cl::detail::Wrapper<T>::release' 1> with 1> [ 1> T=cl_mem 1> ]

0 Likes
6 Replies
omkaranathan
Adept I

All the objects(memory/command queue/event objects) are derived from Wrapper class which automatically calls release when the object goes out of scope.

See the destructor of Wrapper class

~Wrapper() { if (object_ != NULL) { release(); } }

0 Likes

Ah I see, very convenient. I did try to look at the wrapper class, but I'm afraid my knowledge of C++ was not sufficient to understand it's workings. Thanks for the clarification

0 Likes

Perhaps my question does not completely fit to this topic, but I'll try.

Assume that kernel will execute within a loop many times. Does enqueueing a buffer [just for the first time, let's say during program init] ensure that it's allocated on a GPU all the time during kernel executions? If so, an allocated buffer dies when object becomes out of scope?

0 Likes

Does enqueueing a buffer [just for the first time, let's say during program init] ensure that it's allocated on a GPU all the time during kernel executions?

Yes.

If so, an allocated buffer dies when object becomes out of scope?

 

If you are using C++ bindings, yes.

0 Likes

However, many functions return events. In some samples, there are calls to clReleaseEvent after wait satisfied.

When using C++ bindings I can pass pointer to cl::Event what is convenient if cl::Event created on stack, so it will be released by its destructor.

However, if I have cl::Event as member of the persistent struct { cl::Event _event; }; ) and if I pass pointer of _event to enqueueXXX functions, I afraid I will have a memory leak, because there is no way to free associated cl::Event befire enqueueXXX call. I.e. call with pointer to _event will reassign _event to a new value, without releasing old one.  Attempting assigning NULL to cl::Event fails because NULL is not recognized as a valid type to assign to cl::Event and object is not freed.

So, is there way to force cl::Event internal _object to be released, or I stuck with only having cl::Event on stack? (I do not like to have clReleaseEvent(mystruct->_event()) as this way I have to maintain reference count of event myself).

 

0 Likes

Here is how local stack objects can be destructed without causing segmentation faults.

class A
{
int _v;
public:
A(const int v) : _v(v) { }
int v() const { return _v; }
};


A obj(123);
std::cout << obj.v() << std::endl; // prints 123

obj.A::~A(); // destroy object on stack
new (&obj) A(456); // re-construct object
std::cout << obj.v() << std::endl; // prints 456

This is very unusual C++ though (many would call it strange). I have never seen it in real-life. I don't recommend doing something like this unless there is no other way.

I understand what you are getting at though about mismatches between C++ object scope and OpenCL resource lifetime. My own approach has been to build a managed platform. There are heaps of OpenCL resources per device that are lazily scavenged. This has greatly simplified everything.

0 Likes