Tesseract

Universal components for differentiable scientific computing

Tesseract allows you to compose solvers, geometry ops, ML models, and more into end-to-end differentiable pipelines — for optimization, inference, and training. Each component is containerized, language-agnostic, and supports any gradient implementation. Open source, published in JOSS.

Why Tesseract

Tesseract is built for the needs of differentiable systems that combine several moving parts and backpropagate gradients through them: solver-in-the-loop training, simulation-based inference, shape optimization, and more.

End-to-end gradients

Differentiate through your entire pipeline, no matter how gradients are computed. Mix analytic adjoints, autodiff, and finite differences freely.

Any language

Fortran, C++, Julia, JAX, PyTorch, or shell scripts. Your code stays in its native language, Python is the glue.

JAX native

Every Tesseract becomes a JAX primitive, with full support for grad, jit, and vmap.

Run anywhere

Share a Tesseract, get identical results on any laptop, cloud, or HPC cluster. No dependency conflicts, no version mismatches.

Self-documenting

Schemas, types, and API docs are generated from your code. Know exactly what any Tesseract expects and returns without reading its source.

Community-driven

Created at Pasteur Labs, developed with and for the community. Open source under Apache License 2.0.

How it works

Define a differentiable component in tesseract_api.py, build it into a container, and call it — including its gradients — from the CLI, REST API, or Python SDK. Compose multiple Tesseracts into end-to-end differentiable pipelines.

Define a Tesseract

# tesseract_api.py
import numpy as np
from pydantic import BaseModel
from tesseract_core.runtime import Array
from tesseract_core.runtime import Differentiable
from tesseract_core.runtime import Float64

class InputSchema(BaseModel):
    x: Differentiable[Array[(None,), Float64]]

class OutputSchema(BaseModel):
    y: Differentiable[Array[(None,), Float64]]

def apply(inputs: InputSchema) -> OutputSchema:
    # Replace with your FEM solver, mesh generator,
    # or neural surrogate
    return OutputSchema(y=inputs.x ** 2)

def jacobian(inputs: InputSchema, jac_inputs, jac_outputs):
    # Use autodiff, analytic gradients,
    # finite differences, ...
    return {"y": {"x": np.diag(2 * inputs.x)}}

Use it

$ tesseract build .
 [i] Built image my-tesseract:latest

$ tesseract run my-tesseract apply \
    '{"inputs": {"x": [3.0]}}'
# => {"y": {"object_type": "array", "shape": [1], ..., "data": {"buffer": [9.0], ...}}}

$ tesseract run my-tesseract jacobian \
    '{"inputs": {"x": [3.0]}, "jac_inputs": ["x"], "jac_outputs": ["y"]}'
# => {"y": {"x": {"object_type": "array", "shape": [1, 1], ..., "data": {"buffer": [6.0], ...}}}}
from tesseract_core import Tesseract

with Tesseract.from_image("my-tesseract") as t:
    result = t.apply(inputs={"x": [3.0]})
    # result["y"] => array([9.0])

    jac = t.jacobian(
        inputs={"x": [3.0]},
        jac_inputs=["x"], jac_outputs=["y"],
    )
    # jac["y"]["x"] => array([[6.0]])
import jax
from tesseract_core import Tesseract
from tesseract_jax import apply_tesseract

t = Tesseract.from_image("my-tesseract")
t.serve()

apply_jit = jax.jit(apply_tesseract, static_argnums=(0,))

out = apply_jit(t, {"x": x_array})
# out["y"] => Array([9.0])

jac_fn = jax.jacobian(
    lambda x: apply_jit(t, {"x": x})["y"]
)
# jac_fn(x_array) => Array([[6.0]])

t.teardown()

The example above defines a differentiable Tesseract and calls it from the CLI, Python, and JAX. Ready to build your own? The Get Started tutorial walks you through a complete example from scratch.

Demos

4D-Var Data Assimilation

A complete 4D-Variational data assimilation scheme for a chaotic dynamical system (Lorenz-96), built with a differentiable JAX Tesseract.

4D-Variational Data Assimilation for a Chaotic Dynamical System
CFD Flow Optimization

Optimize initial conditions of a 2D Navier-Stokes simulation so the vorticity evolves into a target image, via a JAX-CFD Tesseract.

Gradient-Based Optimization of Fluid Flows
FEM Shape Optimization

Compose a geometry Tesseract with a FEM solver Tesseract for end-to-end parametric structural optimization.

Parametric Shape Optimization with Differentiable FEM Simulation

The Tesseract Ecosystem

Tesseract Core is the foundation. Additional packages extend its capabilities.

Tesseract Core

CLI, Python SDK, and container runtime for wrapping and running differentiable components.

Tesseract Core Documentation
Tesseract-JAX

Embed Tesseracts as JAX primitives. Fully compatible with jit, vmap, and grad.

https://github.com/pasteurlabs/tesseract-jax
Tesseract-Streamlit

Auto-generate interactive web apps from running Tesseracts. No frontend code required.

https://github.com/pasteurlabs/tesseract-streamlit

Get Involved

Wrap your solver or model as a Tesseract, or compose existing ones into a new pipeline. Show us what you built in the community showcase, or help improve the project.