Skip to content

Commit 03362a0

Browse files
aldmadpo
authored andcommitted
add callback
1 parent 3df8f2a commit 03362a0

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

examples/demo-cutest.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,11 @@ solver = ALSolver(regnlp)
2929
stats = solve!(solver, regnlp, stats, atol = 1e-6, verbose = 1)
3030
print(stats)
3131

32+
callback =
33+
(regnlp, solver, stats) -> begin
34+
@info "iter $(stats.iter), obj $(stats.objective), status $(stats.status)"
35+
end
36+
stats = AL(nlp, h, atol = 1e-6, verbose = 1, callback = callback)
37+
print(stats)
38+
3239
finalize(nlp)

src/AL_alg.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ If adopted, the Hessian is accessed as an abstract operator and need not be the
120120
# Output
121121
122122
- `stats::GenericExecutionStats`: solution and other info, see `SolverCore.jl`.
123+
124+
# Callback
125+
The callback is called at each iteration.
126+
The expected signature of the callback is `callback(nlp, solver, stats)`, and its output is ignored.
127+
Changing any of the input arguments will affect the subsequent iterations.
128+
In particular, setting `stats.status = :user` will stop the algorithm.
129+
All relevant information should be available in `reg_nlp` and `solver`.
130+
Notably, you can access, and modify, the following:
131+
- `solver.x`: current iterate;
132+
- `solver.y`: current dual estimate;
133+
- `stats`: structure holding the output of the algorithm (`GenericExecutionStats`), which contains, among other things:
134+
- `stats.iter`: current iteration counter;
135+
- `stats.objective`: current objective function value;
136+
- `stats.status`: current status of the algorithm. Should be `:unknown` unless the algorithm has attained a stopping criterion. Changing this to anything will stop the algorithm, but you should use `:user` to properly indicate the intention;
137+
- `stats.elapsed_time`: elapsed time in seconds.
123138
"""
124139
mutable struct ALSolver{T, V, M, ST} <: AbstractOptimizationSolver
125140
x::V
@@ -173,6 +188,7 @@ function SolverCore.solve!(
173188
solver::ALSolver{T, V},
174189
reg_nlp::AbstractRegularizedNLPModel{T, V},
175190
stats::GenericExecutionStats{T, V};
191+
callback = (args...) -> nothing,
176192
x::V = reg_nlp.model.meta.x0,
177193
y::V = reg_nlp.model.meta.y0,
178194
atol::T = eps(T),
@@ -252,6 +268,8 @@ function SolverCore.solve!(
252268
@info log_row(Any[iter, subiters, objx, cviol, mu, norm(solver.y), subtol])
253269
end
254270

271+
callback(reg_nlp, solver, stats)
272+
255273
while !done
256274
iter += 1
257275

@@ -324,6 +342,8 @@ function SolverCore.solve!(
324342
),
325343
)
326344

345+
callback(reg_nlp, solver, stats)
346+
327347
done = stats.status != :unknown
328348

329349
if verbose > 0 && (mod(stats.iter, verbose) == 0 || done)

0 commit comments

Comments
 (0)