Skip to content

Commit 33d0800

Browse files
add test solver function
1 parent 80979c4 commit 33d0800

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ using ProximalOperators
44
using ADNLPModels,
55
OptimizationProblems,
66
OptimizationProblems.ADNLPProblems,
7+
ManualNLPModels,
78
NLPModels,
89
NLPModelsModifiers,
910
RegularizedProblems,
@@ -19,6 +20,8 @@ const global bpdn2, bpdn_nls2, sol2 = bpdn_model(compound, bounds = true)
1920
const global λ = norm(grad(bpdn, zeros(bpdn.meta.nvar)), Inf) / 10
2021

2122
include("utils.jl")
23+
include("test-solver.jl")
24+
2225
include("test_AL.jl")
2326

2427
for (mod, mod_name) ((x -> x, "exact"), (LSR1Model, "lsr1"), (LBFGSModel, "lbfgs"))

test/test-solver.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function test_solver(reg_nlp::R, solver_name::String; expected_status = :first_order, solver_constructor_kwargs = (;), solver_kwargs = (;)) where{R}
2+
3+
# Test output with allocating calling form
4+
solver_fun = getfield(RegularizedOptimization, Symbol(solver_name))
5+
stats_basic = solver_fun(reg_nlp.model, reg_nlp.h, ROSolverOptions(); solver_constructor_kwargs..., solver_kwargs...)
6+
7+
x0 = get(solver_kwargs, :x0, reg_nlp.model.meta.x0)
8+
@test typeof(stats_basic.solution) == typeof(x0)
9+
@test length(stats_basic.solution) == reg_nlp.model.meta.nvar
10+
@test typeof(stats_basic.dual_feas) == eltype(stats_basic.solution)
11+
@test stats_basic.status == expected_status
12+
@test obj(reg_nlp, stats_basic.solution) == stats_basic.objective
13+
@test stats_basic.objective <= obj(reg_nlp, x0)
14+
15+
# Test output with optimized calling form
16+
solver_constructor = getfield(RegularizedOptimization, Symbol(solver_name*"Solver"))
17+
solver = solver_constructor(reg_nlp; solver_constructor_kwargs...)
18+
stats_optimized = RegularizedExecutionStats(reg_nlp)
19+
20+
# Remove the x0 entry from solver_kwargs
21+
optimized_solver_kwargs = Base.structdiff(solver_kwargs, NamedTuple{(:x0,)})
22+
solve!(solver, reg_nlp, stats_optimized; x = x0, optimized_solver_kwargs...) # It would be interesting to check for allocations here as well but depending on
23+
# the structure of solver_kwargs, some variables might get boxed, resulting in
24+
# false positives, for example if tol = 1e-3; solver_kwargs = (atol = tol),
25+
# then wrappedallocs would give a > 0 answer...
26+
@test typeof(stats_optimized.solution) == typeof(x0)
27+
@test length(stats_optimized.solution) == reg_nlp.model.meta.nvar
28+
@test typeof(stats_optimized.dual_feas) == eltype(stats_optimized.solution)
29+
@test stats_optimized.status == expected_status
30+
@test obj(reg_nlp, stats_optimized.solution) == stats_optimized.objective
31+
@test stats_optimized.objective <= obj(reg_nlp, x0)
32+
33+
# TODO: test that the optimized entries in stats_optimized and stats_basic are the same.
34+
35+
end

0 commit comments

Comments
 (0)