Skip to content

Refactor PyWebNN around RustNN’s native builder and persistent tensor API - #26

Merged
mtavenrath merged 2 commits into
mainfrom
cleanup_json
Oct 21, 2026
Merged

mtavenrath merged 2 commits into
mainfrom
cleanup_json

Conversation

@mtavenrath

Copy link
Copy Markdown
Contributor

Move graph recording, validation, shape inference, compilation, execution, and serialization into RustNN. PyWebNN now adapts Python arguments and NumPy buffers while retaining native object owners, removing duplicated graph state and execution logic. Changes include:

  • Replace Python-side GraphInfo construction with native builder and operand handles.
  • Reject operands from other builders, enforce builder consumption after compilation, and retain contexts for native object lifetimes.
  • Use explicit, reusable tensor bindings through write_tensor(), dispatch(), and read_tensor().
  • Delegate model loading to context.load_graph() and expose native input/output descriptors, including dynamic dimensions.
  • Save through the builder as WebNN text with safetensors weights.
  • Align operator options, defaults, labels, numeric precision, constant conversion, and pooling operation mappings with RustNN.
  • Replace five JSON-based enum conversions with direct parsing.
  • Remove redundant runtime dependencies and initialize Rust logging only when requested.
  • Migrate examples, Hub integration, documentation, type stubs, and tests to the native API. Generation examples reuse compiled graphs and tensor allocations.
  • Document the outstanding tensor-write deadlock caused by Python callbacks during conversion. This changes the public API: compute(), AsyncMLContext, device-tensor placeholders, graph-level loading/saving, and several inspection and convenience methods are removed. Use explicit tensor dispatch, context-level loading, builder-level saving, and native I/O descriptors instead. Unsupported tensor destruction and support-limit queries raise NotImplementedError.

… API

Move graph recording, validation, shape inference, compilation, execution, and serialization into RustNN. PyWebNN now adapts Python arguments and NumPy buffers while retaining native object owners, removing duplicated graph state and execution logic.
Changes include:
- Replace Python-side GraphInfo construction with native builder and operand handles.
- Reject operands from other builders, enforce builder consumption after compilation, and retain contexts for native object lifetimes.
- Use explicit, reusable tensor bindings through write_tensor(), dispatch(), and read_tensor().
- Delegate model loading to context.load_graph() and expose native input/output descriptors, including dynamic dimensions.
- Save through the builder as WebNN text with safetensors weights.
- Align operator options, defaults, labels, numeric precision, constant conversion, and pooling operation mappings with RustNN.
- Replace five JSON-based enum conversions with direct parsing.
- Remove redundant runtime dependencies and initialize Rust logging only when requested.
- Migrate examples, Hub integration, documentation, type stubs, and tests to the native API. Generation examples reuse compiled graphs and tensor allocations.
- Document the outstanding tensor-write deadlock caused by Python callbacks during conversion.
This changes the public API: compute(), AsyncMLContext, device-tensor placeholders, graph-level loading/saving, and several inspection and convenience methods are removed. Use explicit tensor dispatch, context-level loading, builder-level saving, and native I/O descriptors instead. Unsupported tensor destruction and support-limit queries raise NotImplementedError.
@mtavenrath
mtavenrath requested a review from theHamsta October 20, 2026 20:32
Comment thread tests/runtime_support.py
requires_coreml_backend = pytest.mark.skipif(
not COREML_BACKEND_AVAILABLE,
reason="No working CoreML execution backend is available",
not COREML_BACKEND_AVAILABLE, reason="No working CoreML backend"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current tests are a bit problematic in the sense that they select a specific backend. Either they parametrize over all available backends or one runs all the tests for a specific backend

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I see that explicit backend selection was removed from most test

numpy_array_from_bytes(py, numpy, bytemuck::cast_slice(&buffer), dtype, shape)
}

fn read_ml_tensor_to_numpy<'py>(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole numpy logic is not very nice in this repo. We should be able to take numpy and other arrays directly instead of copying. Eventually also CUDA arrays.

I think we could accommodate this best when introducing an objects for host tensors in Rust rustnn/rustnn#174 . Those could then be also created as a view on ptr, shape, strides.

@theHamsta theHamsta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't review every detail, but I like the amount of deleted lines in this PR.

It is definitely an improvement and a lot easier to work on and iterate over this new revision.

@mtavenrath
mtavenrath merged commit c60ea68 into main Oct 21, 2026
15 of 16 checks passed
@mtavenrath
mtavenrath deleted the cleanup_json branch October 21, 2026 15:40
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

Successfully merging this pull request may close these issues.

2 participants