You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Let developers statically assert uniformity of control flow and expressions. #6955
In #5582 the group decided to add an optional diagnostic for the uniformity of accesses in the resource table. While this could be useful, developers want to know at compile time what the result of the uniformity analysis is: they would make sure to take the uniform indexing fast path instead of automatically falling back to slower non-uniform indexing.
There's probably a way with diagnostic control to produce errors when a resource table access is non-uniform, but it's awkward and limited in its use:
A nice thing: a uniformity assert can be placed close to the creation of the value. This lets you tame/manage the action-at-a-distance nature of the problem. A single badly analyzed value can poison a bunch of different uses of that value; it's best to catch it at the root.
changed the title [-]Let developers statically assert uniformity of CF and expressions.[/-][+]Let developers statically assert uniformity of control flow and expressions.[/+]on Sep 15, 2026
AB: Put up a proposal PR which should be linked. Add a proposal for uniformity assertions #10959. Talked internally and feels like the most ergonomic way would be a builtin function which returns the value of the param given, can use directly inline and easy to wireup in uniformity that it requires the param to be in uniform control flow and a uniform value. Proposed separating the scopes so to use subgroups you must have subgroup-uniformity. Open question if we want it more like the subgroup matrix load and store where that is encoded as a template param. Would need a new enum value for that and not sure what we'd used for the larger size. Could wait for Enums and use those as params and make them const qualified but then mixes decisions between features. Could assert at either level of uniformity and can use directly line. Some examples of how that might be useful in the code. Think it would be simple to integrate into the analysis. Seemed nicer then as an attribute and, unfortunately the statement route doesn't work as we have no reserved words. We have const_assert but we dont' have uniform_assert reserved or uniform reserved, so can't make a new statement type.
JB: Really like the function form. Examples read really nicely. Thought hte let cond = a || assert_uniform(b) is really cool. If a is really uniform then control flow is uniform and if a is not uniform then it is not in the second thing. Nice illustration.
JB: One question, seems that hte paragraph explaining "trigging a uniform diagnostic …" those two things are paird but you can have uniform values in non-uniform control flow, right? And you can have non-uniform values in uniform control flow. So really control-flow and value uniformity are independent. Reason they need to be fused?
AB: Tried to make separate sentences so you'd trigger on either condition
JB: Sentence makes sense, but would users ever say "I dont' care about control flow but is this value uniform" or is that not useful?
AB: Uncertain. It would be easy to add overloads that dis-ambiguate that but not sure if it would be useful or not.
JB: If i say assert_Uniform(1) then current gives control-flow only. But missing is "is this value uniform regardless of control flow"
AB: What's the use case?
JB: Dont' know.
AB: Couldn't think of where it mattered. Maybe you could make ti matter in the bindless resource access. Really there it's that it's uniform relative to the thing, so maybe worth splitting out. Then don't know if we want combined or how many versions we'd like.
DS: Could we leave that bit out?
AB: If we wanted another language feature, probably easier to do now.
LM: How does uniformity propagate through functions. If you have one of these in fn a and call that function …
JB: THat's the question I just asked on the issue. Turns out uniformity handles this as each function is annotated saying which params have to be uniform and these params hows uniformity or lack of contaminates the return value. The functioning ets generic. If any of these params could be non-uniform then my return might be non-uniform and then each call site is inspected
LM: So, contagious, but invisible to authors of outer functions.
AB: Yea.
LM: Raises the question, would we want to make it visible?
JB: Thats what this probably is doing. YOu can say I expect this to be uniform and if not let me know.
LM: So the user that writes the outer function that calls the other function with a uniform value they would be expected to also write the assertion?
AB: Not sure I followed
LM: Function foo has one of these assertions. Bar calls foo and passes something which needs to be uniform because foo requires it. With a type system you want to allow the user to clarify what they need, in bar in this case. Bar takes a param,maybe that param needs to be uniform.
JB: We infer all of this but it's up to the shader translator to create diagnostics to explain where the requirement arose. So might have something saying 'this param needs to be uniform because the callee has a callee that does something' and it's up to the diagnostics. This is already in the spec which says how you process and attach uniformity tags to establish these rules.
LM: Wondering if an alternative spelling, or alternative syntax would be interesting where we tag the type or the function, so that all of this becomes explicit to the user vs being implicitly analysed and reported when failed.
JB: If the user calls the assert_uniform function that is an annotation that they are annotating what they expected. True the function/params do not have any markers.
LM: Right, ultimately saying this variable has to be uniform, sort of like saying has to be f32 or u32. and we'll make sure when you call that function that hte type is u32 and bar is a u32. It's clear all the way up.
JB: Because the developer is required to write on the type or it won't type check.
LM: Even if we infer the type, wgsl analyser will tell you. Can imagine doing that here too, where you say index is a type of a thing that has to be uniform. Rather then saying function style attach to the type
DS: That sounds like a separate proposal. The assertUniform is useful for your own code, and then type annotations would be for callers to understand a function’s requirements. It sounds like a reasonable idea, but it seems like an independent feature.
LM: The assertUniform function seems to me to be making an assertion about the type of its argument.
AB: We say "currently triggers a diagnostic if this must be uniform" is it clear or not if we put an attribute @uniform who's reading which things and what is clearer and how much are you reading to write the code.
LM: Don't know if that's better but seems roughly analogous and might make it visible in this outer caller case. Then this analysis could be part of the explicit contract that users see instead of the implicit one that everyone except the inner function can't see and have to try and find out.
AB: Think the ship is sailed on a different type, woudldn't' want to go that far. Maybe it helps for contex,t when Tint issues a diagnostic it will trace through and show because of this, because of this. So, having as close as possible to where it's needed, then the implementation tells you exactly where necessary. Maybe you make a small change and have to update your interface but having closer the tooling will track and you can document in your interface. If you separate from use you could accidentally add a discrepancy.
JB: THink folks read on signature to determine the contract between callee and caller. Lets assume not changing the types, or using separate types. But certainly have optional annotations on certain values where if they're absent then everything works as now but when present that becomes a point at which diagnostics can be issues. But I think generally true that if developers need to know a functions uniformity requirements in order to use that function then it's valuable to have information about hte uniformity in the signature. At the least can issue error messages earlier. Oh the declaration of this function asserts that this param doesn't need to be uniform but in fact hte body contradicts that. That would be valuable, but think ds is right that this is a separate feature that could be used with or without assert_uniform
LM: You looked at @uniofrm already ?
AB: If i was doing an attribute i'd limit it to function declaration, function param, function return instead of it can go anywhere. Don't want to have to start looking for annotations at any expression level which is why builtin makes sense. Interface wise there are a limited number of places, but have slightly different meanings. On a function must be in uniform control flow, on a value that the value is uniform, on return, that it must be uniform return
LM: THink that's a good explanation for what I was wondering about. Would you rather @Attribute on the function and on the param rather then a function call inside.
AB: Wasn't really thinking about libraries. When I think of diagnostics we will be able to tell you what exact part you're failing. Can see there might be value in self documenting and you could go either way. Could be simple to add to the proposal, already accept attributes in those locations. Could cleanup the spec, instead of saying these statements and functions could add attributes to the overloads like workgroup barrier.
JB: Would give the spec authors a way to say how builtins take uniformity. Would give a formalism to make it explicit.
AB: Think it would be better in this proposal then a separate one. Better to touch this code fewer times.
JB: Implementation seems simple given the analysis we already do. We check what was inferred against what the attributes promised then those are errors.
AB: Yes. Say on a param, I would add the param tag automatically. Might be that it would not otherwise be necessary but up to you. Could see us issuing a warning, don't have to say this is uniform as it isn't' required. But would leave that up to implementations.
JB: Exactly a way for people to say what tags they want on those params. Seems like it would connect nicely.
AB: Would have to think about return value. Almost like all return statements are uniform. I'm promising this return should be uniform, but slightly different. I think it coudl be added to this proposal with low effort. Can make as a question and question if we want to separate control flow from value for these functions.
Activity
dneto0 commentedon Aug 31, 2026
I marked this as Milestone 2 to match #5582
dneto0 commentedon Aug 31, 2026
A nice thing: a uniformity assert can be placed close to the creation of the value. This lets you tame/manage the action-at-a-distance nature of the problem. A single badly analyzed value can poison a bunch of different uses of that value; it's best to catch it at the root.
[-]Let developers statically assert uniformity of CF and expressions.[/-][+]Let developers statically assert uniformity of control flow and expressions.[/+]jimblandy commentedon Sep 22, 2026
What happens if I write:
Would this give
xa parameter tag ofParameterRequiredToBeUniform? I guess that works exactly as intended.jimblandy commentedon Oct 26, 2026
minutes from WGSL committee meeting 2026-9-22
@uniformwho's reading which things and what is clearer and how much are you reading to write the code.Add a proposal for uniformity assertions (#10959)