I have a situation where I need to dynamically allocate buffers in an OpenCL program (not inside a kernel). I am using the C++ wrapper from the cl.hpp header file. I'd like to do the analog of what is possible on a CPU:
No, cl::Buffer doesn’t directly support re-sizing. You would have to allocate a new buffer with the new size, copy over the data, and then release the old buffer.
If you’re looking for a higher-level API which does this, check out the boost::compute::vector<T>) class in the Boost.Compute OpenCL wrapper library which supports dynamic resizing and has an API just like std::vector<T>.
As Kyle pointed out the cl.hpp constructs are intended to be thin and overhead-free wrappers around OpenCL constructs, so dynamic memory management is not present. In fact, the header is almost entirely free of dynamic memory management of any sort - the cases where that fails are allocating strings for info return values and one or two other places.
Having said that, you should be able to allocate a cl::Buffer dynamically. Why not try:
cl::Buffer *buf = new cl::Buffer(…);
Or, better, to be in-keeping with C++ memory management in general:
std::shared_ptr<cl::Buffer> buf;
buf = std::make_shared<cl::Buffer>(…);
It won’t resize dynamically, but it will be allocated dynamically.
Unfortunately construction and assignment or re-assignment to a buffer object is unsafe due to the design of the header. Updating a shared_ptr to a buffer should work ok. The following code worked for me, for example:
std::shared_ptr<cl::Buffer> inputABuffer = std::make_shared<cl::Buffer>(begin(inputA), end(inputA), true);
cl::Buffer inputBBuffer(begin(inputB), end(inputB), true);
cl::Buffer outputBuffer(begin(output), end(output), false);
Actually, I misinterpreted the behaviour of my debugger. This works too:
cl::Buffer inputABuffer(begin(inputA), end(inputA), true);
cl::Buffer inputBBuffer(begin(inputB), end(inputB), true);
cl::Buffer outputBuffer(begin(output), end(output), false);
It correctly manages the lifetime of the underlying buffer using reference counting. So all you are then missing is a resize operator, but as Buffers manage real data in the OpenCL runtime I lean towards making sizes explicit at this level so I’m not sure that a resize operator would be the right thing to do.