---
title: 'Tapenade: Source-to-Source AD Tool'
url: https://www.emergentmind.com/topics/tapenade
type: topic
---

# Tapenade: Source-to-Source AD Tool

Searching arXiv for recent and foundational papers on Tapenade and its applications.
Tapenade is a source-to-source automatic differentiation (AD) tool centered on the generation of tangent-linear and adjoint codes from scientific programs, especially large Fortran code bases. Across the literature, it appears both as an AD compiler in its own right and as a reference point for source-transformation workflows involving checkpointing, generated derivative kernels, and differentiated high-performance computing applications. The published record portrays Tapenade as particularly important in reverse-mode settings where gradients, tangent-linear models, or discrete adjoints are required for variational data assimilation, sensitivity analysis, Jacobian construction, optimization, and uncertainty quantification [1611.03410], [2401.11952], [0711.4444].

## 1. Definition and computational model

Tapenade is described as a source-transformation AD tool that parses source code and emits derivative-augmented code rather than relying on operator overloading at runtime. In a comparative discussion of AD paradigms, source transformation tools “like Tapenade or OpenAD” are characterized as tools that “apply AD by parsing the source code of the program and generating a new code extending it by the additional AD computations” [2307.06075]. In the OPA formulation, a program computing
\[
F : X \in I^m \mapsto Y \in I^n
\]
is decomposed into elementary operations, and Tapenade generates either tangent code computing Jacobian-vector products or adjoint code computing transposed-Jacobian products [0711.4444].

The tangent-linear and adjoint contracts recur across applications. In one general formulation,
\[
\dot y = \frac{d F}{d x}(x) \dot x
\tag{1}
\]
and
\[
\bar x = \frac{d F}{d x}^\top(x) \bar y.
\tag{2}
\]
This notation is used to explain function-level forward and reverse derivative interfaces in CoDiPack external functions, where Tapenade is named as a canonical source-transformation tool [2307.06075]. The same mathematical structure underlies large geophysical and CFD applications: the MITgcm paper writes the nonlinear model as
\[
M : \mathbb{R}^N \ni u \mapsto M(u) = x \in \mathbb{R}^M ,
\tag{1}
\]
with a scalar objective
\[
J : \mathbb{R}^N \ni u \mapsto J(M(u)) = J(x) \in \mathbb{R},
\tag{2}
\]
and then defines tangent-linear propagation and adjoint backpropagation through timestep operators \(L_n\) [2401.11952].

The practical significance of this model is that Tapenade generates derivative code at the level of the implemented discrete program. In the gas-kinetic scheme work, Tapenade is used to construct a discrete adjoint rather than a continuous adjoint, with the stated aim of ensuring strict consistency between the primal discretization and the adjoint discretization [2606.14112]. This suggests that Tapenade’s central identity in the literature is not merely “an AD tool,” but a compiler for discrete derivative programs tied to the actual source implementation.

## 2. Differentiation modes, interfaces, and numerical products

Tapenade is used for both tangent and adjoint generation, although mode choice depends on the input–output dimensions and application structure. In OPA, Tapenade generated both tangent and adjoint codes for a very large FORTRAN95 ocean model [0711.4444]. In ORCA-2/NEMO, the same dual role is explicit: “tangent and adjoint codes have been obtained by Tapenade software” [1212.3116]. In HFBTHO-AD, by contrast, the implementation uses forward mode and vector forward mode because there are 14 inputs and 52 outputs, so forward mode is the chosen efficiency point for the Jacobian of interest [2508.11910].

The generated interfaces are concrete. In the parallel CFD study, a head routine
\[
\texttt{TopSub}(X,Y)
\]
is transformed into
\[
\texttt{TopSub\_d}(X, Xd, Y, Yd)
\]
for tangent mode and
\[
\texttt{TopSub\_b}(X, Xb, Y, Yb)
\]
for adjoint mode [1912.11717]. In CoDiPack external functions, Tapenade-generated or Enzyme-generated routines are expected to satisfy interfaces of the form:

```cpp
void func_d(double const* x, double const* x_d, size_t m, double* y, double* y_d, size_t n, ExternalFunctionUserData* d);
void func_b(double const* x, double* x_b, size_t m, double const* y, double const* y_b, size_t n, ExternalFunctionUserData* d);
```

These interfaces encode the forward and reverse AD maps directly [2307.06075].

A recurring numerical product is the full gradient of a scalar objective with respect to a high-dimensional control vector. In the MITgcm exposition,
\[
\delta J = \left\langle \frac{\partial J}{\partial u}, \delta u \right\rangle
\]
is obtained by adjoint backpropagation through
\[
\delta J = \left\langle \frac{\partial x(t_1)}{\partial u}^T L_1^T \cdots L_{N_t-1}^T \frac{\partial J}{\partial x(t_f)}, \delta u \right\rangle .
\tag{5}
\]
This is the formal basis for gradient-based sensitivity analysis, attribution, state estimation, and uncertainty quantification [2401.11952]. In HFBTHO-AD, the central differentiated object is instead the Jacobian \(J(x)\in \mathbb{R}^{d\times n_x}\) of a residual map, from which
\[
\nabla f(x) = 2 J(x)^T r(x)
\]
is formed for optimization and covariance analysis [2508.11910].

This diversity of targets indicates that Tapenade’s outputs are not restricted to one style of derivative product. The literature covers Jacobian-vector products, transposed-Jacobian products, full Jacobians via vector forward mode, tangent-linear models, adjoint models, and discrete adjoint operators [2508.11910], [0711.4444], [2401.11952].

## 3. Checkpointing and reverse-mode memory tradeoffs

Checkpointing is one of the most persistent themes in the Tapenade literature. Before trace-based binomial checkpointing for arbitrary programs was proposed, systems “like Tapenade” already provided automatic checkpointing at procedure-call boundaries in reverse mode [1611.03410]. Tapenade also supported a more specialized binomial-checkpointing mechanism through user-provided pragmas on DO loops [1611.03410]. The same paper treats this as an important but limited capability because checkpoint placement remained tied to source syntax rather than to the dynamic sequence of primitive computations.

The distinction is precise. Tapenade’s existing checkpoint placement was constrained to syntactic constructs: procedure-call boundaries or DO loops designated by pragmas. The critique is that optimal binomial scheduling is defined over the dynamic sequence of primitive computations, and data-dependent execution costs “not even statically determinable” can defeat syntax-aligned checkpoint placement [1611.03410]. On the irregular nested-loop benchmark discussed there, Tapenade exhibits \(O(n)\) space and time usage for all tested strategies, including no checkpointing, manual checkpointing around the outer loop only, manual checkpointing around the inner loop only, manual checkpointing around both loops, and binomial checkpointing [1611.03410].

Another line of work shows Tapenade as a vehicle for practical checkpointing rather than as the object of critique. In OPA, the authors implemented Griewank and Walther’s binomial checkpointing algorithm around Tapenade-generated adjoints. They report, for example, that for 64 timesteps and 9 snapshots, a multi-level recursive strategy yields average duplicate executions per timestep of 2.25 whereas optimal binomial checkpointing yields 2.0; for 1000 timesteps and 27 snapshots, the corresponding values are 2.7 and 2.57 [0711.4444]. In a one-year sensitivity experiment on 5475 timesteps, the Tapenade-generated adjoint computed the sensitivity map in 8.03 times the runtime of the original simulation [0711.4444].

MITgcm-AD v2 presents a later, production-scale checkpointing comparison. There, TAF uses a highly tuned static \(N\)-level checkpointing strategy, with \(N=3\) by default, while Tapenade uses binomial checkpointing based on the classic Revolve approach [2401.11952]. The paper states the optimality recurrence
\[
t(l,c) = \min_{1\le \ell < l} \left\{ \ell + t(\ell,c) + t(l-\ell,c-1) \right\}
\qquad \forall l>1,\; c>1,
\]
with boundary conditions
\[
t(1,c)=0 \quad \forall c>0, \qquad t(l,1)=\frac{(l-1)l}{2} \quad \forall l>0,
\]
and explicit solution
\[
t(l,c) = r l - \beta(c+1,r-1),
\tag{9}
\]
where
\[
\beta(c,r)=\binom{c+r}{r}.
\]
Tapenade supports this built in, requiring only a preprocessing directive on the time loop [2401.11952].

A further MPI-parallel study combines Tapenade with Adjoinable MPI and binomial checkpointing for a solver with about \(10^6\) explicit time steps [1912.11717]. For a viscous case with
\[
N = 6.8\times 10^5
\]
timesteps and 80 snapshots, Tapenade’s binomial scheme induces an average of 3.9 extra recomputations per time step, and the total normalized runtime of the adjoint code is 15.4 times the primal runtime [1912.11717]. This makes clear that Tapenade’s checkpointing relevance spans serial, large-scale oceanic, and MPI-parallel CFD settings.

## 4. Role in large-scale scientific models and HPC codes

Tapenade has been used in several large scientific computing domains, and the applications collectively define its practical reputation.

### Geophysical circulation and data assimilation

In MITgcm-AD v2, Tapenade is the source-to-source AD tool underpinning an open-source tangent-linear and adjoint modeling framework for MITgcm [2401.11952]. The framework was integrated into the MITgcm main branch, with `genmake2` modified so that generated Makefiles can invoke Tapenade and track differentiated-file dependencies. Build targets `tap_adj` and `tap_tlm` produce the adjoint and tangent-linear executables, respectively [2401.11952]. The paper reports compatibility with 10 tutorial/verification experiments and 25 MITgcm packages, including `cost`, `ctrl`, `ecco`, `profiles`, `seaice`, `dic`, `ggl90`, `gmredi`, `kpp`, `streamice`, `ptracers`, and `diagnostics` [2401.11952].

The ORCA-2/NEMO study uses Tapenade to generate the tangent and adjoint machinery needed for 4D-Var data assimilation with controls extending beyond initial conditions to horizontal boundary discretization coefficients \(\alpha_{xy}\), vertical boundary discretization coefficients \(\alpha_z\), and vertical diffusion coefficients \(A^z\) [1212.3116]. The paper emphasizes that derivatives with respect to internal parameters such as boundary-condition coefficients are much more complex than classical initial-condition derivatives, which is why Tapenade is described as avoiding “huge coding and debugging work” [1212.3116].

OPA provides an earlier but foundational ocean-model case study. After OPA migrated to FORTRAN95, the old hand-written adjoint became obsolete; Tapenade was then used to rebuild tangent and adjoint codes mechanically for OPA 9 [0711.4444]. The full OPA code base is described as about 200 modules, 800 procedures, and over 100,000 lines of FORTRAN95, with a differentiated computational kernel covering 330 procedures [0711.4444].

### CFD, discrete adjoints, and optimization

In the implicit discrete adjoint gas-kinetic scheme, Tapenade is the source-transformation engine that generates the discrete adjoint code for the GKS solver [2606.14112]. The paper poses the optimization problem as
\[
\min_{\boldsymbol{\alpha}} \quad I = I(\boldsymbol{Q}_i, \boldsymbol{Q}_b, \boldsymbol{\alpha}),
\]
subject to
\[
\boldsymbol{R}(\boldsymbol{Q}_i, \boldsymbol{Q}_b, \boldsymbol{\alpha}) = \boldsymbol{0},
\]
with the discrete adjoint system
\[
\left( \frac{\partial \boldsymbol{R}}{\partial \boldsymbol{Q}_i} + \frac{\partial \boldsymbol{R}}{\partial \boldsymbol{Q}_b} \frac{\partial \boldsymbol{Q}_b}{\partial \boldsymbol{Q}_i} \right)^T \boldsymbol{\lambda}
=
\left( \frac{\partial I}{\partial \boldsymbol{Q}_i} + \frac{\partial I}{\partial \boldsymbol{Q}_b} \frac{\partial \boldsymbol{Q}_b}{\partial \boldsymbol{Q}_i} \right)^T.
\]
Tapenade is used because manual derivation of the adjoint for the GKS flux construction is nontrivial and because the authors want strict consistency between primal and adjoint discretizations [2606.14112].

The JAGUAR study differentiates a parallel CFD solver for time-dependent PDEs using Tapenade in both tangent and adjoint modes, with two stated novelties: automatic inversion of the complete MPI communication layer and adjointing an explicit time integration loop running for ca. \(10^6\) time steps [1912.11717]. The workflow combines Tapenade with Adjoinable MPI and binomial checkpointing, demonstrating that source-transformed derivatives can extend to a large parallel solver when communication and time integration are treated explicitly [1912.11717].

### Nuclear EDF solvers and uncertainty quantification

HFBTHO-AD uses Tapenade to differentiate a nuclear energy density functional solver so that derivative-based optimization, sensitivity analysis, and uncertainty quantification become feasible [2508.11910]. The top-level differentiated routine is `HFBTHO_DFT_SOLVER`. The independent variables are 14 EDF parameters—`RHO_NM`, `E_NM`, `K_NM`, `ASS_NM`, `LASS_NM`, `SMASS_NM`, and the two-component arrays `CrDr`, `CpV0`, `CrDJ`, `CJ`—and the dependent variables are the 52 outputs in `eresu` and `ala2` [2508.11910]. This application is notable because it shows Tapenade being integrated into an existing build system and embedded within a two-level architecture: an inner differentiated HFBTHO executable and an outer Python+MPI layer assembling residuals and Jacobians over 72 nuclei [2508.11910].

### Finite element Jacobians

In finite element software, Tapenade has been used to automate Jacobian calculation for nonlinear Newton solves [1702.06365]. The authors differentiate element-level residual routines rather than global assembly, producing dense element Jacobians \(\mathbf{A}_e\) that are then assembled into the global sparse Jacobian via
\[
\mathbf{A} = \sum_{e\in\mathcal{T}} \mathbf{P}_e \mathbf{A}_e \mathbf{P}_e^T.
\]
This architectural choice leverages FE sparsity structure without asking Tapenade to generate sparse global assembly logic [1702.06365].

## 5. Integration patterns, software engineering, and code adaptation

Tapenade is repeatedly presented as effective but not frictionless. The engineering patterns needed to deploy it are a major part of the literature.

A common pattern is explicit integration into the host build system. MITgcm-AD v2 modified `genmake2`, added a `code_tap` directory as the Tapenade analogue of `code_ad`, and introduced build targets `tap_adj` and `tap_tlm` [2401.11952]. HFBTHO-AD integrated Tapenade into the existing HFBTHO build system through Makefile rules, a dedicated `src/hfbtho_ad/MakefileTap`, and an AD-enabled executable in `hfbtho_ad/` [2508.11910]. The finite element Jacobian study constructed a full source-processing workflow around Tapenade: Fortran preprocessor, custom preprocess script, Tapenade, optional midprocess script, postprocess script, and compiler [1702.06365].

Legacy-language and library issues are prominent. OPA required extending Tapenade’s internal representation to handle FORTRAN95 modules, private entities, interfaces, array notation, pointers, and dynamic memory [0711.4444]. The finite element code required workarounds for Cray pointers, min/max intrinsic calls with many arguments, assumed-size array initialization, fixed-form versus free-form syntax, and unsupported newer-standard statements [1702.06365]. HFBTHO-AD required preprocessing BLAS/LAPACK Fortran77 sources into a Fortran90-compatible form, concatenating all required library files into one file, and manually adapting routines such as `dlagts.f`, `dlarfg.f`, `dsyevr.f`, and `dlanst.f` [2508.11910].

Another recurring pattern is selective manual handling of numerically delicate kernels. In HFBTHO-AD, `DSYEVR` is not differentiated through its implementation; instead, a hand-coded forward-mode rule is supplied:
\[
\dot D = I \odot (U^{-1} \dot A U),
\]
\[
\dot U =  U ( F \odot (U^{-1} \dot A U)),
\]
with
\[
F_{ij} =
\begin{cases}
(d_j-d_i)^{-1} & \mbox{for } i \ne j \\
0 & \text{otherwise.}
\end{cases}
\]
The rationale is that differentiating a finitely terminated iterative eigensolver can be mathematically inappropriate [2508.11910]. OPA reports an analogous issue for the preconditioned conjugate gradient solver: direct AD through PCG produced derivatives that became completely wrong after about 80 timesteps, so the authors used Tapenade’s black-box facility and differentiated the underlying linear solve mathematically rather than instruction by instruction [0711.4444].

The literature therefore does not present Tapenade as a universal black box. A consistent message is that source transformation works best when combined with explicit decisions about wrappers, flow directives, build integration, and higher-level derivative rules for difficult interfaces [2401.11952], [2508.11910], [1702.06365].

## 6. Performance, validation, and limitations

Performance claims about Tapenade are context-dependent and often tied to checkpointing, tape growth, or generated-code overhead rather than to AD theory alone.

In MITgcm-AD v2, the Tapenade adjoint is reported as about 2–7 times slower than the TAF adjoint. The paper attributes this mainly to more aggressive checkpointing and recomputation at procedure calls, while also emphasizing that the reported Tapenade version had no performance tuning and that selective directives telling Tapenade not to checkpoint certain calls can yield speedups of 2x or more [2401.11952]. Example timings include `global_with_exf`, where forward runtime is 4.0 s, TAF adjoint 15.8 s, and Tapenade adjoint 35.4 s, and `global_ocean.cs32x15`, where forward runtime is 30.7 s, TAF 173.4 s, and Tapenade 1112.2 s [2401.11952].

In HFBTHO-AD, walltimes for residual plus Jacobian evaluation show AD somewhat slower than finite differences in raw walltime but substantially better in core-hours. For example, at `UNEDFpre`,
\[
T_r=1.12 \text{ min},\quad T_{\mathrm{FD}}=17.60 \text{ min},\quad T_{\mathrm{AD}}=20.12 \text{ min},
\]
with average ratios of about 15.47 for FD and 17.89 for AD relative to residual-only evaluation. However, AD / residual is about 8.94 in core-hours, versus about 15.47 for FD / residual, and the FD timings do not include the expensive ECNoise procedure used to determine reliable finite-difference steps \(h_{ij}\) [2508.11910]. This suggests that resource usage and end-to-end workflow cost can favor Tapenade even when raw walltime does not.

The finite element Jacobian paper reports that the AD-generated Jacobian is much slower than a manual Jacobian but can be improved substantially by exploiting FE structure. Matrix calculation runtimes show, for example, on Mesh 48: manual derivative 0.98 s, unoptimized automatic derivative 13.27 s, and “separation by degree of freedom” 7.04 s; the optimization yields about a 46% speedup [1702.06365].

Validation methods are correspondingly varied. Ocean-model work uses divided differences and identical twin experiments. In OPA, on a complete 1000-timestep global ORCA-2 simulation, the reported values are
\[
(DD \cdot DD) = 4.405352760987440 \times 10^8,
\]
\[
(\dot{Y} \cdot \dot{Y}) = 4.405346876439977 \times 10^8,
\]
\[
(\overline{X} \cdot \dot{X}) = 4.405346876439867 \times 10^8,
\]
showing very close tangent–adjoint agreement and the expected finite-difference discrepancy [0711.4444]. MITgcm-AD v2 compares Tapenade gradients against finite differences and TAF-based gradients, reporting finite-difference values around \(-0.02\) with TAF and Tapenade errors on the order of \(10^{-8}\) to \(10^{-9}\) in one example [2401.11952]. The gas-kinetic adjoint work validates sensitivities against finite differences across subsonic, transonic, supersonic, and hypersonic cases and reports good or excellent agreement [2606.14112]. HFBTHO-AD compares Jacobians across compiler configurations and against finite differences, while also showing a concrete case where AD gives derivative \(78.45\) and FD gives derivative \(53.55\) because of deterministic computational noise in the primal solver [2508.11910].

Several limitations are recurrent. Reverse-mode memory can be prohibitive without optimization. In ORCA-2, automatically generated adjoints require substantial memory because the forward trajectory must be available during backward integration; the authors reduced memory by a factor of 25 through specific optimizations, making a 10-day assimilation window fit in 640 MB [1212.3116]. Tapenade-generated OpenMP derivative code can preserve parallelism, but reverse mode often scales worse than the input programs because primal shared reads become adjoint shared increments, forcing atomics or reductions [2111.01861]. Dynamic allocation support was only partial in OPA: handled in tangent mode, not generally in adjoint mode [0711.4444]. MPI differentiation in the JAGUAR study required replacing raw MPI with Adjoinable MPI wrappers, rewriting unsupported persistent communications, manually providing communication-style metadata, and manually inserting `ADTOOL_AMPI_Turn` at the forward/reverse turning point [1912.11717].

A broader misconception addressed implicitly across papers is that AD-generated code is automatically the derivative of the mathematical model one intended. The finite element paper shows that if a matrix exponential implementation returns the identity for \(\|\mathbf{M}\|_\infty < 10^{-12}\), AD differentiates that branch and yields a zero derivative, even though the mathematical derivative of \(e^{\mathbf{M}}\) at zero is not zero [1702.06365]. This suggests that Tapenade differentiates the implemented algorithm and branch structure, not an abstract symbolic formulation.

## 7. Position in the AD ecosystem

The literature consistently positions Tapenade as a representative and influential source-transformation AD system. In work on hybrid operator-overloading/source-transformation workflows, Tapenade appears as the canonical example of a source-transformation tool that automates derivative generation and reduces the burden of manually implementing custom derivative kernels [2307.06075]. In that benchmarking context, Tapenade-generated derivatives on a Burgers loop yield similar qualitative memory and runtime improvements to Enzyme-generated derivatives when inserted as CoDiPack external functions [2307.06075].

At the same time, some later work uses Tapenade as a foil to motivate more general runtime-level checkpointing. The binomial-checkpointing paper portrays Tapenade as an important prior system for reverse-mode checkpointing, but limited by checkpoint placement at procedure-call boundaries and user-provided DO-loop pragmas [1611.03410]. The contrast is not that Tapenade lacks checkpointing, but that its checkpointing remains syntax-driven rather than trace-driven [1611.03410].

Tapenade is also a platform for research extensions. The OpenMP work extends Tapenade so that it can generate correct derivative code for parallel worksharing loops in forward and reverse mode, including threadprivate stacks, schedule recording, schedule replay, OpenMP-aware scoping rules, and a user override directive of the form:

```fortran
!$ad omp_adjoint shared(a) reduction(+:b) atomic(c)
!$omp parallel do shared(a,b,c)
```

[2111.01861]. This places Tapenade not only as an application tool but as a vehicle for methodological work on differentiating contemporary shared-memory parallel programs.

Across these papers, Tapenade occupies a distinct niche: a mature source-transformation AD system used directly in oceanography, climate modeling, CFD, nuclear physics, and finite elements; a practical baseline in discussions of generated derivative code; and a reference architecture against which newer ideas about arbitrary-program checkpointing or hybrid AD integration are formulated [0711.4444], [2401.11952], [1912.11717], [2307.06075], [1611.03410]. A plausible implication is that Tapenade’s historical importance derives less from any single algorithmic novelty than from its sustained role in making differentiated scientific software operational at scale.

Source: https://www.emergentmind.com/topics/tapenade