Use single-affect VCC constructor in _track_callback#1446
Conversation
VectorContinuousCallback no longer has an affect_neg! field — VCC's per-fire mask carries directionality through to the reverse pass — but _track_callback was still calling the constructor as if affect_neg! slotted between affect! and len. The leftover `nothing` made the third positional argument `Nothing` instead of `Int` (len), so the constructor threw a MethodError on every adjoint pass through any VCC, regardless of Julia version. Drop the stray `nothing` and forward the new initializealg / saved_clock_partitions / maybe_discontinuity / initialize_save_discretes fields so the tracked callback round-trips all the user-supplied configuration. Fixes the MethodError surfaced in test/callbacks/vector_continuous_callbacks.jl (Callbacks2 testset), which had been blocking all VCC adjoint tests on master. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Update: also includes the test-point fixPushed commit With both commits applied, all 11 tests in |
Correction: test-point fix moved to its own PRPushed a force-update reverting commit Order doesn't matter — either PR can land first. With this one alone, 3/4 testsets in |
Please ignore until reviewed by @ChrisRackauckas.
Summary
_track_callback(cb::VectorContinuousCallback, ...)was still calling the VCC constructor with a leftovernothingargument in the oldaffect_neg!slot. After the recent refactor that droppedaffect_neg!from VCC, the constructor signature is(condition, affect!, len, ...)— the straynothingmadelen::Nothinginstead ofInt, so the constructor threw aMethodErroron every adjoint pass through any VCC, regardless of Julia version.nothingand forwardinitializealg,saved_clock_partitions,maybe_discontinuity, andinitialize_save_discretesfrom the original callback so the tracked VCC round-trips all the user-supplied configuration.Test plan
Reproduced the failure locally on Julia 1.12 via
test/callbacks/vector_continuous_callbacks.jl. Before the fix: all 4 sub-testsets in this file error withMethodError: no method matching SciMLBase.VectorContinuousCallback(...). After the fix:MSE loss function bouncing-ball like → callback with linear affect— runs, with 4 numerical assertion failures (separate latent issue, see note below).Test condition function that depends on time only— passes.Structural simultaneous fire (algebraically tied conditions)— passes.Coincidental simultaneous fire (corner trap)— passes.Note on remaining numerical failure
The
callback with linear affecttestset now reaches its assertions but they fail with ~7% mismatch on the u[3]/u[4] gradient components vs ForwardDiff. BothBacksolveAdjointandGaussAdjointagree with each other and disagree with ForwardDiff in exactly the same way, so this is a latent issue in the implicit ∇τ correction for VCC, not a regression from this PR. Master has been red onCallbacks2for over a month and the MethodError was masking this. I deliberately kept this PR small and focused on the constructor fix per CLAUDE.md "small, focused PRs" guidance — the numerical issue deserves its own investigation and PR.