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

bound variables in packages #4905

Open
mighdoll opened this issue Sep 28, 2024 · 8 comments
Open

bound variables in packages #4905

mighdoll opened this issue Sep 28, 2024 · 8 comments
Labels
wgsl WebGPU Shading Language Issues
Milestone

Comments

@mighdoll
Copy link

For WGSL in an npm/cargo package, static group and binding indices aren't a good idea. The indices need to be chosen by the application (preferably the application host code), not a library.

For example, it'd be a bad idea for a package to hard code the group and binding indices like this:

@group(0) @binding(1) var<storage, read> src: array<f32>;         

One approach is to give the indices symbolic names:

@group(FooGroup) @binding(FooBinding) var<storage, read> src: array<f32>;         

And then potentially use override to rewrite the binding indices. @dj2 noted this idea too. There are some issues to work through with override though. For example apps need to be be able to rewrite any default override value set in the package, which would be a change to override semantics. Another issue is that is that unused and unset overrides must be removed from packages, lest shader compilation fail. I think these issues are solvable.

Alternately to override, we could allow managing the symbolic index names through some other new mechanism. @ncthbrt and @k2d222 have been exploring some schemes for parameterizing with generics on modules that could be extended to cover these symbolic indices too.

Another idea is to create a new syntax that doesn't tempt the programmer to use indices at all in WGSL, but instead requires the programmer to set the indices in host code. Given that the indices need to be shared between host code (for binding layouts) and WGSL anyway, and that the host code is in a better position to know how to organize layouts across multiple shaders, perhaps something like the following would bias the programmer to do the right thing in both apps and packages:

@publicBinding var<storage, read> src: array<f32>; 

This WESL issue has some further discussion. (WESL is a project to add community extensions to WGSL via transpiling)

@mighdoll mighdoll added the wgsl WebGPU Shading Language Issues label Sep 28, 2024
@dj2
Copy link
Member

dj2 commented Sep 28, 2024

Apps are able to override any override value in the shader, that's what they're for, so they can be set from the application side. I'm not sure what you mean, or do you mean you want the app to change the default, and to somehow also override the default?

Unused and unset overrides are only needed if they're statically used by the program, if they aren't used they should be fine.

@mighdoll
Copy link
Author

Apps are able to override any override value in the shader, that's what they're for, so they can be set from the application side. I'm not sure what you mean, or do you mean you want the app to change the default, and to somehow also override the default?

Yeah, I wrote that unclearly. I'm distinguishing between host code (e.g. in JavaScript), app code in WGSL, and package code in WGSL. Let's call it root code rather than app code. And of course, the assumption is that there's some way for WGSL root and package code to bring in code from other packages, like an import statement.

So if root WGSL code imports package WGSL containing override fooBinding = 7;, the root WGSL should be empowered to change the 7 to a 9 without relying on host code. That's for encapsulation, root WGSL controls the host api, not some package. So after the app WGSL says import pkg/fooBinding;, something else new like allowing fooBinding = 9; at the root level will be called for. That's what I meant by changing the semantic of override. It's solvable, and probably we need to come up with something anyway for overrides in packages irrespective of whether overrides are allowed for binding/group indices.

But what do you think of the argument that binding/group indices are best set in host code? I think that's the case but I'm not sure. That road might lead to something like @publicBinding (with @binding and @group still available but not recommended).

@dj2
Copy link
Member

dj2 commented Oct 10, 2024

You don't need publicBinding to set them in JS code, we'd just need to make them able to take an override and then you could override from the JS.

@mighdoll
Copy link
Author

Yes, override for bindings can make libraries possible. My question is whether that's the style we should encourage for WGSL libraries or even WGSL applications going forward.

If we encourage WGSL library programmers to use @binding, we need to explain to them that they should never give a constant parameter to @binding, always create an override, but never give a default value for the override. Basically binding numbers should never be written in library WGSL even though @binding syntax makes it tempting.

I'm not arguing that publicBinding is the best alternative, but I hope it illustrates that alternatives are feasible that don't tempt users into putting binding numbers in WGSL.

And wouldn't it anyway be better to encourage future WGSL application writers (not just library writers) to control any bindings from the WebGPU application code (e.g. TypeScript)? If that were possible, I argue that would be the best practice to encourage.

(Also if we do encourage override for @binding, there's the issue of enabling application root WGSL to change library WGSL overrides. That's a separable issue that I've only sketched above, but it's moot for @binding if we discourage @binding anyway.)

@dj2
Copy link
Member

dj2 commented Oct 10, 2024

Library authors can do as they wish, if they want to use a constant value, they can. If they wanted to use an override, they can do that as well. How they write their WGSL is up to them.

I don't understand the overriding part, WGSL doesn't have imports, so that isn't an issue for WGSL, and even if it did, you can just leave the override and have the user set it from JS.

@mighdoll
Copy link
Author

mighdoll commented Oct 11, 2024

I don't understand the overriding part, WGSL doesn't have imports,

Right, to enable libraries today, we'll extend WGSL with a community transpiler that support imports. Hopefully WGSL libraries will become widely supported either through built in features or std tooling.

Library authors can do as they wish, if they want to use a constant value, they can. If they wanted to use an override, they can do that as well. How they write their WGSL is up to them.

And if the question is what are the fewest changes WGSL needs to make for libraries, nothing is urgent here. WGSL and WebGPU is an amazing achievement and we can use it as a transpilation target without any change.

But you all have been on such a long road to get to 1.0! Isn't it a little tempting to start thinking about improved ergonomics for future versions of WGSL? It's in that context that I'm raising the issue. Maybe too soon? Apologies if so.

@mighdoll
Copy link
Author

Apologies for being a little cheeky with that last comment. What I meant to suggest is that there are three frames to address a problem like this one about making WGSL friendlier for libraries.

  1. Since libraries aren't much use w/o a way to package and import WGSL, do nothing.
  2. Look for minimal changes to WGSL so that library code can be mostly legal WGSL, even if some things (e.g. a module system) are handled by community tools for now.
  3. As WGSL looks toward adding more ergonomics post 1.0, look for ways to evolve WGSL to a more library friendly language.

I'm arguing for the third and wider approach. Let's look for the most ergonomic way to enable libraries, even if it might be a bigger change and slower to land. We can polyfill with community tooling in the interim.

I argue that enabling a library ecosystem is important enough that it justifies considering non-minimal changes. So I'm trying to tempt you into the wider frame of possibilities. Who better to help think about the problem? After all, no one has thought more about the ergonomics of web shader languages than you.

@dneto0
Copy link
Contributor

dneto0 commented Oct 29, 2024

Placing this in Milestone 2, with other issues for WGSL for programming-in-the large.

@dneto0 dneto0 added this to the Milestone 2 milestone Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wgsl WebGPU Shading Language Issues
Projects
None yet
Development

No branches or pull requests

3 participants