Correct way to declare a global sampler_t

I have been having a discussion with eyebex on the NVIDIA OpenCL forum about the image support.

One interesting thing came up:
What is the correct way to declare a global sampler_t object?

In my CL file I use this:

const sampler_t demSampler = CLK_NORMALIZED_COORDS_FALSE |
                             CLK_ADDRESS_CLAMP           |
                             CLK_FILTER_LINEAR           ;

__kernel ...

On NVIDIA’s latest OpenCL compiler (from CUDA SDK 3.2.1) it works without problems.
But on AMD’s latest OpenCL compiler (from Stream SDK 2.3) I get this warning:

Warnings being treated as errors
C:\Users\Leith\AppData\Local\Temp\OCL6D5D.tmp.cl(48): error: global variable
          declaration is corrected by the compiler to have addrSpace constant
  const sampler_t demSampler = CLK_NORMALIZED_COORDS_FALSE |
                  ^

1 error detected in the compilation of "C:\Users\Leith\AppData\Local\Temp\OCL6D5
D.tmp.cl".

eyebex suggested I replace const with __constant, which seems to work fine on both NVIDIA and AMD.

But I always thought __constant is to specify that a kernel argument was from the DirectX/OpenGL constant buffer cache, and that const was to tell the compiler to ensure that no code attempts to modify that variable.

I would have thought that const for a global sampler_t was correct though as a sampler_t cannot be modified by the kernel. (In fact in the NVIDIA PTX you can see that a global sampler_t is actually compiled in)

Also on pg. 236 of the OpenCL 1.1 spec:

Samplers can also be declared as global constants in the program source using the following
syntax.
const sampler_t <sampler name> = <value>

Now what is correct, const or __constant, and who is wrong, the spec or AMD?

Now what is correct, const or __constant, and who is wrong, the spec or AMD?

The specification is always right by definition.

“const sampler_t” is the correct way to declare samplers in global scope. “__constant sampler_t” should actually fail since __constant does not imply const.

I retract my previous comment. I think you have found a bug in the spec, because

Samplers can also be declared as global constants in the program source using the following syntax.
const sampler_t <sampler name> = <value>

is in contradiction with page 184:

There is no generic address space name for program scope variables. All program scope variables must be declared in the __constant address space.

I have created a bug report here: http://www.khronos.org/bugzilla/show_bug.cgi?id=397

Thanks a lot for pointing this out! :slight_smile:

So which was is correct?

I found this in the AMD Stream 2.3 Release Notes:

The compiler now accepts the following syntax with a warning:
const sampler_t a = CLK_NORMALIZED_COORDS_TRUE
It is recommended that constant be used instead of const for the above syntax.

So AMD might have already discovered this bug?

Interesting… bug 366.
I noticed that too when I was reading about __constant.

Have you read the other discussion? In post #20 I have a suggeston for how this could be resolved: by introducing a new keyword for global STATE variables vs normal __constant global variables.

The OpenCL Working Group has not decided yet. I can only speculate.

I would guess that AMD is simply trying to be compatible with NVidia. There is a long history of attempting to be bug-compatible with other major implementations.

It appears like adding new keywords to the language is not necessary.

[/quote:2z6dc4zi]
Is this really a contradiction? “__constant” is an address space name, whereas “const” is not. It’s just a semantic hint for the compiler. As I read this, you are not allowed to use any of the address space names for program variables, as they implicitly are “__constant” (which in turn makes them implicitly “const”, too). As “const” is no address space name, there’s no contradiction that program scope samples can be declared using “const”, or? It could be argued, though, whether explicitly specifying “__constant” for program scope variables is allowed or not.

Is this really a contradiction? […] As I read this, you are not allowed to use any of the address space names for program variables, as they implicitly are “__constant”.

When the Working Group was discussing program-scope variables, at first some members wanted to see all program-scope variables to be implicitly in the __constant address space. However, for reasons I don’t remember any more, the Group eventually changed its mind and chose to add the paragraph quoted above. What that paragraph is saying is that variable declarations at program scope must explicitly include an address qualifier and it must be __constant.

This is in contrast with variable declarations at kernel scope, where variables are implicitly in __private memory unless an address qualifier is included in the declaration.

which in turn makes them implicitly “const”, too

Technically speaking, “__constant” does not imply “const”.

I’ve posted my comments in the bugzilla. Will update once the WG discusses and makes a decision.