Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,18 @@ ADTypes = "1.9"
CommonSolve = "0.2.4"
ConcreteStructs = "0.2.3"
DifferentiationInterface = "0.6.2, 0.7"
ExplicitImports = "1.14.0"
FastClosures = "0.3.2"
FiniteDiff = "2.24.0"
ForwardDiff = "0.10.36, 1"
Hwloc = "3"
InteractiveUtils = "<0.0.1, 1"
LineSearches = "7.3.0"
LinearAlgebra = "1.10"
MaybeInplace = "0.1.4"
NonlinearProblemLibrary = "0.1.2"
PrecompileTools = "1.2.0"
ReTestItems = "1.28.0"
ReverseDiff = "1.15.3"
SafeTestsets = "0.1, 1"
SciMLBase = "2.54.0, 3.0"
SciMLJacobianOperators = "0.1"
SciMLTesting = "1"
StaticArraysCore = "1.4"
Test = "1.10"
Tracker = "0.2.35"
Expand All @@ -49,18 +46,15 @@ julia = "1.10"

[extras]
DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63"
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Hwloc = "0e44f5e4-bd66-52a0-8798-143a42290a1d"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
NonlinearProblemLibrary = "b7050fa9-e91f-4b37-bcee-a89a063da141"
ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823"
ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

[targets]
test = ["DifferentiationInterface", "ExplicitImports", "FiniteDiff", "ForwardDiff", "Hwloc", "InteractiveUtils", "LineSearches", "NonlinearProblemLibrary", "ReTestItems", "ReverseDiff", "Test", "Tracker", "Zygote"]
test = ["DifferentiationInterface", "FiniteDiff", "ForwardDiff", "LineSearches", "ReverseDiff", "SafeTestsets", "SciMLTesting", "Test", "Tracker", "Zygote"]
118 changes: 35 additions & 83 deletions test/custom_optimizer_tests.jl
Original file line number Diff line number Diff line change
@@ -1,108 +1,60 @@
# Test based on https://julianlsolvers.github.io/LineSearches.jl/stable/examples/generated/customoptimizer.html
# Note: Enzyme tests are in a separate test group (test/enzyme/)
@testsetup module CustomOptimizer
using LinearAlgebra, SciMLBase, LineSearch, SciMLJacobianOperators

function gradient_descent(
prob, alg; g_atol::Real = 1.0e-5, maxiters::Int = 10000, autodiff = nothing
)
u = copy(prob.u0)
if SciMLBase.isinplace(prob)
fu = similar(u)
prob.f(fu, u, prob.p)
else
fu = prob.f(u, prob.p)
end

ls_cache = init(prob, alg, fu, u)
vjp_op = VecJacOperator(prob, fu, u; autodiff)

alphas = Float64[]
iter = 0
for _ in 1:maxiters
iter += 1
svjp_op = StatefulJacobianOperator(vjp_op, u, prob.p)
gs = svjp_op * fu .* 2
δu = -gs
# Note: Enzyme tests are in a separate test group (test/enzyme/), LineSearches.jl tests in test/linesearchesjl/
using LineSearch, Test

ls_sol = solve!(ls_cache, u, δu)

push!(alphas, ls_sol.step_size)
@. u = u + ls_sol.step_size * δu
gnorm = norm(gs)
module CustomOptimizer
using LinearAlgebra, SciMLBase, LineSearch, SciMLJacobianOperators

function gradient_descent(
prob, alg; g_atol::Real = 1.0e-5, maxiters::Int = 10000, autodiff = nothing
)
u = copy(prob.u0)
if SciMLBase.isinplace(prob)
fu = similar(u)
prob.f(fu, u, prob.p)
else
fu = prob.f(u, prob.p)
end

LineSearch.callback_into_cache!(ls_cache, fu)
ls_cache = init(prob, alg, fu, u)
vjp_op = VecJacOperator(prob, fu, u; autodiff)

gnorm < g_atol && break
end
alphas = Float64[]
iter = 0
for _ in 1:maxiters
iter += 1
svjp_op = StatefulJacobianOperator(vjp_op, u, prob.p)
gs = svjp_op * fu .* 2
δu = -gs

return fu, u, iter, alphas
end
ls_sol = solve!(ls_cache, u, δu)

export gradient_descent
push!(alphas, ls_sol.step_size)
@. u = u + ls_sol.step_size * δu
gnorm = norm(gs)

end
if SciMLBase.isinplace(prob)
fu = similar(u)
prob.f(fu, u, prob.p)
else
fu = prob.f(u, prob.p)
end

@testitem "LineSearches.jl: Custom Optimizer" tags = [:linesearchesjl] setup = [CustomOptimizer] begin
using LineSearches, SciMLBase
using ADTypes, Tracker, ForwardDiff, Zygote, ReverseDiff, FiniteDiff
LineSearch.callback_into_cache!(ls_cache, fu)

@testset "OOP Problem" begin
nlf(x, p) = [p[1] - x[1], 10.0 * (x[2] - x[1]^2)]
nlp = NonlinearProblem(nlf, [-1.0, 1.0], [1.0])

@testset for autodiff in (
AutoTracker(), AutoForwardDiff(), AutoZygote(),
AutoReverseDiff(), AutoFiniteDiff(),
)
@testset "method: $(nameof(typeof(method)))" for method in (
LineSearches.BackTracking(; order = 3),
StrongWolfe(),
HagerZhang(),
MoreThuente(),
)
linesearch = LineSearchesJL(; method, autodiff)
fu, u, iter, alphas = gradient_descent(nlp, linesearch; autodiff)

@test fu ≈ [0.0, 0.0] atol = 1.0e-2
@test u ≈ [1.0, 1.0] atol = 1.0e-2
@test !all(isone, alphas)
end
gnorm < g_atol && break
end
end

@testset "In-Place Problem" begin
nlf(dx, x, p) = (dx .= [p[1] - x[1], 10.0 * (x[2] - x[1]^2)])
nlp = NonlinearProblem(nlf, [-1.0, 1.0], [1.0])
return fu, u, iter, alphas
end

@testset for autodiff in (
AutoForwardDiff(), AutoReverseDiff(), AutoFiniteDiff(),
)
@testset "method: $(nameof(typeof(method)))" for method in (
LineSearches.BackTracking(; order = 3),
StrongWolfe(),
HagerZhang(),
MoreThuente(),
)
linesearch = LineSearchesJL(; method, autodiff)
fu, u, iter, alphas = gradient_descent(nlp, linesearch; autodiff)
export gradient_descent

@test fu ≈ [0.0, 0.0] atol = 1.0e-2
@test u ≈ [1.0, 1.0] atol = 1.0e-2
@test !all(isone, alphas)
end
end
end
end

@testitem "Native Line Search: Custom Optimizer" tags = [:core] setup = [CustomOptimizer] begin
using .CustomOptimizer

@testset "Native Line Search: Custom Optimizer" begin
using SciMLBase
using ADTypes, Tracker, ForwardDiff, Zygote, ReverseDiff, FiniteDiff

Expand Down
107 changes: 107 additions & 0 deletions test/linesearchesjl/custom_optimizer_tests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# LineSearches.jl extension: custom optimizer tests
# Based on https://julianlsolvers.github.io/LineSearches.jl/stable/examples/generated/customoptimizer.html
using LineSearch, Test

module CustomOptimizer
using LinearAlgebra, SciMLBase, LineSearch, SciMLJacobianOperators

function gradient_descent(
prob, alg; g_atol::Real = 1.0e-5, maxiters::Int = 10000, autodiff = nothing
)
u = copy(prob.u0)
if SciMLBase.isinplace(prob)
fu = similar(u)
prob.f(fu, u, prob.p)
else
fu = prob.f(u, prob.p)
end

ls_cache = init(prob, alg, fu, u)
vjp_op = VecJacOperator(prob, fu, u; autodiff)

alphas = Float64[]
iter = 0
for _ in 1:maxiters
iter += 1
svjp_op = StatefulJacobianOperator(vjp_op, u, prob.p)
gs = svjp_op * fu .* 2
δu = -gs

ls_sol = solve!(ls_cache, u, δu)

push!(alphas, ls_sol.step_size)
@. u = u + ls_sol.step_size * δu
gnorm = norm(gs)

if SciMLBase.isinplace(prob)
fu = similar(u)
prob.f(fu, u, prob.p)
else
fu = prob.f(u, prob.p)
end

LineSearch.callback_into_cache!(ls_cache, fu)

gnorm < g_atol && break
end

return fu, u, iter, alphas
end

export gradient_descent

end

using .CustomOptimizer

@testset "LineSearches.jl: Custom Optimizer" begin
using LineSearches, SciMLBase
using ADTypes, Tracker, ForwardDiff, Zygote, ReverseDiff, FiniteDiff

@testset "OOP Problem" begin
nlf(x, p) = [p[1] - x[1], 10.0 * (x[2] - x[1]^2)]
nlp = NonlinearProblem(nlf, [-1.0, 1.0], [1.0])

@testset for autodiff in (
AutoTracker(), AutoForwardDiff(), AutoZygote(),
AutoReverseDiff(), AutoFiniteDiff(),
)
@testset "method: $(nameof(typeof(method)))" for method in (
LineSearches.BackTracking(; order = 3),
StrongWolfe(),
HagerZhang(),
MoreThuente(),
)
linesearch = LineSearchesJL(; method, autodiff)
fu, u, iter, alphas = gradient_descent(nlp, linesearch; autodiff)

@test fu ≈ [0.0, 0.0] atol = 1.0e-2
@test u ≈ [1.0, 1.0] atol = 1.0e-2
@test !all(isone, alphas)
end
end
end

@testset "In-Place Problem" begin
nlf(dx, x, p) = (dx .= [p[1] - x[1], 10.0 * (x[2] - x[1]^2)])
nlp = NonlinearProblem(nlf, [-1.0, 1.0], [1.0])

@testset for autodiff in (
AutoForwardDiff(), AutoReverseDiff(), AutoFiniteDiff(),
)
@testset "method: $(nameof(typeof(method)))" for method in (
LineSearches.BackTracking(; order = 3),
StrongWolfe(),
HagerZhang(),
MoreThuente(),
)
linesearch = LineSearchesJL(; method, autodiff)
fu, u, iter, alphas = gradient_descent(nlp, linesearch; autodiff)

@test fu ≈ [0.0, 0.0] atol = 1.0e-2
@test u ≈ [1.0, 1.0] atol = 1.0e-2
@test !all(isone, alphas)
end
end
end
end
Loading
Loading