diff --git a/AGENTS.md b/AGENTS.md index 7f9c31657..63a443a46 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,6 +30,14 @@ This file contains counter-intuitive rules and aspects of the Tesseract codebase - **Use pre-commit.** Run `pre-commit run --all-files` before committing. Hooks include Ruff for linting/formatting. If linting is failing, run via `pre-commit run --all-files`, not `ruff --fix` or similar, to ensure all hooks run. - **Follow conventional commits.** PR titles must follow the format: `type[(scope)]: description` (e.g., `feat(sdk): add new feature`). +## Demos + +- **Each demo lives in `demo//` with a `demo.ipynb` notebook** plus its Tesseract source, `requirements.txt`, and any companion images. The notebook is the published artifact; the rest supports it. +- **The docs build flattens demos.** `docs/conf.py` copies `demo//demo.ipynb` to `docs/content/demo/.ipynb` and copies companion images (`.png/.gif/.jpg/.svg`) flat into `docs/content/demo/`. So inside a notebook, reference images and sibling demos by bare filename (`illustration.png`, `cfd-optimization.ipynb`), **not** by relative path (`../cfd-optimization/demo.ipynb`) — the latter works on disk but breaks in the rendered docs. +- **Register new demos in the toctree.** Add the flattened name (`.ipynb`) to the `{toctree}` and a grid card in `docs/content/demo/demo.md`. +- **Notebooks are not executed at build time** (`nb_execution_mode = "off"`). Outputs are taken as committed, so run the notebook and save its outputs before committing — stale or missing outputs ship as-is. +- **Follow the shared demo template.** Notebooks open with a `# Title`, an "In this tutorial, you will learn how to:" numbered list, and a `## Context` section; progress through numbered `## Step N` sections; and close with `## Takeaways` (numbered, bolded lessons), a `### What's next` list, and a link to the [community forum](https://si-tesseract.discourse.group/). Keep the tone instructional and technical — confident/marketing framing belongs in the accompanying blog or forum showcase post, not the demo. + ## Architecture - **The runtime is separate from the CLI.** `tesseract_core.runtime` runs inside containers; `tesseract_core.sdk` and CLI run on the host. They don't share code or dependencies. diff --git a/demo/enzyme-lfortran/.gitignore b/demo/enzyme-lfortran/.gitignore new file mode 100644 index 000000000..214d3034c --- /dev/null +++ b/demo/enzyme-lfortran/.gitignore @@ -0,0 +1,3 @@ +# Generated figures (notebook + pipeline-diagram outputs). +# Regenerated on demand; copied into docs/static/blog/ by hand when publishing. +figures/ diff --git a/demo/enzyme-lfortran/README.md b/demo/enzyme-lfortran/README.md new file mode 100644 index 000000000..6beedb6b9 --- /dev/null +++ b/demo/enzyme-lfortran/README.md @@ -0,0 +1,179 @@ +# Enzyme AD: Differentiable 2D Thermal Solver + +This example demonstrates how to obtain **exact automatic derivatives** of a production-style Fortran thermal simulation without writing any manual adjoint code, using [Enzyme](https://enzyme.mit.edu/) for automatic differentiation at the LLVM IR level. + +## What it does + +The Tesseract wraps a 2D transient heat conduction solver: + +``` +rho * cp * dT/dt = div( k(T) * grad(T) ) + Q +``` + +with: + +- **Temperature-dependent conductivity**: `k(T) = k0 + k1*T` (nonlinear material model) +- **Mixed boundary conditions**: Dirichlet (hot wall), convection (Robin), and insulated (Neumann) +- **Multi-step explicit time integration**: the Fortran kernel runs the full time-stepping loop internally + +This is representative of the thermal solvers CAE engineers run in production — a structured-grid finite difference code with nonlinear material properties, mixed BCs, and a time integration loop. The key difference from a toy example is that **the nonlinear conductivity makes the Jacobian solution-dependent**, so you can't derive it analytically and hand-coding the adjoint is error-prone. + +Enzyme differentiates through the **entire time-stepping loop** (including the nonlinear stencil operations at each step), giving exact gradients of the final temperature field with respect to all material properties, boundary conditions, and initial conditions. + +## How it works + +The compilation pipeline is identical to the [1D Enzyme example](../fortran_enzyme/): + +``` +thermal_2d.f90 (Fortran source — 2D solver with k(T), mixed BCs, time loop) + │ + ▼ lfortran --show-llvm +thermal_2d.ll (LLVM IR) + │ + ▼ opt -O1 +thermal_2d_opt.ll (cleaned-up IR, ready for Enzyme) + │ + ▼ llvm-link with wrapper.c +combined.ll (Fortran IR + C wrapper with __enzyme_autodiff / __enzyme_fwddiff) + │ + ▼ opt --load-pass-plugin=LLVMEnzyme-19.so -passes=enzyme +ad.ll (LLVM IR with compiler-generated forward and reverse mode derivatives) + │ + ▼ clang -shared +libthermal_2d_ad.so (shared library: forward, JVP, VJP entry points) +``` + +At runtime, `tesseract_api.py` loads `libthermal_2d_ad.so` via `ctypes` and exposes: + +- **`apply`** — runs the full forward simulation (all time steps) +- **`jacobian_vector_product`** — Enzyme forward-mode (JVP) through the full simulation +- **`vector_jacobian_product`** — Enzyme reverse-mode (VJP) through the full simulation + +## Physics + +### Governing equation + +2D transient heat conduction with temperature-dependent conductivity and volumetric heat source: + +``` +rho * cp * dT/dt = d/dx(k(T) * dT/dx) + d/dy(k(T) * dT/dy) + Q +``` + +### Material model + +``` +k(T) = k0 + k1 * T +``` + +Default values model mild steel: `k0 = 45 W/(m·K)`, `k1 = -0.01 W/(m·K²)`. + +### Boundary conditions + +| Boundary | Type | Condition | +| ------------ | ------------------- | -------------------- | +| Bottom (y=0) | Dirichlet | T = T_hot | +| Top (y=Ly) | Convection (Robin) | -k ∂T/∂n = h(T - T∞) | +| Left (x=0) | Insulated (Neumann) | ∂T/∂x = 0 | +| Right (x=Lx) | Insulated (Neumann) | ∂T/∂x = 0 | + +### Discretization + +- Structured rectangular grid (nx × ny) +- Central differences in space with harmonic-mean conductivity at cell faces +- Explicit Euler in time + +## Why AD matters here + +With constant thermal conductivity, the Jacobian of the heat equation is a constant tridiagonal (or banded) matrix that you could derive by hand. But with `k(T) = k0 + k1*T`: + +1. The stencil coefficients depend on the current temperature field +2. The Jacobian changes at every time step +3. Hand-coding the adjoint through the nonlinear stencil and multi-step loop is tedious and error-prone +4. Finite differences require N+1 forward solves for N parameters + +Enzyme gives you exact gradients through the entire nonlinear time-stepping loop for the cost of roughly one additional forward solve (for reverse mode). This enables: + +- **Material property calibration**: fit k0, k1 to match experimental temperature measurements +- **Boundary condition estimation**: infer h_conv or T_hot from sensor data (inverse heat transfer) +- **Design optimization**: optimize geometry (Lx, Ly) or heat source placement (Q) to achieve a target temperature distribution +- **Sensitivity analysis**: understand how uncertainties in material properties propagate to the temperature field + +## Usage + +```python +from tesseract_core import Tesseract +import numpy as np + +with Tesseract.from_image("enzyme-thermal-2d:latest") as t: + nx, ny = 20, 20 + n = nx * ny + + # Uniform initial temperature + T_init = np.full(n, 293.15) # 20°C everywhere + Q = np.zeros(n) # no internal heating + + # Forward solve + result = t.apply(inputs={ + "T_init": T_init, "Q": Q, + "nx": nx, "ny": ny, "n_steps": 100, + "k0": 45.0, "k1": -0.01, + "rho": 7850.0, "cp": 460.0, + "h_conv": 25.0, "T_inf": 293.15, "T_hot": 373.15, + "Lx": 0.1, "Ly": 0.05, "dt": 0.01, + }) + T_final = result["T_final"].reshape(ny, nx) + + # Gradient of average temperature w.r.t. material properties + # (e.g., for calibrating k0 and h_conv from experimental data) + cotangent = np.full(n, 1.0 / n) # gradient of mean(T_final) + vjp = t.vector_jacobian_product( + inputs={ + "T_init": T_init, "Q": Q, + "nx": nx, "ny": ny, "n_steps": 100, + "k0": 45.0, "k1": -0.01, + "rho": 7850.0, "cp": 460.0, + "h_conv": 25.0, "T_inf": 293.15, "T_hot": 373.15, + "Lx": 0.1, "Ly": 0.05, "dt": 0.01, + }, + vjp_inputs=["k0", "k1", "h_conv", "T_hot"], + vjp_outputs=["T_final"], + cotangent_vector={"T_final": cotangent}, + ) + print(f"d(mean T)/d(k0) = {vjp['k0']:.6f}") + print(f"d(mean T)/d(k1) = {vjp['k1']:.6f}") + print(f"d(mean T)/d(h_conv)= {vjp['h_conv']:.6f}") + print(f"d(mean T)/d(T_hot) = {vjp['T_hot']:.6f}") +``` + +## Toolchain + +All tools are installed from prebuilt binaries during the Docker build (no source compilation of the toolchain itself): + +| Tool | Source | Purpose | +| ------------------------------------------- | --------------- | --------------------------------- | +| [LFortran](https://lfortran.org/) 0.61.0 | conda-forge | Fortran → LLVM IR frontend | +| [LLVM](https://llvm.org/) 19 | apt.llvm.org | IR optimization, linking, codegen | +| [Enzyme](https://enzyme.mit.edu/) (nightly) | GitHub releases | LLVM AD pass | + +## Key design choices + +- **Black-box solver.** The Fortran subroutine takes initial conditions and parameters, runs the full time integration internally, and returns the final temperature field. This mirrors how legacy Fortran solvers are structured — the user doesn't need to refactor their code to expose individual time steps. +- **Temperature-dependent conductivity via harmonic mean at cell faces.** This is the standard approach in finite volume / finite difference thermal codes — it ensures continuity of heat flux across cells with different conductivities. +- **No array intrinsics in the Fortran kernel.** Explicit `do` loops produce clean LLVM IR that Enzyme handles reliably. +- **`--no-array-bounds-checking`** is passed to LFortran. Bounds checks emit calls to LFortran's runtime which Enzyme cannot differentiate through. +- **Enzyme differentiates through the full time-stepping loop** using a store-all (tape) strategy for reverse mode. During the forward pass, Enzyme caches ~148 intermediate values per time step into dynamically allocated tapes (O(n_steps) memory). For the default problem size (~400 grid points, 100 time steps), this is ~115 KB — trivial. For very long simulations (e.g., 100,000 steps), tape memory grows linearly to ~115 MB. Enzyme's checkpointing annotations (`__enzyme_checkpoint`) could be used to trade recomputation for memory in such cases, but are not needed here. +- **Work arrays are passed from C, not allocated in Fortran.** LFortran emits `_lfortran_malloc` for variable-length arrays, which Enzyme cannot differentiate through. The C wrapper allocates `T_cur` and `T_new` on the heap and passes them to the Fortran subroutine, avoiding this issue. + +## File structure + +``` +enzyme-lfortran/ +├── README.md +├── tesseract_api.py # Python API wrapping ctypes calls +├── tesseract_config.yaml # Build config with LLVM/LFortran/Enzyme toolchain +├── tesseract_requirements.txt # numpy +└── enzyme/ + ├── thermal_2d.f90 # Fortran solver (2D, nonlinear, multi-step) + ├── wrapper.c # C wrapper declaring Enzyme AD entry points + └── build.sh # Full compilation pipeline script +``` diff --git a/demo/enzyme-lfortran/demo.ipynb b/demo/enzyme-lfortran/demo.ipynb new file mode 100644 index 000000000..87fa1d851 --- /dev/null +++ b/demo/enzyme-lfortran/demo.ipynb @@ -0,0 +1,813 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "53e629d9", + "metadata": {}, + "source": [ + "# Inverse Heat Transfer with Automatic Differentiation\n", + "\n", + "In this tutorial, you will learn how to:\n", + "\n", + "1. Build a Tesseract that wraps a forward model written in plain **Fortran**, whose\n", + " derivatives are generated automatically by [Enzyme](https://enzyme.mit.edu/) at\n", + " the LLVM IR level -- with no hand-written adjoint code and no source\n", + " modifications.\n", + "2. Bridge the Fortran solver into JAX with\n", + " [`tesseract-jax`](https://github.com/pasteurlabs/tesseract-jax), so that it\n", + " behaves as an ordinary differentiable JAX function.\n", + "3. Verify the resulting gradients against an independently derived analytic\n", + " gradient.\n", + "4. Use the gradients to solve a 900-parameter inverse heat-transfer problem with\n", + " `scipy.optimize`.\n", + "\n", + "## Context\n", + "\n", + "Inverse heat-transfer problems arise across engineering: reconstructing an unknown\n", + "initial temperature distribution, a heat source, or a boundary condition from a\n", + "limited set of later measurements. These problems are typically ill-posed and\n", + "high-dimensional, which makes gradient-based optimization the practical approach --\n", + "provided gradients of the forward solver are available.\n", + "\n", + "The forward model here is a 2D transient heat-conduction solver written in plain\n", + "Fortran. Many established scientific solvers are written in Fortran or C and were\n", + "never designed to be differentiable, so obtaining gradients usually means writing\n", + "and maintaining adjoint code by hand. Enzyme avoids this by differentiating the\n", + "compiled LLVM IR directly: it synthesizes forward- and reverse-mode derivatives\n", + "from the solver as built, without source changes.\n", + "\n", + "Wrapped as a [Tesseract](https://github.com/pasteurlabs/tesseract-core) and bridged\n", + "into JAX with `tesseract-jax`, the Fortran solver becomes an ordinary differentiable\n", + "JAX function, so `jax.grad` flows through it like any other JAX operation. The\n", + "optimizer in this notebook only ever interacts with a JAX function; the underlying\n", + "solver and its differentiation are encapsulated behind the Tesseract." + ] + }, + { + "cell_type": "markdown", + "id": "10eedccbbadf", + "metadata": {}, + "source": [ + "## Step 1: Build and serve the Enzyme AD Tesseract\n", + "\n", + "The build compiles the Fortran source to LLVM IR with LFortran, runs the Enzyme\n", + "AD pass to synthesize forward- and reverse-mode derivatives, and links everything\n", + "into a shared library -- all inside the container. This step downloads the LLVM 19\n", + "toolchain and builds Enzyme from source, so the first build takes a few minutes." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d1505e18eaec", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:44:36.468114Z", + "iopub.status.busy": "2026-06-16T21:44:36.467938Z", + "iopub.status.idle": "2026-06-16T21:44:39.069803Z", + "shell.execute_reply": "2026-06-16T21:44:39.069481Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + " [i] Building image ...\n", + " [i] Built image sha256:0172263cf380, ['enzyme-thermal-2d:1.0.0', 'enzyme-thermal-2d:latest']\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[\"enzyme-thermal-2d:1.0.0\", \"enzyme-thermal-2d:latest\"]\n" + ] + } + ], + "source": [ + "%%bash\n", + "# Render the build status statically instead of an animated progress\n", + "# spinner, which streams as noise in captured notebook output.\n", + "export TERM=dumb\n", + "tesseract build ." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "fcc5e2141f85", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:44:39.071444Z", + "iopub.status.busy": "2026-06-16T21:44:39.071322Z", + "iopub.status.idle": "2026-06-16T21:44:42.871985Z", + "shell.execute_reply": "2026-06-16T21:44:42.871572Z" + } + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "\n", + "import jax\n", + "import jax.numpy as jnp\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from tesseract_jax import apply_tesseract\n", + "\n", + "from tesseract_core import Tesseract\n", + "\n", + "# JAX needs float64 to match the Fortran solver's double precision.\n", + "jax.config.update(\"jax_enable_x64\", True)\n", + "\n", + "# Serve the Tesseract; it stays alive for the rest of the notebook.\n", + "enzyme_tess = Tesseract.from_image(\"enzyme-thermal-2d\")\n", + "enzyme_tess.serve()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "2bdf1ea4fd67", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:44:42.873775Z", + "iopub.status.busy": "2026-06-16T21:44:42.873469Z", + "iopub.status.idle": "2026-06-16T21:44:42.877174Z", + "shell.execute_reply": "2026-06-16T21:44:42.876904Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simulation: 500 steps x 0.05s = 25s total\n" + ] + } + ], + "source": [ + "# Grid and simulation parameters (fixed throughout)\n", + "nx, ny = 30, 30\n", + "n = nx * ny\n", + "n_steps = 500\n", + "dt = 0.05 # 500 steps x 0.05s = 25s (CFL-safe up to k0 ~ 80)\n", + "Lx, Ly = 0.1, 0.05\n", + "\n", + "# Fixed physical parameters\n", + "rho = 7850.0 # density [kg/m^3] (mild steel)\n", + "cp = 460.0 # specific heat [J/(kg*K)]\n", + "h_conv = 25.0 # convection coefficient [W/(m^2*K)]\n", + "T_inf = 293.15 # ambient temperature [K]\n", + "T_hot = 373.15 # hot wall temperature [K]\n", + "\n", + "# Initial condition: uniform ambient temperature\n", + "T_init = np.full(n, T_inf)\n", + "Q = np.zeros(n) # no internal heating\n", + "\n", + "rng = np.random.default_rng(42) # reproducible noise\n", + "\n", + "# Figures are written here (gitignored); copy into docs/static/blog/\n", + "# as enzyme-.png by hand when updating the blog post.\n", + "FIGURE_DIR = Path(\"figures\")\n", + "FIGURE_DIR.mkdir(exist_ok=True)\n", + "\n", + "print(f\"Simulation: {n_steps} steps x {dt}s = {n_steps * dt:.0f}s total\")" + ] + }, + { + "cell_type": "markdown", + "id": "aace31b0", + "metadata": {}, + "source": [ + "## Step 2: Verify the gradients against an analytic derivative\n", + "\n", + "Before using the gradients in an optimizer, we check them against a derivative we\n", + "can compute *independently*, without Enzyme anywhere in the loop.\n", + "\n", + "For one regime we can do exactly that. Setting the conductivity's temperature\n", + "coefficient $k_1 = 0$ makes the solver linear: each explicit step is an affine map\n", + "of the temperature field, $T^{s+1} = A(k_0)\\,T^s + c(k_0)$, where the operators $A$\n", + "and $c$ encode the stencil and the mixed boundary conditions and depend affinely on\n", + "$k_0$. This structure gives the exact derivative of the whole multi-step trajectory\n", + "via the tangent recurrence\n", + "\n", + "$$\\frac{\\partial T^{s+1}}{\\partial k_0} = A_1\\,T^s + A(k_0)\\,\\frac{\\partial T^s}{\\partial k_0} + c_1,$$\n", + "\n", + "which we iterate in plain NumPy. We recover $A$ and $c$ by probing the solver at\n", + "two stable $k_0$ values (the map is exactly affine in $k_0$, so any two recover it\n", + "with no truncation error), confirm the reconstruction reproduces the solver's\n", + "trajectory to roundoff, then compare the analytic gradient against Enzyme's VJP.\n", + "For reference, we also include a finite-difference estimate swept over step size,\n", + "which agrees with the analytic gradient only to limited accuracy." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f44eee45", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:44:42.878520Z", + "iopub.status.busy": "2026-06-16T21:44:42.878436Z", + "iopub.status.idle": "2026-06-16T21:45:06.765102Z", + "shell.execute_reply": "2026-06-16T21:45:06.764836Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Recovering affine map at k0=45.0 (900 probes)...\n", + "Recovering affine map at k0=40.0 (900 probes)...\n", + "affine-model vs solver trajectory rel err = 1.13e-14\n", + "analytic gradient = 2.4101518794e+02\n", + "enzyme gradient = 2.4101518794e+02\n", + "Enzyme rel err vs analytic = 5.63e-12\n" + ] + }, + { + "data": { + "image/png": "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DCIIwmQoCA8Pl9OnTxt8H1nJTXvy8n/6KlWqpILZzZs3y5AhQ0z2GAiUmzdvrk7jx4+XsmXLysqVK+Wtt97K0B/GPA62v749e/ao55BVdYvs2pHe8uXL5aOPPlIl09Dfed0OeByM5G7atMmg2xORaTCQJSK7glEwBECYmY6KAzjMO2rUKHnzzTfVqGSLFi0kMjJS/v77b/Hz85P+/ftnuA/83+DBg2X06NFq9ntQUJAa3dMOPecFRv6MbU9e/k+fh4eHvP3226qiAQJMBHy3bt2SEydOqOebm8fAtkZgjEP52E64jPusVq1alv1h6OMgkEQQ+uKLL8rBgwfVKGtm1SMMaYe+48ePq4oU2BY1atSQGzduqOuxTYxpX/q0g9DQUPn++++lZcuWalQXt8d2daS6wUT5je8uIrIrCEAQaGBULTY2Vi5cuCAff/yxqlOLckrnz5+XggULSv369eXdd9/N8n4mTZqkgpHu3burwGbkyJEqmDGF3LQnL/+nDyWsEFhhxPL69esqf/all17K9WMgsNu+fbta8CAqKkqNgiLY7Ny5c5b9geDWkMdBsIn/ady4sRqFHTFihFolLTft0Ld//36VA4vUApw0GH3FwhW52Q5IKzh06JD6+82bN1VAjJxdBOFEZD5c2YuIiKyONa0IRkTWiwsiEBEREZFNYiBLRERERDaJqQVEREREZJM4IktERERENomBLBERERHZJAayRERERGSTGMgSERERkU1iIEtERERENomBLBERERHZJAayRERERGSTGMgSERERkU1iIEtERERENomBLBERERHZJAayRERERCS26P+CDuKAFdN4mQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# --- Independent analytic-gradient benchmark (linear regime, k1 = 0) ---\n", + "k0_bench = 45.0 # CFL r ~ 0.26; both probe values must keep r < 0.5\n", + "coef = dt / (rho * cp)\n", + "\n", + "\n", + "def _bench_inputs(k0, n_steps_, field):\n", + " return {\n", + " \"T_init\": jnp.asarray(field),\n", + " \"Q\": jnp.asarray(Q),\n", + " \"nx\": nx,\n", + " \"ny\": ny,\n", + " \"n_steps\": n_steps_,\n", + " \"k0\": jnp.float64(k0),\n", + " \"k1\": jnp.float64(0.0), # linear regime\n", + " \"rho\": jnp.float64(rho),\n", + " \"cp\": jnp.float64(cp),\n", + " \"h_conv\": jnp.float64(h_conv),\n", + " \"T_inf\": jnp.float64(T_inf),\n", + " \"T_hot\": jnp.float64(T_hot),\n", + " \"Lx\": jnp.float64(Lx),\n", + " \"Ly\": jnp.float64(Ly),\n", + " \"dt\": jnp.float64(dt),\n", + " }\n", + "\n", + "\n", + "def _step(field, k0):\n", + " \"\"\"One explicit solver step from `field` at conductivity k0.\"\"\"\n", + " out = apply_tesseract(enzyme_tess, _bench_inputs(k0, 1, field))[\"T_final\"]\n", + " return np.asarray(out, dtype=np.float64)\n", + "\n", + "\n", + "def _affine_map(k0):\n", + " \"\"\"Recover U(T;k0) = A T + c via unit probes (n+1 solver calls).\"\"\"\n", + " c = _step(np.zeros(n), k0)\n", + " A = np.zeros((n, n))\n", + " for j in range(n):\n", + " e = np.zeros(n)\n", + " e[j] = 1.0\n", + " A[:, j] = _step(e, k0) - c\n", + " return A, c\n", + "\n", + "\n", + "# Non-uniform initial field so the gradient is non-degenerate.\n", + "xb, yb = np.linspace(0, Lx, nx), np.linspace(0, Ly, ny)\n", + "XXb, YYb = np.meshgrid(xb, yb)\n", + "T_init_bench = (\n", + " T_inf + 40.0 * np.sin(np.pi * XXb / Lx) * np.sin(np.pi * YYb / Ly)\n", + ").ravel()\n", + "\n", + "ka, kb = 45.0, 40.0\n", + "print(f\"Recovering affine map at k0={ka} ({n} probes)...\")\n", + "Aa, ca = _affine_map(ka)\n", + "print(f\"Recovering affine map at k0={kb} ({n} probes)...\")\n", + "Ab, cb = _affine_map(kb)\n", + "\n", + "A1 = (Aa - Ab) / (ka - kb)\n", + "A0 = Aa - ka * A1\n", + "c1 = (ca - cb) / (ka - kb)\n", + "c0 = ca - ka * c1\n", + "A = A0 + k0_bench * A1\n", + "c = c0 + k0_bench * c1\n", + "\n", + "# Exact tangent recurrence over the full 500-step trajectory (pure NumPy).\n", + "T = T_init_bench.copy()\n", + "dT = np.zeros(n)\n", + "for _ in range(n_steps):\n", + " dT = A1 @ T + A @ dT + c1\n", + " T = A @ T + c\n", + "analytic = float(np.sum(dT))\n", + "\n", + "# Consistency check: does the affine model match the solver's real trajectory?\n", + "T_solver = np.asarray(\n", + " apply_tesseract(enzyme_tess, _bench_inputs(k0_bench, n_steps, T_init_bench))[\n", + " \"T_final\"\n", + " ],\n", + " dtype=np.float64,\n", + ")\n", + "traj_rel = np.linalg.norm(T - T_solver) / np.linalg.norm(T_solver)\n", + "print(f\"affine-model vs solver trajectory rel err = {traj_rel:.2e}\")\n", + "\n", + "# Enzyme VJP of the same scalar (cotangent = ones).\n", + "vjp = enzyme_tess.vector_jacobian_product(\n", + " inputs=_bench_inputs(k0_bench, n_steps, T_init_bench),\n", + " vjp_inputs=[\"k0\"],\n", + " vjp_outputs=[\"T_final\"],\n", + " cotangent_vector={\"T_final\": np.ones(n)},\n", + ")\n", + "enzyme_grad = float(vjp[\"k0\"])\n", + "enzyme_err = abs(enzyme_grad - analytic) / (abs(analytic) + 1e-30)\n", + "print(f\"analytic gradient = {analytic:.10e}\")\n", + "print(f\"enzyme gradient = {enzyme_grad:.10e}\")\n", + "print(f\"Enzyme rel err vs analytic = {enzyme_err:.2e}\")\n", + "\n", + "# Central finite differences vs the same analytic reference, swept over step size.\n", + "epsilons = np.logspace(-1, -12, 24)\n", + "fd_err = []\n", + "for eps in epsilons:\n", + " Tp = np.asarray(\n", + " apply_tesseract(\n", + " enzyme_tess, _bench_inputs(k0_bench + eps, n_steps, T_init_bench)\n", + " )[\"T_final\"]\n", + " )\n", + " Tm = np.asarray(\n", + " apply_tesseract(\n", + " enzyme_tess, _bench_inputs(k0_bench - eps, n_steps, T_init_bench)\n", + " )[\"T_final\"]\n", + " )\n", + " fd = np.sum(Tp - Tm) / (2 * eps)\n", + " fd_err.append(abs(fd - analytic) / (abs(analytic) + 1e-30))\n", + "\n", + "fig, ax = plt.subplots(1, 1, figsize=(7, 4.5))\n", + "ax.loglog(\n", + " epsilons, fd_err, \"o-\", ms=4, color=\"#1971c2\", label=\"Central finite differences\"\n", + ")\n", + "ax.axhline(\n", + " enzyme_err, color=\"#e8590c\", lw=2, label=f\"Enzyme AD ($\\\\approx${enzyme_err:.0e})\"\n", + ")\n", + "ax.set_xlabel(\"Finite difference step size $\\\\epsilon$\")\n", + "ax.set_ylabel(\"Relative error vs. independent analytic gradient\")\n", + "ax.set_title(\"Enzyme matches the analytic gradient; FD only in a narrow sweet spot\")\n", + "ax.legend(framealpha=0.9)\n", + "ax.grid(True, alpha=0.2)\n", + "plt.tight_layout()\n", + "fig.savefig(FIGURE_DIR / \"analytic_benchmark.png\", dpi=180, bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "8be059a8e35b", + "metadata": {}, + "source": [ + "## Step 3: Inverse problem -- recovering a hidden heat signature (900 parameters)\n", + "\n", + "Suppose a steel plate was subjected to an unmonitored heating event -- for example\n", + "a laser pulse or a localized defect generating heat. Five seconds later, we measure\n", + "temperatures at 100 sensor locations and want to reconstruct the initial temperature\n", + "distribution.\n", + "\n", + "This is an ill-posed inverse problem: 900 unknowns (the temperature at every grid\n", + "cell) inferred from 100 noisy observations, through a nonlinear PDE. We add a small\n", + "Tikhonov term that penalizes departure from the ambient prior, which regularizes the\n", + "problem; the optimizer is a standard `jax.value_and_grad` + L-BFGS-B loop over all\n", + "900 unknowns. This is a setting where reverse-mode AD is essential rather than\n", + "merely convenient:\n", + "\n", + "| Method | Forward solves per iteration |\n", + "|--------|----------------------------:|\n", + "| Finite differences | 901 (N+1) |\n", + "| Reverse-mode AD | 2 (forward + reverse) |\n", + "| **Speedup** | **~450×** |\n", + "\n", + "Finite differences would need 901 forward solves every iteration to assemble all\n", + "900 gradients; one reverse sweep returns them all for roughly the cost of two\n", + "forward passes. The Tikhonov term is just another addition to the JAX loss, which\n", + "`jax.value_and_grad` differentiates along with the rest." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e337f08f8d05", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:45:06.766933Z", + "iopub.status.busy": "2026-06-16T21:45:06.766821Z", + "iopub.status.idle": "2026-06-16T21:45:06.805743Z", + "shell.execute_reply": "2026-06-16T21:45:06.803846Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid: 30x30 = 900 unknowns\n", + "Sensors: 100\n", + "Simulation: 100 steps x 0.05s = 5s\n", + "True T_init range: 293.2 — 332.7 K\n" + ] + } + ], + "source": [ + "# --- Forensics setup ---\n", + "# Shorter simulation: 5 seconds (we want residual structure in the initial field)\n", + "n_steps_p2 = 100\n", + "dt_p2 = 0.05\n", + "\n", + "# Fixed material properties (known — we're recovering T_init, not k)\n", + "k0_p2 = 45.0\n", + "k1_p2 = -0.01\n", + "\n", + "# Build coordinate arrays for the 30x30 grid\n", + "x = np.linspace(0, Lx, nx)\n", + "y = np.linspace(0, Ly, ny)\n", + "X, Y = np.meshgrid(x, y)\n", + "X_flat, Y_flat = X.flatten(), Y.flatten()\n", + "\n", + "# True initial temperature: two Gaussian hot spots on a warm background\n", + "T_init_true = (\n", + " T_inf\n", + " + 40.0 * np.exp(-((X_flat - 0.04) ** 2 + (Y_flat - 0.025) ** 2) / 0.015**2)\n", + " + 25.0 * np.exp(-((X_flat - 0.08) ** 2 + (Y_flat - 0.035) ** 2) / 0.01**2)\n", + ")\n", + "\n", + "\n", + "def make_inputs_p2(T_init_field):\n", + " \"\"\"Inputs for the forensics problem; T_init_field is the differentiable unknown.\"\"\"\n", + " return {\n", + " \"T_init\": jnp.asarray(T_init_field),\n", + " \"Q\": jnp.asarray(Q),\n", + " \"nx\": nx,\n", + " \"ny\": ny,\n", + " \"n_steps\": n_steps_p2,\n", + " \"k0\": jnp.float64(k0_p2),\n", + " \"k1\": jnp.float64(k1_p2),\n", + " \"rho\": jnp.float64(rho),\n", + " \"cp\": jnp.float64(cp),\n", + " \"h_conv\": jnp.float64(h_conv),\n", + " \"T_inf\": jnp.float64(T_inf),\n", + " \"T_hot\": jnp.float64(T_hot),\n", + " \"Lx\": jnp.float64(Lx),\n", + " \"Ly\": jnp.float64(Ly),\n", + " \"dt\": jnp.float64(dt_p2),\n", + " }\n", + "\n", + "\n", + "def solve_p2(T_init_field):\n", + " return apply_tesseract(enzyme_tess, make_inputs_p2(T_init_field))[\"T_final\"]\n", + "\n", + "\n", + "# Run forward simulation with the true initial field\n", + "T_final_true_p2 = np.asarray(solve_p2(T_init_true))\n", + "\n", + "# 10x10 sensor grid (100 sensors in the interior)\n", + "sensor_ix_p2 = np.linspace(3, nx - 4, 10, dtype=int)\n", + "sensor_jy_p2 = np.linspace(3, ny - 4, 10, dtype=int)\n", + "sensor_grid = np.array([(jy * nx + ix) for jy in sensor_jy_p2 for ix in sensor_ix_p2])\n", + "n_sensors_p2 = len(sensor_grid)\n", + "\n", + "# Observed data: true final temperatures at sensors + noise\n", + "noise_std_p2 = 0.3 # K\n", + "T_obs_p2 = T_final_true_p2[sensor_grid] + rng.normal(0, noise_std_p2, n_sensors_p2)\n", + "\n", + "print(f\"Grid: {nx}x{ny} = {n} unknowns\")\n", + "print(f\"Sensors: {n_sensors_p2}\")\n", + "print(f\"Simulation: {n_steps_p2} steps x {dt_p2}s = {n_steps_p2 * dt_p2:.0f}s\")\n", + "print(f\"True T_init range: {T_init_true.min():.1f} — {T_init_true.max():.1f} K\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "c6473e7ffb35", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:45:06.809478Z", + "iopub.status.busy": "2026-06-16T21:45:06.809317Z", + "iopub.status.idle": "2026-06-16T21:45:09.624319Z", + "shell.execute_reply": "2026-06-16T21:45:09.623958Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initial loss: 4085.86\n", + "Running L-BFGS-B with 900 parameters...\n", + " iter 10: loss=8.0931, elapsed=0.4s\n", + " iter 20: loss=7.5007, elapsed=0.8s\n", + " iter 30: loss=7.4350, elapsed=1.2s\n", + " iter 40: loss=7.4246, elapsed=1.7s\n", + " iter 50: loss=7.4222, elapsed=2.0s\n", + " iter 60: loss=7.4216, elapsed=2.4s\n", + " iter 70: loss=7.4215, elapsed=2.8s\n", + " iter 80: loss=7.4215, elapsed=3.2s\n", + " iter 90: loss=7.4215, elapsed=3.5s\n", + " iter 100: loss=7.4215, elapsed=3.8s\n", + " iter 110: loss=7.4215, elapsed=4.2s\n", + " iter 120: loss=7.4215, elapsed=4.5s\n", + " iter 130: loss=7.4215, elapsed=4.9s\n", + " iter 140: loss=7.4215, elapsed=5.3s\n", + " iter 150: loss=7.4215, elapsed=5.6s\n", + " iter 160: loss=7.4215, elapsed=6.0s\n", + " iter 170: loss=7.4215, elapsed=6.3s\n", + " iter 180: loss=7.4215, elapsed=6.7s\n", + "\n", + "Optimization finished: 187 iterations, 8.4s\n", + "Loss: 4085.86 → 7.4215\n", + "T_init correlation: 0.9804\n", + "\n", + "Cost comparison per iteration:\n", + " Finite differences: 901 forward solves = ~30.5s\n", + " Reverse-mode AD: 2 solves (fwd+rev) = ~0.07s\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "from scipy.optimize import minimize\n", + "\n", + "T_obs_p2_jax = jnp.asarray(T_obs_p2)\n", + "sensor_grid_jax = jnp.asarray(sensor_grid)\n", + "\n", + "# Tikhonov regularization weight: penalizes departure from the ambient prior,\n", + "# which stabilizes this ill-posed problem (900 unknowns, 100 observations).\n", + "alpha_reg = 1e-4\n", + "\n", + "\n", + "def loss_fn_p2(T_init_vec):\n", + " \"\"\"Regularized sensor-misfit loss for the 900-element initial field. Pure JAX.\"\"\"\n", + " T_pred = solve_p2(T_init_vec)\n", + " residuals = T_pred[sensor_grid_jax] - T_obs_p2_jax\n", + " data_loss = 0.5 * jnp.sum(residuals**2)\n", + " reg_loss = 0.5 * alpha_reg * jnp.sum((T_init_vec - T_inf) ** 2)\n", + " return data_loss + reg_loss\n", + "\n", + "\n", + "value_and_grad_p2 = jax.jit(jax.value_and_grad(loss_fn_p2))\n", + "\n", + "# warm up JIT\n", + "_ = value_and_grad_p2(jnp.asarray(T_init))\n", + "\n", + "\n", + "def scipy_objective_p2(T_init_vec):\n", + " loss, grad = value_and_grad_p2(jnp.asarray(T_init_vec))\n", + " return float(loss), np.asarray(grad, dtype=np.float64)\n", + "\n", + "\n", + "# Start from uniform ambient (the wrong answer)\n", + "T_init_guess = np.full(n, T_inf)\n", + "loss_history_p2 = []\n", + "\n", + "iter_count = [0]\n", + "t_start = time.time()\n", + "\n", + "\n", + "def callback_p2(x):\n", + " iter_count[0] += 1\n", + " if iter_count[0] % 10 == 0:\n", + " loss, _ = scipy_objective_p2(x)\n", + " loss_history_p2.append(loss)\n", + " elapsed = time.time() - t_start\n", + " print(f\" iter {iter_count[0]:3d}: loss={loss:.4f}, elapsed={elapsed:.1f}s\")\n", + "\n", + "\n", + "loss0_p2 = scipy_objective_p2(T_init_guess)[0]\n", + "loss_history_p2.append(loss0_p2)\n", + "print(f\"Initial loss: {loss0_p2:.2f}\")\n", + "print(f\"Running L-BFGS-B with {n} parameters...\")\n", + "\n", + "result_p2 = minimize(\n", + " fun=scipy_objective_p2,\n", + " x0=T_init_guess,\n", + " method=\"L-BFGS-B\",\n", + " jac=True,\n", + " bounds=[(250.0, 450.0)] * n,\n", + " callback=callback_p2,\n", + " options={\"maxiter\": 200, \"ftol\": 1e-15, \"gtol\": 1e-10},\n", + ")\n", + "\n", + "elapsed_total = time.time() - t_start\n", + "loss_final = scipy_objective_p2(result_p2.x)[0]\n", + "loss_history_p2.append(loss_final)\n", + "T_init_recovered = result_p2.x\n", + "\n", + "print(f\"\\nOptimization finished: {result_p2.nit} iterations, {elapsed_total:.1f}s\")\n", + "print(f\"Loss: {loss0_p2:.2f} → {loss_final:.4f}\")\n", + "print(f\"T_init correlation: {np.corrcoef(T_init_true, T_init_recovered)[0, 1]:.4f}\")\n", + "print(\"\\nCost comparison per iteration:\")\n", + "print(\n", + " f\" Finite differences: {n + 1} forward solves = \"\n", + " f\"~{(n + 1) * elapsed_total / result_p2.nfev:.1f}s\"\n", + ")\n", + "print(\n", + " f\" Reverse-mode AD: 2 solves (fwd+rev) = \"\n", + " f\"~{2 * elapsed_total / result_p2.nfev:.2f}s\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "44fd35ce4a54", + "metadata": { + "execution": { + "iopub.execute_input": "2026-06-16T21:45:09.625722Z", + "iopub.status.busy": "2026-06-16T21:45:09.625621Z", + "iopub.status.idle": "2026-06-16T21:45:10.529208Z", + "shell.execute_reply": "2026-06-16T21:45:10.528815Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABkgAAAOPCAYAAACAXU2VAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3QeYFEXawPGXnJckUbIgSRAdVFDPNAqiIirnGVDwxHiIGFe5MwEiop7hPEW9D9HTwwDKqZyIOgoGQAFBQRRFsmQQliBx53vecnvsGTZ17U5vz+z/9zxDszNd0zU93VPV/VYoE41GowIAAAAAAAAAAFCKlC3pDAAAAAAAAAAAAPiNAAkAAAAAAAAAACh1CJAAAAAAAAAAAIBShwAJAAAAAAAAAAAodQiQAAAAAAAAAACAUocACQAAAAAAAAAAKHUIkAAAAAAAAAAAgFKHAAkAAAAAAAAAACh1CJAAAAAAAAAAAIBShwAJAABIulNOOUXKlCljHi+88AJ7PAXp9+Z8h/p9wt99dt9998Xe64orriiR80+367yP5gcoim+++UZ69+4tDRs2POjYdv7Wx/Lly309Zlu0aBFLM23atEKl2bVrlwwdOlRat24tlSpViqUHAABA8BEgAQCgkDc43Y8qVaqYGyF68+Xbb79lH0JWrFgh119/vRx22GHmBlnNmjXlxBNPlBdffFGi0Wieaa655hpp3ry5SVO/fn3p06ePfP7557mur++j76fvq+9ftWpVOeKII2T48OGyc+dOvoUkefzxx83NVX0U5WZtsjh508fWrVslSIK+71KR7kdnn+r+TUU7duyQXr16yeTJk2X9+vWS6u6880558MEH5aeffpK9e/dKutDj68ILL5SWLVvG1YHyC7Ru2rRJbr31VmnTpo1UrlxZ6tSpI2eccYb5rvPy9ttvm3V0XU2jafU9Nm/enKRPBgAA8Lvyrv8DAIBC2r17t7kRoo+JEyfKjBkzpHPnzuy/PDz55JOybds28//DDz887fbTl19+aW7uZGVlxZ7Tm2Qa6NBHJBKRf//733FpvvrqKzn99NPll19+iT23ceNGc6NIbyQ9//zzMmDAgLg0GpBLfB8N0N17773y3//+Vz7++GMTOEHx3yTUYJbTG0NbmBfGWWedJZ9++qn5f1G/lyuvvNIcL6pBgwZxrw0bNizuGKlVq1Zgzj/bfYf8AyTOd67B1ZtuuinldtcXX3wha9asMf/Xm+J6w7127dqxY9s5b1SjRo0k6CZNmhT7/1133SU9evRIix4kGoRzfjsKQ8/1k046SVauXBl7bs+ePfLhhx+ahwbz77777rg0Wn7p825LliyRRx99VN5880355JNPpGnTpsXwaQAAAHJHDxIAADzQmzYfffSRPPTQQ1KuXDnznLbc/+c//8l+zKOVsOrUqZPp9aAP7SWRbvr37x8LjoTDYXn33XfNDb969eqZ51566aW4Frf79++XSy+9NBYc0RvpGhjRFrMqOzvb9EZZunRpLM3LL78cC45oD6annnpKXn/99dgN73nz5klmZqaPnxoF0WPdOe71HCiKZs2axd5LW1d7ke7nX6r/Pgbdr7/+an6TitPPP/8c+7/2gtOhttzHtnO86kN71wWd+/NoMPMPf/iDyXuqHwP626Gf5+mnny7Ub8fAgQNjwZHjjjvOBI4eeOABKVu2bCwYog1K3HUqJzii6+i6mqZbt26xYOBVV12VpE+XfpJxrgIAUCpEAQBAnsaNG6djI8UebmeffXbs+Z49ex6UdtWqVdEhQ4ZE27ZtG61cuXK0WrVq0aOPPjr66KOPRvfu3XvQ+rt3744+8cQT0RNOOCFaq1ataIUKFaKNGjUy25kxY0bcuvPnz49efvnl0WbNmkUrVqwYrVGjRvSYY46JPvzww+Z9HBdffHEsjw888EDce+zcuTNavXr12OuLFy+OvbZo0aLowIEDoy1btoxWqlTJvP/xxx9v9kd2dnbc+wwYMCD2Hvfee2/0pZdeinbp0sWk69Onj1nn5JNPjq2j75FX2rfeeit63HHHmf11yCGHRK+55projh07DtpXzzzzTLRdu3bmsx922GHRhx56KBqJRGLv1bx580Id1U8++WT0zDPPjLZo0cJ8xvLly0fr1asX7dGjR/TNN98s1Ht89913ccfI0qVLY6+NHDky9nznzp1jz7/99tux5zMyMqK7du2KvXb66afHXrvttttiz+ux4zx///33x57/7LPPYs/rPt+8eXO0sHTdu+66y+RNj0/d7x06dDDfxfbt2/M8F/T7TPTqq69GzzjjjGjdunXNsduwYUNz/H399dcHreveX/r6ddddZ75vPR7POeec6LJly8xx9vjjj0dbt25tvmf9vl9++eVcP4fttr/99tvoX//6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8EHTwtXphaItWKtWrXpQ3rXltk40m5u8emto6193nrw47bTTTKt/pa0ba9eubVpOKqdlqNPKUoVCobjJe/XzP/LII4XenvbG0X24YcOGfNfLq/eBm7YK1fw+9thjscnatVeJturVVpsOXUc5PSWcVulu7r+rV69+0PqFTaOt2F988cW49bSVtfZicX/Pehz07Nkz18+lr2lLY93XeXG/18MPP2weXo4Zd+8Qd08Y7Rng0N4hDnfr7qJuW3tY5bZtLy3Ii0pbeGuLXr/zofd09XydPn16kY9/W0U9DrU3Rp06dQ7ab4U9ftwSJ9TWv7U3mft3x+tve2KetOeAthAP2veQSH9XzznnnLjn9PPqw3HLLbfkmV7Pt7y+y6IoavmUV28E97HSvn178zudrP2dWxnpLtcPO+ywuF5A7uNSjxU9DxInS9ceJ9qTsDjOg6IobLnmlFPuXpGFLdfyosdCx44d5dtvvzU97/ShvXHbtGljzlPtjdihQ4eDjiPtfaSP4i43rr76atNz58CBA6ZXldLjSnua6bmlvUa03qW/Le5J1d3ft35fbdu2lfnz5x90nOR3rjq9q+655x5TD9TfHaW9aPQ3VHsraU84AADwO/pWAgDggV7Q6w31/v37m7/1Br4O0+S+4PbCGVIjmZo1ayann366+f+qVavkk08+yXV4reLId1GGd3FudDqcGz7KuZHiBFAS/29Dh7FwgiN601KHedKblDo0ivtGkvvmRV40GKJDV+iwSDqM2VdffWVusOlNEIfeDHGGzGnVqlVcoCbx5qr7ZpkznI3787rT6M1jvRmbmKa4FNcxmtf7OENKKfewH7Vq1cp1/cSbakXZtvuYy+1480NhjvtkmDlzZuymvB6/I0aMMMPA6PF/xhlneDr+/ZDbd5jXsVPcx09x5Te338dkfA+Jv43uALw7yJEX/T0syu+rH+VakLefn+IYAi2o50FhyzUNKmi+NGDgNBooKE1B5ZoGnT7//HPTSOLss88262twQgMmY8aMMYH4lStXJrXccDvllFNkzpw5Zig3DVBonULrBHqu6xCqOmRWccjrXL377rvl7bffNvXTo446ygSYdEhJfU4bxbiHAwMAAARIAADwrF69evLcc8+Zm9Zq7969sTk/nBao7uCE3sDWmxGJD7341hb9iXNY6DjVed3M0BbTDp1rxBmLXenNAYeO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QYMy2pvDTQMiWobqsKK6/cRy9PLLLzdDb2k+tXGJ9gTVmz7aOEKf1xs9Tu/bvDz44IMmrdad9PNpnUnzrcNcab3JqV/oa9qYQ4fM1Lxr7xatZyXOiVZUWp/Q+obuT61D6Gcp6DMAAJAbvTbVMlIbA+gQWlpma9no7smhtMzR8lrvIWgZrWW4NjJYsGCBKaeXL19+UBqvdAQG7UW6cuVKM2/pyy+/bObtBADkIwqUYlOmTIleeeWV0Xbt2kWrV68erVixYrR169bRwYMHR9evXx+37vfffx896aSTolWqVNHmmdEBAwaY53/55Zfon//85+ghhxxi3qNnz55m3ebNm8fWUePGjTPpZs+enWteRowYET300EOjZcuWNestW7bMPF/Y9/n444/N87p07N+/P3r33XdHGzZsaPJ92mmnRb/77rto3bp1o9ddd12B+2fjxo3RSy+9NFqjRo1ozZo1o1dccUX0888/N9t59dVX49Z9+eWXo61atTL7sEuXLtGpU6eafGv+Ez333HPRUChk8qTv3alTp2hmZmZ0zZo15vWvvvoqeskll0SbNWsWrVSpUrR+/frRc845JzpnzpzYe0ycODHao0cP85puU9e99tpro2vXri3wcwEA4If8yv4DBw5EDzvsMPPQ8lr99NNP0f79+5tyu0KFCqZeoOWflnlumzdvjt5www3mdS0DmzRpYsrcTZs2xdbReoxTP9F1tKzV/OQmOzs72rRpU5PX+++/P9d19u7dGx09enS0Y8eOpmyuXbu2KcuHDRsW3bZtW2w9fY9Bgwbl+h6aJ31Nt6WfTz9nOBw29QK3FStWRM8999xo1apVTf6HDBkSfe+99w6q5xREt5XX5Y7uq/PPPz/6hz/8Idq9e/foRx99VOj3BQCkt9zKj5NPPtmUgbnRMv2OO+4wZZaWXXpPYMmSJQddy6vt27dHhw4dau47aPmsaY4//vjoI488YsrawqpWrdpB7+344IMPot26dTNlXN++fU29AQCQtzL6T34BFADpRbvu6hip999//0FjjBfGf//7X9Oz47PPPjMtSAEAAAAAAAAgFTEHCZDGdFzwRDq0htKxzr2m1+E0dAgOHerq6KOPLsacAgAAAAAAAIC/mIMESGM6l4qOba7jbOukrNrr45VXXjFzfxSm94fO0aJBku7du5uJz998800zR8sDDzwgVapU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WQoAANLLxx9/7DnNoYcemjoBErcDBw6YniIa5dGhtrRXyb59++T000+PrdOuXTtp1qyZzJw5M88AyZ49e8zD4WWMMgAAkPqoUwAAQFkKAECp4rVXSIr0IDn55JOTvo0SD5AsWLDABER0vhGdZ2TSpEnSoUMHmT9/vlSsWFFq1aoVt36DBg1k3bp1eb7fqFGjZNiwYT7kHAAABIlfdYqaHscorSbexee0cOpZpKnjU95qWKQpV8kikc3OzrBII95aJP2mrU97e7O31ev9Pv9fUrNV1XuSylvEF/ss0my32VDePzd5W26RxvuoAiI2+3p90o9OY7dFmhS53g8krs+9sxm3vIJFmsoWaSpW8qlC0dwijRxnkeZkn/act7HrpfmX/uxni/K3ssePYntM2/xW2zRnzrL4PBmLfCpIbMrSn/zZzE6f6kcoYV7nFUmROUj8UKJzkKi2bduaGxdffPGFXH/99TJgwABZtMjm1+s3Q4cONROyOI9Vq1YVa34BAEAwUacAAICyFACAUinJc5CMGTNGOnfuLBkZGeahjROnTPm9sdVzzz0np5xyinmtTJkysnXr1oPeo0WLFuY190PnJy9pJd6DRFt0tm7d2vw/FArJ7Nmz5YknnpCLLrpI9u7da3amu8Xn+vXrpWHDhnm+X6VKlcwDAACULtQpAACgLAUAoFTK9hj08NiDpEmTJiaY0aZNGzNx+osvvih9+vSRefPmSceOHWXXrl1y5plnmod2YMjL8OHD5eqrr479XaOGzXgDxavEe5Akys7ONnOIaLCkQoUKEolEYq8tXrxYVq5caSJUAAAA1CkAAOD6HACAUi/b4uFB79695ayzzjIBksMPP1xGjhxphraeNWuWef2mm26SO++8M895w90BEe384DyqVbMZJzmNepBoNKlXr15m4vXt27fL+PHjZdq0aTJ16lSpWbOmDBw4UG655RapU6eO6Z4zePBgExwpaEcDAIDShToFAACUpQAAlFqWk7RnZWV5Hp3pwIEDMmHCBNm5c6fnjgzaC2XEiBEmHnDppZfKzTffLOXLFz5EsX//fhM/+Omnn0x6DbisWbPGxA40YJNyAZINGzZI//79Ze3atSYgouOYaXDkjDPOMK8/9thjUrZsWenbt6/pVdKzZ095+umnSzLLAAAggKhTAABAWQoAQKllOUl706ZN456+99575b77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Hn744UBWVlbgnnvuCXz99deBE088MdClS5fAkiVL2rtpCWP8+PGBe++9N/DVV18FPvvss8C+++4bGDBgQGDNmjXBx5xyyimB/v37B6ZNmxb4+OOPA9tvv31ghx12aNd2J4oPP/wwMGjQoMDo0aMDZ555ZvB2ttmGVqxYERg4cGBg4sSJgQ8++CDwww8/BF566aXA7Nmzg4+59tprA507dw48/fTTgc8//zxwwAEHBAYPHhxYt25dIFVdffXVge7duweeffbZwNy5cwOPPfZYoKCgIHDTTTcFH8N2CwSef/75wMUXXxx48sknFTkKPPXUUw22YzTbaO+99w5svvnmgffffz/w9ttvB4YMGRI4/PDD4/p+I3FxTtE8zilahnOK6HFOERvOKaLDOUXb4VjaPI6lLcOxNHocS2PDsTQ6HEuRjDpsgGTbbbcNTJo0Kfh3XV1doE+fPoEpU6a0a7sSWWlpqetcfPPNN93fq1atCmRmZrpOWc+3337rHjN9+vRAKisvLw8MHTo08MorrwR23XXXYICEbRbZ+eefH9hpp50a3Z719fWBXr16Ba677rrgbdqW2dnZgX//+9+BVLXffvsFjj/++Aa3HXTQQYEjjzzS/ZvttqHwAEk02+ibb75xy3300UfBx7zwwguBTp06BX7++ec2eGeRbDin8I9ziuhxTuEP5xSx4ZzCP84pWhfHUv84lkaPY6k/HEtjw7HUP46lSBYdssRWdXW1zZgxw5VR8aSlpbm/p0+f3q5tS2SrV6921926dXPX2oY1NTUNtuPw4cNtwIABKb8dVXZsv/32a7Bt2GaNe+aZZ2zrrbe2//u//3Pl3Lbccku76667gvfPnTvXFi9e3GB7du7c2ZXGS+XP7A477GDTpk2z77//3v39+eef2zvvvGP77LOP+5vt1rxotpGuVVZL+6hHj9dx44MPPmj19xXJhXOK2HBOET3OKfzhnCI2nFO0HOcUseNYGhuOpdHjWOoPx9LYcCxtOY6lSFQZ1gEtW7bM1Qbs2bNng9v193fffddu7Upk9fX1bh6NHXfc0UaOHOluU6diVlaW6zgM3466L1U9/PDD9sknn9hHH320wX1ss8h++OEHu/322+2cc86xiy66yG27M844w+1fxx57bHB/ivSZTeV97YILLrCysjIXmExPT3ffa1dffbWbK0PYbs2LZhvpWoG7UBkZGS5YnMr7H37BOYV/nFNEj3MK/ziniA3nFC3HOUXsOJb6x7E0ehxL/eNYGhuOpS3HsRSJqkMGSBDbiIuvvvrKjU5H4xYsWGBnnnmmvfLKK5aTk8Om8nGCr9H511xzjftbGSTa3+644w4XIEFkjz76qD344IP20EMP2YgRI+yzzz5zgUxNRs52A5CoOKeIDucUseGcIjacUwDJhWNpdDiWxoZjaWw4lgIdV4cssVVcXOxGWy9ZsqTB7fq7V69e7dauRHXaaafZs88+a6+//rr169cveLu2ldKhV61a1eDxqbwdVXastLTUttpqKzfCXJc333zTbr75ZvdvjUpnm22od+/ettlmmzW4bdNNN7X58+e7f3v7E5/Zhs477zw3SuWwww6zUaNG2dFHH21nn322TZkyhe0WpWj2LV3rcx2qtrbWVqxYkbLfdfgfzin84ZwiepxTxIZzithwTtFynFPEjmOpPxxLo8exNDYcS2PDsbTlOJYiUXXIAInK9owZM8bV7g+NkOvvsWPHtmvbEonmS9LJ11NPPWWvvfaaDR48uMH92oaZmZkNtuPMmTNdp3aqbsdx48bZl19+6UbyexdlRqjkkfdvttmGVLpN+04ozasxcOBA92/tezpQhu5rKi2l+R9SdV+TiooKNw9GKAV/9X0mbLfmRbONdK1AsH5gefSdqO2suUqQ2jiniA7nFP5xThEbziliwzlFy3FOETuOpdHhWOofx9LYcCyNDcfSluNYioQV6KAefvjhQHZ2duC+++4LfPPNN4GTTjop0KVLl8DixYvbu2kJ49RTTw107tw58MYbbwQWLVoUvFRUVAQfc8oppwQGDBgQeO211wIff/xxYOzYse6C/9l1110DZ555JtusCR9++GEgIyMjcPXVVwdmzZoVePDBBwN5eXmBBx54IPiYa6+91n1G//Of/wS++OKLwIQJEwKDBw8OrFu3LmV3t2OPPTbQt2/fwLPPPhuYO3du4MknnwwUFxcHJk+eHHwM2y0QKC8vD3z66afuosPaDTfc4P79448/Rr2N9t5778CWW24Z+OCDDwLvvPNOYOjQoYHDDz+8Xd53JB7OKZrHOUXr4JyieZxTxIZziuhwTtF2OJY2j2Np6+BY2jyOpbHhWBodjqVIRh02QCK33HKL69zPysoKbLvttoH333+/vZuUUNSRGOly7733Bh+j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AAAAAKmHAAlSjteRrsCFR+W2jjnmGBs6dKjdcMMNdtZZZ9m0adNsl112sVWrVgUf98orr7jbvvnmGzvzzDPtr3/9q/3qV7+yZ599NviYV1991caPH+8CMJo4/pxzzrH33nvPdtxxR/faouCESko9+uijG7TvkUcecQEBBSdEQYztt9/eBVguuOAC95oKchx44IERgxcKjqh9l112mXu8qKSV95p//vOf7dJLL3WP2WmnnYJtkpdfftkOPvhgt31Umkyvcdxxx9nHH39s7UGBJpVEO/TQQ10Qyu9E8X63HQAAAAAAAIDUQYktdGh1dXVu7hFZvny53X333a6zX8ECZYrIjz/+aJdffrldddVVdtFFFwWXPeigg2zLLbe02267zd2u5zr55JOtd+/e9tlnnzUIsAQCgeC/zzvvPJetMH36dHct6pDXc+l17r//fvfa+++/v8skufnmm4OlvhYvXuwyQBRY8SgQM2DAAPvoo49cFoUXBFFw4/zzz7ff/OY3DdZZr6ngjveca9assTPOOMN+97vf2d///vfg44499lgbNmyYXXPNNcHb9XwqgfXOO++48mSy66672l577WUDBw60eJs5c6Z9+eWXttlmmwVvC88caYrfbQcAAAAAAAAgdZBBgg5N5ZV69OjhLpp75LrrrrMDDjigQRmmJ5980s1vccghh7hginfp1auXyyh5/fXX3eM+/fRTmzt3rssuCQ2OiDIuZNGiRS54MnHixGBwRFSGa88997Tnn38+eJuyIpRlEtrhr4CJ2qL7ZMWKFS6LQm1TWTCvbQr2KEtl1qxZ9vPPPzdoy4knnthgbhVlvSgL5vDDD2+wfnrMdtttF1w/r+0KnHjBEVG7QwMU8aTgTKyvHcu2AwAAAAAAAJA6yCBBh6aSTHfddZcLOsyZM8eV0lq6dGmDib7VUa4MEAVDIsnMzHTXWl680leRKBtFlJkRbtNNN7WXXnopOHH63nvv7QIRKqk1btw49xj9e4sttrBNNtnE/T179mzXNpXE0iUSBVn69u0b/Hvw4MEN7tf6ye677x5x+aKiogZtj7QdtD6ffPKJNWX16tW2bt264N9ZWVkNgkSxCF8XP2LZdgAAAAAAAABSBwESdGgKROyxxx7BvzUPyFZbbeVKZqm0lSh4ogwQTWIemnnh0bwdbUEln7y5MFTGa8mSJfbuu++6klcetU3+8Ic/uKyHSIYMGdLgb690WPhzaB4SZcWEy8hona8BlbNS+bDQ7A8/5bAiCV+X0GydcCqBFiqWbQcAAAAAAAAgdRAgQUpRqaujjjrK7rzzTtdxrvkpNt54Y5dpoGwFL3MjEj1OvvrqqwZBl1DePB2aOyNSua/i4mIXtPGolJaCCpozRBOJqx1eeS3ZaKONglksjb1mc7x2l5SUNPkcXtu9jJNQkdYn3OTJk9229XTt2tXagve8KhsWysuAac1tBwAAAAAAAKDjYg4SpBx15NfU1NgNN9wQnIxdmSNXXnllg8nWRX9rzgpR5omCKDfeeOMGnfPecprAXSWyFPQIfYyCKi+//LLtu+++DZZTx73KUKm0li7bbrttg7JSCmrstttuLqCjOULCqVxYc5Q9oTJaykzRejf2HKFtV7ms0DlMvvnmm2ZfR3OFaH28y5gxY6wtKJCj9+utt95qcLuycEK1xrYDAAAAAAAA0HGRQYKUo458BSr+8Y9/uLkplGFx1VVX2YUXXmjz5s1zZa8KCwvdhOwqf3XSSSe5bJO0tDS7/fbbbf/993eBhOOOO84FFZQZ8vXXX7v5RUQTwe+zzz42duxYO+GEE9y8HLfccoubb+SKK65o0BZlNyhA8/DDD7u5Sa6//voN2jt16lTbaaedbNSoUW4CdmVGqBzX9OnT7aeffrLPP/+8yfVVcETtPvroo12Q57DDDnOT1s+fP9+ee+45V3bs1ltvdY+dMmWK7bfffu71jj/+eDfRudo+YsQIW7NmjSUCbcf/+7//c+1SuS29f88++6ybT6S1tx0AAAAAAACAjosMEqSk8847zwUk1MkuF1xwgT3xxBMuCKJMEgVEnnnmGdtrr73sgAMOaJCN8frrr7tSXH/961/tnHPOceWxFDTxKHvixRdftO7du9tll13mgh7bb7+9m18k0qTjKqnlBR8OOeSQiAGdjz/+2AUu7rvvPps0aZLdcccdrq16/mgcccQRrp2akFwBHM0XoqCMF+jxaOL4xx57zM3noYDRk08+affee69tvfXWlkj0vk2YMMFth0suucSVSgud/6Q1tx0AAAAAAACAjqlTILymEJCEBg0aZBMnTtwgQwOIlspxaT9SIAUAAAAAAABAx0cGCQAAAAAAAAAASDkESAAAAAAAAAAAQMohQAIAAAAAAAAAAFIOc5AAAAAAAAAAAICUQwYJAAAAAAAAAABIOQRIAAAAAAAAAABAyiFAAgAAACAuBg0aZBMnTozqsQsWLLCcnBx79913raO57777rFOnTjZv3rxW3WatRa+n1w2l9l5xxRXBv++44w4bMGCAVVVVxbVtABCLfffd10488UQ2XgKLdOxJdLvttpu7tLftt9/eJk+e3N7NAJIWARKgGXPmzLEjjjjCSkpKLDc314YOHWoXX3xxVNtt1apVdtJJJ1mPHj0sPz/ffvWrX9knn3wS1bI6yI4cOXKD26dNm2Z5eXm21VZb2YoVK3j/onD11VfbAQccYD179tzgx30sz6XniPTeNHaSV1BQsMHtX3zxhRUXF7sTwGg6RwAg3vRdF83ljTfe4M1Bm/jjH/9o2223ne24445s4QSkc5zq6mq7884727spQJv+Fjz55JNto402cgHboqIi951000032bp169jySUKB9pdfftnOP//8mH8nvvrqq+73vH7DdenSxbbddlv717/+FTH43djlwQcfbLKd3vIff/yxr/XT78nw19K+usUWW9itt95qdXV1G/Q1NNbG7777rsFjS0tL7YILLrBRo0a537X6HAwZMsSOO+44e+eddzZoy5dffmm//e1vbeDAge6xffv2tT333NNuueUW86uiosK9J+19rvnNN9+4diTy73bt21OnTrXFixe3d1OApJTR3g0AEtlnn33mTh50UD/33HOte/fuNn/+fDeisTn19fW233772eeff27nnXeeO5G67bbb3PPNmDHDBVr8eu2112z//fe3YcOGuRO0bt26xbhmqeWSSy6xXr162ZZbbmkvvfRSzM/z008/2TXXXOOCXS3x1Vdf2bhx49zzvP7660k3SgZAagj/0f/Pf/7TXnnllQ1u33TTTePcMqSCpUuX2v333+8uHdHRRx9thx12mGVnZ1uyUsfXscceazfccIOdfvrprmMN6Eiee+45+7//+z/3OT3mmGPcACkFBdUprN93X3/9tf39739v72YiCtddd537/aWO/Vh+Jz7zzDN24IEH2tixY11Hub7vHn30UbdfLFu2zM4++2z3uF122WWD8yT529/+5voF1Ia2dPjhh7tMGVm9erU9//zz7vv5xx9/dNsgVL9+/WzKlCkbPEefPn2C//7www9dn0Z5ebk7Zp1yyinu8zB37lx7+umnXUDnzTffdOst7733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s4K/W955551Gvy/1GdZr6rX13TRu3Dj3XR363a/neOyxxyI+x8MPP+y+C/RdOXLkyMAzzzwTOPjgg91tsRwD/Kzn8uXLA6eddlqgb9++bhvrN76+g5YtWxbTsTWSAw44wG2TWH8nin57b7vttoEuXbq4dd9uu+0Cjz/+eMTXu+CCC9xzfPHFFwE/vGNDY5cFCxZEXE7HkvDH6hi60UYbBc477zx3nhXr79lFixa559hss83cemv763mPOeaYwFtvvdXgsS+88ELg+OOPd/tNQUGBez91TnL66ae7/bQ5kY497733nnuv9Vzhx6E5c+a4dmif176vfejXv/51g/elqWOxzqeOO+44d96p9ur86Lvvvot43L3rrrvceqenpzfYPyLt01pX73nVbn1G1I5I75mO2+FC11OfA32+tU11zNb5m/a9Rx99tMEyOofQ+YP6qwD410n/iyaQAiBxbbvttm50izeKAwAAINlptLRGTioLwqMMT5XE9Dt5clvTqHFlz2rksTJfUoEylTQyViOkNaoZQMeiUfPKbguf8yIZ6Tii44eyToYOHdrezQFanSZwP+KII1z5v2jnbgXwP8xBAiQ5lZ5Q+qjKhwAAAHQUl19+uSs7prIUiUQ17xsrv9mWpU4TjebpU6kVlb0BkLw0L1X4fF8qNanfmB3lO03lLFVi6i9/+Ut7NwVoEyr/pXKaBEeA2JBBAgAAACApJEIGiea800XzhGjC1Xfeecf+/e9/u8431cIHgGSiOYk016PmttIcT8qy0PwfmpdB37Xh8zEAANDRMEk7AAAAAERp9OjRbpJUjURWJq83cbs3sS8AJBOVB9Tk6P/4xz9s6dKllp+f7yY21wTwBEcAAKmgXTNIrrjiCrvyyisb3DZs2DA3YkEqKyvt3HPPtYcfftjVuB0/frzddttt7kcIAAAAAAAAAABA0s5BMmLECFu0aFHwohR1z9lnn23//e9/3cTTb775pi1cuNAOOuigdm0vAAAAAAAAAABIfu1eYkvp6b169drg9tWrV9vdd99tDz30kO2+++7BiQA33XRTe//992377bdvh9YCAAAAAAAAAICOoN0DJLNmzXITgeXk5NjYsWNtypQpNmDAAJsxY4bV1NS4ycI8w4cPd/dNnz690QCJSnHp4qmvr7cVK1a42pmdOnWKyzoBABKPKkqWl5e7Y05aWrsn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zjnHLr/8cvvkk0/cY8ePH2+lpaUNAhKff/65zZ071x566CFbsmSJJUKAhDlIAABALCixBQAAAABtLHRS9QE9Cmyn4b3dxZusPT97mBXkZtn222/vgiPhy0QKbnjzkDQ14Xs0j0Hq2GeffdylMTfccIObdP24445zf99xxx323HPP2T333GMXXHBBg8f27NnTBVDefvtt++1vfxvx+VSGSxdPWVmZu66vr3eXWGg5lfXyli8qKnLXK1eujPk54yW87ckiWdudzG1P1nYnc9uTtd3J2vZkais6PgIkAADEGZO0A0DqiRSoWLNmjW3UsyhYRnHPPfdsdplIz1uY27nZ127uMUB1dbXNmDHDLrzwwuDGSEtLsz322MOmT5/u/la2iOYgURBPk6KrZNepp57a6MabMmWKXXnllRvcvnTpUqusrIy5U02vrc5AtU/zooiyXEIzXRJReNuTRbK2O5nbnqztTua2J2u7k7Xt5eXl7d0EIIgACQAAcUaABABSU2igQuWANOfI4MGD7YADDmh0rik/wQ3NUUKmCGK1bNkyq6urc5khofT3d9995/79448/2kknnRScnP3000+3UaNGNfqcCraoZFdoBkn//v2tR48ewcyPWDoC9XnRc6gjsG/fvu72devWWUlJiSWy8LYni2RtdzK3PVnbncxtT9Z2J2vbNc8VkCgIkAAAEG/qA/M75zpztANAh+EFR3Q9f/5817GrUfmtMQm8V45LmSeU00Jr23bbbe2zzz6L+vHZ2dnuEk4deC3pxFNHoPcc3bp1CwZfkqFjMLTtySRZ253MbU/Wdidz25O13cnY9mRpJ1IDeyMAAHHGJO0AkLpCgyPehOwtDY5IcxO6A80pLi525arCJ13X37169UrYDdi58/+ysgAAAPwiQAIAQJwRIAGA1KLsjjmLV9uCRUs3CI54E7K3lDeh+7KyyogTugPNycrKsjFjxti0adMalG3R32PHjk3YDdilSxd3rfr7AAAAflFiCwCAOGMOEgBIHV7pqzkLltgPH75kg7tmWJ9eJa0aHIl2QndgzZo1Nnv27OCGmDt3riuZpTJVAwYMcPOFHHvssbb11lu7clo33nijrV271o477rgWbbypU6e6i+Y4aW1kkAAAgJZImQDJF98vtfTs6NPMs7P9b5rOnTesrdqc3t38j+zqkpvue5m8DP/LZGf6TzDS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Zo373BMgAQAA0SBAAgBAEpXYSnVbbLGFGwEeCASC15p/5PHHH3f/Ft2ukmIAOp7N+nezHYb3tHmla2xQSYENKvllxLgyRxQcWbW2yl7/cqF9OfsnW/v9O1a5ttwFhydOnBhzcGRdVa0999UcW7hy3QYZKgASbx4SBUiUQQIAABANAiQAAHSwEluRvPHGG9YRzJ07t72bAKCd7TS8t+043FxpLS9QoaCFMkcUHCnKrLXnn3rchhZn2tCBfV1wxE3IHqNVFVW2cKUyVHJdpgqTsgOJPQ/JTz/95DJIAAAAokGABACAFAiQdBQDBw5s7yYAaCcqcxU614gCJB4FSlRWS5kjCo5k1lda/z79WxwckS552dana14wg4RJ2YHEziARMkgAAEC0CJAAABBnlNiKjeYY0RwqaWlpUT3+66+/tmHDhrma5ACSX+hcI5EyORQk2a5fts3ukWX9eve3I486xkrX1ptl1LSoJFZudob9duzGDeYgAeDP1KlT3aWtS2Aqg0TIIAEAANGixwAAgDgjgyQ2W265pS1evNh69OgR1ePHjh1rn332mW200UYxviKARKLghDI4vAySSJkc247Zwgpys6xLcS974cslwce2dN4QLds5P7uFawCkrkmTJrlLWVlZMIjRlhkkBEgAAEC0CJAAABBnZJDERpOwX3rppZaXt2GnaCTV1dUxvhKARKQghQIdyhwJzeRQR6gyxQoKCtzfm222mc1ZvLrJbJPw0l3hzwkgOXnBF0psAQCApAiQ3H777e4yb9489/eIESPssssus3322cf9XVlZaeeee649/PDDVlVVZePHj7fbbrvNevbs2Z7NBgCgRcggic0uu+xiM2fOjPrxyiDJzc2N8dUAJCIFMEIDHQqO3HfffS5AovlGvCBJNNkmkeY1aWmmCYD2RQYJAABIqgBJv3797Nprr7WhQ4e6UaH333+/TZgwwT799FMXLDn77LPtueees8cee8yNBDnttNPsoIMOsnfffbc9mw0AANrBG2+8wXYHsEFwRNfdu3d3vyeayzbxO68JgOTCJO0AACCpAiT7779/g7+vvvpql1Hy/vvvu+DJ3XffbQ899JDtvvvu7v57773XNt10U3f/9ttv306tBgCgZTqtL7PldxkASHbh5awilbdqruTVopUVNuO7efbJ689afXWFC44oe6SwsLDJbJNIos00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fGTE0Lh11f63W0UMy2zSsyAuncRrqmp9L1NVE593KJX6vBMxg+T111+P6nG1tbVu3pHnn3/e2sull15qeXlNf2/ecMMNcWsPgF8oc0TBkdr6evtp+Rq797Vv7YKDxgTLaOl6360GBjNMvNs1yvu9996z8ePHu6BJ3+75jQZRYg2MzC0ts3e/W2TLyqo2KO8FoGMhgwQAALR6gOSss86yfv36RT3p6YIFC9zEqYkUIAEAIFEk4hwk8uijj9ohhxzSZHBE9z/55JPWnr788kvLymp8IAMZJkD7UNAjPyfTfl6x1tLSOtlPy9favNIyGzWwezBQ8fwnP7rgx5zFZS5IUVe11u677z4XJNHcRnvvvbe7vbUyPbx5T2YtXG2lZZW2+aBuG5T3AtAxAyRkkAAAgFYtsfXxxx8HJ0RtDoERAACSK4NEjjnmGOvatavtueeeG9xXV1fngiPTp0+39vbUU09FfU4CoOUlqYoLo5sHRHOOHLnLUPv7y99Yenony0hPs0ATc5DMnr/Q3nzhKRcc6d69u+24447ucQqKtFbwwnvN3t3ybGnZOvfvTfp0bpXMFACJiUnaAQBAqwdILr/8cisoiL78y0UXXWTdunXz1RAAANC+/vznP9tBBx1kr776qm233XbB2+vr611w5N1337XXXnutXdtIdggQH17mhSt11TXXdh8aXanarTcuse9GrLIfS8ttYEmhDS4pijgHSZesWnvpmcetcm25C45MnDixTQZZhb7m1kNKbKfhvWxQSRHltYAOjAwSAADQJgESPy688EJfjwcAIJUk4iTtcuaZZ9qKFSts3333tbfeestGjBjhMkcOPfRQe/vtt11wRLe1p0AgdDw6gLbSINtjZYWtqsi2gVEsp+yPo3bZJGKJLP1b5bOUOdJWwZHwidi912RydiB1kEECAADapMQWAABoHQp1+A13xGsO+yuvvNIFSfbaay83cfsll1xib775pk2bNs1Gjhxp7e3ee+8NdnwAaDuhmRd9uuZZl7zsqIMTedmNzxuSn51u06c91+LgSHggZIOsl5CJ2FuzZBeAxEcGCQAAaNMAyfLly+2yyy5znSalpaWu7EYodaoAAIDkm6Tdc8stt9jKlStt8803dyU2FRwZPXq0JYJjjz22vZsApITQzAvNQbKufGWTj/eCE/OXrrFVa6usS362DehREAxSeDQRu7LUXnrpJTviiCPMMnJszuLVviZkbywQEj7HCROxA6mJDBIAANCmAZKjjz7aZs+ebSeccIL17NmTWuAAAPiU1umXi99l2to555wT/Lcma1c5qy222MLuu+++Bo+74YYb2r4xANqdl3mhAVHrypt+rIIRCo7U1tXbktXrrFfXvAZBCn2frKms/SXro2dfO+mkk9zfkQIdzWksENIg66VbHhOxAymKDBIAANCmARLVIH/nnXfcqFIAANBxMkg+/fTTBn+PHTvWamtrG9zOJOlA6vDKWCmDpDkqq6XMkdLV60xfV2vW1dhGvYpckGLVqlX2rwcfttqeI21NIDcYDIk140PPqWU0EXzvbvlWUVXr2sp8IwCEDBIAANCmAZLhw4fbunXr/C4GAABCxLFiVtRUPhMAwstYFRdm25Z9siy3sKt1zo88F0lFVY0rq9W7a56VV9banpv3tTEblVhd1VqXhfbDT4ttwVcLbc8JhwSDIS3L+AhYbX29zVq4ylaUVzYo58V8I0Bq8zJI1G9RXV1tWVlZ7d0kAADQkQIkt912m11wwQVuHhJN1pqZ2TANvqioqDXbBwBAh5OoGSQA4PGyO4ryMm3GnFJbvTLdvi6ttUN2HBqxDJaCGwpSaJl+3fOte0GOyxx54pEH3XX/Pr1s2NCdbHl5VTAYEp7xIdHMR6LHLyurcpktX/y4wvp2z2fOEQAR+yRWr15tPXr0YOsAAIDWC5BoNEZZWZntvvvuDW5XXWF13tTV1fl9SgAAUkoizkGi+Uf+9Kc/WX5+flSPv/DCC+28886zbt26WbxoXpRoA0UrVqxo8/YAHZmX3TFr4WoLWCfrnJdp3y9abfNKy2zUwO4bPN4LdswtLbN3v1tk/379S/vhw5dscNcM69OrxCZOnOgmZPeCIV4AxMv4WLSywh58+3srr6iJOLl7pLZpzpMeRTlWWV3nlvGXgQKgo0pPT7fCwkIrLy8nQAIAAFo/QHLkkUe6rJGHHnooqSZp37Rfka/sltUVNb5f45ufy3wv82NZhe9l1tbU+l6mT36u72WKC/2nIqsGtF+Lyyt9L/Nlqf9tvWBVte9l0mPokRzZy3+QUJ0Ofgws9vd4WVfjv11VNfW+l8nP9v21Yuuq/betPhDwvUx2ZprvZSpj2G6xfH+ofIlfCkz7tXyN/7bV1vt/nYwYPjvJcjzpqG666SYX9Ig2QDJ16lQ78cQT4xogufHGG4P/Xr58uV111VU2fvx4N1eKTJ8+3V566SW79NJL49YmoKMKDXi8/uUCm79kqS2vTLd3vltsg0qKIgYvdJvOAxYsWmaz3n/Rli1fYcP6DnHBEXVW/vKYzhHLeT301vf2yQ/LrNv642FT85GEZp5o7hOV92ou6wRIdgsWLHDnSv369XN/f/jhh+43+WabbWYnnXRSezcvIechUYBEGWwAAABN8d2T+dVXX7nJWocNG+Z3UQAAkKAlthRw22STTaJ+nbVr11q8HXvsscF/H3zwwfbHP/7RTjvttOBtZ5xxht1666326quv2tlnnx339gEdZVJ2L9igy+iB3d33w4vlq61Xzy62rKyyyeCFm5R97ucuONK7Zw87+cTfBYMjjdHzla2rsa4F2e75i3Kz3LXXjvB2CXONINUcccQRLhBy9NFH2+LFi23PPfe0ESNG2IMPPuj+VglsNKx88dNPP7kMEgAAgFYNkGy99dZu9AoBEgAAYqMQhN9wR1vn19x7772+l1EmaXtRpsif//znDW7fe++93VxpAPxREOKBt2bavNI1NqikwI7aZVgwGDGoR6EraTWvrMb6dMtvspSVlvnj2SfYY08+bRN+va/1Kfklyyw0yCGhAQ9v/pLaunqrqq2zn1essTtf+da2GVJsB267kT3/yY/BidybKr0FdGQaqLjtttu6fz/66KNuPtB3333XXn75ZTvllFMIkETIIBEySAAAQKsHSE4//XQ788wzXd3xUaNGbTBJ++jRo/0+JQAAKSWtUyd38btMvLIzkkH37t3tP//5j5177rkNbtdtug+AP5pb5KPZy1y2yNKySttpeG9XSkuBDE2Grr/HZuVbzy4FEQMUlZWVlpOT4/5d3KXATj3+qOB9Co48+t5sF+QoLsq2tZV1Nn9puW3cu8iO333TYMmsGT+U2rMfz7dlZetcOxSsmblw5frlcpiIHSmtpqbGsrN/KUGnTMkDDjjA/Xv48OG2aNGidm5dYmaQCAESAADQ6gGSQw891F0ff/zxwdtUjoNJ2gEAiI5iHX7jHUzR0tCVV15pv/vd7+yNN96w7bbbzt32wQcf2Isvvmh33XUXuyLgk2ab6mQBN8eXppFaW1UbDGr06Zpruw8tso16dra0tA3n81IH5H333WebjtzchozcaoP5QBRk8YIc3y9c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xG426GA1J9BnlIiIuiVZlx988EHSryEJilRVValt38CBA+M9HCIiIooTltgiIiKKUw8Srf8R9Qan0xnT4IhodnrQ1OqBxDhlKs1Nx9jy/F59TCIiAhYtWoQzzjhD9ciSE3ReffXVfVbL3LlzVYlFybKYNGkSli5d2idXXbDMlmSQEBERUepigISIiCjG2IOEEomUGBkzZkzMgiNi/e56FSQpzUmHzWzEKePKUJLDBu1ERL2tpaVFfedLEKQr0oPr5ptvxp133okVK1ao+06fPh3V1dV97sUJltWSEwSIiIgodbGWAREREVEKkzOIpVzKUUcdpYIlsTC8NAcFditqHE70z0vHkcOKY/K4RESpbsaMGWrqzoMPPoirrroKl19+ubr+2GOP4Y033sBTTz2FW2+9VfPjSY8PmYKCDdH9fr+aoiHzSYneaOcPstvt6rK+vv6glxXrscdaso47mceerONO5rEn67iTdezJNFbq+xggISIiijG2IKF4k7NlpX78aaedBpPJpIIksQqOCMkWufWc8SqTRIIlzB4hIoo/t9uN5cuX47bbbgvdptfrMW3aNCxevDiqZc6ZMwd33333PrfX1NSoEo/RHlSTslhyMFDGF620tDR1uXPnzphlyPTU2GMtWcedzGNP1nEn89iTddzJOvampqZ4D4EohAESIiKiWGOEhBKkIbv8gDrzzDPjMg4JijAwQkSUOGpra+Hz+VBUVNThdrm+bt260HUJmKxevVqV6+rfvz/mz5+PyZMnd7lMCbZIya7wDJKysjIUFBSEMjiiORAogX1ZxsEcCCwsLAwtL/jv3tZTY4+1ZB13Mo89WcedzGNP1nEn69ilzxVRomCAhIiIKMaiabrOJu3U08ER6Tly/PHHc8USEZEm7777bsT3lezErjIU5QDewRzEkwOBB7uMnJwcdSlnXcfygGJPjD0eknXcyTz2ZB13Mo89WcedjGNPlnFSamCAhIiIKMaamhyqUbvWeYh6MjgSq4bsRESUHPLz82EwGFBVVdXhdrleXFzcZ5u0S4CEiIiIUhcDJERERDFiNpvVAYahFWVRzS/zyjKItGJwhIiIDkT2MSZMmICFCxdi5syZobItcv26667rcyswKysrtI0kIiKi1MUACRERUQzrrG7ZskU1QY32wAVrtZJW0qzxxRdfZOYIERGhubkZGzduDK0J2S9Z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3kNLGB9++KHacfjss8+wYMECtXE7+eST0dLSErrPTTfdhP/+979qB0juLxu6c845J67jThSff/45Hn/8cfUjMxzX2b7q6+tx9NFHw2QyqR/ha9euxR/+8Afk5OSE7nP//ffjz3/+Mx577DEsWbJE7WDJZ1YOUKWq3/3ud+pAxl/+8hd8/fXX6rqsp4cffjh0H643qO8s+Y6XndWuRLKO5CDfV199pb4LX3/9dbVTevXVV8fkdSZK5H0BuZTr8iPqvffewyeffAK3261+tPn9/qT+DPXv31+d6LB8+XIVsD/hhBPUwWB5HpFszyWILQeJZX18+umneOaZZ9SBFznAkegO9NxbW1vVQYJf/OIX3S4jGV/zAz13eY1l+v3vf48vv/xSvZ5vv/22Cv70hdc9ktd+woQJmDdvntrveOedd9RBO/kOkOfdF54/9c3f8vJevPDCC9VndeXKlSowIZN8jhPt93VXJFi5Z8+e0LRt2zbE2qGHHtphDB9//HG3902U9R38TR4+blnv4vvf/35Cre+e+L0Sr2Ne+xu77C/IY8tJfXL573//WwUFzzzzzB59z/X0uINkXyd8DP/85z/3u8xEWOcifMwyPfXUU2pfXU7miec6J0pqgT5q4sSJgdmzZ4eu+3y+QGlpaWDOnDlxHVciq66ultPSAx9++KG63tDQEDCZTIH58+eH7vP111+r+yxevDiQypqamgJDhw4NLFiwIHDssccGbrjhBnU711nXbrnllsCUKVO6XZ9+vz9QXFwceOCBB0K3ybq0WCyBf/7zn4FUddpppwWuuOKKDredc845gYsuukj9m+ttX/L99Morr4SuR7KO1q5dq+b7/PPPQ/d56623AjqdLrBr165eeGWJkmdf4J133gno9fpAY2Njh8+QfD5kG9jXPkM5OTmBv/3tbxFtz9988021biorK0P3efTRRwN2uz3gcrkCySb43MO9//776jnX19d3uL0vvebdPfegl156KWA2mwMej6dPvu4Hev6rV69Wr/XGjRv77POn5P8tf95556n95nCTJk0K/PCHPwwk0ja1K/PmzQtkZWUF4unOO+8MjBkzJuL7J+r6FvK7fPDgweo3QKKu72h+ryTKMa/OY+/K0qVL1f22bdvWY++53hj3rFmzAmeddZam5STqOpfnccIJJ+z3PrFe50TJpk9mkMgZTXJWlKQlBun1enV98eLFcR1bIguWD8jNzVWXsg7lrJfw9SgpeFJuINXXo5wZJGfPha8bwXXWtf/85z84/PDD1Zk8km4+btw4PPHEE6G/b9myBZWVlR3WZ1ZWlkpZTeX32lFHHYWFCxfim2++UddXr16tzvKYMWOGus71dmCRrCO5lPIw8h4NkvvLdkPO4CJK5X0Bl8ulzkizWCyh+0hJAfl8BM866wufITkr/oUXXlBn7EnJoUi253IpJSWKiopC95GzCB0OR+hs/GR87pHoC695pM9dPhNytrHRaOxTr3skz19ul2wSKfVZVlbW554/9Z3f8nJ7599l8r6M9++IztvU7kh5woEDB6rPWXhGVyxJOScp5zNo0CCVISil9LqTqOtb3jv/+Mc/cMUVV6h9l0Re3+Gi+U2XyMe85H0v61/2E3rqPddbPvjgA3V8QkprXnvttdi7d2+3903UdS7lX994440O2a6JvM6JElWfDJDU1taqHf7wHXch12XDQ/uSMhnSR0PKIB122GHqNllXZrN5nw1bqq9H+SEp6ZRSY7YzrrOubd68WZWKGjp0qCrXIDsfUtNbyjIE15vgZ7ajW2+9FRdccIE6KCflySSwJJ9T2ZnheotMJO8tuZQd43ByIEx+zKbydx2lnq72BY488khV5kHqS0sZBTlg+tOf/lTtZ0lqfrJ/htasWaP6i0gA6JprrsErr7yCkSNHRrQ9l8uuvluCf0t03T33SCTza67luctvCun9FV46LNlf90ie/yOPPKL+LpOURpWSNfJ56CvPn/reb/nu3pfxfE92tU3tihyYlfI4r732mjq4L/PJSVI7d+6M2VjlQHywpKD8ZpMD9scccwyampqSZn0L6dMgPbOkt0Qir+/OovktnKjHvKQkmOwzSgk2Obmgp95zvUHKa/39739XJyRKKWspkScnIgZLSibLOpdjKtL36ECl8BNhnRMlsvZToSjlSUaE1AxlDcL927FjB2644Qb1QzHWzfOSmex4ylmm9957r7ouB/rl/SY1VmfNmhXv4SWsl156Cc899xyef/55VS901apV6oeWnPXB9UZEsdgXkCbN0oNDAttSG1vOlJMfvePHj1f/TnZyoES+W+Vsx5dffll9t8oP5FTQ3XOPNEjS15+7ZERItrDcJo1NU+n5y4kYJ510kgqCSj+W8847T/Uf4r4vUc//vpbsrfAM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1T6BjkRc50GPP/642g43NDR0uYx4rHOiZKaT/8U7i4WIiIiIiIiIiIiIiCiW+mQPEiIiIiIiIiIiIiIiov1hgISIiIiIiIiIiIiIiFIOAyRERERERERERERERJRyGCAhIiIiIiIiIiIiIqKUwwAJERERERERERERERGlHAZIiIiIiIiIiIiIiIgo5TBAQkREREREREREREREKYcBEiIiIiIiIiIiIiIiSjkMkBAlqa1bt0Kn06lp7NixcRnDXXfdFRrDQw89FJcxEBERUfI5mH2I8vLy0LwNDQ29NkYiIkodsk159dVXe/33+6pVq9CbLrvsMsycObNXH4OIqK9hgIQoyb377rtYuHBhXB77pz/9Kfbs2YP+/fvH5fGJiIhSQTAY0N0kwYZYnpjR3fT0009rWuahhx6q9iOuvvrqDsGP8IBJIBBQ+xt2ux0ffPCBuu3zzz/Hv/71rx58dkRE1NdVVlbi+uuvx6BBg2CxWFBWVoYzzjgjbr+le8uf/vQnzdvj3g4OERElOmO8B0BEBycvL09N8ZCRkaEmg8EQl8cnIiJKBRJECHrxxRdxxx13YP369aHbZFscHlDw+XwwGnt2N18OJIWP4/e//z3efvttdaJGUFZWlqZlyhiLi4u7/bs8j6uuugqvv/463n//fUyYMEHdXlBQgNzc3KieBxERpR4J8h999NHIzs7GAw88gFGjRsHj8eCdd97B7NmzsW7dOvQVWrfFRETEDBKihFBTU6MOENx7772h2z799FOYzWbNZ7QEU2plWUVFRWon8J577oHX68XPfvYzdUBBMj7mzZu3z1mhL730Eo455hikpaXhiCOOwDfffKPO0jz88MPVwZcZM2aosRIREVHsyD5CcJIDH7LNDl6XgzqZmZl46623VABBzor9+OOPuyyxceONN+K4444LXff7/ZgzZw4qKirUtn/MmDF4+eWXuxyDnAwRPg7ZLwgGOIKTLKOnuFwufP/731cBmI8++igUHCEiItLqRz/6kdp2Ll26FOeeey6GDRumshhvvvlmfPbZZ6H71dbW4uyzz4bNZsPQoUPxn//8p8NyvvzyS/WbWLaB8lv7kksuUfOEb1fvv/9+DBkyRG2PBwwYgN/+9rfdngRwxRVXYMSIEdi+fbu6Tcb46KOPqseQbapku3TeLq9ZswYnnHCC+rucKClZmM3NzaG/d97+y3b/xz/+MX7+85+rYwGyvQ7PPJXMTSHPWx4/eJ2IKJWwxBZRApAzIZ966im1o7Js2TI0NTWpna3rrrsOJ554oublvffee9i9ezcWLVqEBx98EHfeeSdOP/105OTkYMmSJbjmmmvwwx/+EDt37uwwn9zvV7/6FVasWKEOevzgBz9QO1KSpisHJzZu3KjOWiUiIqLEcuutt+K+++7D119/jdGjR0c0jwRH/v73v+Oxxx7DV199hZtuugkXX3wxPvzww6jHsWnTJnUw5qijjlJZJtGQAz2nnXYa1q5di08++QTDhw+PejxERJTa6urqVMajZIqkp6fv83c5oTDo7rvvxnnnnYcvvvgCp556Ki666CI1v5CeVxKYGDdunPrNLsusqqpS9w+67bbb1Lb49ttvV9uw559/XgVSujsJQPqRyO9sCaQEybwSxFm9erV6/AsuuEBt20VLSwumT5+uftfLiYzz589XJxLIcYP9eeaZZ9Rzl2MBEsCREygXLFig/ibLEXICpWSKBq8TEaUSltgiShCyAyZlJGQnSDI2ZAdGDlxEQ84M+fOf/wy9Xq8OKshOUGtrK37xi1902HGTM0xlhytIanzLDpe44YYbcOGFF6oMFklHFldeeaXmeqZERETU++Rgx0knnRTx/eXgjGSbyoGVyZMnq9vkTFXZN3j88cdx7LHHRjWOW265Bb/73e8wceJEHH/88eoA0MCBAzUt49e//rXKipEDQnISCRERUbTkJD8pPymZGgci2RfyG1jINlJ+U0vWySmnnIK//OUvKjgSXvVBTnKUEpRSeaGkpESdWCj3mzVrlvr74MGDMWXKlC5PApDtsJSP7FwSS7ab//d//xfaHkog4+GHH8YjjzyiAi5Op1Od3BAM9sjjSS8V2fZ2FYwRcuKEnAwpJDNG5pHf+bLfENzOSqBof2UviYj6MmaQECUQOdNSSmHJmSDPPfecSsuNhqQLS3AkSHaUpM5qeJkMScetrq7uMF/4GafBnavw+eS2zvMQERFR/MnJFVoPGMnJE3JwJNhTTCY56CJZINGSg0STJk1SZTrkAJAEXLQ6+eST1Vmy4QehiIiIoiHBkUiF/x6WAITdbg/9/pWMDglohG8zg0EX2W5KUF+CHgeqACEBGNnG/e9//+uyX0jwpIXw68EMErmUcpjhmTByMqOU9grvTba/5yUkmMPf9URE32EGCVECkR0rKY0lOzjSFyQ8OKGFyWTqcF0OUnR1mzxOd/PJ37u6rfM8REREFH+dy4bIiRKdDwpJQ9qgYL3yN954A/369etwv2hP0OhMzkYNlibRQg4uXX/99TjrrLPUfoeckUtERBQNyZiQ37GRNGLf329m2W4GMzU6k4DD5s2bI64c8Y9//AOLFy9WJbtiIZJjAUREqYwZJEQJwu12q7rf559/vkqllbRantVBRERE0ZCSGVJLPJzUOg8aOXKkCoRIY1hpJhs+SbmQnlBfX6/KfkZDskj++9//4oknnlDNZYmIiKIh2yEpIz137lyVudGZ9BaJxPjx41W/Lmli3nm7KScpSCBGGqdL6ar9ufbaa1W56zPPPLPLnl/hTeOD1w855BD1b7mUTJbw5yG9uoKltQ8mgCJN44mIUhUDJEQJ4pe//CUaGxtVnVOp3z1s2DBcccUV8R4WERERJSE5K1WayErJrA0bNqja419++WXo79LjQ3qPSWN2ad4qWawrVqxQdc7lerTkAI00gZXslTfffHOf2utaTJs2Da+//jqefPLJAzagJSIi6o4ERyQAIP2x/vWvf6ntopSrkt/enUtadUeavEtWpJTIkkbmst185513cPnll6tlW61W9Tv+5z//eahcpQQ3ZBvWmWRJ/uY3v8Hpp5++TylKKbctvU2kZKVsu6UHSnAbKP1K5XGkx4ls06Xklyzrkksu6bb/SCQk6COBncrKSnVyAxFRqmGJLaIE8MEHH+Chhx5SOzhS51Q8++yzqr7oo48+qs4yISIiIoqUnC17++23qwM10tBVTrq49NJLsWbNmtB9JGNVMk3mzJmjSoNISSw5Q/YXv/hF1CtaliVZsJIZe84552hu0N5VoEfKgMlBJAm6SGPZYBlQIiKiSAwaNEidBPDb3/4WP/nJT1SGpWz/JkyYoH5vR6K0tFRla0gQRLIcpd+IbOOkgXuw/6dsd41GI+644w5VOltKb11zzTVdLu/GG29UZa6k5Nbbb7+No446St1+991344UXXsCPfvQjNf8///lPlfUpbDabCsrccMMNOOKII9T1c889Fw8++OBBvRH+8Ic/4Oabb1ZZm1J2U8p9ExGlEl1AS8cqIkoYstNSUVGBlStXYuzYsXEdi5xxIjt4MhEREREdyF133YVXX321Q9kvrSeXHH/88epMVwnsEBERJTs5AeCVV17BzJkz4z0UIqKUwhJbRElOzjQJnm0Sa/feey8yMjJU/XIiIiIiLSSbRfYjHnnkEU3zHXrooZgxYwZXNhERERERHTRmkBAlKa/XG0p9lSarPdVQVQupwSqTkBTlrKysmI+BiIiIks/B7ENs27YNHo8nVDYlWNqEiIgomTGDhIgoPhggISIiIiIiIiIiIiKilMPTrYiIiIiIiIiIiIiIKOUwQEJERERERERERERERCmHARIiIiIiIiIiIiIiIko5DJAQEREREREREREREVHKYYCEiIiIiIiIiIiIiIhSDgMkRERERERERERERESUchggISIiIiIiIiIiIiKilMMACRERERERERERERERIdX8P46zcx3X2WO3AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(2, 3, figsize=(16, 9), layout=\"constrained\")\n", + "\n", + "extent = [0, Lx * 1e3, 0, Ly * 1e3]\n", + "\n", + "# --- Top row: initial temperature fields ---\n", + "vmin_init = min(T_init_true.min(), T_init_recovered.min(), T_inf)\n", + "vmax_init = max(T_init_true.max(), T_init_recovered.max())\n", + "\n", + "axes[0, 0].imshow(\n", + " T_init_guess.reshape(ny, nx),\n", + " origin=\"lower\",\n", + " cmap=\"hot\",\n", + " extent=extent,\n", + " aspect=\"auto\",\n", + " vmin=vmin_init,\n", + " vmax=vmax_init,\n", + ")\n", + "axes[0, 0].set_title(\"Starting guess\\n(uniform ambient)\")\n", + "\n", + "axes[0, 1].imshow(\n", + " T_init_recovered.reshape(ny, nx),\n", + " origin=\"lower\",\n", + " cmap=\"hot\",\n", + " extent=extent,\n", + " aspect=\"auto\",\n", + " vmin=vmin_init,\n", + " vmax=vmax_init,\n", + ")\n", + "axes[0, 1].set_title(\n", + " f\"Recovered T₀\\n(corr={np.corrcoef(T_init_true, T_init_recovered)[0, 1]:.3f})\"\n", + ")\n", + "\n", + "im_true = axes[0, 2].imshow(\n", + " T_init_true.reshape(ny, nx),\n", + " origin=\"lower\",\n", + " cmap=\"hot\",\n", + " extent=extent,\n", + " aspect=\"auto\",\n", + " vmin=vmin_init,\n", + " vmax=vmax_init,\n", + ")\n", + "axes[0, 2].set_title(\"True T₀\\n(two Gaussian hot spots)\")\n", + "\n", + "plt.colorbar(im_true, ax=axes[0, :].tolist(), label=\"Temperature [K]\", shrink=0.85)\n", + "\n", + "# Mark sensor locations on all top-row plots\n", + "for ax in axes[0, :]:\n", + " for jy_idx in sensor_jy_p2:\n", + " for ix_idx in sensor_ix_p2:\n", + " x_mm = ix_idx / (nx - 1) * Lx * 1e3\n", + " y_mm = jy_idx / (ny - 1) * Ly * 1e3\n", + " ax.plot(x_mm, y_mm, \".\", color=\"cyan\", markersize=2, alpha=0.5)\n", + " ax.set_xlabel(\"x [mm]\")\n", + " ax.set_ylabel(\"y [mm]\")\n", + "\n", + "# --- Bottom row: diagnostics ---\n", + "error_p2 = np.abs(T_init_recovered - T_init_true).reshape(ny, nx)\n", + "im_err = axes[1, 0].imshow(\n", + " error_p2, origin=\"lower\", cmap=\"Blues\", extent=extent, aspect=\"auto\"\n", + ")\n", + "axes[1, 0].set_title(\n", + " f\"|Recovered - True|\\nmax={error_p2.max():.1f} K, mean={error_p2.mean():.1f} K\"\n", + ")\n", + "axes[1, 0].set_xlabel(\"x [mm]\")\n", + "axes[1, 0].set_ylabel(\"y [mm]\")\n", + "plt.colorbar(im_err, ax=axes[1, 0], label=\"Error [K]\", shrink=0.85)\n", + "\n", + "axes[1, 1].scatter(T_init_true, T_init_recovered, s=3, alpha=0.5, c=\"steelblue\")\n", + "lims = [vmin_init - 5, vmax_init + 5]\n", + "axes[1, 1].plot(lims, lims, \"k--\", alpha=0.5, label=\"perfect recovery\")\n", + "axes[1, 1].set_xlim(lims)\n", + "axes[1, 1].set_ylim(lims)\n", + "axes[1, 1].set_xlabel(\"True T₀ [K]\")\n", + "axes[1, 1].set_ylabel(\"Recovered T₀ [K]\")\n", + "axes[1, 1].set_title(\"True vs. recovered (per grid cell)\")\n", + "axes[1, 1].legend()\n", + "axes[1, 1].set_aspect(\"equal\")\n", + "axes[1, 1].grid(True, alpha=0.3)\n", + "\n", + "axes[1, 2].semilogy(loss_history_p2, \"k.-\", linewidth=1.5)\n", + "axes[1, 2].set_xlabel(\"Checkpoint\")\n", + "axes[1, 2].set_ylabel(\"Loss\")\n", + "axes[1, 2].set_title(f\"Convergence ({result_p2.nit} L-BFGS iterations)\")\n", + "axes[1, 2].grid(True, alpha=0.3)\n", + "\n", + "plt.suptitle(\n", + " \"Recovering a 900-element initial temperature field from 100 sensors\",\n", + " fontsize=13,\n", + " fontweight=\"bold\",\n", + ")\n", + "fig.savefig(FIGURE_DIR / \"thermal_forensics.png\", dpi=180, bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "b8bf0b54853e", + "metadata": {}, + "source": [ + "## Takeaways\n", + "\n", + "Each `jax.value_and_grad` call above triggered the following chain:\n", + "\n", + "| Layer | Technology | Role |\n", + "|-------|-----------|------|\n", + "| Optimizer | SciPy L-BFGS-B | Quasi-Newton update loop |\n", + "| AD framework | JAX reverse-mode | Propagates cotangents |\n", + "| Tesseract bridge | `tesseract-jax` | Registers JAX primitive, dispatches HTTP calls |\n", + "| Transport | HTTP + JSON | Crosses the process/container boundary |\n", + "| AD engine | Enzyme (LLVM pass) | Generates the VJP from compiled Fortran IR |\n", + "| Solver | Fortran 90 | `thermal_2d_solve` |\n", + "\n", + "1. **Compiled Fortran can participate in end-to-end AD.** The forward solver is\n", + " plain Fortran and was never modified. Enzyme differentiated it from the compiled\n", + " LLVM IR, and Tesseract made it callable -- and differentiable -- from JAX.\n", + "\n", + "2. **No hand-coded adjoints.** Both the forward- and reverse-mode derivatives are\n", + " synthesized by the Enzyme pass, rather than derived and maintained by hand.\n", + "\n", + "3. **The gradients are verifiable.** In the linear regime, Enzyme's VJP matches an\n", + " independently derived analytic gradient to roundoff.\n", + "\n", + "4. **Reverse-mode AD scales to high-dimensional inverse problems.** The same\n", + " `jax.value_and_grad` call returns all 900 gradient components from a single\n", + " reverse sweep, which is what makes the 900-parameter reconstruction tractable.\n", + "\n", + "### What's next\n", + "\n", + "- **Change the forward model.** Edit the Fortran source and rebuild; Enzyme\n", + " regenerates the derivatives with no adjoint code to update.\n", + "- **Try a different inverse problem.** Recover a boundary condition or a heat\n", + " source instead of the initial field, or vary the number and placement of sensors.\n", + "- **Swap in a different optimizer.** Replace L-BFGS-B with any other\n", + " `scipy.optimize` or `optax` optimizer to compare convergence behavior.\n", + "- **Explore other demos.** See the [CFD optimization](cfd-optimization.ipynb),\n", + " [data assimilation](data-assimilation.ipynb), and\n", + " [FEM shape optimization](fem-shape-optimization.ipynb) demos for other ways to\n", + " compose Tesseracts with JAX.\n", + "\n", + "Questions? Feedback? Please reach out through the [Tesseract Community Forum](https://si-tesseract.discourse.group/)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/demo/enzyme-lfortran/enzyme/build.sh b/demo/enzyme-lfortran/enzyme/build.sh new file mode 100644 index 000000000..340133cc2 --- /dev/null +++ b/demo/enzyme-lfortran/enzyme/build.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Copyright 2025 Pasteur Labs. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Build pipeline: Fortran -> LFortran -> LLVM IR -> Enzyme AD -> shared library +# +# This script implements the full compilation pipeline: +# 1. LFortran compiles Fortran to LLVM IR +# 2. LLVM opt cleans up the IR (-O1) +# 3. Clang compiles the C wrapper (with Enzyme calls) to LLVM IR +# 4. llvm-link merges the Fortran and C IR modules +# 5. Enzyme LLVM pass generates derivative code +# 6. Clang compiles the differentiated IR to a shared library + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ENZYME_LIB="${ENZYME_LIB:-/usr/local/lib/LLVMEnzyme-19.so}" +OUTPUT="${1:-${SCRIPT_DIR}/libthermal_2d_ad.so}" + +echo "=== Step 1: LFortran -> LLVM IR ===" +lfortran --show-llvm --no-array-bounds-checking \ + "${SCRIPT_DIR}/thermal_2d.f90" > /tmp/thermal_2d.ll + +echo "=== Step 2: Optimize IR ===" +# Use -O1 before Enzyme to avoid aggressive transforms (vectorization, code +# motion) that produce IR patterns Enzyme's reverse-mode pass mishandles — +# specifically NaN gradients when adjacent cell values are equal and +# intermediate terms cancel. Post-Enzyme -O3 is fine. +opt -O1 -S /tmp/thermal_2d.ll -o /tmp/thermal_2d_opt.ll + +echo "=== Step 3: Compile C wrapper -> LLVM IR ===" +clang -emit-llvm -S -O1 "${SCRIPT_DIR}/wrapper.c" -o /tmp/wrapper.ll + +echo "=== Step 4: Link IR modules ===" +llvm-link /tmp/wrapper.ll /tmp/thermal_2d_opt.ll -S -o /tmp/combined.ll + +echo "=== Step 5: Enzyme AD pass ===" +opt --load-pass-plugin="${ENZYME_LIB}" -passes=enzyme \ + -S /tmp/combined.ll -o /tmp/ad.ll + +echo "=== Step 5b: Optimize post-Enzyme IR ===" +opt -O3 -S /tmp/ad.ll -o /tmp/ad_opt.ll + +echo "=== Step 6: Compile to shared library ===" +clang -shared -O3 /tmp/ad_opt.ll -o "${OUTPUT}" -lm + +echo "=== Built ${OUTPUT} ===" diff --git a/demo/enzyme-lfortran/enzyme/thermal_2d.f90 b/demo/enzyme-lfortran/enzyme/thermal_2d.f90 new file mode 100644 index 000000000..1a7f983b8 --- /dev/null +++ b/demo/enzyme-lfortran/enzyme/thermal_2d.f90 @@ -0,0 +1,218 @@ +! Copyright 2025 Pasteur Labs. All Rights Reserved. +! SPDX-License-Identifier: Apache-2.0 +! +! 2D transient heat conduction solver with temperature-dependent conductivity. +! +! Solves: +! +! rho * cp * dT/dt = div( k(T) * grad(T) ) + Q +! +! on a rectangular domain [0, Lx] x [0, Ly] with a structured grid. +! +! Material model: +! k(T) = k0 + k1 * T +! +! Boundary conditions: +! Bottom (y=0): Dirichlet, T = T_hot +! Top (y=Ly): Convection, -k dT/dn = h_conv * (T - T_inf) +! Left (x=0): Neumann (insulated), dT/dx = 0 +! Right (x=Lx): Neumann (insulated), dT/dx = 0 +! +! Time integration: explicit Euler with n_steps steps of size dt. +! +! Work arrays T_cur and T_new are passed in from the caller to avoid +! dynamic allocation (LFortran emits _lfortran_malloc for VLAs, which +! Enzyme cannot differentiate through). +! +! This subroutine is compiled to LLVM IR via LFortran, then +! differentiated by Enzyme to obtain exact JVP and VJP functions. + +subroutine thermal_2d_solve(n, nx, ny, n_steps, & + T_init, T_final, T_cur, T_new, & + k0, k1, rho, cp, & + h_conv, T_inf, T_hot, & + Q, Lx, Ly, dt) + implicit none + integer, intent(in) :: n, nx, ny, n_steps + double precision, intent(in) :: T_init(n) + double precision, intent(out) :: T_final(n) + double precision, intent(out) :: T_cur(n) + double precision, intent(out) :: T_new(n) + double precision, intent(in) :: k0, k1, rho, cp + double precision, intent(in) :: h_conv, T_inf, T_hot + double precision, intent(in) :: Q(n) + double precision, intent(in) :: Lx, Ly, dt + + double precision :: dx, dy + double precision :: kx_east, kx_west, ky_north, ky_south + double precision :: T_c, T_e, T_w, T_nn, T_s + double precision :: flux_x, flux_y + integer :: i, j, idx, step + + dx = Lx / dble(nx - 1) + dy = Ly / dble(ny - 1) + + ! Copy initial condition + do idx = 1, n + T_cur(idx) = T_init(idx) + end do + + ! Time integration loop + do step = 1, n_steps + + ! --- Interior points --- + do j = 2, ny - 1 + do i = 2, nx - 1 + idx = (j - 1) * nx + i + + T_c = T_cur(idx) + T_e = T_cur(idx + 1) + T_w = T_cur(idx - 1) + T_nn = T_cur(idx + nx) + T_s = T_cur(idx - nx) + + ! Harmonic-mean conductivity at cell faces + kx_east = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_e) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_e)) + kx_west = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_w) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_w)) + ky_north = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_nn) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_nn)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + flux_x = (kx_east * (T_e - T_c) - kx_west * (T_c - T_w)) / (dx * dx) + flux_y = (ky_north * (T_nn - T_c) - ky_south * (T_c - T_s)) / (dy * dy) + + T_new(idx) = T_c + dt / (rho * cp) * (flux_x + flux_y + Q(idx)) + end do + end do + + ! --- Bottom boundary (j=1): Dirichlet T = T_hot --- + do i = 1, nx + idx = i + T_new(idx) = T_hot + end do + + ! --- Top boundary (j=ny): Convection BC --- + ! -k dT/dn = h_conv * (T - T_inf) + ! (one-sided difference for the normal derivative) + do i = 2, nx - 1 + idx = (ny - 1) * nx + i + + T_c = T_cur(idx) + T_e = T_cur(idx + 1) + T_w = T_cur(idx - 1) + T_s = T_cur(idx - nx) + + kx_east = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_e) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_e)) + kx_west = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_w) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_w)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + flux_x = (kx_east * (T_e - T_c) - kx_west * (T_c - T_w)) / (dx * dx) + + T_new(idx) = T_c + dt / (rho * cp) * ( & + flux_x & + + ky_south * (T_s - T_c) / (dy * dy) & + - h_conv * (T_c - T_inf) / dy & + + Q(idx)) + end do + + ! --- Left boundary (i=1): insulated (zero flux) --- + ! Mirror: T_w = T_e => flux_x uses only east neighbor + do j = 2, ny - 1 + idx = (j - 1) * nx + 1 + + T_c = T_cur(idx) + T_e = T_cur(idx + 1) + T_nn = T_cur(idx + nx) + T_s = T_cur(idx - nx) + + kx_east = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_e) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_e)) + ky_north = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_nn) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_nn)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + ! Zero-flux left: symmetric difference gives 2*(T_e - T_c)/(2*dx^2) + flux_x = kx_east * (T_e - T_c) / (dx * dx) + flux_y = (ky_north * (T_nn - T_c) - ky_south * (T_c - T_s)) / (dy * dy) + + T_new(idx) = T_c + dt / (rho * cp) * (flux_x + flux_y + Q(idx)) + end do + + ! --- Right boundary (i=nx): insulated (zero flux) --- + do j = 2, ny - 1 + idx = (j - 1) * nx + nx + + T_c = T_cur(idx) + T_w = T_cur(idx - 1) + T_nn = T_cur(idx + nx) + T_s = T_cur(idx - nx) + + kx_west = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_w) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_w)) + ky_north = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_nn) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_nn)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + flux_x = kx_west * (T_w - T_c) / (dx * dx) + flux_y = (ky_north * (T_nn - T_c) - ky_south * (T_c - T_s)) / (dy * dy) + + T_new(idx) = T_c + dt / (rho * cp) * (flux_x + flux_y + Q(idx)) + end do + + ! --- Corners --- + ! Bottom-left and bottom-right: Dirichlet (already set above) + ! Top-left corner (i=1, j=ny) + idx = (ny - 1) * nx + 1 + T_c = T_cur(idx) + T_e = T_cur(idx + 1) + T_s = T_cur(idx - nx) + + kx_east = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_e) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_e)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + T_new(idx) = T_c + dt / (rho * cp) * ( & + kx_east * (T_e - T_c) / (dx * dx) & + + ky_south * (T_s - T_c) / (dy * dy) & + - h_conv * (T_c - T_inf) / dy & + + Q(idx)) + + ! Top-right corner (i=nx, j=ny) + idx = ny * nx + T_c = T_cur(idx) + T_w = T_cur(idx - 1) + T_s = T_cur(idx - nx) + + kx_west = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_w) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_w)) + ky_south = 2.0d0 * (k0 + k1 * T_c) * (k0 + k1 * T_s) & + / ((k0 + k1 * T_c) + (k0 + k1 * T_s)) + + T_new(idx) = T_c + dt / (rho * cp) * ( & + kx_west * (T_w - T_c) / (dx * dx) & + + ky_south * (T_s - T_c) / (dy * dy) & + - h_conv * (T_c - T_inf) / dy & + + Q(idx)) + + ! Swap: T_cur <- T_new + do idx = 1, n + T_cur(idx) = T_new(idx) + end do + + end do + + ! Copy result + do idx = 1, n + T_final(idx) = T_cur(idx) + end do + +end subroutine diff --git a/demo/enzyme-lfortran/enzyme/wrapper.c b/demo/enzyme-lfortran/enzyme/wrapper.c new file mode 100644 index 000000000..d49c7a42d --- /dev/null +++ b/demo/enzyme-lfortran/enzyme/wrapper.c @@ -0,0 +1,186 @@ +/* Copyright 2025 Pasteur Labs. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * C wrapper that declares Enzyme AD entry points for the 2D thermal solver. + * After the Enzyme LLVM pass runs, the __enzyme_autodiff and __enzyme_fwddiff + * calls are replaced with compiler-generated derivative code. + * + * Work arrays (T_cur, T_new) are allocated here and passed to the Fortran + * subroutine to avoid _lfortran_malloc calls in the differentiated code. + * + * The resulting shared library exports three functions callable from Python + * via ctypes: + * + * thermal_2d_forward -- primal forward evaluation + * thermal_2d_vjp -- reverse-mode AD (vector-Jacobian product) + * thermal_2d_jvp -- forward-mode AD (Jacobian-vector product) + */ + +#include +#include + +/* Enzyme annotation sentinels (resolved by the Enzyme LLVM pass) */ +int enzyme_dup; +int enzyme_const; + +/* Fortran subroutine (Fortran ABI: everything by pointer) + * Note: n = nx*ny is passed explicitly so the Fortran side sees fixed-size + * arrays and never calls _lfortran_malloc. */ +extern void thermal_2d_solve(int* n, int* nx, int* ny, int* n_steps, + double* T_init, double* T_final, + double* T_cur, double* T_new, + double* k0, double* k1, + double* rho, double* cp, + double* h_conv, double* T_inf, double* T_hot, + double* Q, double* Lx, double* Ly, double* dt); + +/* Enzyme magic functions -- replaced by generated code after the pass */ +extern void __enzyme_autodiff(void*, ...); +extern void __enzyme_fwddiff(void*, ...); + + +/* -- Forward evaluation --------------------------------------------------- */ + +void thermal_2d_forward(int nx, int ny, int n_steps, + const double* T_init, double* T_final, + double k0, double k1, + double rho, double cp, + double h_conv, double T_inf, double T_hot, + const double* Q, double Lx, double Ly, double dt) +{ + int n = nx * ny; + int nx_ = nx, ny_ = ny, n_steps_ = n_steps, n_ = n; + double k0_ = k0, k1_ = k1, rho_ = rho, cp_ = cp; + double h_conv_ = h_conv, T_inf_ = T_inf, T_hot_ = T_hot; + double Lx_ = Lx, Ly_ = Ly, dt_ = dt; + + double* T_cur = (double*)calloc(n, sizeof(double)); + double* T_new = (double*)calloc(n, sizeof(double)); + + thermal_2d_solve(&n_, &nx_, &ny_, &n_steps_, + (double*)T_init, T_final, T_cur, T_new, + &k0_, &k1_, &rho_, &cp_, + &h_conv_, &T_inf_, &T_hot_, + (double*)Q, &Lx_, &Ly_, &dt_); + + free(T_cur); + free(T_new); +} + + +/* -- Reverse mode (VJP) --------------------------------------------------- */ + +void thermal_2d_vjp(int nx, int ny, int n_steps, + const double* T_init, double* dT_init, + const double* T_final, double* dT_final, + double k0, double* dk0, + double k1, double* dk1, + double rho, double* drho, + double cp, double* dcp, + double h_conv, double* dh_conv, + double T_inf, double* dT_inf, + double T_hot, double* dT_hot, + const double* Q, double* dQ, + double Lx, double* dLx, + double Ly, double* dLy, + double dt, double* ddt) +{ + int n = nx * ny; + int nx_ = nx, ny_ = ny, n_steps_ = n_steps, n_ = n; + double k0_ = k0, k1_ = k1, rho_ = rho, cp_ = cp; + double h_conv_ = h_conv, T_inf_ = T_inf, T_hot_ = T_hot; + double Lx_ = Lx, Ly_ = Ly, dt_ = dt; + + /* Work arrays and their shadows (zero-initialized) */ + double* T_cur = (double*)calloc(n, sizeof(double)); + double* dT_cur = (double*)calloc(n, sizeof(double)); + double* T_new = (double*)calloc(n, sizeof(double)); + double* dT_new = (double*)calloc(n, sizeof(double)); + + __enzyme_autodiff((void*)thermal_2d_solve, + enzyme_const, &n_, + enzyme_const, &nx_, + enzyme_const, &ny_, + enzyme_const, &n_steps_, + enzyme_dup, (double*)T_init, dT_init, + enzyme_dup, (double*)T_final, dT_final, + enzyme_dup, T_cur, dT_cur, + enzyme_dup, T_new, dT_new, + enzyme_dup, &k0_, dk0, + enzyme_dup, &k1_, dk1, + enzyme_dup, &rho_, drho, + enzyme_dup, &cp_, dcp, + enzyme_dup, &h_conv_, dh_conv, + enzyme_dup, &T_inf_, dT_inf, + enzyme_dup, &T_hot_, dT_hot, + enzyme_dup, (double*)Q, dQ, + enzyme_dup, &Lx_, dLx, + enzyme_dup, &Ly_, dLy, + enzyme_dup, &dt_, ddt); + + free(T_cur); + free(dT_cur); + free(T_new); + free(dT_new); +} + + +/* -- Forward mode (JVP) --------------------------------------------------- */ + +void thermal_2d_jvp(int nx, int ny, int n_steps, + const double* T_init, const double* dT_init, + double* T_final, double* dT_final, + double k0, double dk0, + double k1, double dk1, + double rho, double drho, + double cp, double dcp, + double h_conv, double dh_conv, + double T_inf, double dT_inf, + double T_hot, double dT_hot, + const double* Q, const double* dQ, + double Lx, double dLx, + double Ly, double dLy, + double dt, double ddt) +{ + int n = nx * ny; + int nx_ = nx, ny_ = ny, n_steps_ = n_steps, n_ = n; + int dnx_ = 0, dny_ = 0, dn_steps_ = 0, dn_ = 0; + double k0_ = k0, k1_ = k1, rho_ = rho, cp_ = cp; + double h_conv_ = h_conv, T_inf_ = T_inf, T_hot_ = T_hot; + double Lx_ = Lx, Ly_ = Ly, dt_ = dt; + double dk0_ = dk0, dk1_ = dk1, drho_ = drho, dcp_ = dcp; + double dh_conv_ = dh_conv, dT_inf_ = dT_inf, dT_hot_ = dT_hot; + double dLx_ = dLx, dLy_ = dLy, ddt_ = ddt; + + /* Work arrays and their tangent shadows */ + double* T_cur = (double*)calloc(n, sizeof(double)); + double* dT_cur = (double*)calloc(n, sizeof(double)); + double* T_new = (double*)calloc(n, sizeof(double)); + double* dT_new = (double*)calloc(n, sizeof(double)); + + __enzyme_fwddiff((void*)thermal_2d_solve, + enzyme_dup, &n_, &dn_, + enzyme_dup, &nx_, &dnx_, + enzyme_dup, &ny_, &dny_, + enzyme_dup, &n_steps_, &dn_steps_, + enzyme_dup, (double*)T_init, (double*)dT_init, + enzyme_dup, T_final, dT_final, + enzyme_dup, T_cur, dT_cur, + enzyme_dup, T_new, dT_new, + enzyme_dup, &k0_, &dk0_, + enzyme_dup, &k1_, &dk1_, + enzyme_dup, &rho_, &drho_, + enzyme_dup, &cp_, &dcp_, + enzyme_dup, &h_conv_, &dh_conv_, + enzyme_dup, &T_inf_, &dT_inf_, + enzyme_dup, &T_hot_, &dT_hot_, + enzyme_dup, (double*)Q, (double*)dQ, + enzyme_dup, &Lx_, &dLx_, + enzyme_dup, &Ly_, &dLy_, + enzyme_dup, &dt_, &ddt_); + + free(T_cur); + free(dT_cur); + free(T_new); + free(dT_new); +} diff --git a/demo/enzyme-lfortran/generate_pipeline_diagram.py b/demo/enzyme-lfortran/generate_pipeline_diagram.py new file mode 100644 index 000000000..ffa116852 --- /dev/null +++ b/demo/enzyme-lfortran/generate_pipeline_diagram.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python3 +# Copyright 2025 Pasteur Labs. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Generate the compilation pipeline diagram for the Enzyme AD blog post. + +Vertical recipe: six numbered steps flow top to bottom, each a single stage of +the Fortran -> Enzyme AD -> shared library pipeline. Artifact boxes are +color-coded by what produced them; the command for each step sits on the arrow +that produces the next artifact. +""" + +from pathlib import Path + +import matplotlib.patheffects as pe +import matplotlib.pyplot as plt +from matplotlib.patches import Circle, FancyArrowPatch, FancyBboxPatch + +FIGURE_DIR = Path(__file__).parent / "figures" +FIGURE_DIR.mkdir(exist_ok=True) + +# Colors keyed to the tool that produces each artifact. +C_FORT_BG, C_FORT = "#dbeafe", "#2563eb" # Fortran source +C_WRAP_BG, C_WRAP = "#dcfce7", "#16a34a" # C wrapper source +C_IR_BG, C_IR = "#fef9c4", "#ca8a04" # LLVM IR (LFortran / LLVM) +C_ENZ_BG, C_ENZ = "#ede9fe", "#7c3aed" # Enzyme-differentiated IR +C_SO_BG, C_SO = "#ffedd5", "#ea580c" # final shared library +# Arrows carry the mechanism (the flow of compilation), so they lead: dark and +# solid. Box borders recede to a thin, muted line — the fill already encodes the +# stage, so a heavy border would be redundant data-ink. +C_ARROW = "#4b5563" +C_TEXT = "#374151" + + +def draw_box(ax, cx, cy, w, h, line1, line2, bg, edge, fs=11): + p = FancyBboxPatch( + (cx - w / 2, cy - h / 2), + w, + h, + boxstyle="round,pad=0.04", + facecolor=bg, + edgecolor=edge, + linewidth=0.8, + zorder=2, + ) + ax.add_patch(p) + kw = dict(ha="center", va="center", zorder=3, parse_math=False) + if line2: + ax.text( + cx, cy + 0.16, line1, fontsize=fs, fontweight="bold", color="#1f2937", **kw + ) + ax.text( + cx, cy - 0.18, line2, fontsize=fs - 3, color="#4a4f5a", style="italic", **kw + ) + else: + ax.text(cx, cy, line1, fontsize=fs, fontweight="bold", color="#1f2937", **kw) + + +def draw_arrow(ax, x0, y0, x1, y1, rad=0.0): + a = FancyArrowPatch( + (x0, y0), + (x1, y1), + arrowstyle="-|>", + mutation_scale=15, + color=C_ARROW, + linewidth=2.0, + connectionstyle=f"arc3,rad={rad}", + shrinkA=0, + shrinkB=0, + zorder=1, + ) + ax.add_patch(a) + + +def cmd_label(ax, x, y, text, ha="left"): + # Monospace command annotation sitting beside the arrow it drives. A white + # halo keeps it legible where it crosses an arrow; no enclosing chip (that + # border was non-data-ink). + ax.text( + x, + y, + text, + ha=ha, + va="center", + fontsize=9, + color=C_TEXT, + fontfamily="monospace", + zorder=4, + linespacing=1.3, + path_effects=[pe.withStroke(linewidth=3, foreground="white")], + ) + + +def step_badge(ax, x, y, n, color): + ax.add_patch( + Circle( + (x, y), 0.16, facecolor="white", edgecolor=color, linewidth=1.6, zorder=4 + ) + ) + ax.text( + x, + y, + str(n), + ha="center", + va="center", + fontsize=9.5, + fontweight="bold", + color=color, + zorder=5, + ) + + +def main(): + fig, ax = plt.subplots(figsize=(9, 11)) + + # One row per artifact, descending. Boxes are centered on the main column; + # the C-wrapper source sits in a parallel column and merges at the link step. + X_MAIN = 0.0 + X_SIDE = 3.0 + W, H = 2.6, 0.9 + + # Row y-coordinates (top -> bottom). + Y = { + "f90": 10.0, + "ll": 8.3, + "opt": 6.6, + "combined": 4.9, + "ad": 3.2, + "so": 1.5, + } + # The C wrapper lives beside the main column on the rows it spans, then + # feeds the link step. + Y_WRAPC = 8.3 + Y_WRAPLL = 6.6 + + ax.set_xlim(X_MAIN - W / 2 - 2.2, X_SIDE + W / 2 + 3.4) + ax.set_ylim(0.5, 11.4) + ax.axis("off") + + # Command labels sit in the empty left margin, right-aligned toward the + # main column so each reads as an annotation on the arrow beside it. + LX = X_MAIN - W / 2 - 0.3 + + # ── Main vertical track ── + draw_box( + ax, + X_MAIN, + Y["f90"], + W, + H, + "thermal_2d.f90", + "Fortran source", + C_FORT_BG, + C_FORT, + ) + draw_box(ax, X_MAIN, Y["ll"], W, H, "thermal_2d.ll", "raw LLVM IR", C_IR_BG, C_IR) + draw_box( + ax, X_MAIN, Y["opt"], W, H, "thermal_2d_opt.ll", "optimized IR", C_IR_BG, C_IR + ) + draw_box(ax, X_MAIN, Y["combined"], W, H, "combined.ll", "linked IR", C_IR_BG, C_IR) + draw_box(ax, X_MAIN, Y["ad"], W, H, "ad.ll", "differentiated IR", C_ENZ_BG, C_ENZ) + draw_box( + ax, + X_MAIN, + Y["so"], + W + 0.5, + H + 0.1, + "libthermal_2d_ad.so", + "forward / JVP / VJP", + C_SO_BG, + C_SO, + ) + + # ── C-wrapper side track ── + draw_box( + ax, X_SIDE, Y_WRAPC, W, H, "wrapper.c", "Enzyme annotations", C_WRAP_BG, C_WRAP + ) + draw_box(ax, X_SIDE, Y_WRAPLL, W, H, "wrapper.ll", "wrapper IR", C_IR_BG, C_IR) + + # ── Vertical arrows + step badges + command labels ── + # Main-track commands sit in the left margin, right-aligned to the column. + # Step 1: f90 -> ll + draw_arrow(ax, X_MAIN, Y["f90"] - H / 2, X_MAIN, Y["ll"] + H / 2) + step_badge(ax, X_MAIN, (Y["f90"] + Y["ll"]) / 2, 1, C_FORT) + cmd_label(ax, LX, (Y["f90"] + Y["ll"]) / 2, "lfortran\n--show-llvm", ha="right") + + # Step 2: ll -> opt (mild -O1 BEFORE Enzyme — the whole point of the post) + draw_arrow(ax, X_MAIN, Y["ll"] - H / 2, X_MAIN, Y["opt"] + H / 2) + step_badge(ax, X_MAIN, (Y["ll"] + Y["opt"]) / 2, 2, C_IR) + cmd_label(ax, LX, (Y["ll"] + Y["opt"]) / 2, "opt -O1", ha="right") + + # Step 3: wrapper.c -> wrapper.ll (side track) — label to the right of it. + draw_arrow(ax, X_SIDE, Y_WRAPC - H / 2, X_SIDE, Y_WRAPLL + H / 2) + step_badge(ax, X_SIDE, (Y_WRAPC + Y_WRAPLL) / 2, 3, C_WRAP) + cmd_label( + ax, X_SIDE + W / 2, (Y_WRAPC + Y_WRAPLL) / 2, "clang\n-emit-llvm -O1", ha="left" + ) + + # Step 4: opt.ll + wrapper.ll -> combined.ll + draw_arrow(ax, X_MAIN, Y["opt"] - H / 2, X_MAIN, Y["combined"] + H / 2) + # wrapper.ll merges in from the side + draw_arrow( + ax, X_SIDE - W / 2, Y_WRAPLL, X_MAIN + W / 2, Y["combined"] + 0.05, rad=-0.2 + ) + step_badge(ax, X_MAIN, (Y["opt"] + Y["combined"]) / 2, 4, C_IR) + cmd_label(ax, LX, (Y["opt"] + Y["combined"]) / 2, "llvm-link", ha="right") + + # Step 5: combined.ll -> ad.ll (Enzyme) + draw_arrow(ax, X_MAIN, Y["combined"] - H / 2, X_MAIN, Y["ad"] + H / 2) + step_badge(ax, X_MAIN, (Y["combined"] + Y["ad"]) / 2, 5, C_ENZ) + cmd_label(ax, LX, (Y["combined"] + Y["ad"]) / 2, "opt\n-passes=enzyme", ha="right") + + # Step 6: ad.ll -> .so (post-Enzyme -O3 is where -O3 belongs) + draw_arrow(ax, X_MAIN, Y["ad"] - H / 2, X_MAIN, Y["so"] + (H + 0.1) / 2) + step_badge(ax, X_MAIN, (Y["ad"] + Y["so"]) / 2, 6, C_SO) + cmd_label(ax, LX, (Y["ad"] + Y["so"]) / 2, "opt -O3\nclang -shared", ha="right") + + # ── Tool brackets down the right margin, spanning the rows each tool owns ── + # The box fills already encode the tool; the brackets add version context and + # group the stages without a heavy enclosure. + band_x = X_SIDE + W / 2 + 1.9 + tick = 0.18 + for y_hi, y_lo, txt, color in [ + (Y["f90"], Y["f90"], "LFortran 0.61", C_FORT), + (Y["ll"], Y["combined"], "LLVM 19", C_IR), + (Y["ad"], Y["ad"], "Enzyme\n(LLVM pass)", C_ENZ), + (Y["so"], Y["so"], "LLVM 19 +\nclang", C_SO), + ]: + top, bot = y_hi + H / 2, y_lo - H / 2 + ax.plot( + [band_x, band_x], + [bot, top], + color=color, + lw=1.4, + zorder=1, + solid_capstyle="round", + ) + # short inward ticks close the bracket at top and bottom + ax.plot([band_x - tick, band_x], [top, top], color=color, lw=1.4, zorder=1) + ax.plot([band_x - tick, band_x], [bot, bot], color=color, lw=1.4, zorder=1) + ax.text( + band_x + 0.15, + (y_hi + y_lo) / 2, + txt, + ha="left", + va="center", + fontsize=9.5, + color=color, + fontweight="bold", + linespacing=1.3, + ) + + # Title + ax.text( + (X_MAIN + X_SIDE) / 2, + 11.1, + "Compilation pipeline:\nFortran → Enzyme AD → shared library", + ha="center", + va="center", + fontsize=15, + fontweight="bold", + color="#111827", + linespacing=1.3, + ) + + fig.savefig( + FIGURE_DIR / "pipeline.png", + dpi=200, + bbox_inches="tight", + pad_inches=0.3, + facecolor="white", + ) + plt.close(fig) + print(f"Saved {FIGURE_DIR / 'pipeline.png'}") + + +if __name__ == "__main__": + main() diff --git a/demo/enzyme-lfortran/requirements.txt b/demo/enzyme-lfortran/requirements.txt new file mode 100644 index 000000000..3bb52f9b2 --- /dev/null +++ b/demo/enzyme-lfortran/requirements.txt @@ -0,0 +1,5 @@ +jax[cpu] +matplotlib +numpy +scipy +tesseract-jax diff --git a/demo/enzyme-lfortran/tesseract_api.py b/demo/enzyme-lfortran/tesseract_api.py new file mode 100644 index 000000000..437ac9e5e --- /dev/null +++ b/demo/enzyme-lfortran/tesseract_api.py @@ -0,0 +1,498 @@ +# Copyright 2025 Pasteur Labs. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Tesseract wrapping a 2D Fortran thermal solver differentiated by Enzyme. + +This example demonstrates how to obtain exact automatic derivatives of a +production-style Fortran thermal simulation without writing any adjoint code. + +The solver computes transient 2D heat conduction with: + - Temperature-dependent conductivity: k(T) = k0 + k1*T + - Mixed boundary conditions: Dirichlet (hot wall), convection, insulated + - Volumetric heat source + - Multi-step explicit time integration + +Enzyme generates machine-precision derivatives through the entire time-stepping +loop, enabling gradient-based optimization of material properties, boundary +conditions, or initial conditions with respect to any output. +""" + +import ctypes +from pathlib import Path +from typing import Any + +import numpy as np +from pydantic import BaseModel, Field, model_validator +from typing_extensions import Self + +from tesseract_core.runtime import Array, Differentiable, Float64, ShapeDType + +# -- Shared library loading ------------------------------------------------ + +_LIB_PATH = Path("/tesseract/enzyme/libthermal_2d_ad.so") +_lib = ctypes.CDLL(str(_LIB_PATH)) + +# void thermal_2d_forward(int nx, int ny, int n_steps, +# double* T_init, double* T_final, +# double k0, double k1, double rho, double cp, +# double h_conv, double T_inf, double T_hot, +# double* Q, double Lx, double Ly, double dt) +_lib.thermal_2d_forward.restype = None +_lib.thermal_2d_forward.argtypes = [ + ctypes.c_int, # nx + ctypes.c_int, # ny + ctypes.c_int, # n_steps + ctypes.POINTER(ctypes.c_double), # T_init + ctypes.POINTER(ctypes.c_double), # T_final + ctypes.c_double, # k0 + ctypes.c_double, # k1 + ctypes.c_double, # rho + ctypes.c_double, # cp + ctypes.c_double, # h_conv + ctypes.c_double, # T_inf + ctypes.c_double, # T_hot + ctypes.POINTER(ctypes.c_double), # Q + ctypes.c_double, # Lx + ctypes.c_double, # Ly + ctypes.c_double, # dt +] + +# void thermal_2d_vjp(int nx, int ny, int n_steps, +# double* T_init, double* dT_init, double* T_final, double* dT_final, +# double k0, double* dk0, double k1, double* dk1, +# double rho, double* drho, double cp, double* dcp, +# double h_conv, double* dh_conv, double T_inf, double* dT_inf, +# double T_hot, double* dT_hot, +# double* Q, double* dQ, +# double Lx, double* dLx, double Ly, double* dLy, double dt, double* ddt) +_lib.thermal_2d_vjp.restype = None +_lib.thermal_2d_vjp.argtypes = [ + ctypes.c_int, # nx + ctypes.c_int, # ny + ctypes.c_int, # n_steps + ctypes.POINTER(ctypes.c_double), # T_init + ctypes.POINTER(ctypes.c_double), # dT_init + ctypes.POINTER(ctypes.c_double), # T_final + ctypes.POINTER(ctypes.c_double), # dT_final + ctypes.c_double, # k0 + ctypes.POINTER(ctypes.c_double), # dk0 + ctypes.c_double, # k1 + ctypes.POINTER(ctypes.c_double), # dk1 + ctypes.c_double, # rho + ctypes.POINTER(ctypes.c_double), # drho + ctypes.c_double, # cp + ctypes.POINTER(ctypes.c_double), # dcp + ctypes.c_double, # h_conv + ctypes.POINTER(ctypes.c_double), # dh_conv + ctypes.c_double, # T_inf + ctypes.POINTER(ctypes.c_double), # dT_inf + ctypes.c_double, # T_hot + ctypes.POINTER(ctypes.c_double), # dT_hot + ctypes.POINTER(ctypes.c_double), # Q + ctypes.POINTER(ctypes.c_double), # dQ + ctypes.c_double, # Lx + ctypes.POINTER(ctypes.c_double), # dLx + ctypes.c_double, # Ly + ctypes.POINTER(ctypes.c_double), # dLy + ctypes.c_double, # dt + ctypes.POINTER(ctypes.c_double), # ddt +] + +# void thermal_2d_jvp(int nx, int ny, int n_steps, +# double* T_init, double* dT_init, double* T_final, double* dT_final, +# double k0, double dk0, double k1, double dk1, +# double rho, double drho, double cp, double dcp, +# double h_conv, double dh_conv, double T_inf, double dT_inf, +# double T_hot, double dT_hot, +# double* Q, double* dQ, +# double Lx, double dLx, double Ly, double dLy, double dt, double ddt) +_lib.thermal_2d_jvp.restype = None +_lib.thermal_2d_jvp.argtypes = [ + ctypes.c_int, # nx + ctypes.c_int, # ny + ctypes.c_int, # n_steps + ctypes.POINTER(ctypes.c_double), # T_init + ctypes.POINTER(ctypes.c_double), # dT_init + ctypes.POINTER(ctypes.c_double), # T_final + ctypes.POINTER(ctypes.c_double), # dT_final + ctypes.c_double, # k0 + ctypes.c_double, # dk0 + ctypes.c_double, # k1 + ctypes.c_double, # dk1 + ctypes.c_double, # rho + ctypes.c_double, # drho + ctypes.c_double, # cp + ctypes.c_double, # dcp + ctypes.c_double, # h_conv + ctypes.c_double, # dh_conv + ctypes.c_double, # T_inf + ctypes.c_double, # dT_inf + ctypes.c_double, # T_hot + ctypes.c_double, # dT_hot + ctypes.POINTER(ctypes.c_double), # Q + ctypes.POINTER(ctypes.c_double), # dQ + ctypes.c_double, # Lx + ctypes.c_double, # dLx + ctypes.c_double, # Ly + ctypes.c_double, # dLy + ctypes.c_double, # dt + ctypes.c_double, # ddt +] + + +def _as_ptr(arr: np.ndarray) -> ctypes.POINTER(ctypes.c_double): + """Get a ctypes double pointer from a contiguous float64 array.""" + return arr.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + + +# -- Schemas --------------------------------------------------------------- + + +class InputSchema(BaseModel): + """Input for a 2D transient heat conduction solver. + + Solves rho*cp*dT/dt = div(k(T)*grad(T)) + Q on a rectangular domain + with Dirichlet (hot wall), convection, and insulated boundary conditions. + """ + + # Initial temperature field (flattened row-major, nx*ny) + T_init: Differentiable[Array[(None,), Float64]] = Field( + description=( + "Initial temperature field [K]. Flattened row-major array of " + "shape (nx*ny,). Index (i,j) maps to j*nx+i." + ), + ) + + # Grid dimensions (not differentiable — integer-like) + nx: int = Field( + default=20, + description="Number of grid points in x direction.", + ge=3, + ) + ny: int = Field( + default=20, + description="Number of grid points in y direction.", + ge=3, + ) + + # Time integration + n_steps: int = Field( + default=100, + description="Number of explicit Euler time steps.", + ge=1, + ) + dt: Differentiable[Float64] = Field( + default=0.01, + description="Time step size [s]. Must be > 0.", + ) + + # Domain geometry + Lx: Differentiable[Float64] = Field( + default=0.1, + description="Domain length in x [m]. Must be > 0.", + ) + Ly: Differentiable[Float64] = Field( + default=0.05, + description="Domain length in y [m]. Must be > 0.", + ) + + # Material properties + k0: Differentiable[Float64] = Field( + default=45.0, + description="Base thermal conductivity [W/(m*K)]. k(T) = k0 + k1*T. Must be > 0.", + ) + k1: Differentiable[Float64] = Field( + default=-0.01, + description=( + "Temperature coefficient of conductivity [W/(m*K^2)]. " + "k(T) = k0 + k1*T. Negative values model metals." + ), + ) + rho: Differentiable[Float64] = Field( + default=7850.0, + description="Density [kg/m^3]. Must be > 0.", + ) + cp: Differentiable[Float64] = Field( + default=460.0, + description="Specific heat capacity [J/(kg*K)]. Must be > 0.", + ) + + # Boundary conditions + h_conv: Differentiable[Float64] = Field( + default=25.0, + description=( + "Convective heat transfer coefficient at top boundary " + "[W/(m^2*K)]. Must be > 0." + ), + ) + T_inf: Differentiable[Float64] = Field( + default=293.15, + description="Ambient temperature for convection BC [K].", + ) + T_hot: Differentiable[Float64] = Field( + default=373.15, + description="Fixed temperature at bottom (Dirichlet) boundary [K].", + ) + + # Volumetric heat source (flattened row-major, nx*ny) + Q: Differentiable[Array[(None,), Float64]] = Field( + description=( + "Volumetric heat source [W/m^3]. Flattened row-major array of " + "shape (nx*ny,). Use zeros for no internal heating." + ), + ) + + @model_validator(mode="after") + def check_array_sizes(self) -> Self: + """Verify T_init and Q have the correct size.""" + if isinstance(self.T_init, ShapeDType): + return self # skip during abstract_eval + expected = self.nx * self.ny + if len(self.T_init) != expected: + raise ValueError( + f"T_init has {len(self.T_init)} elements, expected nx*ny = {expected}." + ) + if len(self.Q) != expected: + raise ValueError( + f"Q has {len(self.Q)} elements, expected nx*ny = {expected}." + ) + return self + + @model_validator(mode="after") + def check_stability(self) -> Self: + """Check positivity and CFL stability for the explicit scheme. + + For temperature-dependent conductivity, use k_max = k0 + k1*T_hot + (conservative estimate with the hottest expected temperature). + """ + if isinstance(self.dt, ShapeDType): + return self # skip during abstract_eval + for name in ("dt", "Lx", "Ly", "k0", "rho", "cp", "h_conv"): + if getattr(self, name) <= 0: + raise ValueError(f"{name} must be > 0, got {getattr(self, name)}.") + dx = self.Lx / (self.nx - 1) + dy = self.Ly / (self.ny - 1) + k_max = self.k0 + self.k1 * self.T_hot + if k_max <= 0: + raise ValueError( + f"Conductivity k(T_hot) = {k_max:.4f} <= 0. Increase k0 or reduce |k1|." + ) + r = k_max * self.dt / (self.rho * self.cp) * (1.0 / (dx * dx) + 1.0 / (dy * dy)) + if r > 0.5: + raise ValueError( + f"CFL stability condition violated: r = {r:.4f} > 0.5. " + f"Reduce dt, or increase grid spacing." + ) + return self + + +class OutputSchema(BaseModel): + """Output: temperature field after time integration.""" + + T_final: Differentiable[Array[(None,), Float64]] = Field( + description=( + "Temperature field after n_steps time steps [K]. " + "Flattened row-major array of shape (nx*ny,)." + ), + ) + + +# -- Required endpoints ---------------------------------------------------- + + +def apply(inputs: InputSchema) -> OutputSchema: + """Run the 2D thermal solver for n_steps explicit Euler steps.""" + T_init = np.ascontiguousarray(inputs.T_init, dtype=np.float64) + Q = np.ascontiguousarray(inputs.Q, dtype=np.float64) + n = inputs.nx * inputs.ny + T_final = np.zeros(n, dtype=np.float64) + + _lib.thermal_2d_forward( + inputs.nx, + inputs.ny, + inputs.n_steps, + _as_ptr(T_init), + _as_ptr(T_final), + inputs.k0, + inputs.k1, + inputs.rho, + inputs.cp, + inputs.h_conv, + inputs.T_inf, + inputs.T_hot, + _as_ptr(Q), + inputs.Lx, + inputs.Ly, + inputs.dt, + ) + + return OutputSchema(T_final=T_final) + + +def abstract_eval(abstract_inputs): + """Calculate output shape from input shapes (required for tesseract-jax).""" + T_init_shape = abstract_inputs.T_init + return {"T_final": ShapeDType(shape=T_init_shape.shape, dtype=T_init_shape.dtype)} + + +# -- Optional endpoints (AD via Enzyme) ------------------------------------ + + +# All differentiable scalar parameters, in the order they appear in the wrapper +_SCALAR_PARAMS = ["k0", "k1", "rho", "cp", "h_conv", "T_inf", "T_hot", "Lx", "Ly", "dt"] + + +def _run_vjp(inputs: InputSchema, cotangent_T_final: np.ndarray): + """Run Enzyme reverse-mode AD and return all gradients.""" + T_init = np.ascontiguousarray(inputs.T_init, dtype=np.float64) + Q = np.ascontiguousarray(inputs.Q, dtype=np.float64) + n = inputs.nx * inputs.ny + + # Shadow arrays (Enzyme accumulates gradients into these) + dT_init = np.zeros(n, dtype=np.float64) + T_final = np.zeros(n, dtype=np.float64) + dT_final = np.array(cotangent_T_final, dtype=np.float64) + dQ = np.zeros(n, dtype=np.float64) + + # Shadow scalars + dk0 = ctypes.c_double(0.0) + dk1 = ctypes.c_double(0.0) + drho = ctypes.c_double(0.0) + dcp = ctypes.c_double(0.0) + dh_conv = ctypes.c_double(0.0) + dT_inf = ctypes.c_double(0.0) + dT_hot = ctypes.c_double(0.0) + dLx = ctypes.c_double(0.0) + dLy = ctypes.c_double(0.0) + ddt = ctypes.c_double(0.0) + + _lib.thermal_2d_vjp( + inputs.nx, + inputs.ny, + inputs.n_steps, + _as_ptr(T_init), + _as_ptr(dT_init), + _as_ptr(T_final), + _as_ptr(dT_final), + inputs.k0, + ctypes.byref(dk0), + inputs.k1, + ctypes.byref(dk1), + inputs.rho, + ctypes.byref(drho), + inputs.cp, + ctypes.byref(dcp), + inputs.h_conv, + ctypes.byref(dh_conv), + inputs.T_inf, + ctypes.byref(dT_inf), + inputs.T_hot, + ctypes.byref(dT_hot), + _as_ptr(Q), + _as_ptr(dQ), + inputs.Lx, + ctypes.byref(dLx), + inputs.Ly, + ctypes.byref(dLy), + inputs.dt, + ctypes.byref(ddt), + ) + + return { + "T_init": dT_init, + "Q": dQ, + "k0": dk0.value, + "k1": dk1.value, + "rho": drho.value, + "cp": dcp.value, + "h_conv": dh_conv.value, + "T_inf": dT_inf.value, + "T_hot": dT_hot.value, + "Lx": dLx.value, + "Ly": dLy.value, + "dt": ddt.value, + } + + +def _run_jvp(inputs: InputSchema, tangents: dict[str, Any]): + """Run Enzyme forward-mode AD and return output tangent.""" + T_init = np.ascontiguousarray(inputs.T_init, dtype=np.float64) + Q = np.ascontiguousarray(inputs.Q, dtype=np.float64) + n = inputs.nx * inputs.ny + + dT_init = np.ascontiguousarray( + tangents.get("T_init", np.zeros(n, dtype=np.float64)), + dtype=np.float64, + ) + dQ = np.ascontiguousarray( + tangents.get("Q", np.zeros(n, dtype=np.float64)), + dtype=np.float64, + ) + T_final = np.zeros(n, dtype=np.float64) + dT_final = np.zeros(n, dtype=np.float64) + + _lib.thermal_2d_jvp( + inputs.nx, + inputs.ny, + inputs.n_steps, + _as_ptr(T_init), + _as_ptr(dT_init), + _as_ptr(T_final), + _as_ptr(dT_final), + inputs.k0, + float(tangents.get("k0", 0.0)), + inputs.k1, + float(tangents.get("k1", 0.0)), + inputs.rho, + float(tangents.get("rho", 0.0)), + inputs.cp, + float(tangents.get("cp", 0.0)), + inputs.h_conv, + float(tangents.get("h_conv", 0.0)), + inputs.T_inf, + float(tangents.get("T_inf", 0.0)), + inputs.T_hot, + float(tangents.get("T_hot", 0.0)), + _as_ptr(Q), + _as_ptr(dQ), + inputs.Lx, + float(tangents.get("Lx", 0.0)), + inputs.Ly, + float(tangents.get("Ly", 0.0)), + inputs.dt, + float(tangents.get("dt", 0.0)), + ) + + return dT_final + + +def vector_jacobian_product( + inputs: InputSchema, + vjp_inputs: set[str], + vjp_outputs: set[str], + cotangent_vector: dict[str, Any], +): + """Reverse-mode AD via Enzyme: compute v^T @ J.""" + n = inputs.nx * inputs.ny + cotangent_T_final = cotangent_vector.get( + "T_final", + np.zeros(n, dtype=np.float64), + ) + all_grads = _run_vjp(inputs, cotangent_T_final) + + return {k: v for k, v in all_grads.items() if k in vjp_inputs} + + +def jacobian_vector_product( + inputs: InputSchema, + jvp_inputs: set[str], + jvp_outputs: set[str], + tangent_vector: dict[str, Any], +): + """Forward-mode AD via Enzyme: compute J @ v.""" + dT_final = _run_jvp(inputs, tangent_vector) + + result = {} + if "T_final" in jvp_outputs: + result["T_final"] = dT_final + return result diff --git a/demo/enzyme-lfortran/tesseract_config.yaml b/demo/enzyme-lfortran/tesseract_config.yaml new file mode 100644 index 000000000..84a7624fe --- /dev/null +++ b/demo/enzyme-lfortran/tesseract_config.yaml @@ -0,0 +1,72 @@ +name: "enzyme-thermal-2d" +version: "1.0.0" +description: | + Differentiable 2D transient heat conduction solver using Enzyme automatic + differentiation. + + Solves rho*cp*dT/dt = div(k(T)*grad(T)) + Q on a structured rectangular + grid with temperature-dependent conductivity k(T) = k0 + k1*T, mixed + boundary conditions (Dirichlet, convection, insulated), and multi-step + explicit time integration. + + Enzyme generates both forward-mode (JVP) and reverse-mode (VJP) derivatives + through the entire time-stepping loop directly from the compiled Fortran code + at the LLVM IR level — no manual adjoint code required. + + Industry relevance: gradient-based calibration of thermal material properties, + inverse heat transfer problems, sensitivity analysis for thermal management + design, and differentiable physics for digital twins. + +build_config: + base_image: "debian:bookworm-slim" + target_platform: "linux/amd64" + + extra_packages: + - wget + - gnupg + - ca-certificates + - bzip2 + - cmake + - git + - build-essential + - libzstd-dev + + package_data: + - ["enzyme/thermal_2d.f90", "enzyme/thermal_2d.f90"] + - ["enzyme/wrapper.c", "enzyme/wrapper.c"] + - ["enzyme/build.sh", "enzyme/build.sh"] + + custom_build_steps: + # Install LLVM 19 toolchain (including dev headers for building Enzyme) + - | + RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /etc/apt/keyrings/llvm.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/llvm.gpg] http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-19 main" > /etc/apt/sources.list.d/llvm.list && \ + apt-get update && apt-get install -y --no-install-recommends llvm-19 llvm-19-dev clang-19 && \ + rm -rf /var/lib/apt/lists/* && \ + for tool in opt llvm-as llvm-link llvm-dis llc clang clang++; do \ + ln -sf /usr/bin/${tool}-19 /usr/local/bin/${tool} 2>/dev/null || true; \ + done + + # Install LFortran via micromamba (prebuilt from conda-forge) + - | + RUN wget -q https://github.com/mamba-org/micromamba-releases/releases/latest/download/micromamba-linux-64 \ + -O /usr/local/bin/micromamba && chmod +x /usr/local/bin/micromamba && \ + MAMBA_ROOT_PREFIX=/opt/conda micromamba create -y -n base -c conda-forge lfortran=0.61.0 && \ + ln -sf $(find /opt/conda -name lfortran -type f | head -1) /usr/local/bin/lfortran && \ + echo /opt/conda/lib > /etc/ld.so.conf.d/conda.conf && ldconfig + + # Build Enzyme from a pinned release + - | + RUN git clone --depth 1 --branch v0.0.258 https://github.com/EnzymeAD/Enzyme.git /tmp/enzyme-src && \ + cmake -S /tmp/enzyme-src/enzyme -B /tmp/enzyme-build \ + -DLLVM_DIR=/usr/lib/llvm-19/lib/cmake/llvm \ + -DCMAKE_BUILD_TYPE=Release \ + -DENZYME_CLANG=OFF -DENZYME_MLIR=OFF && \ + cmake --build /tmp/enzyme-build --target LLVMEnzyme-19 -j"$(nproc)" && \ + cp /tmp/enzyme-build/Enzyme/LLVMEnzyme-19.so /usr/local/lib/ && \ + rm -rf /tmp/enzyme-src /tmp/enzyme-build + + # Build the differentiated shared library + - | + RUN chmod +x /tesseract/enzyme/build.sh && \ + /tesseract/enzyme/build.sh /tesseract/enzyme/libthermal_2d_ad.so diff --git a/demo/enzyme-lfortran/tesseract_requirements.txt b/demo/enzyme-lfortran/tesseract_requirements.txt new file mode 100644 index 000000000..24ce15ab7 --- /dev/null +++ b/demo/enzyme-lfortran/tesseract_requirements.txt @@ -0,0 +1 @@ +numpy diff --git a/demo/fem-shape-optimization/demo.ipynb b/demo/fem-shape-optimization/demo.ipynb index 8d4f11873..5210e8e54 100644 --- a/demo/fem-shape-optimization/demo.ipynb +++ b/demo/fem-shape-optimization/demo.ipynb @@ -27662,7 +27662,7 @@ "- **Try different parametrizations.** Adjust the number of bars, segments, or bar radius to explore how the design space affects the optimized structure.\n", "- **Swap in a different optimizer.** Replace SGD with Adam, L-BFGS, or any other `optax` optimizer to compare convergence behavior.\n", "- **Scale up.** Increase the mesh resolution (`Nx`, `Ny`) or add 3D geometry to tackle more realistic engineering problems.\n", - "- **Explore other demos.** See the [data assimilation](data-assimilation.ipynb) and [data assimilation](data-assimilation.ipynb) demo for another way to compose Tesseracts with JAX.\n", + "- **Explore other demos.** See the [CFD optimization](cfd-optimization.ipynb), [data assimilation](data-assimilation.ipynb), and [inverse heat transfer](enzyme-lfortran.ipynb) demos for other ways to compose Tesseracts with JAX.\n", "\n", "Questions? Feedback? Please reach out through the [Tesseract Community Forum](https://si-tesseract.discourse.group/)." ] diff --git a/docs/_templates/blog_post.html b/docs/_templates/blog_post.html index f23428b70..ac0344877 100644 --- a/docs/_templates/blog_post.html +++ b/docs/_templates/blog_post.html @@ -28,6 +28,12 @@ {% endif %} {{ body }} + +