Skip to main content

Make OSDI device models (Verilog-A compiled to .osdi) differentiable via JAX

Project description

bosdi — Batched OSDI

CI License: MIT Python 3.13 Platform: Linux | macOS Status: Experimental

Experimental — bosdi is under active development. The OSDI binary evaluation path is stable and well-tested, but the Verilog-A to JAX lowering compiler (bosdi.va) is in alpha and its API may change without notice. The VA lowering depends on a custom fork of OpenVAF that exposes the compiler's intermediate representation; this fork is not yet merged upstream.

Evaluate OSDI device models (Verilog-A compiled to .osdi binaries) in batched parallel via JAX.

Two evaluation paths

bosdi provides two ways to evaluate Verilog-A compact models inside JAX:

OSDI binary path (stable)

Loads a pre-compiled .osdi binary and evaluates N device instances in parallel via Rayon inside a JAX XLA custom call. The OSDI ABI provides analytical Jacobians with respect to node voltages only (conductances dI/dV, capacitances dQ/dV). A @custom_jvp rule makes jax.grad() work through node voltages — but not through model parameters or state.

from osdi_loader import load_osdi_model
from osdi_jax import osdi_eval

model = load_osdi_model("path/to/device.osdi")
N = 1024
voltages = jnp.zeros((N, model.num_nodes), dtype=jnp.float64)
params = jnp.full((N, model.num_params), jnp.nan, dtype=jnp.float64)
old_state = jnp.zeros((N, model.num_states), dtype=jnp.float64)

cur, cond, chg, cap, new_state = osdi_eval(model.id, voltages, params, old_state)

# jax.grad works through node voltages
grad_fn = jax.grad(lambda v: osdi_eval(model.id, v, params, old_state)[0].sum())

VA to JAX lowering (alpha)

Compiles Verilog-A source directly into pure JAX/Python, producing a function that is fully differentiable through all inputs — voltages, parameters, and temperature. This enables parameter optimization, sensitivity analysis, and end-to-end gradient-based design flows that the OSDI path cannot support.

Requires openvaf-r (a custom OpenVAF fork).

python -m bosdi.va device.va

When to use which

OSDI binary VA to JAX
Use case Circuit simulation (Newton solve) Parameter fitting, sensitivity analysis, inverse design
Differentiable w.r.t. Node voltages only Voltages, parameters, and temperature
Performance Fast — Rayon-parallel C/Rust, batched XLA FFI Pure Python/JAX — slower per-eval, but composable with jax.jit/jax.vmap
Maturity Stable Alpha
Dependencies None beyond bosdi openvaf-r fork

The OSDI path treats the compiled model as a black box and extracts only what the ABI exposes: currents, charges, and their Jacobians w.r.t. node voltages. This is exactly what a Newton solver needs, but the parameter axis is opaque to JAX — you cannot backpropagate through it.

The VA to JAX path exists to remove that limitation. By lowering the Verilog-A source into native JAX operations, every computation becomes visible to JAX's autodiff, making the model fully differentiable. This is what enables gradient-based parameter extraction, design-space exploration, and end-to-end optimization of circuits where device parameters are the degrees of freedom.

Architecture

OSDI path:
  Python: osdi_eval()  →  JAX XLA custom call
    →  C++ (nanobind/XLA FFI): unpack buffers
      →  Rust (Rayon): evaluate N devices in parallel
        →  OSDI binary: currents, conductances, charges, capacitances

VA path:
  Verilog-A source  →  openvaf-r (MIR dump)
    →  bosdi.va lowering + SCCP optimization
      →  Pure JAX/Python function (fully differentiable)

Installation

Using Pixi (recommended)

git clone https://github.com/gdsfactory/bosdi && cd bosdi
pixi run build

Using pip

pip install bosdi

Build & test

pixi run build   # compile Rust static lib + C++ extension
pixi run test    # run pytest suite

# single test
pixi run pytest tests/test_osdi.py::test_resistor_dc_evaluation -v

OSDI outputs

The OSDI path returns per-device arrays shaped by model.num_nodes (terminals + internal nodes + branch-current auxiliaries):

Output Shape Description
cur [N, num_nodes] Resistive current residual at each unknown
cond [N, num_nodes²] G = ∂cur/∂V Jacobian (flattened row-major)
chg [N, num_nodes] Charge residual at each unknown
cap [N, num_nodes²] C = ∂chg/∂V Jacobian (flattened row-major)

Pass jnp.nan for any parameter to use its Verilog-A default. Parameters can be addressed by name via model.param_names. See tests/test_bsim4_model_card.py for a full example.

Further reading

  • OSDI technical reference — parameter handling, model introspection, output layout, host-simulator integration (companion method vs MNA/DAE), and debug utilities

Limitations

  • Platform: Linux and macOS; Python 3.11+; OSDI 0.4 ABI only. .osdi binaries are platform-specific — compile from .va sources via openvaf-r on each target
  • OSDI differentiability: jax.grad() works through node voltages only, not model parameters — use the VA path for parameter gradients
  • Stateful models (num_states > 0): evaluation is skipped and outputs are zeroed
  • VA lowering (alpha): user-defined analog function calls and noise contributions are not yet supported

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bosdi-0.1.5.tar.gz (238.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bosdi-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bosdi-0.1.5-cp313-cp313-macosx_11_0_arm64.whl (849.0 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

bosdi-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bosdi-0.1.5-cp312-cp312-macosx_11_0_arm64.whl (850.3 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file bosdi-0.1.5.tar.gz.

File metadata

  • Download URL: bosdi-0.1.5.tar.gz
  • Upload date:
  • Size: 238.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bosdi-0.1.5.tar.gz
Algorithm Hash digest
SHA256 77dfb0e9de326b062b2f2092fbf2e2b6ecb2fd5903772d79dba429df61d5e744
MD5 bfa70a87144f7e0bfcae53e16d7c7e9b
BLAKE2b-256 371201b9473616b8a5d098884ae5a12059a2b968bda8c180552234b2edebf3c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosdi-0.1.5.tar.gz:

Publisher: release.yml on gdsfactory/bosdi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bosdi-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bosdi-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3a67b15efa120342b586340c4b41efb4916b94d840f034fb604dea322267183c
MD5 dd236894f305be7c0bcf2c340151b692
BLAKE2b-256 4df65a1e9ebca0701ed239c188d3e18174c8af792bd57192f0c177378086170e

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosdi-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yml on gdsfactory/bosdi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bosdi-0.1.5-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bosdi-0.1.5-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d03c1ab4a2415c9e985bbca05df33d5ec8dc93de9df6494fb7808feba34e3dd8
MD5 1879a20f50fbeeb37f9d9f15e39690dc
BLAKE2b-256 312050e260ffe4e9c4b1a2c15d10d6578e08bb8276d49248b4e5c8be0e8bd916

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosdi-0.1.5-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on gdsfactory/bosdi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bosdi-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bosdi-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2e249f96ade8f45a3b321a5065d50ad8beae15c6c5e5951ee1547706324be2bc
MD5 6efec0607876c8a43ca937969ded402d
BLAKE2b-256 fae1ed6b88a1d9f015f0bb72aa7ec2b9c7e3547f6f30eb3179618d464e3399ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosdi-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yml on gdsfactory/bosdi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bosdi-0.1.5-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for bosdi-0.1.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bce01d67fbb97aa7f014fc3c9aae9a83829036b26a9fe74689872ea0fe4ced81
MD5 dcc129693769984789212883e4bf7077
BLAKE2b-256 e6d3e8d34617e9b9ddc6315598e3e85d11af35a4379d882f97b3c74b4318d8ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosdi-0.1.5-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on gdsfactory/bosdi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page