Set LocalSize Dynamically

#1

I have been trying to use Vulkan for compute coming from a CUDA background and curious how I am suppose to set the LocalSize from Vulkan since I realize AMD Wavefronts are 64 compared to NVIDIA warps of 32

To my knowledge you can only set your LocalSize by setting it in GLSL as
layout (local_size_x = 32) in;

but I also noticed the glslang is setting WorkgroupSize on top of that to be (32, 1, 1) which according to the Vulkan spec apparently overrides the LocalSize value?

I want to be able to query my subgroup size and then set the LocalSize to be that at runtime… anyone help me with how this is possible?

#2

“Local size” and “work group size” are different names for the same thing. The reason LocalSize and WorkgroupSize both exist is that they do different things. LocalSize/Id is how you specify the local size for the shader; WorkgroupSize decorates a global value, thus allowing your shader to read what the local size is and use that in computations.

LocalSize/Id is an execution mode, and in SPIR-V, execution mode specifiers are not results. You cannot use them as the inputs of later expressions. The WorkgroupSize is the decorator for a result <id>, so you can use it as the input for some expression.

GLSlang is not setting the WorkgroupSize to something; it is specifying that a particular result <id> shall contain the workgroup size.

If you look at it from a GLSL analogy, the SPIR-V LocalSize is like the layout(local_size_* = ##) in; declaration, while WorkgroupSize is like accessing gl_WorkGroupSize. Two different locations, but both talking about the same thing.

The names almost make it seem like they were both written by the same people :wink:

However, that doesn’t really solve your problem. There is no way to “query my subgroup size” in Vulkan. But given such a value, you can use SPIR-V’s specialization constants to specify the value at specialization/pipeline building time. And of course, GLSL-for-Vulkan adds this feature as well.