I am migrating code from CUDA to OpenGL compute shaders. I could not find a way to set the local workgroup size outside the shader; is there a way to set gl_WorkGroupSize in the calling program like one can do for gl_NumWorkGroups? Thanks in advance
Core OpenGL has no mechanism for this. The ARB_compute_variable_group_size extension provides such a feature. It doesn't allow for indirect compute operations though.
It doesn't seem to have much AMD support though (outside of open source Linux drivers). And Intel support is nil.
In addition to the more direct existing answer, there is a way to work around this in unextended OpenGL to some degree, feeding from the fact that in contrast to CUDA OpenGL compute shaders are not pre-compiled with application build (well, they can nowadays, but aren't by default). Instead you usually compile your compute shaders at some point during application runtime.
So a way to achieve a somewhat customizable workgroup size is to use a macro for it and then redefine this dynamically during application runtime but before shader compile time.
layout(local_size_x = BLOCKSIZE) in;
And in the application all you have to do is prepend a
"#define BLOCKSIZE <whatever>\n" to the shader source string you feed into
glCompileShader. Of course in practice you have to care about stuff like the
#version directive being the first line in a shader. You could as well have the define in the shader code already (maybe with a meaningful default size) and do a text replacement instead. But you get the idea.
Of course this means recompiling your compute shader for each and every workgroup size you're using. It's practically not much different from just having different shaders for each workgroup size. But at least it's a way to dynamically select the workgroup size during runtime while maintaining a single shader source.