Enzyme gradients through parameter-dependent continuous event times are incorrect

Aperta
#533 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

@ChrisRackauckas-Claude ci sta già lavorando.

Dal 2/10/2026.

  • #570 di @ChrisRackauckas-Claude — aperta

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
julia
Ambito
hpc, performance

Direzione di ricerca

Inizia con continuous_event_reproducer.jl e l’entry point continuous_loss, quindi esamina il percorso ContinuousCallback e EnsembleGPUKernel(CPU()) utilizzato dal riproduttore. Eseguilo con il progetto Julia e il branch Enzyme indicati, confronta il risultato dell’evento continuo con il caso riuscito del callback fixed-time e indaga finché le derivate dei parametri non siano tutte -1.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

A continuous callback locates the event correctly in the forward solve, but Enzyme reverse mode returns incorrect event-time sensitivities. For u′=1, u(0)=0, and a reset to zero when u=p, with 0.5<p<1, exactly one event occurs before t=1. Thus u(1)=1-p and every parameter derivative must be -1.

Reproduced on Julia 1.12.7, Enzyme 0.13.201, KernelAbstractions 0.9.42, and SciMLBase 3.53.1, using the CPU backend and the Enzyme restoration branch from https://github.com/SciML/DiffEqGPU.jl/pull/532. This is a remaining limitation of that restoration, not a claim that its changes introduced the event-time problem. The unmodified base cannot execute the ensemble-gradient reproducer because it fails earlier in Enzyme compilation.

using DiffEqGPU, Enzyme, KernelAbstractions, SciMLBase, StaticArrays, Test
function continuous_loss(p)
    prob = ODEProblem{false}((u, p, t) -> SVector(1.0), SVector(0.0), (0.0, 1.0), SVector(p[1]))
    pf = (prob, ctx) -> remake(prob; p = SVector(p[ctx.sim_id]))
    condition(u, t, integrator) = u[1] - integrator.p[1]
    affect!(integrator) = (integrator.u = zero(integrator.u))
    cb = ContinuousCallback(condition, affect!; save_positions = (false, false))
    sol = solve(EnsembleProblem(prob; prob_func = pf, safetycopy = false), GPUTsit5(), EnsembleGPUKernel(CPU(), 0.0); trajectories = length(p), adaptive = false, dt = 0.05, callback = cb, merge_callbacks = true, save_everystep = false)
    return sum(s -> sum(s.u[end]), sol.u)
end

p = [0.63, 0.71, 0.84]
@test continuous_loss(p) ≈ 3 - sum(p)
dp = zero(p)
Enzyme.autodiff(Reverse, continuous_loss, Active, Duplicated(p, dp))
@show dp
@test dp ≈ -ones(3) rtol = 1.0e-6

Run with julia +1.12 --project=<environment developed against the Enzyme branch> continuous_event_reproducer.jl.

The forward-value assertion passes. The derivative assertion fails:

dp = [-1.0000000000000027, -0.4999999999999896, -0.7599918704695224]
Test Failed:
  Expression: dp ≈ -ones(3) rtol = 1e-6
  Evaluated: [-1.0000000000000027, -0.4999999999999896, -0.7599918704695224] ≈ [-1.0, -1.0, -1.0] (rtol=1.0e-6)

The same probe with a fixed-time discrete callback (doubling the exponential solution at t=0.5, using tstops=[0.5] and merge_callbacks=true) passes its analytic gradient check. This distinction should be reflected in documentation: callback execution is supported, but that does not establish correct sensitivities through parameter-dependent event times. Root localization and the differentiated event update need investigation; no cause has been bisected, and GPU behavior has not been verified.

🤖 Investigated with Codex CLI 0.153.4 (model: gpt-6-astra; local session ID: 01a07fcc-1c4f-7ee3-9a1e-51eaab7df293).

Lingua principale
Julia
Stelle
331
Fork
43
Merge medio
1g 20h
PR unite (30g)
10

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di SciML/DiffEqGPU.jl

Tutte le issue di SciML/DiffEqGPU.jl

Issue simili

Altre issue su Julia

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.