Skip to content

Commit ba7d2bd

Browse files
arnavk23ChrisRackauckas
authored andcommitted
new changes to CUTEst benchmarks
1 parent ead71b0 commit ba7d2bd

File tree

8 files changed

+521
-417
lines changed

8 files changed

+521
-417
lines changed

Project.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,22 @@ version = "0.1.3"
55

66
[deps]
77
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
8+
CUTEst = "1b53aba6-35b6-5f92-a507-53c67d53f819"
89
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
910
Git = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2"
1011
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
1112
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
13+
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
1214
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
1315
OMJulia = "0f4fe800-344e-11e9-2949-fb537ad918e1"
16+
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
17+
OptimizationMOI = "fd9f6733-72f4-499f-8506-86b2bdd0dea1"
18+
OptimizationNLPModels = "064b21be-54cf-11ef-1646-cdfee32b588f"
19+
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
1420
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
21+
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
22+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
23+
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
1524
Weave = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
1625

1726
[compat]

benchmarks/OptimizationCUTEst/CUTEst_bounded.jmd

Lines changed: 85 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,36 @@ optimization routines. The wrapper
1212
to the problem collection, which we can leverage to test the optimizers made available by
1313
Optimization.jl.
1414

15-
This benchmark uses the following packages:
16-
1715

1816
```julia; eval = true; @setup
1917
using Pkg; Pkg.activate("."); Pkg.instantiate()
20-
```
21-
22-
```julia; eval = true
2318
using Optimization
2419
using OptimizationNLPModels
2520
using CUTEst
2621
using OptimizationOptimJL
22+
using OptimizationOptimisers
23+
using OptimizationOptimJL: LBFGS, ConjugateGradient, NelderMead, SimulatedAnnealing, ParticleSwarm
2724
using Ipopt
2825
using OptimizationMOI
2926
using OptimizationMOI: MOI as MOI
3027
using DataFrames
3128
using Plots
3229
using StatsPlots
3330
using StatsBase: countmap
34-
using OptimizationOptimJL: LBFGS, ConjugateGradient, NelderMead, SimulatedAnnealing, ParticleSwarm
3531

3632
optimizers = [
37-
("LBFGS", LBFGS()),
38-
("ConjugateGradient", ConjugateGradient()),
39-
("NelderMead", NelderMead()),
40-
("SimulatedAnnealing", SimulatedAnnealing()),
41-
("ParticleSwarm", ParticleSwarm()),
33+
("Ipopt", MOI.OptimizerWithAttributes(Ipopt.Optimizer,
34+
"max_iter" => 5000,
35+
"tol" => 1e-6,
36+
"print_level" => 5)),
4237
]
4338

4439
function get_stats(sol, optimizer_name)
45-
if hasfield(typeof(sol), :stats) && hasfield(typeof(sol.stats), :time)
46-
solve_time = sol.stats.time
47-
else
48-
solve_time = NaN
40+
# Robustly get solve_time, even if stats or time is missing
41+
solve_time = try
42+
hasfield(typeof(sol), :stats) && hasfield(typeof(sol.stats), :time) ? getfield(sol.stats, :time) : NaN
43+
catch
44+
NaN
4945
end
5046
return (length(sol.u), solve_time, optimizer_name, Symbol(sol.retcode))
5147
end
@@ -135,15 +131,22 @@ problems on this section.
135131

136132
```julia
137133
@info "before"
138-
eq_bou_problems = CUTEst.select_sif_problems(min_con=1, only_equ_con=true, only_free_var=false)
139-
@info "after1 - testing $(length(eq_bou_problems)) equality-constrained problems"
140134

141-
# Limit to first 50 problems for 100GB memory systems
142-
eq_bou_problems = eq_bou_problems[1:min(50, length(eq_bou_problems))]
143-
@info "Limited to $(length(eq_bou_problems)) problems for comprehensive testing"
135+
# Select a moderate subset of equality-constrained bounded problems for a realistic mix
136+
eq_bou_problems = CUTEst.select_sif_problems(min_con=1, only_equ_con=true, only_free_var=false)
137+
eq_bou_problems = eq_bou_problems[1:min(30, length(eq_bou_problems))]
138+
# Skip HIER13, BLOWEYA, LUKVLE8, READING2, NINENEW, READING6, DITTERT, CVXQP2, and MSS1 if present
139+
eq_bou_problems = filter(p -> !(lowercase(p) in ["hier13", "bloweya", "lukvle8", "patternne", "reading2", "ninenew", "reading6", "dittert", "cvxqp2", "mss1"]), eq_bou_problems)
140+
@info "Testing $(length(eq_bou_problems)) equality-constrained bounded problems (subset)"
144141

145142
# Analysis
146-
eq_bou_results = run_benchmarks(eq_bou_problems, optimizers)
143+
eq_bou_results = run_benchmarks(eq_bou_problems, optimizers; chunk_size=3)
144+
145+
total_attempts = nrow(eq_bou_results)
146+
successful_codes = [:Success, :MaxIters, :MaxTime, :FirstOrderOptimal]
147+
successful_results = filter(row -> row.retcode in successful_codes, eq_bou_results)
148+
successful_attempts = nrow(successful_results)
149+
success_rate = total_attempts > 0 ? round(successful_attempts / total_attempts * 100, digits=1) : 0
147150

148151
# Calculate and display success rates
149152
successful_codes = [:Success, :MaxIters, :MaxTime, :FirstOrderOptimal]
@@ -152,56 +155,94 @@ total_attempts = nrow(eq_bou_results)
152155
successful_attempts = nrow(successful_results)
153156
success_rate = total_attempts > 0 ? round(successful_attempts / total_attempts * 100, digits=1) : 0
154157

155-
@info "SUCCESS RATE ANALYSIS:"
156-
@info "Total attempts: $(total_attempts)"
157-
@info "Successful attempts: $(successful_attempts)"
158-
@info "Success rate: $(success_rate)%"
159-
160-
@info "after2"
158+
println("Full results table for equality-constrained bounded problems:")
159+
display(eq_bou_results)
160+
161+
println("SUCCESS RATE ANALYSIS (Equality Constrained, Bounded):")
162+
println("Total attempts: ", total_attempts)
163+
println("Successful attempts: ", successful_attempts)
164+
println("Success rate: ", success_rate, "%")
165+
println("Return code distribution:")
166+
if total_attempts > 0
167+
for (code, count) in sort(collect(pairs(countmap(eq_bou_results.retcode))), by=x->x[2], rev=true)
168+
println(" ", code, ": ", count, " occurrences")
169+
end
170+
else
171+
println(" No results to analyze")
172+
end
161173

162-
@df eq_bou_results scatter(:n_vars, :secs,
174+
if nrow(eq_bou_results) > 0
175+
@df eq_bou_results scatter(:n_vars, :secs,
163176
group = :solver,
164177
xlabel = "n. variables",
165178
ylabel = "secs.",
166179
title = "Time to solution by optimizer and number of vars",
167180
)
168-
@info "after3"
181+
println("Plotted equality-constrained bounded results.")
182+
else
183+
println("No equality-constrained bounded results to plot. DataFrame is empty.")
184+
println("Attempted problems:")
185+
println(eq_bou_problems)
186+
end
169187
```
170188

171189
Next, we examine the same relationship for inequality-constrained problems.
172190

173191
```julia
174192
@info "after4"
175-
neq_bou_problems = CUTEst.select_sif_problems(min_con=1, only_ineq_con=true, only_free_var=false)
176-
@info "after5 - testing $(length(neq_bou_problems)) inequality-constrained problems"
177193

178-
# Limit to first 50 problems for 100GB memory systems
179-
neq_bou_problems = neq_bou_problems[1:min(50, length(neq_bou_problems))]
180-
@info "Limited to $(length(neq_bou_problems)) problems for comprehensive testing"
194+
# Select a moderate subset of inequality-constrained bounded problems for a realistic mix
195+
neq_bou_problems = CUTEst.select_sif_problems(min_con=1, only_ineq_con=true, only_free_var=false)
196+
neq_bou_problems = neq_bou_problems[1:min(30, length(neq_bou_problems))]
197+
# Skip HIER13, BLOWEYA, CHARDIS1, LUKVLE8, READING2, CVPXQ2, and MSS1 if present (in case they appear in this list too)
198+
neq_bou_problems = filter(p -> !(lowercase(p) in ("chardis1", "hs67", "hs101", "haifal", "himmelp2", "hanging", "synthes1", "lukvli13", "liswet9", "hs85", "lukvli7", "expfita", "s268")), neq_bou_problems)
199+
@info "Testing $(length(neq_bou_problems)) inequality-constrained bounded problems (subset)"
181200

182201
# Analysis
183-
neq_bou_results = run_benchmarks(neq_bou_problems, optimizers)
202+
neq_bou_results = run_benchmarks(neq_bou_problems, optimizers; chunk_size=3)
184203

185-
# Calculate and display success rates
204+
total_attempts = nrow(neq_bou_results)
186205
successful_codes = [:Success, :MaxIters, :MaxTime, :FirstOrderOptimal]
187206
successful_results = filter(row -> row.retcode in successful_codes, neq_bou_results)
188-
total_attempts = nrow(neq_bou_results)
189207
successful_attempts = nrow(successful_results)
190208
success_rate = total_attempts > 0 ? round(successful_attempts / total_attempts * 100, digits=1) : 0
191209

192-
@info "INEQUALITY CONSTRAINED SUCCESS RATE: $(success_rate)% ($(successful_attempts)/$(total_attempts))"
210+
# Calculate and display success rates
211+
successful_codes = [:Success, :MaxIters, :MaxTime, :FirstOrderOptimal]
212+
successful_results = filter(row -> row.retcode in successful_codes, neq_bou_results)
213+
total_attempts = nrow(neq_bou_results)
214+
successful_attempts = nrow(successful_results)
215+
success_rate = total_attempts > 0 ? round(successful_attempts / total_attempts * 100, digits=1) : 0
193216

194-
@info "after6"
217+
println("Full results table for inequality-constrained bounded problems:")
218+
display(neq_bou_results)
219+
220+
println("SUCCESS RATE ANALYSIS (Inequality Constrained, Bounded):")
221+
println("Total attempts: ", total_attempts)
222+
println("Successful attempts: ", successful_attempts)
223+
println("Success rate: ", success_rate, "%")
224+
println("Return code distribution:")
225+
if total_attempts > 0
226+
for (code, count) in sort(collect(pairs(countmap(neq_bou_results.retcode))), by=x->x[2], rev=true)
227+
println(" ", code, ": ", count, " occurrences")
228+
end
229+
else
230+
println(" No results to analyze")
231+
end
195232

196-
@df neq_bou_results scatter(:n_vars, :secs,
233+
if nrow(neq_bou_results) > 0
234+
@df neq_bou_results scatter(:n_vars, :secs,
197235
group = :solver,
198236
xlabel = "n. variables",
199237
ylabel = "secs.",
200238
title = "Time to solution by optimizer and number of vars",
201239
)
240+
println("Plotted inequality-constrained bounded results.")
241+
else
242+
println("No inequality-constrained bounded results to plot. DataFrame is empty.")
243+
println("Attempted problems:")
244+
println(neq_bou_problems)
245+
end
202246
```
203247

204-
```julia, echo = false
205-
using SciMLBenchmarks
206-
SciMLBenchmarks.bench_footer(WEAVE_ARGS[:folder],WEAVE_ARGS[:file])
207-
```
248+

0 commit comments

Comments
 (0)