Skip to content

Conversation

@apkille
Copy link
Contributor

@apkille apkille commented Jun 24, 2025

I added a test suite that exhaustively checks automatic differentiation capabilities for each solver. With this PR, FiniteDiff.jl and ForwardDiff.jl are fully supported for schroedinger and master solvers (including their dynamic versions). I added DifferentiationInterface.jl as a test dependency to quickly test other autodiff libraries supported in Julia in the future (such as Zygote.jl and Enzyme.jl). In the future I will also add support for the stochastic, semi-classical, and Monte Carlo solvers.

One note: here I am simply testing whether or not each differentiation operation runs on each solver with random test cases. I'm open to testing for correctness within some numerical tolerance, but I'd imagine we'd have to be extremely careful that the hundreds of tests pass every time, particularly when we have a handful of autodiff libraries supported in the suite.

Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

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

On first pass, this looks awesome, thank you!

There are test failures though -- I have not looked into them, do you know how to address them?

@apkille
Copy link
Contributor Author

apkille commented Jun 28, 2025

Yes, I will do that soon, just got busy this week and didn't have time to deal with them :)

@Krastanov
Copy link
Member

I will mark this as a draft, just to organize my review queue a bit. Feel free to mark it back at any time.

@Krastanov Krastanov marked this pull request as draft August 17, 2025 20:55
@Krastanov Krastanov marked this pull request as ready for review November 28, 2025 16:37
Comment on lines +156 to +178
function _promote_time_and_state(u0, H::AbstractOperator, J, rates, tspan)
# TODO: Find an alternative to promote_dual, which was moved to
# an extension in DiffEqBase 6.162.0
ext = Base.get_extension(DiffEqBase, :DiffEqBaseForwardDiffExt)
Ts = reduce(ext.promote_dual, (eltype(H), DiffEqBase.anyeltypedual(J), DiffEqBase.anyeltypedual(rates)))
Tt = real(Ts)
p = Vector{Tt}(undef,0)
u0_promote = DiffEqBase.promote_u0(u0, p, tspan[1])
tspan_promote = DiffEqBase.promote_tspan(u0_promote.data, p, tspan, nothing, Dict{Symbol, Any}())
return tspan_promote, u0_promote
end
_promote_time_and_state(u0, f::Function, tspan) = _promote_time_and_state(u0, f(first(tspan)..., u0), tspan)
function _promote_time_and_state(u0, f::Union{Tuple, Vector}, tspan)
# TODO: Find an alternative to promote_dual, which was moved to
# an extension in DiffEqBase 6.162.0
ext = Base.get_extension(DiffEqBase, :DiffEqBaseForwardDiffExt)
Ts = reduce(ext.promote_dual, (eltype(f[1]), DiffEqBase.anyeltypedual.(f[2:end])...))
Tt = real(Ts)
p = Vector{Tt}(undef,0)
u0_promote = DiffEqBase.promote_u0(u0, p, tspan[1])
tspan_promote = DiffEqBase.promote_tspan(u0_promote.data, p, tspan, nothing, Dict{Symbol, Any}())
return tspan_promote, u0_promote
end
Copy link
Member

Choose a reason for hiding this comment

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

I think the piece of code linked below (that is based on something you provided) is currently the cleanest way to fix the issues stemming from promote_dual

https://github.com/qojulia/QuantumOptics.jl/pull/461/files#diff-7c2211b1dee4c04149fb91346494d2d7b8ac943a7a52c0b1b2d1c39e4ac351c9R139

@Krastanov
Copy link
Member

unmarked it from draft status to run the buildkite CI

@gdalle
Copy link

gdalle commented Nov 29, 2025

You might be interested in DifferentiationInterfaceTest.jl

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.

3 participants