这是indexloc提供的服务,不要输入任何密码
Skip to content

Annotation for the uniformity analysis #2323

@Kangz

Description

@Kangz

#2321 adds an orthogonal type system for uniformity in addition to the regular type system that describes the shape of manipulated values. That type system is completely implicit and done as a whole-program analysis. This makes it somewhat hard for developers to reason about it because changes on a leaf function could cause type violation in functions higher in the callgraph.

The analysis provides some way to produce good errors messages but they will be at the function level (unless we keep the whole uniformity implication graph in memory) and could be really long as they don't stop at function boundary. It is also hard for developers to know at a glance what uniformity guarantees a function requires.

That's why I suggest that we have optional type annotations in WGSL that declare that a given variable must be uniform, or a function must be called in uniform control flow. This way developers can annotate the expectations of their code, which will be checked by the compiler. I'm not attached to the particular syntax but here's an example of what it could look like:

@uniform fn myFunction() {}

if (nonUniformBool) {
    // Compilation error: "myFunction is called in non-uniform control flow".
    myFunction();
}
fn myFunction(b: @uniform bool) {}

// Compilation error: "myFunction parameter is called with a non-uniform `b`"
myFunction(nonUniformBool);

In addition to letting developers spell out the contract of their functions better, it allows them to write compile time assertions of their understanding of uniformity:

@uniform fn assertUniformControlFlow() {}
fn assertUniformU32(v: @uniform u32) {}

It also allows specifying the uniformity constraints of builtins independently of the uniformity analysis. Some examples:

@uniform dpdx(e:T) -> T
@uniform textureSample(t: @uniform texture_2d<f32>, s: sampler, coords: vec2<f32>) -> vec4<f32>
@uniform workgroupBarrier()
workgroup_id : @uniform u32

Finally I think we should differentiate between various kinds of uniformity:

  • Completely uniform values for a draw / dispatch: things that depend only on constants / uniform buffer values.
  • Workgroup uniform values.
  • Subgroup uniform values (when we have that extension)
  • Quad uniform values (without quad ops it's the same as completely uniform for a draw, but would come with an extension)
  • Maybe (but I'm not sure at all) compile-time / override-uniform. This means we can express that the offset of textureSample must be a constexpr.

This could be done by having the attribute @uniform default to a different uniformity value depending on the shader stage (VS: full uniform, FS: quad uniform, CS: workgroup uniform), then also have a way for users to specify the exact uniformity. uniform(complete/workgroup/subgroup/quad/none).

Metadata

Metadata

Assignees

No one assigned

    Labels

    wgslWebGPU Shading Language Issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions