clSetKernelArg set NULL __global buffer pointer ( Unclear )

According to the documentation on clSetKernelArg

on arg_value

“A NULL value can also be specified if the argument is a buffer object in which case a NULL value will be used as the value for the argument declared as a pointer to __global or __constant memory in the kernel”

So is possible to pass a NULL __global pointer to a kernel

On this situation arg_size, assuming that the word “argument” mean “kernel argument” like on all document, I assume

clSetKernelArg(kernel, n , sizeof(cl_mem), NULL) OK
clSetKernelArg(kernel, n , 0, NULL) WRONG
clSetKernelArg(kernel, n , sizeof(cl_mem), &zero_buffer) ??

When i follow to read reaching Errors section i see

CL_INVALID_ARG_VALUE if arg_value specified is NULL for an argument that is not declared with the __local qualifier or vice-versa

This mean

clSetKernelArg(kernel, n , sizeof(cl_mem), NULL) WRONG
clSetKernelArg(kernel, n , 0, NULL) WRONG
clSetKernelArg(kernel, n , sizeof(cl_mem), &zero_buffer) ??

CL_INVALID_MEM_OBJECT for an argument declared to be a memory object when the specified arg_value is not a valid memory object

clSetKernelArg(kernel, n , sizeof(cl_mem), NULL) WRONG
clSetKernelArg(kernel, n , 0, NULL) WRONG
clSetKernelArg(kernel, n , sizeof(cl_mem), &zero_buffer) WRONG?

Is Null a valid memory object ? For Nvidia the answer is YES and the third call work, for AMD the answer is NO, no one of this call work and there is no way to set a pointer kernel argument to NULL

What revision of the OpenCL specification are you looking at? The most recent published revision of the OpenCL 1.1. specification is #44 and this is what it says:

If the argument is a buffer object, the arg_value pointer can be
NULL or point to a NULL value in which case a NULL value will be used as the value for the argument declared as a pointer to __global or __constant memory in the kernel.

In other words, both of these options are valid and will set the kernel argument to NULL.


cl_mem null_mem_object = NULL;
clSetKernelArg(kernel, n , sizeof(cl_mem), NULL);
clSetKernelArg(kernel, n, sizeof(cl_mem), &null_mem_object);

If there’s a vendor that is not honoring the specification it is best to contact their customer representatives directly.

I follow the OpenCL documentation 1.1 Revision 44 Online Manual

The name of this vendor is AMD. But i do not think the mistake is from AMD. AMD that followed the documentation, i think the documentation is contradictory Infact after reading the statement you have reported there is also

CL_INVALID_MEM_OBJECT for an argument declared to be a memory object when the specified arg_value is not a valid memory object.

This statement say that

clSetKernelArg (kernel, n , sizeof(cl_mem), &null_mem_object); should return CL_INVALID_MEM_OBJECT if null is an invalid cl_mem object ( Is unclear if null is considered a valid or invalid memobject) (and infact is what AMD does)

Anyway the following statement has not interpretation

“CL_INVALID_ARG_VALUE if arg_value specified is NULL for an argument that is not declared with the __local qualifier or vice-versa”.

say that

clSetKernelArg(kernel, n, sizeof(cl_mem), NULL) should return CL_INVALID_ARG_VALUE

Following your documentation there is no way to declare a null cl_mem object null pointer ( or may be one if null is a valid mem object ), and this is what AMD follow

I’m afraid we must be looking at a different revision of the specification. I got mine a few days ago from http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf.

This version reads:

If the argument is a buffer object, the arg_value pointer can be NULL or point to a NULL value in which case a NULL value will be used as the value for the argument declared as a pointer to __global or __constant memory in the kernel. If the argument is declared with the __local qualifier, the arg_value entry must be NULL.

[…]

If the argument is declared to be a pointer of a built-in scalar or vector type, or a user defined structure type in the global or constant address space, the memory object specified as argument value must be a buffer object (or NULL).

[…]

clSetKernelArg returns CL_SUCCESS if the function was executed successfully. Otherwise, it returns one of the following errors:

  • CL_INVALID_ARG_VALUE if arg_value specified is not a valid value.
  • CL_INVALID_MEM_OBJECT for an argument declared to be a memory object when the specified arg_value is not a valid memory object.

I hope this is clear.