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.
Differentiate through your entire pipeline, no matter how gradients are computed. Mix analytic adjoints, autodiff, and finite differences freely.
Fortran, C++, Julia, JAX, PyTorch, or shell scripts. Your code stays in its native language, Python is the glue.
Every Tesseract becomes a JAX primitive,
with full support for grad, jit, and vmap.
Share a Tesseract, get identical results on any laptop, cloud, or HPC cluster. No dependency conflicts, no version mismatches.
Schemas, types, and API docs are generated from your code. Know exactly what any Tesseract expects and returns without reading its source.
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¶
A complete 4D-Variational data assimilation scheme for a chaotic dynamical system (Lorenz-96), built with a differentiable JAX Tesseract.
Optimize initial conditions of a 2D Navier-Stokes simulation so the vorticity evolves into a target image, via a JAX-CFD Tesseract.
Compose a geometry Tesseract with a FEM solver Tesseract for end-to-end parametric structural optimization.
The Tesseract Ecosystem¶
Tesseract Core is the foundation. Additional packages extend its capabilities.
CLI, Python SDK, and container runtime for wrapping and running differentiable components.
Embed Tesseracts as JAX primitives. Fully compatible with jit, vmap,
and grad.
Auto-generate interactive web apps from running Tesseracts. No frontend code required.
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.