From 9950c2ca1b938f1dc61a9ec6bd473ec19439feb5 Mon Sep 17 00:00:00 2001 From: Abel Soares Siqueira Date: Mon, 20 May 2024 19:09:57 +0200 Subject: [PATCH] WIP --- src/selection.jl | 2 +- src/solve.jl | 12 +++++-- test/qp_tests.jl | 48 +++++++++++++++++++++------- test/runtests.jl | 81 +++++++++++++++++++++++++++++++++++------------- 4 files changed, 106 insertions(+), 37 deletions(-) diff --git a/src/selection.jl b/src/selection.jl index d42f638..3d18cff 100644 --- a/src/selection.jl +++ b/src/selection.jl @@ -57,7 +57,7 @@ There are 7 optimizers available: ``` """ function select_optimizers( - nlp::AbstractNLPModel{T, S}, + nlp::AbstractNLPModel{T, S}; verbose = 1, highest_derivative_available::Integer = 2, ) where {T, S} diff --git a/src/solve.jl b/src/solve.jl index 818a9da..4235dd3 100644 --- a/src/solve.jl +++ b/src/solve.jl @@ -4,7 +4,11 @@ function minimize( highest_derivative_available::Integer = 2, kwargs..., ) - select = select_optimizers(nlp, verbose, highest_derivative_available) + select = select_optimizers( + nlp; + verbose = verbose, + highest_derivative_available = highest_derivative_available, + ) (verbose ≥ 1) && println("Solve using $(first(select).name):") solver = first(select) return minimize(Val(Symbol(solver.name)), nlp; verbose = verbose, kwargs...) @@ -16,7 +20,11 @@ function minimize( highest_derivative_available::Integer = 2, kwargs..., ) - select = select_optimizers(nlp, verbose, highest_derivative_available) + select = select_optimizers( + nlp; + verbose = verbose, + highest_derivative_available = highest_derivative_available, + ) nls_select = select[select.specialized_nls, :] solver = if !isempty(nls_select) first(nls_select) diff --git a/test/qp_tests.jl b/test/qp_tests.jl index bcb861e..1088234 100644 --- a/test/qp_tests.jl +++ b/test/qp_tests.jl @@ -8,11 +8,17 @@ c0 = 1.0 x0 = [-1.2; 1.0] qp_model = QuadraticModel(c, H, c0 = c0, x0 = x0, name = "uncqp_QP") - stats = minimize(qp_model) + stats = with_logger(NullLogger()) do + minimize(qp_model) + end @test true - minimize(c, H, c0 = c0, x0 = x0, name = "uncqp_QP") + with_logger(NullLogger()) do + minimize(c, H, c0 = c0, x0 = x0, name = "uncqp_QP") + end @test true - minimize("RipQP", c, H, c0 = c0, x0 = x0, name = "uncqp_QP") + with_logger(NullLogger()) do + minimize("RipQP", c, H, c0 = c0, x0 = x0, name = "uncqp_QP") + end @test true end @@ -23,11 +29,17 @@ lvar = [0.0; 0.0] x0 = [0.5; 0.5] qp_model = QuadraticModel(c, H, lvar, uvar, x0 = x0, name = "bndqp_QP") - stats = minimize(qp_model) + stats = with_logger(NullLogger()) do + minimize(qp_model) + end @test true - minimize(c, H, lvar, uvar, x0 = x0, name = "bndqp_QP") + with_logger(NullLogger()) do + minimize(c, H, lvar, uvar, x0 = x0, name = "bndqp_QP") + end @test true - minimize("RipQP", c, H, lvar, uvar, x0 = x0, name = "bndqp_QP") + with_logger(NullLogger()) do + minimize("RipQP", c, H, lvar, uvar, x0 = x0, name = "bndqp_QP") + end @test true end @@ -40,11 +52,17 @@ lcon = [1.0] ucon = [1.0] qp_model = QuadraticModel(c, H, A, lcon, ucon, name = "eqconqp_QP") - stats = minimize(qp_model) + stats = with_logger(NullLogger()) do + minimize(qp_model) + end @test true - minimize(c, H, A, lcon, ucon, name = "eqconqp_QP") + with_logger(NullLogger()) do + minimize(c, H, A, lcon, ucon, name = "eqconqp_QP") + end @test true - minimize("RipQP", c, H, A, lcon, ucon, name = "eqconqp_QP") + with_logger(NullLogger()) do + minimize("RipQP", c, H, A, lcon, ucon, name = "eqconqp_QP") + end @test true end @@ -63,11 +81,17 @@ ucon = [Inf; 0.0; 1.0] x0 = ones(2) qp_model = QuadraticModel(c, H, A, lcon, ucon, c0 = c0, x0 = x0, name = "ineqconqp_QP") - stats = minimize(qp_model) + stats = with_logger(NullLogger()) do + minimize(qp_model) + end @test true - minimize(c, H, A, lcon, ucon, c0 = c0, x0 = x0, name = "ineqconqp_QP") + with_logger(NullLogger()) do + minimize(c, H, A, lcon, ucon, c0 = c0, x0 = x0, name = "ineqconqp_QP") + end @test true - minimize("RipQP", c, H, A, lcon, ucon, c0 = c0, x0 = x0, name = "ineqconqp_QP") + with_logger(NullLogger()) do + minimize("RipQP", c, H, A, lcon, ucon, c0 = c0, x0 = x0, name = "ineqconqp_QP") + end @test true end end diff --git a/test/runtests.jl b/test/runtests.jl index 538aa66..1a9d061 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,7 +2,7 @@ using JSOSuite # stdlib -using LinearAlgebra, SparseArrays, Test +using LinearAlgebra, Logging, SparseArrays, Test # others using JuMP, NLPModelsJuMP @@ -11,6 +11,7 @@ using JuMP, NLPModelsJuMP using ADNLPModels, NLPModels, NLSProblems, QuadraticModels, OptimizationProblems, SparseMatricesCOO using JSOSolvers, Percival, SolverCore +#= @testset "Test not loaded solvers" begin nlp = ADNLPModel(x -> sum(x), ones(2)) @@ -22,6 +23,7 @@ using JSOSolvers, Percival, SolverCore @test_throws ArgumentError minimize("RipQP", nlp) end +=# # optionals using KNITRO if KNITRO.has_knitro() @@ -30,17 +32,25 @@ end using CaNNOLeS, DCISolver, FletcherPenaltySolver, NLPModelsIpopt, RipQP using SolverBenchmark +default_solver_options = (verbose = 0,) +solver_options = Dict(:IpoptSolver => (print_level = 0,), :RipQP => ()) +get_solver_options(name) = get(solver_options, name, default_solver_options) + meta = OptimizationProblems.meta function test_in_place_solve(nlp, solver_name) pkg_name = JSOSuite.optimizers[JSOSuite.optimizers.name_solver .== solver_name, :name_pkg][1] pkg_name = replace(pkg_name, ".jl" => "") solver = eval(Meta.parse(pkg_name * ".$solver_name"))(nlp) - stats = solve!(solver, nlp) + stats = with_logger(NullLogger()) do + solve!(solver, nlp; get_solver_options(solver_name)...) + end @test stats.status == :first_order reset!(solver, nlp) stats = GenericExecutionStats(nlp) - solve!(solver, nlp, stats) + with_logger(NullLogger()) do + solve!(solver, nlp, stats; get_solver_options(solver_name)...) + end @test stats.status == :first_order end @@ -49,14 +59,19 @@ function test_in_place_solve(model::JuMP.Model, solver_name) pkg_name = JSOSuite.optimizers[JSOSuite.optimizers.name_solver .== solver_name, :name_pkg][1] pkg_name = replace(pkg_name, ".jl" => "") solver = eval(Meta.parse(pkg_name * ".$solver_name"))(nlp) - stats = solve!(solver, model) + stats = with_logger(NullLogger()) do + solve!(solver, model; get_solver_options(solver_name)...) + end @test stats.status == :first_order reset!(solver, nlp) stats = GenericExecutionStats(nlp) - solve!(solver, model, stats) + with_logger(NullLogger()) do + solve!(solver, model, stats; get_solver_options(solver_name)...) + end @test stats.status == :first_order end +#= @testset "Test in-place solve!" begin nlp = OptimizationProblems.ADNLPProblems.arglina() model = OptimizationProblems.PureJuMP.arglina() @@ -81,30 +96,46 @@ end end end end +=# include("qp_tests.jl") @testset "Test `Float32`" begin nlp = OptimizationProblems.ADNLPProblems.genrose(type = Val(Float32)) atol, rtol = √eps(Float32), √eps(Float32) - for solver in eachrow(JSOSuite.select_optimizers(nlp)) + for solver in eachrow(JSOSuite.select_optimizers(nlp, verbose = 0)) if solver.nonlinear_obj - minimize(solver.name, nlp, verbose = 0, atol = atol, rtol = rtol) + minimize( + solver.name, + nlp, + verbose = 0, + atol = atol, + rtol = rtol; + get_solver_options(solver_name)..., + ) @test true else nlp_qm = QuadraticModel(nlp, nlp.meta.x0) - minimize(solver.name, nlp_qm, verbose = 0, atol = atol, rtol = rtol) + minimize( + solver.name, + nlp_qm, + verbose = 0, + atol = atol, + rtol = rtol; + get_solver_options(solver_name)..., + ) @test true end end end +#= @testset "JSOSuite JuMP API" begin model = OptimizationProblems.PureJuMP.genrose() jum = MathOptNLPModel(model) - @test JSOSuite.select_optimizers(model) == JSOSuite.select_optimizers(jum) - for solver in eachrow(JSOSuite.select_optimizers(model)) - minimize(solver.name, model, verbose = 0) + @test JSOSuite.select_optimizers(model, verbose=0) == JSOSuite.select_optimizers(jum, verbose=0) + for solver in eachrow(JSOSuite.select_optimizers(model, verbose=0)) + minimize(solver.name, model, verbose = 0; get_solver_options(solver_name)...) @test true end end @@ -124,27 +155,27 @@ end @testset "Basic solve tests" begin f = x -> 100 * (x[2] - x[1]^2)^2 + (x[1] - 1)^2 - stats = minimize(f, [-1.2; 1.0], verbose = 0) + stats = minimize(f, [-1.2; 1.0], verbose = 0; get_solver_options(solver_name)...) @test stats.status_reliable && (stats.status == :first_order) - stats = minimize("DCISolver", f, [-1.2; 1.0], verbose = 0) + stats = minimize("DCISolver", f, [-1.2; 1.0], verbose = 0; get_solver_options(solver_name)...) @test stats.status_reliable && (stats.status == :first_order) F = x -> [10 * (x[2] - x[1]^2); x[1] - 1] - stats = minimize(F, [-1.2; 1.0], 2, verbose = 0) + stats = minimize(F, [-1.2; 1.0], 2, verbose = 0; get_solver_options(solver_name)...) @test stats.status_reliable && (stats.status == :first_order) - stats = minimize("DCISolver", F, [-1.2; 1.0], 2, verbose = 0) + stats = minimize("DCISolver", F, [-1.2; 1.0], 2, verbose = 0; get_solver_options(solver_name)...) @test stats.status_reliable && (stats.status == :first_order) end @testset "Test solve OptimizationProblems: $name" for name in first(meta[meta.nvar .< 10, :name], 5) name in ["bennett5", "channel", "hs253", "hs73", "misra1c"] && continue nlp = OptimizationProblems.ADNLPProblems.eval(Meta.parse(name))() - minimize(nlp, verbose = 0) + minimize(nlp, verbose = 0; get_solver_options(solver_name)...) @test true model = OptimizationProblems.PureJuMP.eval(Meta.parse(name))() - minimize(model, verbose = 0) + minimize(model, verbose = 0; get_solver_options(solver_name)...) @test true end @@ -169,7 +200,8 @@ for solver in eachrow(JSOSuite.optimizers) rtol = 1e-5, max_time = 12.0, max_eval = 10, - verbose = 0, + verbose = 0; + get_solver_options(solver_name)...) ) @test true else @@ -181,7 +213,8 @@ for solver in eachrow(JSOSuite.optimizers) rtol = 1e-5, max_time = 12.0, max_eval = 10, - verbose = 0, + verbose = 0; + get_solver_options(solver_name)...) ) @test true end @@ -208,7 +241,8 @@ end max_iter = 100, max_eval = 10, callback = callback, - verbose = 0, + verbose = 0; + get_solver_options(solver_name)...) ) @test true elseif solver.specialized_nls @@ -223,7 +257,8 @@ end max_iter = 100, max_eval = 10, callback = callback, - verbose = 0, + verbose = 0; + get_solver_options(solver_name)...) ) @test true else # RipQP @@ -237,10 +272,12 @@ end max_iter = 100, max_eval = 10, callback = callback, - verbose = 0, + verbose = 0; + get_solver_options(solver_name)...) ) @test true end end end end +=#