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…