JIT unit-stripping decorator: write Pint-annotated code, run at float speed
Project description
unit-jit
JIT unit-stripping decorator for Pint-annotated Python. Write clean, unit-safe code; pay no Pint overhead in hot loops.
from unit_jit import unit_jit, ureg
@unit_jit
def simulate(n: int) -> np.ndarray:
mrna = 10.0 * ureg.mol / ureg.L
dt = 0.1 * ureg.s
delta = 0.01 / ureg.s
out = np.empty(n)
for i in range(n):
mrna = mrna - delta * mrna * dt
out[i] = mrna.to_base_units().magnitude
return out
First call runs the original Pint function (warm-up). All subsequent calls run a rewritten, pure-float version — ~10× faster for tight loops.
How it works
- Module-level compilation — on first call, all
@unit_jitfunctions in the same module are rewritten together:.magnitude,.to_base_units(), andcast("Quantity", x)are stripped from the source. - Eager snapshot — Quantity attributes on objects (e.g.
self.params.alpha) are pre-converted to SI floats once at boundary entry. Attribute access inside the loop is a plain dict lookup. - Fast zone — a thread-local flag marks the outermost
@unit_jitframe. Inner@unit_jitcalls skip boundary conversion entirely. - Return wrapping — the SI unit of the return value is inferred from the first call and used to wrap subsequent results back into
Quantity. - Dimension guard — argument dimensions are cached from the first call; any later call with a different dimension raises
TypeErrorimmediately.
The right entry point is the outermost function that owns the hot loop — not the leaf functions it calls.
Installation
# uv (recommended)
uv add unit-jit
# pip
pip install unit-jit
From source:
git clone ...
cd unit-jit
# uv
uv sync --extra dev
# pip
pip install -e ".[dev]"
Usage
Simple function
from unit_jit import unit_jit, ureg
@unit_jit
def velocity(d, t):
return d / t
velocity(10 * ureg.m, 2 * ureg.s) # warm-up (runs Pint)
velocity(10 * ureg.m, 2 * ureg.s) # fast (pure float internally)
velocity(10 * ureg.cm, 2 * ureg.s) # fine — same dimension, different unit
velocity(10 * ureg.m, 2 * ureg.m) # TypeError — wrong dimension for arg 1
Class with Quantity attributes
from dataclasses import dataclass
from unit_jit import unit_jit, ureg
@dataclass
class Params:
alpha: Quantity # [mol/L/s]
delta: Quantity # [1/s]
class Model:
def __init__(self, params):
self.params = params
@unit_jit
def rate(self, mrna):
return self.params.alpha - self.params.delta * mrna
@unit_jit # ← entry point: owns the hot loop
def simulate(self, n):
mrna = self.params.alpha / self.params.delta
out = np.empty(n)
for i in range(n):
mrna = mrna + self.rate(mrna) * (0.1 * ureg.s) # rate() in fast zone
out[i] = mrna.to_base_units().magnitude
return out
self.params.alpha and all other Quantity attributes are converted to SI floats once when simulate is first called fast; self.rate() is called from inside the fast zone, so it skips boundary conversion entirely.
Running tests
pytest
License
Apache-2.0
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 unit_jit-0.1.0.tar.gz.
File metadata
- Download URL: unit_jit-0.1.0.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
202fd71bed16126d5d4f285858d176d36cba5c1aeed4a033873ded2a94558c7b
|
|
| MD5 |
06849fddee680a59c6142599500acd87
|
|
| BLAKE2b-256 |
d3d872e3d3d8b78c47ee41b8bef72f8a19511a79a02f6722a17b9acdad648d6f
|
File details
Details for the file unit_jit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: unit_jit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3896ff080ea386398f44bfcf63ec4d51daced7c8f61e8bdfde8d136a0b481fe1
|
|
| MD5 |
a9e5f97c023bffea8e714f87384c862e
|
|
| BLAKE2b-256 |
a8364c7c5d15cccabdce6654289205ef9d8ca85d3dcb7936268dbc7dea1dff3d
|