Skip to content

Commit

Permalink
add back codegen stage (#3)
Browse files Browse the repository at this point in the history
* add back codegen stage
  • Loading branch information
mikedh authored Jan 15, 2024
1 parent f78829b commit cbc94a1
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 10,749 deletions.
35 changes: 30 additions & 5 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,50 @@ on:
pull_request: {}

jobs:
codegen:
name: Run Codegen
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install Ruff
run: |
python -m pip install cffi ruff
- name: Run Codegen
run: |
python codegen/fetch_wgpu_bins.py
bun codegen/generate.ts
- uses: actions/upload-artifact@v3
with:
name: codegen-${{ github.run_id }}-${{ github.run_number }}
path: ./webgoo/*.py

build_wheels:
name: Build wheels on ${{ matrix.os }}
needs: codegen
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]

os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Download binaries
run: |
python -m pip install ruff requests
python codegen/fetch_wgpu_bins.py
- uses: actions/download-artifact@v3
with:
name: codegen-${{ github.run_id }}-${{ github.run_number }}
path: webgoo/
- name: Build Wheels
run: |
python -m pip install cibuildwheel==2.16.2
python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl
57 changes: 47 additions & 10 deletions codegen/fetch_wgpu_bins.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,55 @@
import os
import hashlib
import shutil
import zipfile
from platform import uname

import requests


def download_file(url, local_path):
resp = requests.get(url)
if resp.status_code == 404:
from typing import Optional
from urllib.request import urlopen


def fetch(url: str, sha256: Optional[str] = None) -> bytes:
"""
A simple standard-library only "fetch remote URL" function.
Parameters
------------
url
Location of remote resource.
sha256
The SHA256 hash of the resource once retrieved,
will raise a `ValueError` if the hash doesn't match.
Returns
-------------
data
Retrieved data.
"""
data = urlopen(url).read()

if sha256 is not None:
hashed = hashlib.sha256(data).hexdigest()
if hashed != sha256:
raise ValueError("sha256 hash does not match!")

return data


def download_file(url: str, local_path: str) -> None:
"""
Download a remote file and write it to the local file system.
Parameters
------------
url
URL to download.
local_path
File location to write retrieved data.
"""
response = fetch(url)
if len(response) == 0:
raise Exception(f"404: {url}")
with open(local_path, "wb") as f:
f.write(resp.content)
print(f"Downloaded {os.path.getsize(local_path)} bytes -> {local_path}")
f.write(response)
print(f"Downloaded {len(response)} bytes -> {local_path}")


class Lib:
Expand Down
16 changes: 9 additions & 7 deletions codegen/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class CFlags implements CType {

return `
class ${this.pyName}:
def __init__(self, flags: ${pyUnion(`list[${etypename}]`, `int`, ftq)}):
def __init__(self, flags: ${pyUnion(`List[${etypename}]`, `int`, ftq)}):
if isinstance(flags, list):
self.value = sum(set(flags))
else:
Expand Down Expand Up @@ -588,7 +588,7 @@ class ApiInfo {
// assume this is a (count, ptr) combo
const wrapperName = this.getListWrapper(next.ctype);
const lname = quoted(wrapperName);
const maybeList = pyUnion(lname, `list[${next.ctype.pyName}]`);
const maybeList = pyUnion(lname, `List[${next.ctype.pyName}]`);
pyArgs.push(`${next.name}: ${maybeList}`);
staging.push(`if isinstance(${next.name}, list):`);
staging.push(` ${next.name}_staged = ${wrapperName}(${next.name})`);
Expand Down Expand Up @@ -697,7 +697,7 @@ class ArrayField implements CStructField {
}

argType(): string {
return pyUnion(this.listType(), `list[${quoted(this.ctype.pyName)}]`);
return pyUnion(this.listType(), `List[${quoted(this.ctype.pyName)}]`);
}

arg(): string {
Expand Down Expand Up @@ -1121,7 +1121,7 @@ class ListWrapper implements Emittable {
emit(): string {
return `
class ${listName(this.ctype.pyName)}:
def __init__(self, items: list[${this.ctype.pyAnnotation(false, false)}]):
def __init__(self, items: List[${this.ctype.pyAnnotation(false, false)}]):
self._count = len(items)
self._ptr = _ffi_new('${this.ctype.cName}[]', self._count)
for idx, item in enumerate(items):
Expand Down Expand Up @@ -1320,15 +1320,17 @@ if __name__ == "__main__":
# todo : this is platform specific, we should check the extension of path_compiled
if sys.platform.startswith("linux"):
subprocess.check_call(['patchelf', "--set-rpath", "$ORIGIN", path_compiled], cwd=cwd)
elif sys.platform.startswith("darwin"):
# on mac change the @rpath to a @loader_path
subprocess.check_call(['install_name_tool', "-change", "@rpath/libwgpu_native.dylib", "@loader_path/libwgpu_native.dylib", path_compiled], cwd=cwd)
`;

const pylibOutput = `# AUTOGENERATED
from abc import ABC, abstractmethod
from collections.abc import Callable
from enum import IntEnum
from typing import Any, Iterator, Optional, Union
from typing import Any, Iterator, Callable, Optional, Union, List
from ._wgpu_native_cffi import ffi, lib
Expand Down Expand Up @@ -1386,7 +1388,7 @@ class Chainable(ABC):
...
class ChainedStruct:
def __init__(self, chain: list["Chainable"]):
def __init__(self, chain: List["Chainable"]):
self.chain = chain
if len(chain) == 0:
self._cdata = ffi.NULL
Expand Down
2 changes: 1 addition & 1 deletion codegen/patches.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function listFeatures(raw_ffi_func: string): string[] {
return [
'def enumerateFeatures(self) -> list["FeatureName"]:',
'def enumerateFeatures(self) -> List["FeatureName"]:',
` # Hand-written because of idiosyncratic convention for using this function`,
` feature_count = lib.${raw_ffi_func}(self._cdata, ffi.NULL)`,
` feature_list = ffi.new("WGPUFeatureName[]", feature_count)`,
Expand Down
Loading

0 comments on commit cbc94a1

Please sign in to comment.