-
Notifications
You must be signed in to change notification settings - Fork 90
Open
Description
Summary
Broadcasting into ComponentArray fields fails with Enzyme. Explicit loops work fine, but broadcast syntax (.=) fails.
Environment
- Julia version: 1.12.4
- Enzyme version: 0.13.118
- ComponentArrays version: 0.15.31
Minimal Reproducible Example
using Enzyme
using ComponentArrays
u = ComponentArray(a = [1.0, 2.0])
p = ComponentArray(p = 2.0)
# ✓ WORKS: Using explicit loop
function f_loop!(du, u, p)
for i in eachindex(du.a)
du.a[i] = u.a[i] * p.p
end
return nothing
end
du1 = similar(u)
du1_shadow = ComponentArray(a = ones(2))
dp1_shadow = ComponentArray(p = 0.0)
f_loop!(du1, u, p)
Enzyme.autodiff(
Enzyme.Reverse,
f_loop!,
Const,
Duplicated(du1, du1_shadow),
Const(u),
Duplicated(p, dp1_shadow)
)
println("Loop version works: dp_shadow = ", dp1_shadow) # (p = 3.0) ✓
# ✗ FAILS: Using broadcast
function f_broadcast!(du, u, p)
du.a .= u.a .* p.p # This line causes the issue
return nothing
end
du2 = similar(u)
du2_shadow = ComponentArray(a = ones(2))
dp2_shadow = ComponentArray(p = 0.0)
f_broadcast!(du2, u, p)
# Without runtime activity: EnzymeRuntimeActivityError
Enzyme.autodiff(
Enzyme.Reverse,
f_broadcast!,
Const,
Duplicated(du2, du2_shadow),
Const(u),
Duplicated(p, dp2_shadow)
)Errors
Without runtime activity:
EnzymeRuntimeActivityError: Detected potential need for runtime activity.
With runtime activity (set_runtime_activity(Reverse)):
AssertionError: x.indices == dx.indices
The assertion failure occurs in EnzymeCore.jl at the Duplicated constructor.
Analysis
The issue appears to be:
- ComponentArray field access (
du.a) returns aSubArrayview into the underlying data - When Enzyme creates shadow arrays for the broadcast operation with runtime activity mode, it creates a
Duplicated(primal_subarray, shadow_subarray)pair - The primal and shadow
SubArrays have different internalindicesfields (even though they have the same shape), triggering the assertion failure
Impact
This affects SciML users trying to use EnzymeVJP with ComponentArrays for ODE sensitivity analysis. See: SciML/SciMLSensitivity.jl#1287
Workaround
Users can work around this by using explicit loops instead of broadcasting, or by using a different AD backend (Zygote, ReverseDiff).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels