Skip to content

Commit fb34d08

Browse files
reorganize test folders
1 parent 0d483a7 commit fb34d08

File tree

8 files changed

+335
-110
lines changed

8 files changed

+335
-110
lines changed

test/bpdn/test-bpdn-allocs.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Test non allocating solve!
2+
@testset "BPDN allocs" begin
3+
for (h, h_name) ((NormL0(λ), "l0"),)
4+
for (solver, solver_name) (
5+
(:R2Solver, "R2"),
6+
(:R2DHSolver, "R2DH"),
7+
(:R2NSolver, "R2N"),
8+
(:TRDHSolver, "TRDH"),
9+
(:TRSolver, "TR"),
10+
)
11+
@testset "$(solver_name)" begin
12+
(solver_name == "R2N" || solver_name == "TR") && continue #FIXME
13+
reg_nlp = RegularizedNLPModel(LBFGSModel(bpdn), h)
14+
solver = eval(solver)(reg_nlp)
15+
stats = RegularizedExecutionStats(reg_nlp)
16+
solver_name == "R2" && @test @wrappedallocs(
17+
solve!(solver, reg_nlp, stats, ν = 1.0, atol = 1e-6, rtol = 1e-6)
18+
) == 0
19+
solver_name == "R2DH" && @test @wrappedallocs(
20+
solve!(solver, reg_nlp, stats, σk = 1.0, atol = 1e-6, rtol = 1e-6)
21+
) == 0
22+
solver_name == "TRDH" &&
23+
@test @wrappedallocs(solve!(solver, reg_nlp, stats, atol = 1e-6, rtol = 1e-6)) ==
24+
0
25+
@test stats.status == :first_order
26+
end
27+
end
28+
29+
end
30+
31+
for (h, h_name) ((NormL0(λ), "l0"),)
32+
for (solver, solver_name) ((:LMSolver, "LM"),)
33+
@testset "$(solver_name)" begin
34+
solver_name == "LM" && continue #FIXME
35+
reg_nlp = RegularizedNLPModel(bpdn_nls, h)
36+
solver = eval(solver)(reg_nlp)
37+
stats = RegularizedExecutionStats(reg_nlp)
38+
@test @wrappedallocs(
39+
solve!(solver, reg_nlp, stats, σk = 1.0, atol = 1e-6, rtol = 1e-6)
40+
) == 0
41+
@test stats.status == :first_order
42+
end
43+
end
44+
end
45+
end

test/bpdn/test-bpdn-bounds.jl

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
const subsolver_options = deepcopy(options)
2+
TR_TRDH(args...; kwargs...) = TR(args...; subsolver = TRDHSolver, kwargs...)
3+
4+
for (mod, mod_name) ((x -> x, "exact"), (LSR1Model, "lsr1"), (LBFGSModel, "lbfgs"))
5+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"))
6+
for solver_sym (:TR, :R2, :TR_TRDH)
7+
solver_sym (:TR, :TR_TRDH) && mod_name == "exact" && continue
8+
solver_name = string(solver_sym)
9+
solver = eval(solver_sym)
10+
@testset "bpdn-with-bounds-$(mod_name)-$(solver_name)-$(h_name)" begin
11+
x0 = zeros(bpdn2.meta.nvar)
12+
p = randperm(bpdn2.meta.nvar)[1:nz]
13+
args = solver_sym == :R2 ? () : (NormLinf(1.0),)
14+
@test has_bounds(mod(bpdn2))
15+
out = solver(mod(bpdn2), h, args..., options; x0 = x0)
16+
@test typeof(out.solution) == typeof(bpdn2.meta.x0)
17+
@test length(out.solution) == bpdn2.meta.nvar
18+
@test typeof(out.dual_feas) == eltype(out.solution)
19+
@test out.status == :first_order
20+
end
21+
end
22+
end
23+
end
24+
25+
for (mod, mod_name) ((SpectralGradientModel, "spg"),)
26+
# ((DiagonalPSBModel, "psb"),(DiagonalAndreiModel, "andrei")) work but do not always terminate
27+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"))
28+
@testset "bpdn-with-bounds-$(mod_name)-TRDH-$(h_name)" begin
29+
x0 = zeros(bpdn2.meta.nvar)
30+
p = randperm(bpdn2.meta.nvar)[1:nz]
31+
χ = NormLinf(1.0)
32+
out = TRDH(mod(bpdn2), h, χ, options; x0 = x0)
33+
@test typeof(out.solution) == typeof(bpdn2.meta.x0)
34+
@test length(out.solution) == bpdn2.meta.nvar
35+
@test typeof(out.dual_feas) == eltype(out.solution)
36+
@test out.status == :first_order
37+
end
38+
end
39+
end
40+
41+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"))
42+
for solver_sym (:LMTR, :LM)
43+
solver_name = string(solver_sym)
44+
solver = eval(solver_sym)
45+
@testset "bpdn-with-bounds-ls-$(solver_name)-$(h_name)" begin
46+
x0 = zeros(bpdn_nls2.meta.nvar)
47+
args = solver_sym == :LM ? () : (NormLinf(1.0),)
48+
@test has_bounds(bpdn_nls2)
49+
out = solver(bpdn_nls2, h, args..., options, x0 = x0)
50+
@test typeof(out.solution) == typeof(bpdn.meta.x0)
51+
@test length(out.solution) == bpdn.meta.nvar
52+
@test typeof(out.dual_feas) == eltype(out.solution)
53+
@test out.status == :first_order
54+
end
55+
end
56+
end
57+
58+
# LMTR with TRDH as subsolver
59+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"))
60+
@testset "bpdn-with-bounds-ls-LMTR-$(h_name)-TRDH" begin
61+
x0 = zeros(bpdn_nls2.meta.nvar)
62+
@test has_bounds(bpdn_nls2)
63+
LMTR_out = LMTR(
64+
bpdn_nls2,
65+
h,
66+
NormLinf(1.0),
67+
options,
68+
x0 = x0,
69+
subsolver = TRDH,
70+
subsolver_options = subsolver_options,
71+
)
72+
@test typeof(LMTR_out.solution) == typeof(bpdn_nls2.meta.x0)
73+
@test length(LMTR_out.solution) == bpdn_nls2.meta.nvar
74+
@test typeof(LMTR_out.solver_specific[:Fhist]) == typeof(LMTR_out.solution)
75+
@test typeof(LMTR_out.solver_specific[:Hhist]) == typeof(LMTR_out.solution)
76+
@test typeof(LMTR_out.solver_specific[:SubsolverCounter]) == Array{Int, 1}
77+
@test typeof(LMTR_out.dual_feas) == eltype(LMTR_out.solution)
78+
@test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:Hhist])
79+
@test length(LMTR_out.solver_specific[:Fhist]) ==
80+
length(LMTR_out.solver_specific[:SubsolverCounter])
81+
@test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:NLSGradHist])
82+
@test LMTR_out.solver_specific[:NLSGradHist][end] ==
83+
bpdn_nls2.counters.neval_jprod_residual + bpdn_nls2.counters.neval_jtprod_residual - 1
84+
@test obj(bpdn_nls2, LMTR_out.solution) == LMTR_out.solver_specific[:Fhist][end]
85+
@test h(LMTR_out.solution) == LMTR_out.solver_specific[:Hhist][end]
86+
@test LMTR_out.status == :first_order
87+
end
88+
end
89+
90+
# LM with R2DH as subsolver
91+
for (h, h_name) ((NormL0(λ), "l0"),)
92+
@testset "bpdn-with-bounds-ls-LM-$(h_name)-R2DH" begin
93+
x0 = zeros(bpdn_nls2.meta.nvar)
94+
@test has_bounds(bpdn_nls2)
95+
LM_out = LM(bpdn_nls2, h, options, x0 = x0, subsolver = R2DHSolver)#, subsolver_options = subsolver_options)
96+
@test typeof(LM_out.solution) == typeof(bpdn.meta.x0)
97+
@test length(LM_out.solution) == bpdn.meta.nvar
98+
@test typeof(LM_out.dual_feas) == eltype(LM_out.solution)
99+
@test LM_out.status == :first_order
100+
end
101+
end

test/bpdn/test-bpdn.jl

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
compound = 1
2+
nz = 10 * compound
3+
options = ROSolverOptions= 1.0, β = 1e16, ϵa = 1e-6, ϵr = 1e-6, verbose = 10)
4+
bpdn, bpdn_nls, sol = bpdn_model(compound)
5+
bpdn2, bpdn_nls2, sol2 = bpdn_model(compound, bounds = true)
6+
λ = norm(grad(bpdn, zeros(bpdn.meta.nvar)), Inf) / 10
7+
8+
for (mod, mod_name) ((x -> x, "exact"), (LSR1Model, "lsr1"), (LBFGSModel, "lbfgs"))
9+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"), (IndBallL0(10 * compound), "B0"))
10+
for solver_sym (:R2, :TR)
11+
solver_sym == :TR && mod_name == "exact" && continue
12+
solver_sym == :TR && h_name == "B0" && continue # FIXME
13+
solver_name = string(solver_sym)
14+
solver = eval(solver_sym)
15+
@testset "bpdn-$(mod_name)-$(solver_name)-$(h_name)" begin
16+
x0 = zeros(bpdn.meta.nvar)
17+
p = randperm(bpdn.meta.nvar)[1:nz]
18+
x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
19+
args = solver_sym == :R2 ? () : (NormLinf(1.0),)
20+
out = solver(mod(bpdn), h, args..., options, x0 = x0)
21+
@test typeof(out.solution) == typeof(bpdn.meta.x0)
22+
@test length(out.solution) == bpdn.meta.nvar
23+
@test typeof(out.dual_feas) == eltype(out.solution)
24+
@test out.status == :first_order
25+
end
26+
end
27+
end
28+
end
29+
30+
for (mod, mod_name) ((SpectralGradientModel, "spg"),)
31+
# ((DiagonalPSBModel, "psb"),(DiagonalAndreiModel, "andrei")) work but do not always terminate
32+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1")) #, (IndBallL0(10 * compound), "B0"))
33+
@testset "bpdn-$(mod_name)-TRDH-$(h_name)" begin
34+
x0 = zeros(bpdn.meta.nvar)
35+
p = randperm(bpdn.meta.nvar)[1:nz]
36+
# x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
37+
χ = NormLinf(1.0)
38+
out = TRDH(mod(bpdn), h, χ, options, x0 = x0)
39+
@test typeof(out.solution) == typeof(bpdn.meta.x0)
40+
@test length(out.solution) == bpdn.meta.nvar
41+
@test typeof(out.dual_feas) == eltype(out.solution)
42+
@test out.status == :first_order
43+
end
44+
end
45+
end
46+
47+
# TR with h = L1 and χ = L2 is a special case
48+
for (mod, mod_name) ((LSR1Model, "lsr1"), (LBFGSModel, "lbfgs"))
49+
for (h, h_name) ((NormL1(λ), "l1"),)
50+
@testset "bpdn-$(mod_name)-TR-$(h_name)" begin
51+
x0 = zeros(bpdn.meta.nvar)
52+
p = randperm(bpdn.meta.nvar)[1:nz]
53+
x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
54+
TR_out = TR(mod(bpdn), h, NormL2(1.0), options, x0 = x0)
55+
@test typeof(TR_out.solution) == typeof(bpdn.meta.x0)
56+
@test length(TR_out.solution) == bpdn.meta.nvar
57+
@test typeof(TR_out.dual_feas) == eltype(TR_out.solution)
58+
@test TR_out.status == :first_order
59+
end
60+
end
61+
end
62+
63+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"), (IndBallL0(10 * compound), "B0"))
64+
for solver_sym (:LM, :LMTR)
65+
solver_name = string(solver_sym)
66+
solver = eval(solver_sym)
67+
solver_sym == :LMTR && h_name == "B0" && continue # FIXME
68+
@testset "bpdn-ls-$(solver_name)-$(h_name)" begin
69+
x0 = zeros(bpdn_nls.meta.nvar)
70+
p = randperm(bpdn_nls.meta.nvar)[1:nz]
71+
x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
72+
args = solver_sym == :LM ? () : (NormLinf(1.0),)
73+
out = solver(bpdn_nls, h, args..., options, x0 = x0)
74+
@test typeof(out.solution) == typeof(bpdn.meta.x0)
75+
@test length(out.solution) == bpdn.meta.nvar
76+
@test typeof(out.dual_feas) == eltype(out.solution)
77+
@test out.status == :first_order
78+
end
79+
end
80+
end
81+
82+
# LMTR with h = L1 and χ = L2 is a special case
83+
for (h, h_name) ((NormL1(λ), "l1"),)
84+
@testset "bpdn-ls-LMTR-$(h_name)" begin
85+
x0 = zeros(bpdn_nls.meta.nvar)
86+
p = randperm(bpdn_nls.meta.nvar)[1:nz]
87+
x0[p[1:nz]] = sign.(randn(nz)) # initial guess with nz nonzeros (necessary for h = B0)
88+
LMTR_out = LMTR(bpdn_nls, h, NormL2(1.0), options, x0 = x0)
89+
@test typeof(LMTR_out.solution) == typeof(bpdn_nls.meta.x0)
90+
@test length(LMTR_out.solution) == bpdn_nls.meta.nvar
91+
@test typeof(LMTR_out.solver_specific[:Fhist]) == typeof(LMTR_out.solution)
92+
@test typeof(LMTR_out.solver_specific[:Hhist]) == typeof(LMTR_out.solution)
93+
@test typeof(LMTR_out.solver_specific[:SubsolverCounter]) == Array{Int, 1}
94+
@test typeof(LMTR_out.dual_feas) == eltype(LMTR_out.solution)
95+
@test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:Hhist])
96+
@test length(LMTR_out.solver_specific[:Fhist]) ==
97+
length(LMTR_out.solver_specific[:SubsolverCounter])
98+
@test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:NLSGradHist])
99+
@test LMTR_out.solver_specific[:NLSGradHist][end] ==
100+
bpdn_nls.counters.neval_jprod_residual + bpdn_nls.counters.neval_jtprod_residual - 1
101+
@test obj(bpdn_nls, LMTR_out.solution) == LMTR_out.solver_specific[:Fhist][end]
102+
@test h(LMTR_out.solution) == LMTR_out.solver_specific[:Hhist][end]
103+
@test LMTR_out.status == :first_order
104+
end
105+
end
106+
107+
R2N_R2DH(args...; kwargs...) = R2N(args...; subsolver = R2DHSolver, kwargs...)
108+
for (mod, mod_name) (
109+
(SpectralGradientModel, "spg"),
110+
(DiagonalPSBModel, "psb"),
111+
(LSR1Model, "lsr1"),
112+
(LBFGSModel, "lbfgs"),
113+
)
114+
for (h, h_name) ((NormL0(λ), "l0"), (NormL1(λ), "l1"))
115+
for solver_sym (:R2DH, :R2N, :R2N_R2DH)
116+
solver_sym (:R2N, :R2N_R2DH) && mod_name ("spg", "psb") && continue
117+
solver_sym == :R2DH && mod_name != "spg" && continue
118+
solver_sym == :R2N_R2DH && h_name == "l1" && continue # this test seems to fail because s seems to be equal to zeros within the subsolver
119+
solver_name = string(solver_sym)
120+
solver = eval(solver_sym)
121+
@testset "bpdn-$(mod_name)-$(solver_name)-$(h_name)" begin
122+
x0 = zeros(bpdn.meta.nvar)
123+
out = solver(mod(bpdn), h, options, x0 = x0)
124+
@test typeof(out.solution) == typeof(bpdn.meta.x0)
125+
@test length(out.solution) == bpdn.meta.nvar
126+
@test typeof(out.dual_feas) == eltype(out.solution)
127+
@test out.status == :first_order
128+
end
129+
end
130+
end
131+
end

test/runtests.jl

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ using ADNLPModels,
1010
RegularizedOptimization,
1111
SolverCore
1212

13-
for (root, dirs, files) in walkdir(@__DIR__)
14-
for file in files
15-
if isnothing(match(r"^test-.*\.jl$", file))
16-
continue
17-
end
18-
title = titlecase(replace(splitext(file[6:end])[1], "-" => " "))
19-
@testset "$title" begin
20-
include(file)
21-
end
22-
end
23-
end
13+
Random.seed!(0)
14+
include("utils.jl")
15+
16+
include("test-AL.jl")
17+
18+
include("bpdn/test-bpdn.jl")
19+
include("bpdn/test-bpdn-bounds.jl")
20+
include("bpdn/test-bpdn-allocs.jl")

test/test-AL.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ problem_list = [:hs8]
1111
@test stats.dual_feas <= 1e-2
1212
@test length(stats.solution) == nlp.meta.nvar
1313
@test typeof(stats.solution) == typeof(nlp.meta.x0)
14+
15+
# Test allocations
16+
reg_nlp = RegularizedNLPModel(hs8(backend = :generic), h)
17+
solver = ALSolver(reg_nlp)
18+
stats = RegularizedExecutionStats(reg_nlp)
19+
#@test @wrappedallocs(solve!(solver, reg_nlp, stats, atol = 1e-3)) == 0 #FIXME
1420
end
15-
finalize(nlp)
1621
end
1722
end

0 commit comments

Comments
 (0)