Skip to content

“Enzyme: No forward mode derivative found” when using function that calls autodiff-generated function inside closure #143516

Open
@SabrinaJewson

Description

@SabrinaJewson

I tried this code:

#![feature(autodiff)]
use std::autodiff::autodiff_forward;

#[autodiff_forward(cdf_pdf_inner, Const, Dual, Dual)]
fn cdf(dist: &[f64; 3], x: f64) -> f64 {
    let [μ, σ, ξ] = *dist;
    (-(1.0 + ξ * (x - μ) / σ).powf(-1.0 / ξ)).exp()
}

#[autodiff_forward(cdf_pdf_d1_inner, Dual, Const, DualOnly)]
fn cdf_pdf(dist: &[f64; 3], x: f64) -> (f64, f64) {
    cdf_pdf_inner(dist, x, 1.0)
}

fn cdf_pdf_d1(dist: &[f64; 3], d1: &mut [(f64, f64); 3], x: f64) {
    d1[0] = cdf_pdf_d1_inner(dist, &[1.0, 0.0, 0.0], x);
    d1[1] = cdf_pdf_d1_inner(dist, &[0.0, 1.0, 0.0], x);
    d1[2] = cdf_pdf_d1_inner(dist, &[0.0, 0.0, 1.0], x);
}

fn other() {
    let dist = [0.0, 1.0, 0.1];
    cdf_pdf_d1(&dist, &mut [(0.0, 0.0); 3], 1.0);
}

fn main() {
    (|| other())();
}

I expected to see this happen: Runs without error.

Instead, this happened:

error: src/testing.rs:4:54: in function preprocess__ZN7testing13cdf_pdf_inner17h11969517470231b6E { double, double } (ptr, double, double): Enzyme: No forward mode derivative found for __enzyme_fwddiff_ZN7testing13cdf_pdf_inner17h11969517470231b6E
 at context:   %4 = call { double, double } (...) @__enzyme_fwddiff_ZN7testing13cdf_pdf_inner17h11969517470231b6E(ptr @_ZN7testing3cdf17hb3d4d0038b898c9aE, metadata !"enzyme_primal_return", metadata !"enzyme_const", ptr %0, metadata !"enzyme_dup", double %1, double %2) #147, !dbg !71

error: could not compile `x` (bin "testing")

Caused by:
  process didn't exit successfully: `~/.local/share/rustup/toolchains/enzyme/bin/rustc --crate-name testing --edition=2024 src/testing.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=174 --crate-type bin --emit=dep-info,link -C lto=fat -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=0b226bb2ffabf037 -C extra-filename=-2b9f80dfd7fd82f0 --out-dir ./target/debug/deps -C linker=/usr/bin/clang -C incremental=./target/debug/incremental -L dependency=./target/debug/deps --extern x=./target/debug/deps/libx-a93ab6ba3304f9da.rlib -Clink-arg=--ld-path=/usr/bin/mold -Zautodiff=Enable` (exit status: 1)

Another reproducer is:

fn caller(f: impl FnOnce()) {
    f();
}
fn main() {
    caller(other);
}

However, it does not occur if we just call other(); directly in main(), nor does it occur if we use caller(other as fn());. It is unaffected by the contents of cdf, but cdf_pdf must call cdf_pdf_inner – i.e. we need those two levels of autodiff.

Meta

rustc --version --verbose:

rustc 1.90.0-nightly (48aee7e38 2025-07-03)
binary: rustc
commit-hash: 48aee7e383503c234cce4206dee9f19f57edb617
commit-date: 2025-07-03
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.7

Built following the Enzyme installation instructions on the rustc dev guide.

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.F-autodiff`#![feature(autodiff)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions