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

First class async support #391

Open
almarklein opened this issue Oct 23, 2023 · 2 comments
Open

First class async support #391

almarklein opened this issue Oct 23, 2023 · 2 comments

Comments

@almarklein
Copy link
Member

almarklein commented Oct 23, 2023

Introduction

WebGPU defines certain functions and props as async, so that in an async setting, there is less wait time. Would make a lot of sense to also support that in wgpu-py.

Would be great if we can make this work without forcing asyncio, but also supporting e.g. trio.

At the moment the async API of wgpu-native is a bit crude (there is a function to poll its loop). Last I heard was that this API will change at some point. So might be worth waiting for that.

In our code, all async methods have an _async suffix, and they all have a sync version of the function (that simply waits).

Aync parts in WebGPU spec

Updated on 25-09-2024

Methods that are async-only in WebGPU:

  • gpu.request_adapter_async()
  • gpu.enumerate_adapters_async()
  • adapter.request_device_async()
  • buffer.map_async()
  • device.lost_async
  • shadermodule.get_compilation_info_async()
  • queue.on_submitted_work_done_async()

Method that have both a sync and async variant:

  • create_compute_pipeline()
  • create_render_pipeline()

Considerations

  • Would be nice to be able to use the API synchronously, e.g. make a script that does compute.
  • wgpu (and derived code) should work well in an interactive session.
  • Also support e.g. Trio.
  • Not all GUI event loops support async/await, e.g. Qt.
  • For WebGPU: no way to make the async functions synchronous (I think).
  • How much is performance afected by using sync versions of createRenderPipelineAsync and mapAsync?
  • Maybe prefix the sync variants with _sync to indicate that an async variant is available?

Thoughts

I think I'd like to try making wgpu-py async according to the spec, dropping the sync versions. Let's see how far we can take that. In render engines, one could run "draw iteration" on asyncio, if necessary with loop.run_until_complete(). Also when inside Qt.

If we can make that work, we're more compliant, avoid busy waiting in user code, and remove the biggest hurlde to move to the browser.

Async in wgpu-native

01-10-2024

At the time of writing, this is still somewhat in flux.

References:

State:

@Korijn
Copy link
Collaborator

Korijn commented Oct 27, 2023

Clarification: Right now we've implemented all async functions with polling, in a blocking fashion.

It still needs to be investigated if the API exposed by wgpu-native enables a true async implementation in wgpu-py.

@almarklein
Copy link
Member Author

Proposed approach

  • In wgpu-py support both the sync and async flavor. Use _sync and _async suffixes for clarity.
  • In pygfx require the animate() function to be a co-routine, so we can use the async variant all the way.
  • Maybe also allow sync version if creating a sync and async path is viable and worth the effort.
  • In event-loops that don't support async/await, like wx and (older) Qt, the _draw_frame_and_present() method can use loop.run_until_complete(). This is the trickiest part of this proposal (e.g. what happens if the user schedules new asyncio tasks).

We should probably just try and see how far we get.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants