Query clGetMemInfo for CL_IMAGE_BUFFER

Hi,

I’d like to get the buffer object of a cl_mem (of type CL_MEM_OBJECT_IMAGE1D_BUFFER). I’d therefore use

clGetImageInfo(myMem, CL_IMAGE_BUFFER, Sizeof.cl_mem, XXX, null);

but I don’t know what I need to pass in for the parameter value, i.e. XXX. I’ve tried naively with

cl_mem myMem2 = new cl_mem();
Pointer XXX = Pointer.to(myMem2);

but this doesn’t work. Does anybody know how this is supposed to work?

Thanks very much in advance

First, some disclaimers: I have not actively worked with images in OpenCL extensively. Also, most samples still use the (deprecated) createImage... functions, and not the createImage function that was introduced with OpenCL 1.2.


Apart from that: I think it should work as you described it. But this is either just wrong (and I don’t know why), or it might be a limitation of the underlying OpenCL implementation (which might as well not „fully“ support the „newer“ OpenCL features - „new“ is a relative term, but … particularly NVIDIA was not sooo eager to support OpenCL, because they want people to use their proprietary CUDA…)

I usually hestiate to suggest (or even claim) that such a behavior is due to OpenCL. And there certainly are some limitations of JOCL when it comes to ~„obtaining ‚special‘ values from ‚special‘ objects“.

But I just tested it with this example:

#include "CL/cl.h"

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char** argv) {

  cl_platform_id platformId = NULL;
  cl_device_id deviceID = NULL;
  cl_uint retNumDevices;
  cl_uint retNumPlatforms;
  clGetPlatformIDs(1, &platformId, &retNumPlatforms);
  clGetDeviceIDs(platformId, CL_DEVICE_TYPE_DEFAULT, 1, &deviceID, &retNumDevices);
  cl_context context = clCreateContext(NULL, 1, &deviceID, NULL, NULL, NULL);

  int n = 16;
  int* pixels = new int[n];

  cl_mem imageBuffer = clCreateBuffer(context,
    CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
    sizeof(cl_int) * n, pixels, NULL);

  cl_image_format imageFormat;
  imageFormat.image_channel_order = CL_RGBA;
  imageFormat.image_channel_data_type = CL_UNSIGNED_INT8;

  cl_image_desc imageDesc{ 0 };
  imageDesc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;

  imageDesc.image_width = n;
  imageDesc.image_height = 1;
  imageDesc.buffer = imageBuffer;

  cl_mem imageMem = clCreateImage(
    context, 0,
    &imageFormat, &imageDesc, NULL, NULL);

  size_t width = 999;
  clGetImageInfo(imageMem, CL_IMAGE_WIDTH, sizeof(size_t),
    &width, NULL);
  printf("Obtained image width: %zu\n", width);

  cl_mem result;
  clGetImageInfo(imageMem, CL_IMAGE_BUFFER, sizeof(cl_mem),
    &result, NULL);

  printf("Obtained image buffer: %p \n", result);

  return 0;

}

And for me (with a recent (CUDA 11.2, relatively new) NVIDIA OpenCL backend) it prints

Obtained image width: 16
Obtained image buffer: 0000000000000000

So it can obtain the size, but the buffer remains NULL.


As a workaround… you could consider to somehow „transport“ the buffer (that is part of the imageDesc) to the point where it is needed, instead of obtaining it from the image. That may be clumsy and inconvenient, but the only idea that I can come up with…

…iff this is really a limitation of OpenCL.
If someone can tell me what’s wrong with the code above, I’d be curious to hear that…

Thanks for your reply.
I tried your code and get the same result (and yes, it’s also NVIDIA). So maybe that’s just the way it is.

I only need access to the buffer to delete it at the end. I guess it’s not just enough to delete the image… (although I couldn’t find any information about this).

Thanks again