raptor
raptor: one manifest, any engine
A compiled GPU kernel ships with a small JSON file that says what it takes, what it returns and where it can run. raptor defines that file, so one package can build a kernel and another can run it.
Runs on: CPU, no GPU needed · You need: Python 3.9+, nothing else to install raptor itself
raptor holds the shared contracts of the RAPTOR family: the manifest format and certification contracts that let a kernel built once work with the code you already have. See where RAPTOR fits for how the four pieces combine.
| 0 | 4 | 1 |
|---|---|---|
| hard dependencies (pure Python) | array libraries certified: NumPy, CuPy, PyTorch, Warp | JSON manifest per kernel bundle (a kernel's compiled artifact(s) plus its manifest) |
See it working: orbits from hand-written physics plus a small learned drag correction, trained in torch and compiled into one kernel — Demo has the commands and output.
For package authors
from raptor.schema import validate_manifest
manifest = {
"schema_version": 2,
"pattern": "pure",
"aether_abi": "aether-abi/2",
"exec_targets": ["host", "device"],
"exec_access": "sample_local",
"plugins": [{"id": "two_body_step", "order": 0, "enabled": True, "artifact": "two_body_step.ptx",
"sidecar": "two_body_step.json", "format": "ptx"}],
}
validate_manifest(manifest) # raises on a malformed or out-of-order document
| key | meaning |
|---|---|
schema_version |
which rules this document follows |
pattern |
which kind of kernel this is; pure = no side effects |
aether_abi |
the binary-format tag paired with schema_version (e.g. "aether-abi/2" for v2) |
exec_targets |
host / device: where this kernel may run |
exec_access |
how it touches per-sample vs. cross-sample data |
plugins |
the compiled artifact(s) this manifest describes (ptx = NVIDIA's GPU assembly format) |
Any class with a matching build(directory) method satisfies
ManifestProvider — "duck typing": judged by which methods exist, checked
with isinstance, never by which class it inherits from:
from raptor.protocols import ManifestProvider
class Bundle:
def build(self, directory):
return f"{directory}/manifest.json"
isinstance(Bundle(), ManifestProvider) # True — duck-typed, no inheritance needed
Threading
Free-threaded CPython (3.13t/3.14t) is supported: the compiled modules declare GIL-free operation and the GIL stays disabled after import. Any number of threads may call module-level functions, build, compile, plan and cache concurrently. Distinct objects may be used from distinct threads without synchronisation. One stateful object (a stream, capture, launcher, graph, composer, plan, pipeline, active set, host kernel or arg block) shared by several threads is memory-safe — its calls serialise and a consumed object raises — but the ORDER of those calls is the caller's responsibility, exactly as for a NumPy array or a CuPy stream. CUDA adds two rules of its own: a stream capture is begun, filled and ended by one thread, and while any capture is open no thread may synchronise the whole device (stream-level synchronisation is fine). GPU routes are supported on free-threaded 3.14; on 3.13t the CPU route runs.
Install
pip install raptor-core # Python 3.9+, no dependencies
The import name is raptor. The rest of the family (hawk, eagle) and the GPU extras: installation.
To work on the code, from a clone: git clone https://github.com/amasat01/raptor.git, then pip install -e .. Test with pip install pytest && pytest tests -m "not cross_repo" (-m "not cross_repo" leaves out the tests that check eagle against raptor's contracts — they need
an eagle checkout next to this one, and fail rather than skip without it). To set up a development machine for
the whole family, see tools/devbox/.
Demo
examples/two_body_hybrid.py is a small end-to-end example: a batch of
orbits propagated by a hand-written physics formula plus a small learned
correction, traced into one compiled kernel that this package's manifest
describes. See Going deeper below for exactly
what it computes and prints.
# CPU route: hawk and eagle come from PyPI (no extras, no nvcc); [demo] adds numpy and torch.
# The default Linux torch wheel bundles the CUDA libraries (several GB); for a small CPU-only install run
# pip install torch --index-url https://download.pytorch.org/whl/cpu first, then the lines below
git clone https://github.com/amasat01/raptor.git && cd raptor
pip install raptor-hawk raptor-eagle
pip install -e ".[demo]"
python examples/two_body_hybrid.py --host
On a GPU, install the CUDA extras instead of the plain hawk and eagle line and run the device comparison:
pip install "raptor-hawk[cuda12]" "raptor-eagle[cuda12]" # or [cuda13] on both
python examples/two_body_hybrid.py --device --steps 400 --batch 65536
--host prints the following (output of python examples/two_body_hybrid.py --host; the wall-per-step line varies by
machine, everything above it is exact, the same seed every run):
target : host (manifest exec_targets ['host'])
batch x steps : 1024 x 200 at dt = 0.01
training loss : 1.230e-06
(a) max |compiled - torch eager| : 1.788e-06 (tolerance 1e-04)
(b) final-state error vs truth : corrected 6.491e-03 vs two-body only 1.930e-01
Lines (a) and (b) show the run is right. Line (c) compares time per step; at this batch on CPU threads, torch eager is the faster one, and the compiled step pays off on a GPU (the --device run). To see which is faster on your machine, run python examples/two_body_hybrid.py --host --batch 1024 and read line (c); change --batch to try other sizes.
Going deeper (optional)
What the demo computes, package internals, and three scripts' own machine-local measurements — none of it needed to install or use raptor.
What's inside
raptor.schema— the kernel-manifest schema, two layers:schema.manifest(the core layer every producer writes against) andschema.blocks(theneural_blockextension; hawk never imports it).schema.dtypescarries the scalar-type tag vocabulary.raptor.schema.validate_manifest(doc)is a minimal shape validator (key order, top keys, schema_version, pattern vocabulary) — not a port of eagle's deepvalidate_sidecar. Schema versions 1 and 2 both load (manifest.MAX_SCHEMA_VERSION): v2 adds three flat, versioned top-level keys —exec_targets(device/hostlist),exec_access(sample_local/cross_sample_read/cross_sample_write/mapreduce),exec_op(required iffexec_access="mapreduce") — and requiresaether_abi: "aether-abi/2"; v1 rejects anyexec_*key outright (manifest.check_execution_axis).raptor.protocols— thetyping.Protocoldefinitions:Backend/Executable(program-level execution),KernelLauncher/Marshal(kernel-level launch/marshal, mirroring eagle's public surface 1:1),ManifestProvider(the kernel-provider protocol's one facet).raptor.conformance— the interop certification declaration (UNIVERSE/CERTIFIED/ROADMAP/ROWS) and its reusable matrix-hygiene scanners; the full row-by-row certification matrix is on the interop protocols page.goldens/— the golden conformance corpus (harvested from eagle's test fixtures) thatraptor.schema.validate_manifestis exercised against.tests/*cross_repo*: the eagle conformance battery (test_verbatim_against_eagle.py,test_goldens.py), markedcross_repoand failing rather than skipping when a sibling checkout is absent — deselected here only via-m "not cross_repo", run for real by the local gate and a downstream package's own CI.raptor.schema.manifest.SCHEMA_VERSIONis the cross-repo pin (1; the highest accepted version isMAX_SCHEMA_VERSION, 2);eagle.roles.SCHEMA_VERSIONderives from it directly, so no standalone text-scan cross-check is kept as a redundant leg.
What the demo computes
A batch of planar orbits is propagated with RK4 (a standard 4th-order numerical-integration formula). The textbook two-body formula is written by hand; the piece it misses — drag — is learned by a small (4 → 32 → 2) neural network trained in torch on CPU. hawk traces ONE kernel that performs a whole RK4 step with the network evaluated inline, compiles it, and publishes it with a manifest this package's schema validates; eagle loads that manifest and runs the kernel, either on CPU threads or as a replayed CUDA graph (a GPU's sequence of launches recorded once and replayed without re-issuing each one). The script prints how closely the compiled rollout tracks a plain torch rollout of the same arithmetic, how much closer to the truth the corrected orbits land than uncorrected ones, and a wall-per-step line.
early termination: samples that finish at different times (measured when the script runs — numbers vary by machine)
examples/early_termination.py shows the other half of this one-kernel
idea: irregular work whose samples finish at different times, with the host
out of the loop. A batch of planar orbits ends when it crosses a collision
or an escape radius, and a device-side live count guards each step with a
conditional graph node (a graph step that can skip itself at replay time),
so the whole horizon is queued as graph replays with zero host round-trips
until every sample is done — later replays then do no work at all. Measured
against the identical captured graph with the guard removed (so the guard
is the only difference), the skip is a real wall-clock saving that scales
with how much of the horizon runs past the last termination — this
script's own measurement, on your machine; the card below records the figure from the machine that built this page, for a million samples over 4000 steps. The script also runs
the same kernel eagerly, host-side guard check and all: at a million samples the
guarded graph and this host-guarded eager loop are about equal on the Quadro P2000 (see the card below; the kernel itself
dominates there); at the smallest batches (1, 32 samples) the skip does not
pay for itself — the conditional node's own fixed cost exceeds a tiny
kernel's, so the unguarded graph is the fastest arm. The eager loop also
carries one host round-trip per two-step replay against the graph's one for
the whole captured horizon, a gap the numbers above already price in. CPU
mode (--host) runs the same kernel with the guard evaluated eagerly, so it
needs no GPU. --torch (device only) times the same RK4 two-body physics
written in idiomatic torch — eager, eager with a host check, and both as a
replayed CUDA graph — against the guarded graph and prints each arm's ratio.
Run it yourself for your own machine's numbers.
python examples/early_termination.py --host
python examples/early_termination.py --device
python examples/early_termination.py --device --torch
zero-copy interop (measured when the script runs — numbers vary by machine)
examples/zero_copy_interop.py backs the third leg of the same idea:
exchanging GPU arrays with NumPy, CuPy and PyTorch without copies, and only
where the family's own certification matrix says there is none. A
CUDA-resident torch tensor is handed straight into one hawk kernel through
eagle's zero-copy to_cupy view, and the kernel writes its result into a
second torch CUDA buffer through the same view — no allocation, no copy,
matching the aliasing rows of raptor's interop matrix
exactly. The same tensor read from
CPU memory instead takes the honest upload the matrix declares as a copy.
The script prints each crossing's measured pointer
identity next to the row that covers it, and a behavioural proof for the
input alias: mutating the torch tensor in place and replaying the same
kernel with no rebind shows the output tracking the change. --device also
times that alias path against the copying round-trip a caller without this
protocol would naturally write — this script's own measurement, on your machine; the card below records the figure from the machine that built this page, at 256 MB. CPU mode (--host) needs neither a GPU nor torch: it runs the same
kernel on CPU threads with plain numpy in and out.
python examples/zero_copy_interop.py --host
python examples/zero_copy_interop.py --device
autodiff vs. torch (measured when the script runs — numbers vary by machine)
examples/autodiff_vs_torch.py closes the loop on the same one-kernel
idea: hawk differentiates the traced kernel itself rather than executing a
separate tape. One RK4 two-body step is traced once, and hawk.diff.vjp/
jvp derive a reverse-mode gradient kernel (vjp: given a cotangent — a
weighting of the output — produce the matching weighting of the input) and
a forward-mode directional-derivative kernel (jvp: given a tangent — a
direction in the input — produce the matching direction in the output) from
it, published in the same manifest as the primal (the original, undifferentiated
kernel). --device checks both against torch.autograd.grad and
torch.func.jvp on the identical physics written in torch, and against a
float64 finite-difference Jacobian (the matrix of every output's derivative
with respect to every input, approximated numerically) so the check does
not rest on torch alone; every plane (one array per sample) in and out — the
state, the cotangent, the tangent, both derivative outputs — is a torch CUDA
tensor crossing through eagle's zero-copy to_cupy view, read back from
torch's own storage. It also times hawk's vjp/jvp kernels against torch's,
and each side's primal alone so the derivative's own overhead is visible.
The measured headline, generated from the committed performance cards (details on the
performance page):
hawk + eagle (eagle.simulate) integrates 1,000,000 RK4 oscillators, each stopping at its own step, in 613 µs on an NVIDIA H100 80GB HBM3 (199 µs for 100,000), 2.5×–600× faster than NVIDIA Warp (2.5×), JAX (76×), CuPy (600×), PyTorch with torch.compile (130×) at N = 1,000,000 (1.1×–1700× at N = 100,000), in 40 MiB of GPU memory
Measured on the machine that built this page, from the committed cards under benchmarks/:
- Guarded graph (Quadro P2000): 1,000,000 samples over 4,000 steps, the last one stopping at step 285; 13.8x faster per step than the unguarded control and 1.02x the speed of the eager loop.
- Zero-copy alias (Quadro P2000): a 256 MB buffer crosses 155x faster as an alias than through the copying round-trip.
- hawk vjp / jvp vs torch (Quadro P2000): across a batch sweep from 1 to 1,048,576 samples, hawk's vjp measured 67.2-179x faster per call than
torch.autograd.gradand its jvp 63.3-578x faster thantorch.func.jvp; at 1,048,576 samples 91.2x and 63.3x. hawk's derivatives cost 0.952-1.52x their own primal.
Script md5s: early_termination_card.py=da8723e95522e5806d722c7bd55d25f4, zero_copy_interop_card.py=3d2ced36cc2fa0236ca980e15bc77792, autodiff_vs_torch_card.py=a917a7b2f5f77a3b3594255d90fa9515
CPU mode (--host) needs no GPU or cupy; its reference is the float64
finite difference alone, with torch (if installed) added as an optional CPU
cross-check.
python examples/autodiff_vs_torch.py --host
python examples/autodiff_vs_torch.py --device
python examples/autodiff_vs_torch.py --sweep
hawk write it · eagle run it · aether the numerics core · raptor the shared contracts (this repo) — the RAPTOR family
Apache-2.0 (see LICENSE and
NOTICE) · cite via "Cite this repository"
(CITATION.cff; every tagged release is archived on Zenodo: doi:10.5281/zenodo.23250234) · built to
make GPU computing accessible on modest hardware, for research and education. Collaboration is the point, and a
citation is the currency — get in touch.
Metadata
Release files for raptor-core 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| raptor_core-0.3.1.tar.gz | 74.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| raptor_core-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.5 kB
Release files / raptor_core-0.3.1.tar.gz
| Download URL | raptor_core-0.3.1.tar.gz |
|---|---|
| Size | 74.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c9de3cda705671b0f7c3928409a2b115156fdfc84e0b7545c25085d0037158b2
|
|
BLAKE2b-256 checksum How to use checksums |
54835b16600b32947670cb89e7f0280ab40df99b51ae65c81a6919a310125fb5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / raptor_core-0.3.1-py3-none-any.whl
| Download URL | raptor_core-0.3.1-py3-none-any.whl |
|---|---|
| Size | 47.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b2a6056790cf8c3c2bdc99c6ddc6944cad421e966ab012f686f22aa66f164f65
|
|
BLAKE2b-256 checksum How to use checksums |
e27e868bb3a362b61a8296f2da7c10587fdf63710c72e5968a52a00ba6b1a02f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logSecurity for raptor-core 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for raptor_core-0.3.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.