Usage of RuntimeArray w/StorageClassWorkgroup

Is it valid to create a Vulkan SPIR-V shader with a RuntimeArray declared w/StorageClassWorkgroup? If so, are there any examples for how to allocate and bind the correct shared memory allocation from the Vulkan API? All I can find are examples (like nbody) that use fixed static sized Arrays using StorageClassWorkgroup. If not, how are dynamic shared memory allocations handled in SPIR-V?

Thank you!

– dg

The Vulkan specification has a section describing the limitations it imposes onto SPIR-V. For OpTypeRuntimeArray:

OpTypeRuntimeArray must only be used for the last member of a Block-decorated OpTypeStruct in StorageBuffer or PhysicalStorageBuffer storage classes; BufferBlock-decorated OpTypeStruct in Uniform storage class; the outermost dimension of an arrayed variable in the StorageBuffer, Uniform, or UniformConstant storage classes.

So no, you may not do this.

Thanks for clarifying. So whats the proposed way to support dynamically sized shared memory allocations in SPIR-V (where the size is only known at runtime for a StorageClassWorkgroup allocation)?

— dg

I thought that was made clear:

You don’t.

Shared memory isn’t something you “allocate” per-se. It’s something that needs to exist to make your shader work group intercommunication functional. Having a runtime variable size would be… exceedingly difficult to work with.

So you’re just going to have to pick a number that is big enough and then use less of it at runtime.

Yes, I understood your explanation, however this seems like a shortcoming of the spec. OpenCL, CUDA and other APIs support dynamic shared memory allocation. Perhaps this should be reconsidered in a later revision of SPIR-V.

Perhaps this is because they support shared memory allocation. Vulkan does not. Shared variables are a static resource, not something you allocate.

SPIR-V allows you to do this. Vulkan does not.

Is there a better forum to add feedback to the SPIR-V spec? I feel like this dynamic shared memory allocation needs to be discussed and not written off entirely.

You keep talking about the SPIR-V specification as if that is what is preventing you from doing that. As I previously pointed out twice now, it is the Vulkan specification that says you can’t do it.

I stand corrected. Is there a better forum to provide feedback to the restrictions Vulkan imposes on SPIR-V to support dynamic shared memory allocation for compute shaders so we have feature parity with OpenCL, CUDA and other GPU based APIs?

You can bring it up as an issue on the Vulkan bug repo in GitHub. It’s run by the Khronos people, and they seem to have a good track record on keeping up with things there. Though not always following through, you’re likely to at least get a response.

That being said, it would be a very good idea to explain more specifically why Vulkan in particular needs this capability. Vulkan compute is not intended to replace OpenCL/CUDA/other dedicated compute APIs. Vulkan compute is really more of a helper for graphics tasks. So just saying that other dedicated compute APIs can do it is probably not by itself enough justification.

However, if D3D12 and/or Metal have the capabilities you’re looking for, that would likely be a big deal in terms of justifying the feature. If you have some specific use cases, those too would be a big help in moving it forward.

Perfect! Thanks very much! I’ll follow up over there! Much appreciated.

— dg