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

Supporting JS/webgpu as a backend for e.g. PyScript #407

Open
almarklein opened this issue Nov 6, 2023 · 8 comments
Open

Supporting JS/webgpu as a backend for e.g. PyScript #407

almarklein opened this issue Nov 6, 2023 · 8 comments

Comments

@almarklein
Copy link
Member

almarklein commented Nov 6, 2023

With PyScript most of wgpu should be runnable in a browser. If we can translate out API to WebGPU calls, people can use WebGPU via Python in a browser, which seems like a pretty big thing!

Since we follow the WebGPU IDL spec quite closely, this should not be that hard, though there are some cases to take into account.

I briefly looked into this. Some hurdles to take are:

  • We must provide a wheel that pyscript can load. This must either be a none-any.whl or a wasm32.whl. Even though we don't have any wasm in it, having none-any.whl can accidentally be installed on a desktop and we don't want that.
  • Code must be async, since there is no way to synchronously wait for a Future in js, we cannot implement our sync version of the async method. I find this the scariest hurdle. (I hope I'm overlooking something that still allows us to do that.)
  • We must provide a jswebgpu backend. Can partially autogenerate this. I don't expect this to be the hardest part.
  • We must provide a jscanvas gui backend if we want to render stuff.

Sub-goals to achieve:

  • Support importing wgpu and displaying the version numer.
  • Perform compute tasks.
  • Perform rendering tasks.
  • Now it should be possible to just run pygfx examples.
@almarklein almarklein changed the title Supporting JS / PyScript as a backend Supporting JS/webgpu as a backend for e.g. PyScrip Nov 9, 2023
@almarklein almarklein changed the title Supporting JS/webgpu as a backend for e.g. PyScrip Supporting JS/webgpu as a backend for e.g. PyScript Nov 9, 2023
@almarklein
Copy link
Member Author

I briefly played with PyScipt and webgpu yesterday, and have some more insights into what's needed. Added notes in the top post.

@Korijn
Copy link
Collaborator

Korijn commented Nov 9, 2023

We could consider creating a none-any wheel that packs all the binaries for all platforms... But it seems like a big concession

@almarklein
Copy link
Member Author

I wonder if we can create wgpu0.12.0-py3-none-wasm32.whl, so targeted for wasm, but no specific python or emscripten version 🤔

@willemkokke
Copy link

Hi Almar.

I'm interested in contributing towards making wgpu-py usable inside pyodide. (which I think would make it work inside PyScript too)

I have to start somewhere, so decided to look into this question first.

Looking at the source code for micropip, it uses packaging.tags.sys_tags() to match against the allowed wheel names.

Running that in the pyodide repl at https://pyodide.org/en/stable/console.html gives me:

>>> import packaging.tags
>>> for t in packaging.tags.sys_tags():
...     print(t)
... 
cp311-cp311-emscripten_3_1_45_wasm32
cp311-abi3-emscripten_3_1_45_wasm32
cp311-none-emscripten_3_1_45_wasm32
cp310-abi3-emscripten_3_1_45_wasm32
cp39-abi3-emscripten_3_1_45_wasm32
cp38-abi3-emscripten_3_1_45_wasm32
cp37-abi3-emscripten_3_1_45_wasm32
cp36-abi3-emscripten_3_1_45_wasm32
cp35-abi3-emscripten_3_1_45_wasm32
cp34-abi3-emscripten_3_1_45_wasm32
cp33-abi3-emscripten_3_1_45_wasm32
cp32-abi3-emscripten_3_1_45_wasm32
py311-none-emscripten_3_1_45_wasm32
py3-none-emscripten_3_1_45_wasm32
py310-none-emscripten_3_1_45_wasm32
py39-none-emscripten_3_1_45_wasm32
py38-none-emscripten_3_1_45_wasm32
py37-none-emscripten_3_1_45_wasm32
py36-none-emscripten_3_1_45_wasm32
py35-none-emscripten_3_1_45_wasm32
py34-none-emscripten_3_1_45_wasm32
py33-none-emscripten_3_1_45_wasm32
py32-none-emscripten_3_1_45_wasm32
py31-none-emscripten_3_1_45_wasm32
py30-none-emscripten_3_1_45_wasm32
cp311-none-any
py311-none-any
py3-none-any
py310-none-any
py39-none-any
py38-none-any
py37-none-any
py36-none-any
py35-none-any
py34-none-any
py33-none-any
py32-none-any
py31-none-any
py30-none-any

The emscripten_3_1_45_wasm32 platform tags makes sense as https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#basic-platform-tags defines that it is the result of sysconfig.get_platform() with - and . replaced with _.

According to https://github.com/pypi/warehouse/blob/c6c4033477feca74aee226d9f3b27f445d1aa964/warehouse/forklift/legacy.py#L107PyPi only allows platform tags for windows, linux, macOS, or any

This means that if you want to have the wheel installable with micropip inside pyodide from PyPi, the most specific you can get is cp311-none-any

This would still do the right thing in nearly all occasions, as it would prefer the more specific platform tag if available. The only gotcha is that cp311-none-any would be preferred over building from source if a specific match isn't available. I'm not sure that is a big issue though.

Until there is official platform support for emscripten/wasm as a platform in PyPi, the only other option completely in your hands is building the wheel for emscripten in CI per release, and tell people to host it themselves or use a GitHub release url as the source to micro pip from. Also a very acceptable option in my opinion.

I would not be surprised if the pyodide team would be happy enough to include it as part of their distribution when mature enough as it should be a very small python only wheel. They have a lot of infrastructure for this sort of thing already.

@willemkokke
Copy link

For the async issue: Can we not implement the sync versions by calling the async javascript function, and immediately awaiting in using pyodide's javascript interop/marshalling?

I haven't made my way through the entire spec yet, but I haven't come across anything that requires an action to happen in between an async method being called and it being resolved.

@willemkokke
Copy link

Implementing the js canvas should be pretty trivial using https://pyodide.org/en/stable/usage/api/js-api.html#js-api-pyodide-canvas

@Mortezanavidi
Copy link

any progression on this?

@almarklein
Copy link
Member Author

From our end this does not have priority. Although in the process of stabilizing/finalizing the API, we are also thinking about #391, which is (oddly enough) a crucial part to enable the path to the browser.

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

4 participants