Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions backends/native/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# ExecuTorch Native

> [!NOTE]
> Experimental. The Python API, the `.ptn` format, and operator coverage may change.

ExecuTorch Native lowers a PyTorch model to a single `.ptn` file and runs it on
one of several engines. In a `.pte`, delegates lower the graph ahead of time for
specific backends. A `.ptn` keeps the whole graph without backend-specific
information, and each engine lowers it when compiling a method.

```
.pte: export -> [quantize] -> to_edge -> to_backend -> to_executorch -> .pte (+ .ptd)
.ptn: export -> [quantize] -> to_native -> .ptn
```

## Export

```python
import torch
from executorch.exir.native import to_native

ep = torch.export.export(model, example_inputs)
to_native(ep).save("model.ptn")

# Several methods in one file.
to_native({"forward": ep_forward, "prefill": ep_prefill}).save("model.ptn")
```

The partitioner accepts core ATen ops plus `linear`, `matmul`, `addmm`,
`scaled_dot_product_attention`, `rms_norm`, `native::rope`, and TorchAO affine
quantize/dequantize ops. TorchAO int4 group-wise weights of `linear` and
`embedding`, and GGUF k-quant weights from `executorch.extension.llm.export.gguf`, are
stored packed with their scheme in tensor metadata. Each method must lower wholly
to one delegate; `to_native` raises otherwise.

A `.ptn` is an uncompressed zip with fixed entry names:

| Entry | Contents |
| --- | --- |
| `program.ptg` | Methods as graphs; FlatBuffer defined by `serialization/native_graph.fbs`. |
| `program.safetensors` | Constants. Byte-identical immutable tensors are stored once. |
| `aliases.json` | Deduplicated key to owner key; present only when needed. |

## Runtime

The C++ runtime reads a `.ptn` into an in-memory graph and hands each method to
an engine through the interfaces in `runtime/engine/Engine.h`:

- `EngineHost`: process-wide device resources.
- `EngineContext`: state for one loaded program, including mutable buffers.
- `EngineExecutable`: one compiled method (`set_input`, `execute`, `get_output`).

An engine rejects a method whose semantics it cannot fully honor.

| Engine | Source | Notes |
| --- | --- | --- |
| Vulkan | `runtime/vulkan/` | Builds on the ET-VK `ComputeGraph` and shaders. |
| ggml | `runtime/engine/ggml/` | CPU, CUDA, HIP, and Metal variants. |

The runtime currently builds only with Meta's internal Buck setup; there is no
open-source build yet.
144 changes: 0 additions & 144 deletions exir/native/README.md

This file was deleted.

6 changes: 3 additions & 3 deletions exir/native/native.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
Direct native lowering.

Where the ExecuTorch flow is export -> [quantize] -> to_edge -> to_backend -> to_executorch, this
is export -> [quantize] -> to_native, and yields a NativeProgramManager to save as a .ptn. See README.md.
is export -> [quantize] -> to_native, and yields a NativeProgramManager to save as a .ptn.
See backends/native/README.md.

Lowering runs the same to_edge_transform_and_lower pipeline as the ExecuTorch path
(the default native passes plus NativePartitioner), but opts the partitioner into
Expand Down Expand Up @@ -425,8 +426,7 @@ def to_native(
f"wholly supported by the native backend: an identity method "
f"produces none, and disconnected supported regions produce "
"several. Residual operator targets: "
f"{residual_targets}. See the README for this limitation of "
"the current implementation."
f"{residual_targets}."
)
module = lowered[0][1]
_check_delegate_contract(
Expand Down