wgpu-py: How not to panic

I’ve asked a very similar question before — here gfx-rs/naga#108 . This is rightfully closed: error messages are vastly better than they were a year ago. However, stepping back a bit, I see the wgpu still happily delivers these messages while issuing a Rust-level panic — that is, printing something and swiftly killing the whole process.

Has this become the long term plan? or is there a way to recover from these panics? is the intention that our wgpu-py renderers are separate, easily re-initializable disposable processes? Is this what triangle_subprocess.py is aiming towards? Is wgpu[-py] for cattle rather than pets?

I’m asking this question here and not upstream because, while this behavior very Rust, it’s really not very Python at all — imagine writing wgpu-py from the REPL, or live-coding something built on wgpu-py from Jupyter kernel etc. Now that we have a WSL — a shader language that we can pass along to wgpu as strings (without recourse to an external shader compiler) — we dare not really use it dynamically, because a typo in a shader quits our process with:

Failed to parse WGSL code for Some(""): unknown type: `vec`
thread '<unnamed>' panicked at 'Parsing', src/device.rs:112:5

It speaks to what long-term applications of wgpu-py apps that are viable inside the python ecosystem. And it’s also completely different set of rules from, say both OpenGL and WebGL — which are perfectly recoverable from an error state.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 26 (12 by maintainers)

Most upvoted comments

Getting back to the original issue. The current situation is as follows:

  • wgpy-native has a mechanism to communicate errors via the C API.
  • In wgpu-py we make use of it, and raise Python errors (at the appropriate C call) in most cases, and log the error otherwise.
  • In wgpu-core, most errors now get communicated via this route.
  • There may be Rust panics in some specific cases (e.g. syntax errors in GLSL), but they will most certainly be communicated via the same mechanism eventually.

I think that’s enough to close this issue.

The wgpu-native just received a fix (https://github.com/gfx-rs/wgpu-native/pull/313) that makes errors in GLSL also result in nice exceptions (in wgpu-py) instead of a panic. That’s one part of the problem gone.

for now I am using a janky solution that works to convince my supervisors.

with tempfile.NamedTemporaryFile(suffix=".frag", mode="w") as f:
    f.write(frag_shader_code)
    f.flush()
    try:
        subprocess.run(["naga", f.name], check=True, capture_output=True)
    except subprocess.CalledProcessError as e:
        raise e

it’s pasted about here: https://github.com/pygfx/wgpu-py/blob/2ffacd933d60423537826919c3ac6a950188919c/wgpu/utils/shadertoy.py#L316 perhaps there is a better solution eventually, but it bypasses the panic for me

One more idea for a workaround is to run python in a subprocess with sys.executable, to see if some code will panic or not. You can avoid the dependency on the naga binary that way.

I bypass it now by not just using naga file.frag but naga file.frag file.spv since this translation does panic and hence throw an exception I can work with. However this doesn’t make semantic sense in my implementation as I label those as ‘code_error’. But that’s all on me and trivial to solve.

If you manage to minimize the shader code to expose the place where the error originates, it might be worth reporting this at the Naga repo.

I will open an issue on naga as it’s clearly not intended to have validation be successful and then translation panic. While looking a bit deeper I found one or two open issues that mention a similar error message.

If you manage to minimize the shader code to expose the place where the error originates, it might be worth reporting this at the Naga repo.

I played around a bit with a few shaders, and I think that errors in shaders written in WGSL result in Python exceptions, whereas errors in GLSL result in a panic. This is unfortunate, but there is not much we can do here. It’s simply that they’ve not made this work correctly yet for GLSL. I presume that WGSL support is of higher priority to the Naga devs than GLSL, but I expect things it will be fixed eventually.

You could check the repo to see if there is an issue that already tracks this, and create one if not. (If you know a bit of Rust you might be able to help implement it.)

To chime in here, “incorrect shaders” (including syntactical and semantic typos which could be caught by some SPIRV-ish toolchain, but also incorrect and mismatched layouts of buffers where the shader is correct in and of itself but wrong in context) is an extremely common condition in any creative coding applications. My shaders are likely “correct” in a professional sense only at some unspecified point before the audience walks into the hall; at my desk they spend more time being incorrect than not.

Taking into account that it’s the holiday season my guess would be that we start working on 5-7 weeks from now. Nothing has been done yet, so no dev branch to check.

I’ve asked upstream to get some more info: https://github.com/gfx-rs/wgpu-native/issues/113