Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specialization constant not considered constant for subgroupBroadcast #2919

Closed
FunMiles opened this issue Mar 31, 2022 · 2 comments
Closed

Comments

@FunMiles
Copy link

Compilation of the following code gives an error stating that the argument to subgroupBroadcast should be a compile-time constant. As far as I understand it, a specialization constant is a compilation constant and should be acceptable.

#version 450
#extension GL_KHR_shader_subgroup_basic : enable
#extension GL_KHR_shader_subgroup_ballot : enable
#extension GL_KHR_shader_subgroup_arithmetic : enable
#extension GL_KHR_memory_scope_semantics : enable

layout(local_size_x_id = 0) in;

layout(constant_id = 1) const int subGroupSize = 64;

layout(set = 0, binding = 0) readonly buffer InBuf {
    uint[] in_buf;
};

layout(set = 0, binding = 1) buffer OutBuf {
    uint[] out_buf;
};


void main() {

    uint v = in_buf[gl_GlobalInvocationID.x];
    uint total = subgroupInclusiveAdd(v);
    total += subgroupBroadcast(total, subGroupSize-1);
    out_buf[gl_GlobalInvocationID.x] = total;
}

Error diagnostic:

ERROR: /Users/michel/CLionProjects/GPUGraph/shaders/cms_example.comp:24: 'id' : argument must be compile-time constant 
ERROR: /Users/michel/CLionProjects/GPUGraph/shaders/cms_example.comp:24: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated.

There was a similar issue for texture load but that has been resolved #2178

Using a specialization constant as the broadcast id is useful in prefix sum operations as stated in #1591 where @jekstrand suggests the use of a specialization constant with subgroupBroadcast (which will not work as long as glslang marks this as an error.

@greg-lunarg
Copy link
Contributor

Yes, subGroupSize-1 should be considered a compile-time constant by glslang.

@greg-lunarg
Copy link
Contributor

greg-lunarg commented Apr 22, 2022

I am not seeing the Error diagnostic with the latest glslang. Here is the SPIR-V that is generated, which looks to be correct:

               OpCapability Shader
               OpCapability GroupNonUniform
               OpCapability GroupNonUniformArithmetic
               OpCapability GroupNonUniformBallot
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main" %_ %gl_GlobalInvocationID %__0
               OpExecutionMode %main LocalSize 1 1 1
               OpSource GLSL 450
               OpSourceExtension "GL_KHR_memory_scope_semantics"
               OpSourceExtension "GL_KHR_shader_subgroup_arithmetic"
               OpSourceExtension "GL_KHR_shader_subgroup_ballot"
               OpSourceExtension "GL_KHR_shader_subgroup_basic"
               OpName %main "main"
               OpName %v "v"
               OpName %InBuf "InBuf"
               OpMemberName %InBuf 0 "in_buf"
               OpName %_ ""
               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
               OpName %total "total"
               OpName %subGroupSize "subGroupSize"
               OpName %OutBuf "OutBuf"
               OpMemberName %OutBuf 0 "out_buf"
               OpName %__0 ""
               OpDecorate %_runtimearr_uint ArrayStride 4
               OpMemberDecorate %InBuf 0 NonWritable
               OpMemberDecorate %InBuf 0 Offset 0
               OpDecorate %InBuf Block
               OpDecorate %_ DescriptorSet 0
               OpDecorate %_ Binding 0
               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId

               OpDecorate %subGroupSize SpecId 1
               OpDecorate %_runtimearr_uint_0 ArrayStride 4
               OpMemberDecorate %OutBuf 0 Offset 0
               OpDecorate %OutBuf Block
               OpDecorate %__0 DescriptorSet 0
               OpDecorate %__0 Binding 1
               OpDecorate %45 SpecId 0
               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
       %uint = OpTypeInt 32 0
%_ptr_Function_uint = OpTypePointer Function %uint
%_runtimearr_uint = OpTypeRuntimeArray %uint
      %InBuf = OpTypeStruct %_runtimearr_uint
%_ptr_StorageBuffer_InBuf = OpTypePointer StorageBuffer %InBuf
          %_ = OpVariable %_ptr_StorageBuffer_InBuf StorageBuffer
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
     %v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
     %uint_0 = OpConstant %uint 0
%_ptr_Input_uint = OpTypePointer Input %uint
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
     %uint_3 = OpConstant %uint 3
%subGroupSize = OpSpecConstant %int 64
      %int_1 = OpConstant %int 1
         %32 = OpSpecConstantOp %int ISub %subGroupSize %int_1
         %33 = OpSpecConstantOp %uint IAdd %32 %uint_0
%_runtimearr_uint_0 = OpTypeRuntimeArray %uint
     %OutBuf = OpTypeStruct %_runtimearr_uint_0
%_ptr_StorageBuffer_OutBuf = OpTypePointer StorageBuffer %OutBuf
        %__0 = OpVariable %_ptr_StorageBuffer_OutBuf StorageBuffer
         %45 = OpSpecConstant %uint 1
     %uint_1 = OpConstant %uint 1
%gl_WorkGroupSize = OpSpecConstantComposite %v3uint %45 %uint_1 %uint_1
       %main = OpFunction %void None %3
          %5 = OpLabel
          %v = OpVariable %_ptr_Function_uint Function
      %total = OpVariable %_ptr_Function_uint Function
         %20 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
         %21 = OpLoad %uint %20
         %23 = OpAccessChain %_ptr_StorageBuffer_uint %_ %int_0 %21
         %24 = OpLoad %uint %23
               OpStore %v %24
         %26 = OpLoad %uint %v
         %28 = OpGroupNonUniformIAdd %uint %uint_3 InclusiveScan %26
               OpStore %total %28
         %29 = OpLoad %uint %total
         %34 = OpGroupNonUniformBroadcast %uint %uint_3 %29 %33
         %35 = OpLoad %uint %total
         %36 = OpIAdd %uint %35 %34
               OpStore %total %36
         %41 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
         %42 = OpLoad %uint %41
         %43 = OpLoad %uint %total
         %44 = OpAccessChain %_ptr_StorageBuffer_uint %__0 %int_0 %42
               OpStore %44 %43
               OpReturn
               OpFunctionEnd

I am going to close this. If you don't see a similar result with the latest glslang, please comment and I will re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants