Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excise getindex adjoint #1328

Merged
merged 5 commits into from
Oct 25, 2023
Merged

Excise getindex adjoint #1328

merged 5 commits into from
Oct 25, 2023

Conversation

ToucheSir
Copy link
Member

We have a better rule in Chainrules now.

Draft for now because I suspect downstream CI will have something to say about this. If it works though, would fix #820 and #1327.

PR Checklist

@ToucheSir
Copy link
Member Author

ToucheSir commented Nov 10, 2022

Aside from some cascading failures from Flux defining methods on a now-nonexistent OneElement and a couple unbroken hessian tests, the biggest issue is that we're hitting https://github.com/JuliaDiff/ChainRules.jl/blob/39c2d17df672836659493d6adb7d4ad8593250a5/src/rulesets/Base/indexing.jl#L105 in tests like

Zygote.jl/test/gradcheck.jl

Lines 163 to 164 in 81380f0

_, back = Zygote._pullback(x->x[1]*im, randn(2))
@test back(1.0)[2] == real([-im, 0]) == [0, 0]
. Because wrap_chainrules_input([nothing]) == [ZeroTangent()], ∇getindex ends up calling _setindex_zero(x::Vector{Float64}, dy::ZeroTangent, inds::Vector{Int64}) which calls fill!(dest::Vector{ZeroTangent}, x::Bool). I don't understand why CR is using eltype(y) for eltype(dx), so summoning @mcabbott for help.

@mcabbott
Copy link
Member

Maybe there should be a getindex_pullback(z::AbstractZero) = z type of thing in CR?

@ToucheSir
Copy link
Member Author

Do you mean something like JuliaDiff/ChainRules.jl#683?

@marius311
Copy link
Contributor

marius311 commented Dec 21, 2022

Thanks for pointing me to this @ToucheSir. I just rebased this on master (totally clean) and gave it a try and works great for the issue I was running into.

I also note that

 _, back = Zygote._pullback(x->x[1]*im, randn(2)) 
@test back(1.0)[2] == real([-im, 0]) == [0, 0] 

now passes with (ChainRules v1.46.0) with no other modifications other than the rebase.

Anything I can do to help this along? Currently I'm fairly motivated to have this working.

@ToucheSir
Copy link
Member Author

We need to figure out how to make CI and downstream tests pass. This may or may not entail changes on the ChainRules side.

@mcabbott
Copy link
Member

Try locally with this perhaps: JuliaDiff/ChainRules.jl@7bb7d98

@mcabbott
Copy link
Member

With JuliaDiff/ChainRules.jl#687 the getindex failures are:

getindex: Test Failed at /Users/me/.julia/dev/Zygote/test/gradcheck.jl:177
  Expression: back([nothing]) == (zeros(4), nothing)
   Evaluated: nothing == ([0.0, 0.0, 0.0, 0.0], nothing)
Stacktrace:
 [1] macro expansion
   @ ~/.julia/dev/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:477 [inlined]
 [2] macro expansion
   @ ~/.julia/dev/Zygote/test/gradcheck.jl:177 [inlined]
 [3] macro expansion
   @ ~/.julia/dev/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:1496 [inlined]
 [4] top-level scope
   @ ~/.julia/dev/Zygote/test/gradcheck.jl:147
getindex: Test Failed at /Users/me/.julia/dev/Zygote/test/gradcheck.jl:181
  Expression: back([nothing]) == (nothing, nothing)
   Evaluated: nothing == (nothing, nothing)
Stacktrace:
 [1] macro expansion
   @ ~/.julia/dev/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:477 [inlined]
 [2] macro expansion
   @ ~/.julia/dev/Zygote/test/gradcheck.jl:181 [inlined]
 [3] macro expansion
   @ ~/.julia/dev/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:1496 [inlined]
 [4] top-level scope
   @ ~/.julia/dev/Zygote/test/gradcheck.jl:147

src/lib/array.jl Outdated
end
Base.size(A::OneElement) = map(length, A.axes)
Base.axes(A::OneElement) = A.axes
Base.getindex(A::OneElement{T,N}, i::Vararg{Int,N}) where {T,N} = ifelse(i==A.ind, A.val, zero(T))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting this struct makes Flux fail.

It could just be left in deprecations. Or it could be hooked up more narrowly to CR's rule, something like this shouldn't upset 2nd derivative definitions:

ChainRules.∇getindex(x::Array{<:Number,N}, dy, inds::Vararg{Integer,N}) where N =
  OneElement(dy, inds, axes(x))

But that's piracy...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't bother reverting the deletion into a deprecation because #1328 (comment) was still unresolved, but that seems like the way to go.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. To be clear I think returning one nothing is an upgrade even though it makes those tests fail.

If someone approves JuliaDiff/ChainRules.jl#687 then perhaps CI can be made happy here.

@ToucheSir
Copy link
Member Author

Dusting this one off since remaining failures in #1389 have remained quite stubborn. Downstream doesn't appear to have a problem with collapsing zeros, so I don't think it should be breaking?

We have a better rule in Chainrules now
@oxinabox
Copy link
Member

oxinabox commented Oct 4, 2023

@ToucheSir what is the status of this right now?

@ToucheSir
Copy link
Member Author

I think I was waiting for an opinion on #1328 (comment). This PR means we'll be collapsing zeros more aggressively than Zygote currently does. I'm not sure if that counts as a breaking change or not. I do anticipate it happening more and more if/when we migrate more rules over to ChainRules and use CR zero types more internally.

@oxinabox
Copy link
Member

oxinabox commented Oct 5, 2023

I think collapsing zeros more aggressively is fine

@ToucheSir
Copy link
Member Author

Zygote's own tests pass now and the Flux failure is due to a broken hessian test passing. That just leaves Molly, which is failing because it overloads Zygote.∇getindex here. Per #1131 (comment), the reason that overload exists is to workaround a correctness issue which ChainRules has already fixed. To that end, 12bdca9 leaves a stub definition in which is non-functional but can be innocuously overriden. Then Molly and any other package which was relying on ∇getindex can simply remove their overloads when upgrading to a new Zygote version. @jgreener64 does that work for you?

@jgreener64
Copy link
Contributor

Thanks for keeping me in the loop here. I tried this PR and Molly with the Zygote.∇getindex method removed from Molly, ChainRules 1.55.0 and Julia 1.9.2. Most tests passed but there was one error when hitting the ChainRules indexing code. I don't know if it is my problem or a ChainRules problem.

The offending line in Molly is https://github.com/JuliaMolSim/Molly.jl/blob/master/src/interactions/implicit_solvent.jl#L642 and the stack trace is below. I can look into it more and open an issue but am posting it here in case anyone can quickly see the problem or the fix.

Otherwise this PR seems good, I can remove the Zygote.∇getindex method and lower bound to the next Zygote release. The stub should stay though, since previous Molly versions did not always upper bound the Zygote version.

Differentiable simulation: Error During Test at /home/jgreener/.julia/dev/Molly/test/zygote.jl:30
  Got exception outside of a @test
  GPU broadcast resulted in non-concrete element type Any.
  This probably means that the function you are broadcasting contains an error or type instability.
  Stacktrace:
    [1] error(s::String)
      @ Base ./error.jl:35
    [2] copy
      @ ~/.julia/packages/GPUArrays/5XhED/src/host/broadcast.jl:34 [inlined]
    [3] materialize(bc::Base.Broadcast.Broadcasted{CUDA.CuArrayStyle{1}, Nothing, ChainRulesCore.var"#49#50", Tuple{CuArray{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{SOneTo{3}}}}}, 1, CUDA.Mem.DeviceBuffer}, CuArray{Union{ChainRulesCore.ZeroTangent, SVector{3, Float64}}, 1, CUDA.Mem.DeviceBuffer}}})
      @ Base.Broadcast ./broadcast.jl:873
    [4] map(f::Function, x::CuArray{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{SOneTo{3}}}}}, 1, CUDA.Mem.DeviceBuffer}, xs::CuArray{Union{ChainRulesCore.ZeroTangent, SVector{3, Float64}}, 1, CUDA.Mem.DeviceBuffer})
      @ GPUArrays ~/.julia/packages/GPUArrays/5XhED/src/host/broadcast.jl:84
    [5] (::ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:elements, :axes), Tuple{CuArray{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{SOneTo{3}}}}}, 1, CUDA.Mem.DeviceBuffer}, Tuple{Base.OneTo{Int64}}}}})(dx::CuArray{Union{ChainRulesCore.ZeroTangent, SVector{3, Float64}}, 1, CUDA.Mem.DeviceBuffer})
      @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:238
    [6] ∇getindex(x::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, dy::CuArray{SVector{3, Float64}, 2, CUDA.Mem.DeviceBuffer}, inds::CuArray{Int64, 2, CUDA.Mem.DeviceBuffer})
      @ ChainRules ~/.julia/packages/ChainRules/RGbGv/src/rulesets/Base/indexing.jl:91
    [7] (::ChainRules.var"#1602#1604"{CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 2, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}})()
      @ ChainRules ~/.julia/packages/ChainRules/RGbGv/src/rulesets/Base/indexing.jl:69
    [8] unthunk
      @ ~/.julia/packages/ChainRulesCore/0t04l/src/tangent_types/thunks.jl:204 [inlined]
    [9] unthunk(x::ChainRulesCore.InplaceableThunk{ChainRulesCore.Thunk{ChainRules.var"#1602#1604"{CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 2, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}}}, ChainRules.var"#1601#1603"{CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 2, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}}})
      @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/tangent_types/thunks.jl:237
   [10] wrap_chainrules_output
      @ ~/.julia/dev/Zygote/src/compiler/chainrules.jl:110 [inlined]
   [11] map
      @ ./tuple.jl:275 [inlined]
   [12] wrap_chainrules_output
      @ ~/.julia/dev/Zygote/src/compiler/chainrules.jl:111 [inlined]
   [13] (::Zygote.ZBack{ChainRules.var"#view_pullback#1612"{CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, Tuple{ChainRulesCore.NoTangent}}})(dy::CuArray{SVector{3, Float64}, 2, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/chainrules.jl:211
   [14] Pullback
      @ ~/.julia/dev/Molly/src/interactions/implicit_solvent.jl:642 [inlined]
   [15] (::Zygote.Pullback{Tuple{typeof(born_radii_and_grad), ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}}, Any})(Δ::Tuple{CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, CuArray{Float64, 2, CUDA.Mem.DeviceBuffer}})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [16] Pullback
      @ ~/.julia/dev/Molly/src/interactions/implicit_solvent.jl:1066 [inlined]
   [17] (::Zygote.Pullback{Tuple{Molly.var"##forces#173", Int64, typeof(forces), ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}, System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [18] Pullback
      @ ~/.julia/dev/Molly/src/interactions/implicit_solvent.jl:1065 [inlined]
   [19] (::Zygote.Pullback{Tuple{typeof(Core.kwcall), NamedTuple{(:n_threads,), Tuple{Int64}}, typeof(forces), ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}, System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [20] Pullback
      @ ~/.julia/dev/Molly/src/force.jl:337 [inlined]
   [21] (::Zygote.Pullback{Tuple{Molly.var"##forces#129", Int64, typeof(forces), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [22] Pullback
      @ ~/.julia/dev/Molly/src/force.jl:305 [inlined]
   [23] (::Zygote.Pullback{Tuple{typeof(Core.kwcall), NamedTuple{(:n_threads,), Tuple{Int64}}, typeof(forces), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [24] Pullback
      @ ~/.julia/dev/Molly/src/force.jl:23 [inlined]
   [25] (::Zygote.Pullback{Tuple{Molly.var"##accelerations#111", Int64, typeof(accelerations), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{Zygote.Pullback{Tuple{typeof(Core.kwcall), NamedTuple{(:n_threads,), Tuple{Int64}}, typeof(forces), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any}, Zygote.Pullback{Tuple{typeof(Base.Broadcast.materialize), CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}}, Tuple{}}, Zygote.Pullback{Tuple{Type{NamedTuple{(:n_threads,)}}, Tuple{Int64}}, Tuple{Zygote.Pullback{Tuple{Type{NamedTuple{(:n_threads,), Tuple{Int64}}}, Tuple{Int64}}, Tuple{Zygote.var"#2224#back#315"{Zygote.Jnew{NamedTuple{(:n_threads,), Tuple{Int64}}, Nothing, true}}}}}}, Zygote.Pullback{Tuple{typeof(Base.Broadcast.broadcasted), typeof(/), CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, Tuple{Zygote.var"#2017#back#204"{typeof(identity)}, Zygote.var"#2017#back#204"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.Broadcast.broadcastable), CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}}, Tuple{}}, Zygote.var"#2849#back#672"{Zygote.var"#map_back#666"{typeof(Base.Broadcast.broadcastable), 1, Tuple{Tuple{}}, Tuple{Val{0}}, Tuple{}}}, Zygote.var"#2173#back#293"{Zygote.var"#291#292"{Tuple{Tuple{Nothing, Nothing}, Tuple{}}, Zygote.var"#combine_styles_pullback#1166"{Tuple{Nothing, Nothing, Nothing}}}}, Zygote.Pullback{Tuple{typeof(Base.Broadcast.broadcastable), CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, Tuple{}}, Zygote.var"#2173#back#293"{Zygote.var"#291#292"{Tuple{NTuple{4, Nothing}, Tuple{}}, Molly.var"#1348#back#759"{Molly.var"#bc_fwd_back#527"{3, Float64, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, ForwardDiff.Dual{Nothing, Float64, 4}}, 1, CUDA.Mem.DeviceBuffer}}}}}}}, Zygote.var"#2017#back#204"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(masses), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{Zygote.var"#2184#back#303"{Zygote.var"#back#302"{:masses, Zygote.Context{false}, System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}}}}}})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [26] Pullback
      @ ~/.julia/dev/Molly/src/force.jl:22 [inlined]
   [27] (::Zygote.Pullback{Tuple{typeof(Core.kwcall), NamedTuple{(:n_threads,), Tuple{Int64}}, typeof(accelerations), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, NeighborList{CuArray{Tuple{Int32, Int32, Bool}, 1, CUDA.Mem.DeviceBuffer}}}, Any})(Δ::CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [28] Pullback
      @ ~/.julia/dev/Molly/src/simulators.jl:147 [inlined]
   [29] (::Zygote.Pullback{Tuple{Molly.var"##simulate!#204", Int64, Bool, typeof(simulate!), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, VelocityVerlet{Float64, RescaleThermostat{Float64}}, Int64}, Any})(Δ::Nothing)
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [30] Pullback
      @ ~/.julia/dev/Molly/src/simulators.jl:128 [inlined]
   [31] (::Zygote.Pullback{Tuple{typeof(Core.kwcall), NamedTuple{(:n_threads,), Tuple{Int64}}, typeof(simulate!), System{3, true, Float64, CuArray{Atom{Float64, Float64, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, CubicBoundary{Float64}, CuArray{SVector{3, Float64}, 1, CUDA.Mem.DeviceBuffer}, Vector{Any}, Nothing, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Tuple{InteractionList2Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicBond{Float32, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}}, Tuple{ImplicitSolventOBC{Float64, Float64, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Float64, Float64, Float64, CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}, SubArray{Float64, 2, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}, Tuple{CuArray{Int64, 2, CUDA.Mem.DeviceBuffer}}, false}}}, Tuple{}, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, Tuple{}, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}, CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}}, VelocityVerlet{Float64, RescaleThermostat{Float64}}, Int64}, Any})(Δ::Nothing)
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [32] Pullback
      @ ~/.julia/dev/Molly/test/zygote.jl:151 [inlined]
   [33] (::Zygote.Pullback{Tuple{var"#loss#41"{Bool, Bool, Bool, Bool, Bool, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, Vector{Float64}, CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Vector{SVector{3, ForwardDiff.Dual{Nothing, Float64, 1}}}, Vector{SVector{3, ForwardDiff.Dual{Nothing, Float64, 1}}}, Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}, VelocityVerlet{Float64, RescaleThermostat{Float64}}, CubicBoundary{Float64}, Float64, Int64, Int64, var"#mean_min_separation#30"{var"#abs2_vec#29"}}, Float64, Float64}, Any})(Δ::Float64)
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface2.jl:0
   [34] (::Zygote.var"#75#76"{Zygote.Pullback{Tuple{var"#loss#41"{Bool, Bool, Bool, Bool, Bool, DistanceNeighborFinder{CuArray{Bool, 2, CUDA.Mem.DeviceBuffer}, Float64}, InteractionList4Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{PeriodicTorsion{6, Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, InteractionList3Atoms{CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{HarmonicAngle{Float64, Float64}, 1, CUDA.Mem.DeviceBuffer}}, Vector{Float64}, CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, CuArray{Int32, 1, CUDA.Mem.DeviceBuffer}, Tuple{LennardJones{false, DistanceCutoff{Float64, Float64, Float64}, Int64, Int64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}, CoulombReactionField{Float64, Float64, Int64, Float64, Unitful.FreeUnits{(), NoDims, nothing}, Unitful.FreeUnits{(), NoDims, nothing}}}, Vector{SVector{3, ForwardDiff.Dual{Nothing, Float64, 1}}}, Vector{SVector{3, ForwardDiff.Dual{Nothing, Float64, 1}}}, Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}, VelocityVerlet{Float64, RescaleThermostat{Float64}}, CubicBoundary{Float64}, Float64, Int64, Int64, var"#mean_min_separation#30"{var"#abs2_vec#29"}}, Float64, Float64}, Any}})(Δ::Float64)
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface.jl:45
   [35] gradient(::Function, ::Float64, ::Vararg{Float64})
      @ Zygote ~/.julia/dev/Zygote/src/compiler/interface.jl:97
   [36] macro expansion
      @ ~/.julia/dev/Molly/test/zygote.jl:200 [inlined]
   [37] macro expansion
      @ ~/soft/julia/julia-1.9.2/share/julia/stdlib/v1.9/Test/src/Test.jl:1498 [inlined]
   [38] top-level scope
      @ ~/.julia/dev/Molly/test/zygote.jl:31
   [39] include(fname::String)
      @ Base.MainInclude ./client.jl:478
   [40] top-level scope
      @ ~/.julia/dev/Molly/test/runtests.jl:94
   [41] include(mod::Module, _path::String)
      @ Base ./Base.jl:457
   [42] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:307
   [43] _start()
      @ Base ./client.jl:522

@ToucheSir
Copy link
Member Author

Thanks for looking into this. It is possible to retroactively upper-bound the Zygote dep for older versions of Molly in the registry, but that would be more work and reduce future version compatibility quite a bit more than keeping the stub. I also don't know what the error you're running into could be, but we could always hold off on tagging until you've figured it out.

@jgreener64
Copy link
Contributor

I fixed the above issue so I think this PR should be merged and I can lower bound on the next Zygote release with the appropriate changes.

@jgreener64
Copy link
Contributor

Any chance this could be merged and tagged?

test/gradcheck.jl Outdated Show resolved Hide resolved
test/gradcheck.jl Outdated Show resolved Hide resolved
@ToucheSir ToucheSir merged commit fbe8271 into master Oct 25, 2023
9 of 12 checks passed
@ToucheSir ToucheSir deleted the bc/rm-getindex-adjoint branch October 25, 2023 19:07
@jgreener64
Copy link
Contributor

Thanks!

@devmotion devmotion mentioned this pull request Oct 26, 2023
@marius311
Copy link
Contributor

This finally kills a very long-standing fork I've been having to keep around for a project that needed this, thank you @ToucheSir!

@bicycle1885
Copy link

I'm not perfectly sure but this change might have caused a regression I reported here: JuliaML/MLUtils.jl#170.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

∇getindex mutates, causing issues with higher order AD over getindex.
7 participants