← Back to Blog
Architecture

AAD Technologies: Tape vs Code Transformation vs Code Generation

Three approaches to automatic adjoint differentiation exist in production today. They differ in integration effort, memory usage, performance, and scalability. Here's how they compare.

Dmitri Goloubentsev
Dmitri Goloubentsev
· 2 min read
AAD tape-based code transformation code generation comparison CppAD Adept Enzyme

The benefits of Automated Adjoint Differentiation are clear: fast XVA risk, model calibration, hedging, and live risk. Many financial institutions have implemented an AAD solution and now experience both benefits and limitations of their chosen approach.

As Antoine Savine noted: “The main challenge faced by global investment banks today is a computational one.” Computation of risks is a primary factor driving operational costs. An average compute bill for a Tier 2 bank exceeds $10M per year.

The three approaches

1. Tape-Based AAD

Operator overloading captures elementary operations while executing analytics. All mathematical operations are recorded on a “tape” data structure, then processed backwards to compute all risks.

Examples: CppAD, Adept, dco/c++, most in-house implementations.

2. Code Transformation

Source-to-source transformation converts the original program into an adjoint program at the source level. An external tool reads your C++ (or Fortran) and generates the differentiated version.

Examples: Enzyme, Tapenade.

3. Code Generation (JIT Compilation)

Records the computation graph like tape-based, but then JIT-compiles it to native machine code with SIMD vectorization. The compiled kernel replays without tape overhead.

Examples: AADC.

Comparison

CharacteristicTape-BasedCode TransformationCode Generation
Integration methodTemplatesCompiler pluginOperator overloading
Integration easeHardMediumEasy
Timeline3-12 months6-18 months2-6 weeks
Adjoint factor2-5×~2×<1×
Original code speed0.5× (slower)1× (unchanged)1× or faster
Memory overheadHigh (tape)LowLow (compiled kernel)
VectorizationDifficultLimitedNative (AVX-2/512)
Multi-threadingDifficultLimitedNative
Control flowLimitedGoodFull
Scale to 10M+ LOCLimited by memoryComplex build systemYes
Second-order GreeksSlow (double tape)PossibleBump-on-adjoint
Dev productivity impact~2× slowdownMinimalMinimal

The adjoint factor below 1× for code generation means the kernel with Greeks runs faster than the original code without Greeks — because the JIT compiler optimizes the recorded computation more aggressively than the original source compiler.

Business impact

FactorTapeTransformationCode Generation
Time to first result6-12 months12-18 months2-6 weeks
Quant productivityDegradedNeutralNeutral
Cloud compute cost2-5× baseline~2× baseline≤1× baseline
Maintenance burdenHighMediumLow

Implemented using AADC, a commercial adjoint AD compiler (matlogica.com).

Want to see these results on your own portfolio?

Get in Touch

Interested in these opportunities?

Let's arrange a free demo for you and your team.

Book a Demo