Developer Guide

AADC Debugging and Validation

Master AADC's comprehensive debugging and validation toolkit to handle branches correctly, detect numerical differences, verify adjoint accuracy, and ensure robust integration of automatic differentiation in your quantitative finance code.

Comprehensive Debugging for Robust Integration

AADC provides a complete suite of debugging and validation tools to ensure your integration handles all scenarios correctly while maintaining numerical accuracy. This guide covers branch handling, numerical debugging, adjoint verification, and runtime validation.

What You'll Learn

  • Branch Types and Handling
  • Numerical Difference Detection

What You'll Learn

  • Adjoint Verification
  • Validation Framework

Branch Handling in AADC

Understanding and correctly handling conditional logic

Why Branches Matter

Branches represent conditional logic in your analytical code. Most branches work normally with AADC, but those depending on kernel inputs require special handling. Branches create two critical challenges: during recording, AADC captures only one execution path, so different input values triggering different branches can leave the compiled kernel incomplete. Additionally, branches create discontinuities that affect gradient computation at those points.

Static Branches

Challenge: Conditions independent of kernel inputs—algorithm configuration, constant comparisons, or fixed market data decisions.

These require no transformation. Standard if/else works normally because the condition is determined before kernel execution and doesn't change between runs.

Stochastic Branches

Conditions depending on variables marked as inputs that can evaluate differently for different inputs. Examples include barrier option logic, path-dependent conditions, and Monte Carlo simulation paths. These must use functional forms like iIf() or conditional assignment functions to ensure all paths are properly recorded.

The ibool Type

What is ibool?

Comparisons between idouble variables return ibool (AADC's active boolean type) rather than native bool. This active type allows AADC to track conditional dependencies and handle branching correctly during both recording and differentiation.

Supported Operations

ibool supports standard comparison operations including equality (==, !=) and ordering (<, <=, >, >=). Use these with idouble variables to create conditions that AADC can properly track.

Functional Conditionals

The iIf() function is the primary tool for simple stochastic branches, analogous to Excel's IF() function. For modifying existing variables conditionally, use condAssign(). For complex multi-branch logic with nested conditions, consider AADC's Branch Manager.

Best Practices for Branch Handling

  • Identify branch types during design: Distinguish static conditions from stochastic ones early
  • Use mathematical functions when possible: std::max, std::min, std::abs work automatically with idouble
  • Test multiple input scenarios: Ensure all execution paths are handled properly
  • Monitor Active-to-Passive conversions: Use AADC's reporting features to catch unintended conversions
  • Consider smoothing for discontinuities: Branches create gradient discontinuities that may need smoothing for stable derivatives

Branch Handling Checklist

Static Conditions: Use standard if/else - no transformation needed
Stochastic Conditions: Use iIf() or condAssign() functional forms
Complex Branching: Consider Branch Manager for nested logic
Barrier Options: All barrier scenarios use functional conditionals
Path Dependency: Monte Carlo paths use proper ibool handling
Gradient Smoothness: Apply smoothing where continuous derivatives are needed

Numerical Difference Detection

Identify and resolve discrepancies between recording and kernel execution

The AADC debugging framework helps identify and resolve numerical discrepancies between the recording stage and kernel execution without requiring source code modifications. When the recording stage and AADC kernel give different values, this framework pinpoints the exact source.

Diagnostic Capabilities

  • Identify exact code location of numerical divergence
  • Compare recording values vs. kernel execution values
  • Track intermediate variable mismatches
  • Detect random number generation inconsistencies
  • Identify data ordering problems in SIMD execution

Debugger Integration

  • Pause execution at specific instrumentation checkpoints
  • Compatible with GDB, Visual Studio Debugger, and WinDbg
  • Examine variable values at precise problem locations
  • Step through execution to understand discrepancy causes

Debugging Workflow

1

Detect Differences

Run your kernel and observe if results differ between recording and execution. AADC will flag when discrepancies exceed acceptable thresholds.

2

Enable Instrumentation

Activate automatic instrumentation through environment variables. This generates detailed logs tracking intermediate values throughout execution without requiring code changes.

3

Analyze with Python Script

Use AADC's Python analysis script to process instrumentation logs and identify the precise location of numerical divergence.

4

Interactive Debugging

Set stop points at specific checkpoints to pause execution and examine the state in your debugger. This allows detailed inspection of variable values and call stacks.

5

Apply Fix and Verify

Implement the necessary correction and re-run with instrumentation to verify the fix resolves the discrepancy.

Common Scenarios and Solutions

Scenario Difference Resolution
Recording vs. Kernel Mismatch Significant Enable instrumentation, use analyzer script to locate source
RNG Inconsistency Random variations Ensure RNG state is properly captured during recording
Branch Path Divergence Conditional-dependent Use functional conditional forms (iIf, condAssign)
SIMD Data Ordering Lane-specific Review vectorized code for data ordering assumptions
Floating-Point Reordering 1e-13 to 1e-16 Accept - within floating-point precision limits

Adjoint Verification

Validate derivative accuracy using finite difference comparison

Adjoint debugging is a verification technique that compares analytical adjoints computed by AADC against finite difference (FD) approximations. This process introduces controlled shifts in intermediate variable values, recomputes to derive FD sensitivities, and compares these with analytical results to identify discrepancies.

Interpreting Results

When comparing analytical and finite difference adjoints:

Category Difference Action
Very Small Difference < 1e-10 Accept - within numerical precision
Small Difference 1e-10 to 1e-6 Review - may indicate accumulated error
Moderate Difference 1e-6 to 1e-3 Investigate - likely indicates an issue
Large Difference > 1e-3 Fix required - adjoint computation error

Tolerance Guidelines

Type Description Absolute Relative
Standard Calculations Option pricing, typical Greeks 1e-10 1e-8
Higher-Order Greeks Gamma, cross-Greeks 1e-8 1e-6
Path-Dependent Derivatives Monte Carlo sensitivities 1e-6 1e-4

Validation Framework

Runtime validation with hierarchical context tracking

AADC's validation framework provides runtime validation across three execution phases: normal program execution, recording, and kernel execution. The framework enables business rule checking with hierarchical context tracking for complex nested computations.

  • Runtime Assertions (AADC_ASSERT)
  • Hierarchical Context (AADC_CONTEXT)
  • Smart Check Registration
  • Vectorized Validation
  • Error Iteration & Analysis
  • Custom Integration Support

AADC_CONTEXT: Hierarchical Context

  • Creates nested context levels using RAII pattern
  • Provides meaningful location information in error messages
  • Automatically closes contexts when scope exits
  • Proper cleanup even during exception handling
  • Addresses the debugging challenge: 'price must be positive: -50' alone provides limited value - context shows where

Vectorized Validation

  • Processes multiple computational lanes simultaneously
  • Typically 4 double values per AVX vector checked together
  • Efficient aggregation minimizes overhead when all checks pass
  • Lane-specific analysis available for detailed debugging
  • Per-lane error display shows scalar values for specific streams

Validation Checklist

  • Critical invariants: Assert business rules that must hold (prices positive, rates bounded)
  • Computation boundaries: Validate inputs and outputs at function boundaries
  • Context for nested code: Use AADC_CONTEXT for hierarchical computations (portfolios, trades, paths)
  • Meaningful messages: Include variable values that help diagnose failures
  • Performance balance: Choose appropriate granularity for context markers
  • CI integration: Run validation in automated test pipelines

Related Resources

Need Help with Integration?

Our team can help you debug and optimize your AADC integration