Public Alpha Rextio plugin with proven CPU lowering and a build-only CUDA candidate for tch (plugin API 1.7).
Project description
rextio-torch
Public Alpha Rextio plugin that lowers a proven subset of Python
PyTorch inference code to Rust expressions backed by
tch.
| Field | Value |
|---|---|
| Package version | 0.1.3 (from rextio_torch.__about__) |
| Release status | 0.1.3 public Alpha on PyPI (2026-07-27). The product CPU surface is released; CUDA E2 remains a build-only, non-certifying engineering candidate (support_claim=false, certification_ready=false) and is not a CUDA support claim |
| Distribution | rextio-torch==0.1.3 |
| Plugin API | 1.7 (REQUIRED_PLUGIN_API) |
| Product mode | Proven CPU inference plus a Linux x86_64 build-only CUDA candidate; no CUDA support claim |
| Certified host | macOS arm64 (Apple Silicon), CPython 3.11, torch 2.11.0 |
| Experimental hosts | Linux x86_64, Linux AArch64 — runtime-backed but not certified |
| Availability-gated | macOS x86_64 — pinned torch 2.11.0 CPython 3.11 wheel absent |
| Unsupported | Linux/macOS i686 and ARMv7 — no pinned runtime; impossible modern macOS targets |
| Deferred | Windows — unverified; no support claim |
This README documents the 0.1.3 public Alpha product release: Core API 1.7
function-scope no-grad integration, diagnostic small-batch scoring,
classification-head and bounded CPU surface, the still build-only CUDA E2
candidate (not product-promoted), and the opt-in real-NVIDIA
execution-evidence candidate. Product release status and CUDA candidate status
are deliberately separate — publishing rextio-torch does not promote CUDA.
RXT075/legacy/type-only paths deliberately retain per-operation guards. Every
form, rank, pin, and fail-closed behavior below is backed by current claim /
lower / rules / rust_snippets sources and focused or real-Cargo tests.
Unsupported sites must stay on the ordinary Python fallback or be explicitly
rejected — never falsely claimed.
Performance numbers under benchmarks/results/ and
benchmarks/results_phase_b/ are historical context only. They are not
a release gate for this Alpha cut. The 0.1.3 small-batch scoring harness is
diagnostic only (no official cohort, no speedup claim).
Version and ABI contract
| Component | Exact pin | Why it must match |
|---|---|---|
| CPython | 3.11 only (requires-python = ">=3.11,<3.12") |
PyO3 extension ABI and the dedicated certification venv; other CPython minor versions are not in the package contract. |
| Rextio package | >=0.1.7,<0.2 |
Required for the reviewed provider-local function-scope guard contract in addition to device authorization. |
| Plugin API | 1.7 | Adds function_scope_guard and the provider-local LoweringContext.function_scope_guard_active fact. |
| PyTorch | torch==2.11.0 |
Same major/minor/patch as the libtorch that published tch 0.24.0 expects. |
| Rust crate | tch =0.24.0 with feature python-extension |
Emitted by crate_dependencies(); python-extension supplies pyobject_unpack / pyobject_wrap for zero-storage-copy boundaries. |
| Generated Rust crate | Edition 2021, rust-version = "1.83", PyO3 0.29 |
Inherited from the Rextio 0.1.7 generated Cargo manifest. This is an MSRV/API contract, not an exact rustc patch pin. |
| Certified Rust toolchain | rustc 1.93.1, cargo 1.93.1 on aarch64-apple-darwin |
The real-Cargo Alpha evidence was reproduced with this local toolchain. This repo has no rust-toolchain.toml. |
| libtorch linkage | LIBTORCH_USE_PYTORCH=1 |
Builds against the active Python torch install. |
| Version-check bypass | Forbidden | LIBTORCH_BYPASS_VERSION_CHECK is not an accepted build path (stripped in e2e env setup; never set). |
| Device | CPU proven; CUDA device 0 build-only | CPU types retain their old checks. CUDA marker types require already-resident cuda:0 values and never lower transfers. |
| Dtype | float32 only | Boundary extract rejects non-float32 at runtime. |
| Mode | Inference / no-grad | Eligible PyO3 functions install one Core-owned tch::no_grad_guard() and use distinct *_function_scoped helpers. RXT075, legacy/no-hook, standalone, and type-only paths retain per-operation guards. Native outputs have requires_grad is False. |
Why tch / libtorch / PyTorch / CPython must be one matched set
- tch 0.24.0 ↔ libtorch / PyTorch 2.11.0 — the published
tchrelease targets that libtorch line exactly. Linking a different torch version fails the exact version check unless bypassed (bypass is rejected here). LIBTORCH_USE_PYTORCH=1—torch-sysdiscovers Python viaPATH/VIRTUAL_ENV(not onlyPYO3_PYTHON) and reads that interpreter’s torch. A mismatched torch onPATHfails the 2.11.0 check.- CPython 3.11 — the generated native extension must load under the same CPython 3.11 + torch 2.11.0 environment that built it (PyO3 ABI + tch python-extension bridge).
- Rextio 0.1.7+ / provider API 1.7 — the function-scope guard activation fact is unavailable on older plugin APIs. The provider declares API 1.7 while Core's loader handles compatible later 1.x hosts. Registration fails closed for API 1.6 and older, other majors, or malformed host versions before registration can reach fields unavailable on older Core.
Certification and real-Cargo tests configure this environment explicitly.
Host OS is not a runtime claim gate in this plugin: the source does not
reject Linux solely because it is not macOS. Pins (CPython, torch, tch,
API) and toolchain availability still apply; mismatched or unavailable
tooling must fail visibly (never via LIBTORCH_BYPASS_VERSION_CHECK).
Host platforms and CI truth model
Architecture labels are normalized here: x86 means i686 (32-bit), x64
means x86_64/AMD64, ARM32 means ARMv7, and ARM64 means AArch64.
Every requested Linux/macOS cell is represented in
rextio_torch.platforms; a green static contract cell is not a native support
claim.
| OS / arch | Alpha status | Native evidence / required result |
|---|---|---|
| macOS ARM64 | Certified | Real Cargo on macos-15 for every PR/push, with CPython 3.11, torch 2.11.0, tch 0.24.0, and rustc/cargo 1.93.1. |
| Linux x64 | Experimental, runtime-backed | Real Cargo on ubuntu-24.04 for every PR/push with the same pins. Green is engineering evidence, not certification. |
| Linux ARM64 | Experimental, runtime-backed | Real Cargo on ubuntu-24.04-arm in scheduled/manual CI. It is deliberately non-blocking until hosted-runner evidence is reviewed. |
| macOS x64 | Availability-gated, not supported | The exact torch 2.11.0 CPython 3.11 wheel has no macOS x86_64 artifact. Scheduled/manual CI verifies that premise and requests reassessment if it changes. |
| Linux x86 / ARM32 | Unsupported | Static contract tests require a stable fail-closed result; torch 2.11.0 publishes no CPython 3.11 i686/ARMv7 wheel. No fake native job. |
| macOS x86 / ARM32 | Unsupported / impossible modern target | Static contract tests require a stable fail-closed result; neither a viable hosted runner nor pinned wheel exists. |
| Windows (all) | Deferred | Unverified and outside this Alpha train; no support claim. |
The blocking workflow separates quality, the eight-cell
platform-contract, runtime-backed native-e2e, and package jobs. Actions
receive only contents: read; third-party Actions are pinned to immutable
commit SHAs. A stable CI gate result aggregates every blocking lane for
branch protection. Native jobs build a clean wheel with pinned tooling, install
that wheel into a fresh venv, and reject any skipped runtime-backed test. The
scheduled/manual workflow owns expensive or
availability-gated experimental evidence.
Rules that carry verified=True mean the native rule family was compiled and
executed under the certified host contract above. They do not mean
every experimental Linux box is certified.
Linux experimental verification recipe
Use this only to exercise the pinned environment on Linux. It does not promote Linux to certified status.
# CPython 3.11 venv: product pins plus the CI Core commit pin (CI has not yet
# switched to PyPI rextio 0.1.7 for Core installs at this documentation cut)
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install 'pip==26.1'
python -m pip install \
'git+https://github.com/rextio/rextio.git@b8b8ed11f6b7b7aae4c7ae5205d88529608e8e97' \
'torch==2.11.0' 'pytest==9.1.1' 'ruff==0.15.22' 'mypy==2.3.0'
python -m pip install --no-deps -e .
# Required link mode; version-check bypass is forbidden
export LIBTORCH_USE_PYTORCH=1
unset LIBTORCH_BYPASS_VERSION_CHECK
# Fail closed if PATH does not resolve torch 2.11.0 for torch-sys
python -c "import torch; v=torch.__version__.split('+')[0]; assert v=='2.11.0', v"
# Focused unit tests (no native build)
pytest -q tests --ignore=tests/e2e
# Opt-in real-Cargo native slice (needs cargo + rustc; skips only if cargo missing)
# Failures from wrong torch / missing libtorch / ABI mismatch must surface — do not bypass.
pytest -q tests/e2e -m needs_cargo
Or run the maintainable wrapper (same contract, explicit env checks):
./scripts/linux-smoke.sh # unit tests only
./scripts/linux-smoke.sh --cargo # also run real-Cargo e2e when cargo is on PATH
If the pinned torch, CPython, Rextio API, or Cargo toolchain is wrong or
missing in a way that blocks the native path, the smoke must fail or skip
with a clear reason — never mask by setting LIBTORCH_BYPASS_VERSION_CHECK.
Annotation vocabulary (rextio_torch.types)
| Annotation | Plugin type key | dtype | device | rank |
|---|---|---|---|---|
TensorF32Cpu2D |
rextio-torch/tensor-f32-cpu-2d |
float32 | CPU | 2 |
TensorF32Cpu1D |
rextio-torch/tensor-f32-cpu-1d |
float32 | CPU | 1 |
TensorI64Cpu1D |
rextio-torch/tensor-i64-cpu-1d |
int64 | CPU | 1 (classification result only) |
TensorF32Cuda0_2D |
rextio-torch/tensor-f32-cuda0-2d |
float32 | CUDA device 0 | 2 (build-only) |
TensorF32Cuda0_1D |
rextio-torch/tensor-f32-cuda0-1d |
float32 | CUDA device 0 | 1 (build-only) |
Marker classes intentionally import neither torch nor Rextio. Runtime values
remain ordinary torch.Tensor objects; the analyzer resolves the dotted
spellings when the plugin is enabled.
What annotations prove: dtype, device, and rank only.
What they do not prove: concrete dimensions. Matmul inner-size compatibility and concrete PyTorch broadcasting are validated by libtorch via fallible tch APIs at execution time.
Native Rust representation: plugin-owned RxtTorchTensor(tch::Tensor).
Boundary unpack/wrap uses tch’s python-extension bridge (another ref-counted
handle, no storage copy). Clone uses shallow_clone() — in-place ops are
excluded because shallow clones alias storage.
Build-only CUDA E2 candidate
The CUDA candidate is frozen to Linux x86_64, CPython 3.11, PyTorch/libtorch
2.11.0, tch 0.24.0, LIBTORCH_USE_PYTORCH=1, float32 rank-1/rank-2
cuda:0, and inference/no-grad. It accepts only named-intermediate
rank2 @ rank2 -> rank2 + rank1 bias -> rank2.relu() -> rank2.mean(dim=1) -> rank1. Lowering requires the exact
rextio-device-cuda/cuda-libtorch-linux-x86_64 authorization.
This is support_claim=false. CI runs actual Core orchestration with the real
provider implementation fed by a fixed synthetic probe report, then compiles
but never loads or runs the generated CUDA Rust slice. It does not inspect
host hardware or prove real NVIDIA execution, one-libtorch-image/ABI identity,
numerical equivalence, stream behavior, or performance. .cuda()/.to(),
CPU/CUDA mixing, reverse/same-rank add, mixed-rank CUDA matmul, functional CUDA
spellings, other devices, training/autograd, Windows, and macOS remain
excluded. See the complete frozen CUDA contract.
CUDA input and output boundaries also fail closed on non-strided layouts.
Because tch 0.24 has no general layout getter, native checks use its exposed
is_sparse() / is_mkldnn() flags and both Python boundaries additionally
require the pinned PyTorch 2.11.0 tensor.layout to render as
torch.strided; this catches sparse CSR/CSC/BSR/BSC without claiming a
version-independent tch layout query.
A separate manual Linux x86_64/NVIDIA harness executes the same exact slice
on a trusted maintainer host. It uses the real provider probe, compares
contiguous and noncontiguous values with eager PyTorch, requires
non-default-stream CUDA Graph replay and expected ATen CUDA activity, rejects
observed host/device transfers, and binds canonical wheel-relative
libtorch/c10 identities into offline-verifiable evidence. It remains
support_claim=false and certification_ready=false, is excluded from normal
CI, and does not expand the accepted operation or platform surface. See the
CUDA candidate contract and commands.
Exactly supported Python forms and result ranks
Claims require API 1.7 metadata that proves the form (operand / receiver type
keys, call target, static keyword literals). Result ranks are those of the
claimed result_type.
| Form | Syntax contract | Operand / receiver ranks | Result rank | Rule id (native) |
|---|---|---|---|---|
| Functional linear (tensor bias) | torch.nn.functional.linear(x, w, b) — three positional tensors |
x, w: 2; b: 1 | 2 | rextio-torch/functional-linear-f32-cpu-2d |
| Functional linear (no bias) | torch.nn.functional.linear(x, w), (x, w, None), or (x, w, bias=None); x/w stay positional |
x, w: 2 | 2 | rextio-torch/functional-linear-none-f32-cpu-2d |
| ReLU method | .relu() — zero args, no keywords |
receiver 1 or 2 | same as receiver | …/tensor-relu-f32-cpu-1d or …/tensor-relu-f32-cpu-2d |
| Sigmoid method | .sigmoid() — zero args, no keywords |
receiver 1 or 2 | same as receiver | …/tensor-sigmoid-f32-cpu-1d or …/tensor-sigmoid-f32-cpu-2d |
| Tanh method | .tanh() — zero args, no keywords |
receiver 1 or 2 | same as receiver | …/tensor-tanh-f32-cpu-1d or …/tensor-tanh-f32-cpu-2d |
| Functional activations | Exact torch.relu(t), torch.sigmoid(t), or torch.tanh(t); one positional tensor, no keywords; exact torch.nn.functional.relu(t) additionally permits omitted or literal inplace=False |
input 1 or 2 | same as input | …/function-{relu,sigmoid,tanh}-f32-cpu-rank1-2; …/functional-relu-f32-cpu-rank1-2 |
| Unary math | Exact torch.{abs,neg,negative,square,exp,log,sqrt}(t) or matching zero-argument tensor method; one tensor and no keywords |
input/receiver 1 or 2 | same as input | …/unary-{abs,neg,negative,square,exp,log,sqrt}-f32-cpu-rank1-2 |
| Exact GELU | torch.nn.functional.gelu(t) or gelu(t, approximate="none"); one positional tensor and no other options |
input 1 or 2 | same as input | …/functional-gelu-none-f32-cpu-rank1-2 |
| Matmul binop | a @ b |
2/2, 2/1, or 1/2 | 2 for 2/2; 1 for mixed ranks | …/tensor-matmul-f32-cpu-{2d,mixed-rank} |
| Matmul call | torch.matmul(a, b) — two positional; no keywords |
2/2, 2/1, or 1/2 | 2 for 2/2; 1 for mixed ranks | …/tensor-matmul-call-f32-cpu-{2d,mixed-rank} |
| Matmul method | a.matmul(b) — one positional; no keywords |
receiver/other 2/2, 2/1, or 1/2 | 2 for 2/2; 1 for mixed ranks | same as call form |
Elementwise + (same rank) |
a + b |
both 1, or both 2 | same as left | rextio-torch/tensor-add-f32-cpu-same-rank |
Elementwise + (bias broadcast) |
a + b |
one 2, one 1 (either order) | 2 | rextio-torch/tensor-add-f32-cpu-2d-1d-broadcast |
Elementwise * (same rank) |
a * b |
both 1, or both 2 | same as left | rextio-torch/tensor-mul-f32-cpu-same-rank |
Elementwise * (bias broadcast) |
a * b |
one 2, one 1 (either order) | 2 | rextio-torch/tensor-mul-f32-cpu-2d-1d-broadcast |
Elementwise - |
a - b, same-rank or rank-2/rank-1 trailing broadcast in either operand order |
input ranks 1/1, 2/2, 2/1, or 1/2 | same rank, or 2 for mixed ranks | …/tensor-sub-f32-cpu-{same-rank,2d-1d-broadcast} |
Elementwise true / |
a / b, with the same rank/broadcast matrix as subtraction; binop only |
input ranks 1/1, 2/2, 2/1, or 1/2 | same rank, or 2 for mixed ranks | …/tensor-div-f32-cpu-{same-rank,2d-1d-broadcast} |
| Functional elementwise arithmetic | Exact torch.add/sub/mul/div(a, b); two positional tensors and no keywords, using the same rank/broadcast matrix as the operators |
input ranks 1/1, 2/2, 2/1, or 1/2 | same rank, or 2 for mixed ranks | …/function-{add,sub,mul,div}-f32-cpu-rank1-2 |
| Mean / sum | Receiver methods or exact torch.mean / torch.sum; `dim=0 |
1once (positional literal or keyword);keepdim` omitted=False or named bool |
rank-2: dim 0/1; rank-1: only dim 0 + keepdim=True | registered float32 rank 1 or 2 only |
| Softmax | Receiver method or exact torch.softmax; exact torch.nn.functional.softmax additionally permits omitted or literal dtype=None; literal dim once |
rank-1 dim 0; rank-2 dim 0/1 | same as input | legacy dim1 rule, …/softmax-static-dim-f32-cpu-rank1-2, or …/functional-softmax-f32-cpu-rank1-2 |
| Argmax | Receiver method or exact torch.argmax; literal dim once; keepdim omitted=False or named bool |
rank-2 dim 0/1 + keepdim=False; rank-1 dim 0 + keepdim=True | 1 int64 | legacy dim1 rule or …/argmax-static-dim-i64-cpu-rank1 |
Native op helpers (all fallible, under the enclosing or local no_grad guard):
| Python form | Rust helper | tch API used |
|---|---|---|
| linear | __rxttorch_linear / __rxttorch_linear_no_bias |
f_linear(Some(bias)) / f_linear(None) |
| activation method/function | __rxttorch_{relu,sigmoid,tanh} |
fallible matching tch activation |
| unary math method/function | __rxttorch_{abs,neg,negative,square,exp,log,sqrt} |
exact fallible f_abs, f_neg, f_negative, f_square, f_exp, f_log, or f_sqrt |
| exact GELU | __rxttorch_gelu_none |
fixed fallible f_gelu("none"); the source option is never interpolated |
| mean / sum | __rxttorch_{mean,sum}_dim{0,1}_keepdim_{true,false} |
f_mean_dim / f_sum_dim_intlist with fixed literals |
+ |
__rxttorch_add |
f_add |
* |
__rxttorch_mul |
f_mul |
- |
__rxttorch_sub |
f_sub |
/ |
__rxttorch_div |
f_div |
matmul / @ |
__rxttorch_matmul |
f_matmul |
| softmax | __rxttorch_softmax_dim{0,1} |
f_softmax with fixed dim |
| argmax | __rxttorch_argmax_dim{0,1}_keepdim_{true,false} (only rank-1 outputs) |
f_argmax plus exact CPU/int64/rank-1 check |
Coverage symbols declared for the analyzer include
torch.nn.functional.{linear,gelu,relu,softmax}, torch.matmul,
torch.{relu,sigmoid,tanh,abs,neg,negative,square,exp,log,sqrt,add,sub,mul,div,mean,sum,softmax,argmax},
and the corresponding receiver methods. Binary + / * / - / / / @
are also claimed via binop sites. Functional options that change or widen
semantics, such as alpha, out, or rounding_mode, remain rejected.
Control flow around claimed ops
Python for / if with Rextio-lowerable scalar int / bool conditions become
Rust control flow around the native tch helpers (certified control-flow
vertical slice). Tensor comparisons and tensor-data-dependent conditions are
not claimable by the current plugin API 1.7 surface and remain on the Python fallback.
Core receiver limitation (not a plugin gap): Rextio core does not offer method calls whose receiver is a bare BinOp to plugins. Write named temps:
# Accepted pattern
even = hidden @ weight + bias
hidden = even.relu()
# Not offered to plugins (bare BinOp receiver)
# hidden = (hidden @ weight + bias).relu()
Use distinct temp names per if-arm when both branches need intermediates
(core scopes Rust let bindings per arm).
Static preconditions (analysis / claim time)
A site is claimed only when all of the following hold for that form.
Otherwise the plugin returns Rejected (recognized surface, wrong shape) or
NotCovered (unrelated / unresolved) — see Compile-time fallback vs runtime
fail-closed.
| Check | Enforcement |
|---|---|
| Plugin type keys are the registered float32 CPU rank-1/2 keys | is_tensor_type / exact type equality per rule |
Linear: exact torch.nn.functional.linear; three positional tensors (2,2,1), or rank-2 input/weight with bias omitted / positional literal None / keyword literal bias=None |
claim/linear.py; tensor-valued keywords remain unrepresentable in the current Core ClaimSite contract |
Activations: receiver zero-arg methods, or exact torch.relu/sigmoid/tanh with one positional tensor; exact torch.nn.functional.relu also permits omitted/literal inplace=False; rank 1/2 only |
claim/activations.py |
Unary math: receiver zero-arg methods, or exact torch.abs/neg/negative/square/exp/log/sqrt with one positional tensor; rank 1/2 and no keywords |
claim/unary.py |
GELU: exact torch.nn.functional.gelu; one positional rank-1/2 tensor; approximate omitted or exactly the static string literal "none"; lower always hardcodes "none" |
claim/gelu.py |
Reductions: receiver or exact torch.mean/sum; dim literal 0/1 once positionally/keyword; keepdim omitted=False or named bool; output must already map to rank-1/2 |
claim/reductions.py |
Classification: receiver or exact torch.softmax/argmax; exact torch.nn.functional.softmax also permits omitted/literal dtype=None; positional dim literal alignment and options are revalidated; argmax must map exactly to TensorI64Cpu1D |
claim/classification.py |
Matmul @ / torch.matmul / .matmul: rank-2/rank-2 or one rank-2 plus one rank-1 operand in either order; call forms disallow keywords; method form takes one positional operand; rank-1/rank-1 stays rejected because it would return rank-0 |
claim/binops.py |
Elementwise arithmetic: binary + / * / - / /, or exact torch.add/sub/mul/div(a, b) with two positional non-literal tensors and no keywords; same-rank 1/1 or 2/2, or {1,2} broadcast; scalar/method/option variants and other ranks rejected |
claim/binops.py |
| Claim metadata is pure function of site kind, target, operand types, receiver, static keyword literals | claim/__init__.py (config unused) |
Keyword order for dim / keepdim does not matter. A positional dim must be
an aligned non-bool int literal and is compile-time metadata, never a runtime
tensor helper operand. A second positional keepdim is excluded; keepdim is
omitted (real default False) or supplied as a named bool literal.
Lowering independently revalidates the same metadata (rule_id, ranks,
operand counts, receiver) and raises ValueError on drift — guards use
exceptions, not assert, so they survive python -O.
Unsupported / fallback forms
These stay unclaimed, rejected, or out of scope. They must never become silent native claims.
| Category | Examples / notes | Claim outcome (when offered as a torch site) |
|---|---|---|
| Other devices | CUDA other than the exact build-only cuda:0 slice; MPS and other accelerators |
Outside the accepted vocabulary/slice; mixed devices and transfers are rejected |
| Other dtypes | float64, int, etc. | Outside vocabulary; boundary rejects non-float32 at runtime on native paths |
| Other ranks | rank-0 / rank-3+, rank-1 × rank-1 matmul, linear with wrong ranks | Rejected when form is recognized with wrong ranks |
| Training / autograd | backward, optimizers, parameter mutation | Out of scope; native helpers always no_grad |
| Modules | arbitrary nn.Module capture/execution |
Uncovered / not claimed |
| Linear variants | tensor-valued keyword bias/input/weight, other keywords, method linear | Tensor keywords are not offered by the Core API 1.7 ClaimSite contract; others reject/fallback |
| In-place ops | relu_, sigmoid_, tanh_, unary _ variants, in-place operators; F.relu(..., inplace=True) |
Not claimed (zero-arg out-of-place methods only; F.relu admits only omitted/literal inplace=False) |
| Unary variants | scalar inputs; out; alternate aliases such as torch.absolute; method arguments or keywords |
Rejected for recognized exact functions/methods or otherwise unclaimed |
| GELU variants | approximate="tanh", dynamic/invalid/positional approximate, other keywords, .gelu(), or nn.GELU capture |
Static recognized variants are rejected; dynamic values may be filtered by Core to ordinary fallback before plugin claim |
| Elementwise variants | scalar operands; .add/.sub/.mul/.div; aliases such as torch.subtract; alpha, out, or rounding_mode options |
Rejected for recognized exact functions/options or otherwise unclaimed; / and exact torch.div(a, b) mean tensor-tensor true division only |
| Reductions other shapes | whole-tensor reduction, dynamic/duplicate/out-of-range dim, positional keepdim, dtype/out, or rank-0 result | Rejected or unclaimed |
| Classification variations | dtype override, dynamic/duplicate dim, softmax keepdim, rank-2 argmax keepdim=True, rank-1 argmax keepdim=False, rank-3+ | Rejected or unclaimed; unavailable int64 rank-2/rank-0 types are not invented |
| Classification-result arithmetic | TensorI64Cpu1D or mixed int64/float32 operands with +, *, -, or / |
Rejected; elementwise arithmetic remains float32-only |
| Views / reshape | transpose, view, reshape (alias / shallow-clone risk) | Intentionally not claimed |
| Unsupported broadcast ranks | arithmetic rank combinations other than same-rank or 2d/1d | Rejected |
| Unrelated torch APIs | e.g. torch.subtract / torch.divide aliases |
NotCovered |
| Unresolved types | missing annotation / None operand types |
NotCovered (no false claim) |
| Tensor-dependent control flow | tensor comparisons as if conditions |
Not claimable under the current API 1.7 surface |
| Bare BinOp method receivers | (a @ b).relu() |
Core does not offer site; use temps |
| Version bypass | LIBTORCH_BYPASS_VERSION_CHECK |
Forbidden build path |
| Custom operators | user ops outside the table above | Uncovered |
Rule record rextio-torch/unsupported-tensor-surface (RXTP-TORCH-010,
outcome fallback) documents the fail-closed rejection lane for covered torch
sites whose types or shapes fall outside the Alpha surface.
Compile-time fallback vs runtime fail-closed
Two different layers. Do not conflate them.
Analysis / codegen time (before or while building native code)
| Outcome | Meaning | User effect |
|---|---|---|
| Claimed | Metadata proves a native rule | Site can lower to a tch helper |
| Rejected | Recognized surface, wrong static shape/types | Diagnostic error (RXTP-TORCH-*); site stays on Python fallback — never a false native claim |
| NotCovered | Not this plugin’s target, or types unresolved | Other plugins / ordinary Python fallback |
Lower ValueError |
Claimed metadata changed or is inconsistent at lower | Codegen fails closed (no assert / no silent bad emit) |
Native rules that passed real-Cargo certification are marked verified=True in
rules/records.py. The unsupported-surface fallback record is not a native
op and remains verified=False.
Runtime (native extension executing)
| Check | Failure behavior | Typical message / path |
|---|---|---|
Boundary: value is a torch.Tensor |
Python exception | rextio-torch: expected a torch.Tensor |
| Boundary: device is CPU | ValueError |
rextio-torch: expected a CPU tensor |
| Boundary: dtype is float32 | ValueError |
rextio-torch: expected a float32 tensor |
| Boundary: rank matches annotation | ValueError |
rextio-torch: expected rank-N tensor, got rank M |
| Matmul inner dimensions | Fallible f_matmul → mapped error |
TchError → PyRuntimeError via __rxttorch_map_err |
| Add / multiply broadcast concrete sizes | Fallible f_add / f_mul |
same mapping |
| Other op failures | Fallible f_* APIs under no_grad |
same mapping; no unwrap / panic! / assert |
Unary domain values are normal tensor results, not operation failures:
log/sqrt can produce NaN, zero can map to signed infinity, and overflow can
produce infinity. Native certification compares eager/native NaN and infinity
classes, finite values, and signed zero under the pinned backend. NaN payload
bits and NaN sign are intentionally not portable cross-platform guarantees.
Exact GELU uses the same comparison policy (-∞ produces NaN, +∞ remains
infinite, and signed zero is preserved).
Certified e2e tests force native-only mode for the boundary rejects they exercise, so eager fallback cannot mask float64/wrong-rank failures. Inputs are not mutated; native outputs remain no-grad CPU float32 of the promised rank when contracts hold. The non-CPU check and incompatible concrete matmul/broadcast errors are source-enforced fallible paths, but the CPU-only real-Cargo fixtures do not directly execute those failure cases.
Examples of accepted vs rejected syntax
Accepted (Phase A certified chain)
from rextio_torch.types import TensorF32Cpu1D, TensorF32Cpu2D
import torch.nn.functional as F
def inference(
x: TensorF32Cpu2D,
weight: TensorF32Cpu2D,
bias: TensorF32Cpu1D,
) -> TensorF32Cpu1D:
return F.linear(x, weight, bias).relu().mean(dim=1, keepdim=False)
Claims: linear (2→2), relu (2→2), mean (2→1). Real-Cargo certified.
Accepted (control-flow + expanded Alpha surface)
from rextio_torch.types import TensorF32Cpu1D, TensorF32Cpu2D
import torch
def inference(
x: TensorF32Cpu2D,
weight: TensorF32Cpu2D,
bias: TensorF32Cpu1D,
depth: int,
phase: int,
) -> TensorF32Cpu1D:
hidden = x
for layer in range(depth):
if (layer + phase) % 2 == 0:
even = hidden @ weight + bias
hidden = even.relu()
else:
odd = hidden @ weight + bias
hidden = odd.sigmoid()
return hidden.mean(dim=1, keepdim=False)
def expanded_surface(
x: TensorF32Cpu2D,
weight: TensorF32Cpu2D,
offset: TensorF32Cpu1D,
) -> TensorF32Cpu1D:
hidden = torch.matmul(x, weight)
hidden = hidden.tanh()
hidden = hidden + hidden
hidden = hidden.matmul(weight)
reduced = hidden.sum(dim=1, keepdim=False)
reduced = reduced + offset
return reduced.relu().sigmoid().tanh()
One serialized certification project exercises every Alpha rule family (both matmul call forms, same-rank and 2D+1D add families, sum, tanh, rank-1 activation chaining, and the control-flow route).
Accepted (bounded 0.1.2 CPU follow-up)
def cpu_surface_followup(
x: TensorF32Cpu2D,
weight: TensorF32Cpu2D,
bias: TensorF32Cpu1D,
divisor: TensorF32Cpu1D,
) -> TensorF32Cpu2D:
hidden = torch.nn.functional.linear(x, weight, bias=None)
activated = torch.relu(hidden)
shifted = torch.sigmoid(activated) - bias
scaled = shifted / divisor
totals = torch.sum(scaled, 0, keepdim=True)
averaged = torch.mean(totals, 1, keepdim=True)
probabilities = torch.softmax(averaged, 1)
return torch.tanh(probabilities)
The same serialized real-Cargo project executes this slice plus omitted and
positional-None linear forms, every same-rank/2D↔1D subtraction and division
order, all six mixed-rank matmul spellings/order combinations, functional
rank-2 argmax with default keepdim=False, and rank-1 argmax with named
keepdim=True. It checks numerical parity, exact dtype/device/rank, no-grad
output, non-mutation, native route evidence, and runtime incompatible
matmul/broadcast failures. Direct unary kernels additionally certify NaN/Inf
domain behavior and signed-zero parity for every exact fallible helper; default
and explicit-none GELU are separately routed and compared.
Rejected or not covered (illustrative)
# Rejected: linear wrong ranks (1d input)
# F.linear(x_1d, weight_2d, bias_1d)
# Rejected: rank-1 reduction would produce unregistered rank-0
# vector.mean(dim=0) # keepdim defaults to False
# Rejected: positional keepdim is deliberately not represented
# t.mean(0, True)
# Rejected: duplicate positional and keyword dim
# t.sum(0, dim=1)
# Rejected: rank-1 × rank-1 matmul would produce unregistered rank-0
# a_1d @ b_1d
# Rejected: exact i64 output type is unavailable
# matrix.argmax(dim=1, keepdim=True) # would be int64 rank-2
# vector.argmax(dim=0) # would be int64 rank-0
# Rejected: semantic-changing functional option
# torch.div(a, b, rounding_mode="trunc")
# Rejected: only exact GELU approximation "none" is native
# torch.nn.functional.gelu(x, approximate="tanh")
# Not offered by the current Core API 1.7 ClaimSite contract: runtime tensor-valued keyword
# F.linear(x, weight, bias=bias_tensor)
# Not offered by core to plugins: bare BinOp receiver
# (a @ b + bias).relu()
# Not claimed: in-place / unsupported elementwise forms / views
# x.relu_(); x * 2.0; x.transpose(0, 1)
# Accepted classification head: int64 rank-1 labels
# logits.softmax(dim=1).argmax(dim=1, keepdim=False)
0.1.3: invocation scope and diagnostic scoring
Core plugin API 1.7 provides the reviewed optional
function_scope_guard hook. Eligible PyO3 functions containing Torch op
claims install one RAII tch::no_grad_guard() after input conversion and drop
it before output conversion. Their lowerers select distinct
*_function_scoped helpers without redundant per-op guards.
RXT075 functions decline the whole-function guard so Python callbacks observe ambient grad mode; standalone, type-only, legacy, and declined-hook contexts also retain the original per-operation guarded helpers. The status and safety contract live in:
docs/invocation-scope-proposal-0.1.3.mdrextio_torch.invocation_scope(INVOCATION_SCOPE_OPTIMIZATION_ACTIVE=True)
A self-contained diagnostic small-batch scoring pipeline (batches 1/16/128,
features 32, classes 8, control-flow rounds=4) exercises normalize →
linear → control-flow ReLU/tanh → classification linear → softmax → argmax,
validating full logits and probabilities before exact labels. The primary
diagnostic native lane consumes an already-built project (retained
wrappers, no rebuild inside timed samples); ordinary CLI runs mark native
unavailable unless --built-project is supplied. Eager and
torch.inference_mode remain context lanes. Protocol:
docs/preregister-small-batch-scoring-diagnostic-0.1.3.md.
Timings are labeled diagnostic only; historical Phase A/B results are untouched
and no speedup is claimed solely from the scope optimization.
.venv/bin/python -m pytest tests/test_invocation_scope_proposal.py \
tests/test_analyzer_small_batch_scoring.py \
tests/test_small_batch_scoring_harness.py -q
.venv/bin/python -m benchmarks.bench_small_batch_scoring --smoke
Install
The public PyPI command installs the 0.1.3 / plugin API 1.7 public Alpha
product release. It depends on released Rextio >=0.1.7,<0.2. The product
CPU surface is released; the included CUDA lane remains the explicitly
build-only, non-certifying engineering candidate documented below
(support_claim=false, certification_ready=false — not a CUDA support claim):
python3.11 -m pip install 'rextio>=0.1.7,<0.2' 'rextio-torch==0.1.3'
Or install the product wheel alone (resolver pulls the declared Core range):
python3.11 -m pip install 'rextio-torch==0.1.3'
CI / maintainer Core commit pin (not the public install path). Ordinary CI
still installs Core from the reviewed merge commit until CI switches to PyPI
rextio 0.1.7; do not treat that pin as the public product install:
python3.11 -m pip install \
'git+https://github.com/rextio/rextio.git@b8b8ed11f6b7b7aae4c7ae5205d88529608e8e97' \
'torch==2.11.0'
python3.11 -m pip install --no-deps -e .
Historical 0.1.2 evidence (not the current product install)
To reproduce the reviewed 0.1.2 / plugin API 1.6 source evidence exactly, install the historical Core commit and that era's checkout without dependency resolution:
python3.11 -m pip install \
'git+https://github.com/rextio/rextio.git@7f47f0ce8cea0b6dbeb7fd3c733f65eeaa6bb5e0' \
'torch==2.11.0' 'pytest==9.1.1' 'ruff==0.15.22' 'mypy==2.3.0'
python3.11 -m pip install --no-deps -e .
The historical 0.1.2 evidence pins are Core
7f47f0ce8cea0b6dbeb7fd3c733f65eeaa6bb5e0 and CUDA provider
a5fb427e91710b65f54ee5b8e33706c45840cf9c. The provider is not a mandatory
package dependency; install it only for the maintainer CUDA orchestration/build
gate. That CUDA path remains build-only and non-certifying:
python3.11 -m pip install --no-deps \
'git+https://github.com/rextio/rextio-device-cuda.git@a5fb427e91710b65f54ee5b8e33706c45840cf9c'
export LIBTORCH_USE_PYTORCH=1
unset LIBTORCH_BYPASS_VERSION_CHECK
python3.11 scripts/build_cuda_candidate.py \
--output /tmp/rextio-torch-cuda-build-only
Plugin discovery and rextio_torch.types import without importing torch.
Real native builds need a matching torch 2.11 / libtorch environment and a Rust
toolchain, with:
export LIBTORCH_USE_PYTORCH=1
# never: LIBTORCH_BYPASS_VERSION_CHECK
# ensure `python` on PATH is the same CPython 3.11 env as PyO3 / Rextio
The dev extra includes packaging tools (build, twine,
check-wheel-contents) for release artifact checks.
Historical benchmarks (not a release gate)
Phase A and Phase B product-route benchmarks were preregistered and executed with fixed cells. Recorded numbers live under:
benchmarks/results/(Phase A)benchmarks/results_phase_b/(Phase B deep control)
Those runs measured boundary-inclusive latency and expansion GO criteria. For this Alpha cut they are historical evidence only — usefulness of the pinned AOT surface is the product goal, not beating a speedup threshold.
Residual platform risks
torch-sysdiscovers Python viaPATH/VIRTUAL_ENV, not onlyPYO3_PYTHON; a mismatched torch onPATHfails the exact 2.11.0 check.- Cold builds compile
tch/torch-sysfor each generated project. - The native extension must load under the same CPython 3.11 + torch 2.11.0 that built it.
- Certified real-Cargo evidence remains macOS arm64 only. Linux x86_64/AArch64 are experimental runtime-backed profiles; results there do not rewrite certification without a deliberate re-record.
- The eight-cell platform table is declarative and never probes or silently rejects the ambient host. Native CI calls its explicit runtime requirement before building; unavailable cells fail closed with stable reason codes.
- Linux residual risks include distro libstdc++/glibc differences, torch wheel
manylinux tags, and first-time
tchcompile cost — not silent OS rejection by this plugin. - Windows is deferred (unverified).
- Core limitation: method claims require named or call-chain receivers, not bare BinOp receivers.
- Release artifacts are built from clean
mainand checked independently from the historical benchmark evidence.
Repository safeguards
- The temporary
Privateupload-block classifier was removed after supported-profile CI and clean merged-mainreview. - The annotated tag, PyPI artifacts, and live no-cache install are verified as separate release records rather than inferred from repository metadata.
- Do not use
LIBTORCH_BYPASS_VERSION_CHECK. - Do not add a project-local
AGENTS.mdwithout owner direction. - Package metadata identifies version 0.1.3 as Development Status Alpha. Product release does not promote the CUDA E2 build-only candidate.
For the longer product definition and phase history, see the 0.1.0 implementation plan. Historical benchmark protocols are indexed in benchmarks/README.md; this README is the current support surface.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rextio_torch-0.1.3.tar.gz.
File metadata
- Download URL: rextio_torch-0.1.3.tar.gz
- Upload date:
- Size: 277.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db9e2676da976d6b50818969079b87cf118e969f38120263e9113a7c9a2fe3f7
|
|
| MD5 |
7ae0bd850f118d4ce9d8f59a61a52d0e
|
|
| BLAKE2b-256 |
2b8e6715e413f273d192fc58ea4f2bcd8d0b79361cf28f4d063fce728d64b342
|
File details
Details for the file rextio_torch-0.1.3-py3-none-any.whl.
File metadata
- Download URL: rextio_torch-0.1.3-py3-none-any.whl
- Upload date:
- Size: 72.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d87d50f42c6f6c0c4217ae688811bd865a4352f3b33c9df7272b05491f352d0
|
|
| MD5 |
2a13097f0310613ec2d9573f6dea7d21
|
|
| BLAKE2b-256 |
dc74a992b99c5ff676ffd69f6a5d0b4c2d59322a2322b603ab4f75f8648ed265
|