Results 1 to 4 of 4

Thread: Dynamic allocation of cl::Buffer

Hybrid View

  1. #1
    Junior Member
    Join Date
    Dec 2013
    Posts
    5

    Dynamic allocation of cl::Buffer

    Dear all,

    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:

    cl_uint *myarray;

    if(somecondition)
    {
    cl_uint arraysize = computed_number;
    myarray = (cl_uint*)malloc(arraysize * sizeof(cl_uint));
    }

    Is it possible to do some analogous with cl::Buffer?

    Many thanks!

  2. #2
    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>.

  3. #3
    Junior Member
    Join Date
    May 2011
    Posts
    17
    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);

    vectorAddKernel(
    cl::EnqueueArgs(
    cl::NDRange(numElements),
    cl::NDRange(numElements)),
    *inputABuffer,
    inputBBuffer,
    outputBuffer);

  4. #4
    Junior Member
    Join Date
    May 2011
    Posts
    17
    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);

    {

    cl::Buffer inputCBuffer(begin(inputA), end(inputA), true);
    inputBBuffer = inputCBuffer;
    }


    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •