elworthy
Why elworthy over Numba
Numba @njit is excellent for general-purpose Python loop acceleration. Where elworthy is unique:
| Property | Numba pathwise | elworthy BEL |
|---|---|---|
| Smooth payoff delta (call) | correct, fast | correct, ~equal speed |
| Digital / barrier delta | silently returns 0 (Dirac in f') |
unbiased, hits analytic within stderr |
| Weight derivation | user writes the integrator | symbolic synthesis from the SDE |
| Output type | Numba arrays (no autograd) | plain NumPy → Torch / JAX backprop free |
Demo: python python/benchmarks/demo_digital_payoff_correctness.py shows Numba pathwise digital delta = 0.000 (bias -0.0197) vs elworthy BEL 0.0198 (bias +0.0001) against analytic 0.0197.
A Rust JIT compiler that specialises Bismut-Elworthy-Li formulas into SIMD kernels for unbiased Monte Carlo Greeks on non-stationary SDEs. Python bindings ship on PyPI: pip install elworthy. The Python API returns per-path Malliavin weights as NumPy arrays so users compose payoffs in NumPy / PyTorch / JAX and stay inside their autodiff framework of choice.
Named after K. David Elworthy, co-author of the Bismut-Elworthy-Li integration-by-parts formula:
$$ \partial_x \mathbb{E}[f(X_T) \mid X_0 = x] = \mathbb{E}\left[ f(X_T) \cdot \frac{1}{T} \int_0^T \sigma^{-1}(X_s)^\top \partial_x X_s \mathrm{d}W_s \right]. $$
elworthy takes a symbolic SDE, symbolically differentiates its coefficients, synthesises the Malliavin weight for a requested Greek, and lowers the entire inner-loop body (state update + weight accumulation + payoff) to a single kernel via Cranelift. Each SIMD lane carries one independent Monte Carlo path.
Status
v0.1. Ships:
- Full scalar Cranelift JIT with
exp,log,sin,cos,sqrtvia libm. - 2-lane SIMD
VectorKernel(Cranelift F64X2) covering everyFunvariant per lane; F64X4 scaffolded behind thesimd_avx2feature flag with runtime CPU detection. - In-memory structural-hash kernel cache + disk-persisted AST cache at
$XDG_CACHE_HOME/elworthy/. - Euler-Maruyama and Milstein discretisations for scalar SDEs; multi-dimensional Euler driver with full-truncation clamping for CIR/variance-type components.
- Greek drivers:
- Delta, constant-flow Bismut-Elworthy-Li (GBM / ABM).
- Delta, general tangent-flow Bismut-Elworthy-Li (any scalar SDE).
- Delta, multi-dim pathwise tangent flow (Heston and friends).
- Rho, vega, and arbitrary parameter Greeks, pathwise (smooth payoffs, any scalar SDE).
- Rho and vega for GBM via the likelihood-ratio Malliavin weight, valid for non-smooth payoffs (digitals, barriers); derivation machine-checked with SymPy.
Architecture
elworthy/
├── elworthy-expr/ symbolic AST, canonicalisation, CSE
├── elworthy-diff/ automatic symbolic differentiation
├── elworthy-weight/ Bismut-Elworthy-Li weight synthesis
├── elworthy-codegen/ Expr -> Cranelift IR lowering + scalar interpreter
├── elworthy-rt/ kernel cache, SIMD RNG, Monte Carlo driver
└── elworthy/ CLI + examples
Each subcrate has its own README.
Performance
On a development laptop (x86_64, single core, release profile):
| Scenario | throughput (M path-steps/s) | speedup vs interpreter |
|---|---|---|
| GBM price, tree-walking interpreter | 6.8 | 1.0x |
| GBM price, scalar Cranelift JIT | 150 | 22x |
| GBM price, 2-lane SIMD JIT | 187 | 27x |
| GBM price + Bismut-Elworthy-Li delta | 152 | 22x |
| Heston price (2-D) | 55 | 8x |
| Heston price + pathwise delta (2-D, full Jacobian) | 16 | 2.3x |
Kernel cache hit: 64 ns per retrieval vs ~100 us for a cold Cranelift compile, a 1500x speedup on calibration inner loops.
Cross-validation. The JIT+BEL stack is cross-validated against Black-Scholes closed form (inline, libm::erf) and the independent blackscholes crate (v0.24). On a European call at S_0 = K = 100, r = 0.05, sigma = 0.2, T = 1, 200 000 Milstein paths x 512 steps, elworthy's Monte Carlo price and Bismut-Elworthy-Li delta agree with both analytic references within four Monte Carlo standard errors. Full table in BENCHMARK.md.
Reproduce with:
cargo test --release -p elworthy-rt --test benchmark -- --nocapture --ignored
See BENCHMARK.md for full methodology, caveats, and reproducibility notes.
Install
cargo add elworthy-rt elworthy-expr
Or the CLI:
cargo install elworthy
Quick start (CLI)
elworthy gbm --backend jit --paths 10000
elworthy gbm-delta --paths 40000
Expected output for gbm-delta at default parameters:
price ~ 105.12xx (stderr 0.14xx) | closed form 105.1271
delta ~ 1.05xx (stderr 0.02xx) | closed form 1.0513 [Bismut-Elworthy-Li]
SELinux note (Fedora / RHEL)
The JIT backend requires execmem permission so Cranelift can map newly generated code as executable. Under SELinux enforcing this is denied by default for user binaries and you will see
Error: cranelift module error: Backend error: unable to make memory readable+executable
Workarounds:
- Run via
cargo test(the test harness domain already grantsexecmem). - Temporarily relax policy with
sudo setsebool -P selinuxuser_execheap 1. - Use
--backend interpfor a JIT-free run.
Ubuntu, Debian, macOS, and most CI runners do not hit this restriction.
Next milestones
VectorKernel4(AVX2 F64X4) behind thesimd_avx2feature.- General-SDE Malliavin parameter weight (without relying on a closed-form transition density).
- Gamma via second-order Bismut-Elworthy-Li.
- QuantLib reference benchmarks for Heston delta.
Licence
Apache License 2.0. See LICENSE.
Metadata
Release files for elworthy 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| elworthy-0.1.3.tar.gz | 74.1 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| elworthy-0.1.3-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 3.1 MB
Release files / elworthy-0.1.3.tar.gz
| Download URL | elworthy-0.1.3.tar.gz |
|---|---|
| Size | 74.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
efc07eef0c921af3b0153af1f5b2c35a9f6ce0b016efc944e315c64fff8a469d
|
|
BLAKE2b-256 checksum How to use checksums |
036e77858b7e84ef263671c150d803f67aefdefdb7f188e6f1c95d4ed8803524
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency logRelease files / elworthy-0.1.3-cp310-abi3-win_amd64.whl
| Download URL | elworthy-0.1.3-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 200.5 kB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bc067896afa595536a5a470ed4dd6fb453e49ac22bf544eb2cc34e45582edc63
|
|
BLAKE2b-256 checksum How to use checksums |
a0f596887829e5d2e3fe1f5e59764f0b58a23f42246ce2ffdad73d6e100ab1b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency logRelease files / elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | elworthy-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0490bf6ea8308ff368c5c348b8fb1d125f999e35883384e8143226876af8baca
|
|
BLAKE2b-256 checksum How to use checksums |
0750e136fdf7536ffe22db004870aa2e829c50f62c8e98207dc1a8061168fd56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency logRelease files / elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | elworthy-0.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.0 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
59ef3ca44675336b8b3f187c03d11ef9333086874d4114045c7f82f1ccd6c592
|
|
BLAKE2b-256 checksum How to use checksums |
7cc4ab9cd47023b0b9025ee32cbd84bca2356791bbf078e4f53d5ad7956478ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency logRelease files / elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | elworthy-0.1.3-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 301.2 kB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2f615b44d5a387f4191335ceb8732a8faa65c0f8d255b60f92d097be94f05cfb
|
|
BLAKE2b-256 checksum How to use checksums |
902f7d2035c7b88414d39dbe562a89865d03b8007cf42d68d6e6a3729fb0a20d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency logRelease files / elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | elworthy-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 309.2 kB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
ed122f9eaf08bd348264f7fad42dc4bc6b2e6b450b10a657b1edb4d7e5f043f2
|
|
BLAKE2b-256 checksum How to use checksums |
1ea241ee81106b50e5d5900d783ddc98851c7969fcd112a5f002cbfbb2c61779
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 13, 2026.
Transparency log