-
Notifications
You must be signed in to change notification settings - Fork 303
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
Handling Errors Synchronously #2478
Comments
The browsers can (and likely will) provide a mode in which all WebGPU errors are synchronous (and/or trigger a breakpoint). It sounds like it would address the core of your issue? |
I don't think we should do a mode where WebGPU errors are synchronous (as it would change the application's actual behavior, essentially creating a heisenbug). However I would really like to have a "break on error" option in our dev tools. But you have a lot more experience with WebGL debug tools so maybe you can poke holes in this idea and find out it's insufficient. (Or maybe you're interested in prototyping it? 😛 ) Here's where this is described (if very briefly): |
My personal experience so far is that the debugging experience in WebGPU is much more painful. WebGL has its troubles too, but it is part of my workflow to add |
A bunch of random thoughts
|
Let me also add, if I wanted that wrapper to be invisible I'd need to track error scopes so that I can return the errors I captured to their outer scopes. Not sure how much work that would be. |
A synchronous I think that the best solution is what @kainino0x described where there is a devtools checkbox that causes the devtools to break on WebGPU validation errors (or raise an exception or ...). This would be running the same validation code as the browser so it would be "perfect". In Chromium for example this could be done one of two ways:
Actually option 1) also gives a way to do this without browser support:
That WebGPU interceptor could even be tested by making it run the WebGPU CTS! |
I must be mis-understanding. This issue seems to be wanting to add a sync API and @kainino0x was arguing it should be on the main thread. |
On workers. @kainino0x is suggesting that we could also do it on the main thread but that seems completely against the guidelines for Web APIs. It is always possible to bypass that but it needs to be extremely carefully considered and could cause major standardization and implementation issues. |
I feel like no one has actually used the current WebGPU error reporting in a production app and I feel like if async error checking is so easy and trivial then Dawn should try using Vulkan/Metal/DX12 with nothing but async error reporting as proof that it's trivial and easy to implement graphics with nothing but async reporting. I think you'd find it's extremely non-trivial to use and that you'd give up and beg for sync error reporting. The spec is basically saying that Few if any of the trivial WebGPU samples up there check any errors. It would be good to get more feedback from devs doing production work where they feel they need to check errors and see what their feedback is |
I'm sorry if my last comment seemed aggressive. I just want to make sure that using the API in a robust way (checking for errors) makes sense. It makes sense to me that Just as an example, let's say you wanted to implement OpenGL on top of webgpu (for example use regal). Is it possible? How would you report out-of-memory synchronously to make that work? If you can't make it work does that suggest that maybe other apps will struggle here? What is this like using webgpu in C++ (native or wasm) land? |
The mapSync issue is somewhat different. I'm proposing allowing it (even on the main thread) not just because developers want it, but because developers inevitably will work around it by writing to a canvas and using synchronous canvas readback. Since the ugly solution already exists we're just giving people something that looks reasonable instead of a hack. (Though Corentin suggested to me this isn't a good reason, as if people use a hack they know they're using a hack, and if they use mapSync then it seems valid despite still being bad for users.) Fundamentally though, I'm sure it's true that developers would really benefit from actual synchronous errors and not just breakpoints. If that exists only when enabled via devtools, then I'm fine with it - just was weakly against it due to the heisenbug problem. My intuition is that popErrorScopeSync() is not the most convenient debugging tool though. Maybe a getError style thing (peekErrorScope?) that returns the error held by the current scope - so if you have
I'm not sure we really want to cater to that, but my first solution would be Emscripten's Asyncify (for OpenGL-on-WebGPU, not WebGL-on-WebGPU), and my second would be having the application run GL in a worker, which remotes everything to second worker that sends errors back with an Atomics.notify to the first worker to receive by Atomics.wait. |
This could be an extension exposed behind a flag in workers but that could still be briefly described in the extensions/ subdirectory you suggest adding @kainino0x. This way it is not part of the Web platform, but developers can expect all browsers to expose similarly when the command line flag is added. |
I want to make it clear I'm not saying async errors are not sufficient. I just want to verify that's the case. I also want to take a moment and ask that you please really consider how easy it would be to implement dawn or other GPU projects you may have worked on in the past if you couldn't check for errors synchronously. I think if you really do the thought experiment you might find it's difficult. I don't know all the use cases of babylon.js but in my limited understanding, most things made with it are relatively small? I think bigger projects (Photoshop, Google Maps, Figma, MapBox, ...) are probably more relevant to ask for input? Further, I want to emphasize that devs will want to check errors on users machines. Going with the experience that it's hard to get users to copy and paste info from As for using workers, my experience of WebGL is that workers aren't useful because they are only supported in Chrome. Neither Firefox nor Safari have shipped the required features to use WebGL from workers and even checking now, Firefox doesn't support webgpu in workers (Safari seems to have removed WebGPU at the moment so I can't check). I agree that being able to stop synchronously in the debugger will be great. I'm just not (yet) sure it's sufficient. Still, this isn't a V1 feature. If it turns out this is really needed then it can certainly be added later. |
I understand that WebGPU was designed to be 100% async and that includes errors but I'm curious, what's the recommended way to debug?
WebGL, for the most part, is also designed to be async. The only non-async parts are state queries (gl.getXXX) and readPixels. Given most apps don't call readPixels and except for uniform locations, many apps don't need to do any queries.
But, given the design, you can easily add synchronous error checking. Two examples are the Khronos debug context and webgl-lint. They both wrap the context and call
gl.getError
after each WebGL api call.The nice thing about these is almost no changes are needed to your code.
I can't see any way to do this effectively in WebGPU without either code-generators or really ugly code.
The issue is in order to be "synchronous like" you'd have to do
await
but you can'tawait
conditionally in an invisible wayIf you have code like this
IIUC the way to check for errors is this
But if you want the error synchronously then you need this
Ideally, to be as convenient as WebGL, you'd like to be able to wrap the WebGPU api where appropriate. For example
If you put
await
in the "check for error here" part that's not useful for the user. They need to changeto
You don't want the
await
there in production, only in development. Except of course if you need a user to help debug.To make it possible to switch at runtime with synchronous like checking on it seems like they'd have to do something like this
Now your code is littered with this debug code vs WebGL where it can all be invisible.
Why do you need synchronous debugging? Because with async debugging, although you know you got an error, even with a detailed error message, what you really want is to break in the code exactly where the error occurred. That way you can inspect the state of your program. Check the stack, check your data structures, etc and see why your inputs were wrong. With async debugging, at the time you get the error it's too late to check your stack and state, it's long gone.
Is there a suggested solution here? I guess maybe you could re-implement WebGPU in JavaScript, parse the shaders in JavaScript to extract the inputs and outputs, and then validate all the inputs, outputs, bindings etc synchronously as one, possible solution.
That still probably wouldn't catch all errors synchronously. For example out-of-memory.
The text was updated successfully, but these errors were encountered: