Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ext/SolverCoreNLPModelsExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ function SolverCore.GenericExecutionStats(
multipliers_L::V = similar(nlp.meta.y0, has_bounds(nlp) ? nlp.meta.nvar : 0),
multipliers_U::V = similar(nlp.meta.y0, has_bounds(nlp) ? nlp.meta.nvar : 0),
iter::Int = -1,
step_status::Symbol = :unknown,
elapsed_time::Real = Inf,
solver_specific::Dict{Symbol, Tsp} = Dict{Symbol, Any}(),
) where {T, S, V, Tsp}
Expand All @@ -101,6 +102,8 @@ function SolverCore.GenericExecutionStats(
false,
iter,
false,
step_status,
false,
elapsed_time,
false,
solver_specific,
Expand Down
57 changes: 56 additions & 1 deletion src/stats.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ export AbstractExecutionStats,
set_constraint_multipliers!,
set_bounds_multipliers!,
set_iter!,
set_step_status!,
set_time!,
broadcast_solver_specific!,
Comment thread
tmigot marked this conversation as resolved.
set_solver_specific!,
statsgetfield,
statshead,
statsline,
getStatus,
show_statuses
show_statuses,
show_step_statuses

const STATUSES = Dict(
:exception => "unhandled exception",
Expand Down Expand Up @@ -62,6 +64,32 @@ function show_statuses()
end
end

const STEP_STATUSES =
Dict(:unknown => "unknown", :accepted => "step accepted", :rejected => "step rejected")

function check_step_status(step_status::Symbol)
if !(step_status in keys(STEP_STATUSES))
@error "step_status $step_status is not a valid step status. Use one of the following: " join(
keys(STEP_STATUSES),
", ",
)
throw(KeyError(step_status))
end
end

"""
show_step_statuses()

Show the list of available step statuses to use with `GenericExecutionStats`.
"""
function show_step_statuses()
println("STEP_STATUSES:")
for k in keys(STEP_STATUSES) |> collect |> sort
v = STEP_STATUSES[k]
@printf(" :%-10s => %s\n", k, v)
end
end

abstract type AbstractExecutionStats end

"""
Expand All @@ -79,6 +107,7 @@ It contains the following fields:
- `multipliers_L`: The Lagrange multipliers wrt to the lower bounds on the variables (default: an uninitialized vector like `nlp.meta.x0` if there are bounds, or a zero-length vector if not);
- `multipliers_U`: The Lagrange multipliers wrt to the upper bounds on the variables (default: an uninitialized vector like `nlp.meta.x0` if there are bounds, or a zero-length vector if not);
- `iter`: The number of iterations computed by the solver (default: `-1`);
- `step_status`: The status of the most recently computed step. Use show_step_statuses() for the full list (default: `:unknown`);
- `elapsed_time`: The elapsed time computed by the solver (default: `Inf`);
- `solver_specific::Dict{Symbol,Any}`: A solver specific dictionary.

Expand All @@ -94,6 +123,7 @@ The following fields indicate whether the information above has been updated and
- `multipliers_reliable` (for `multipliers`)
- `bounds_multipliers_reliable` (for `multipliers_L` and `multipliers_U`)
- `iter_reliable`
- `step_status_reliable`
- `time_reliable`
- `solver_specific_reliable`.

Expand Down Expand Up @@ -127,6 +157,8 @@ mutable struct GenericExecutionStats{T, S, V, Tsp} <: AbstractExecutionStats
multipliers_U::V # zU
iter_reliable::Bool
iter::Int
step_status_reliable::Bool
step_status::Symbol
time_reliable::Bool
elapsed_time::Float64
solver_specific_reliable::Bool
Expand All @@ -143,6 +175,7 @@ function GenericExecutionStats{T, S, V, Tsp}(;
multipliers_L::V = V(),
multipliers_U::V = V(),
iter::Int = -1,
step_status::Symbol = :unknown,
elapsed_time::Real = Inf,
solver_specific::Dict{Symbol, Tsp} = Dict{Symbol, Any}(),
) where {T, S, V, Tsp}
Expand All @@ -165,6 +198,8 @@ function GenericExecutionStats{T, S, V, Tsp}(;
false,
iter,
false,
step_status,
false,
elapsed_time,
false,
solver_specific,
Expand All @@ -187,6 +222,7 @@ function reset!(stats::GenericExecutionStats{T, S, V, Tsp}) where {T, S, V, Tsp}
stats.multipliers_reliable = false
stats.bounds_multipliers_reliable = false
stats.iter_reliable = false
stats.step_status_reliable = false
stats.time_reliable = false
stats.solver_specific_reliable = false
stats
Expand Down Expand Up @@ -314,6 +350,18 @@ function set_iter!(stats::GenericExecutionStats, iter::Int)
stats
end

"""
set_step_status!(stats::GenericExecutionStats, step_status::Symbol)

Register `step_status` as most recent step status in `stats` and mark it as reliable.
"""
function set_step_status!(stats::GenericExecutionStats, step_status::Symbol)
check_step_status(step_status)
stats.step_status = step_status
stats.step_status_reliable = true
stats
end

"""
set_time!(stats::GenericExecutionStats, time::Float64)

Expand Down Expand Up @@ -431,6 +479,9 @@ function statsgetfield(stats::AbstractExecutionStats, name::Symbol)
if name == :status
v = getStatus(stats)
t = String
elseif name == :step_status
v = getStepStatus(stats)
t = String
Comment thread
tmigot marked this conversation as resolved.
elseif name in fieldnames(typeof(stats))
v = getfield(stats, name)
t = fieldtype(typeof(stats), name)
Expand Down Expand Up @@ -458,6 +509,10 @@ function getStatus(stats::AbstractExecutionStats)
return STATUSES[stats.status]
end

function getStepStatus(stats::AbstractExecutionStats)
return STEP_STATUSES[stats.step_status]
end

"""
get_status(problem, kwargs...)

Expand Down
4 changes: 4 additions & 0 deletions test/test-stats.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function test_stats()

stats = GenericExecutionStats{Float64, Vector{Float64}, Vector{Float64}, Any}()
@test_throws Exception set_status!(stats, :bad)
@test_throws Exception set_step_status!(stats, :medium_well)
end

@testset "Testing Dummy Solver with multi-precision" begin
Expand Down Expand Up @@ -120,6 +121,7 @@ function test_stats()
"multipliers",
"bounds_multipliers",
"iter",
"step_status",
"time",
"solver_specific",
)
Expand All @@ -143,6 +145,8 @@ function test_stats()
@test stats.bounds_multipliers_reliable
set_iter!(stats, 2)
@test stats.iter_reliable
set_step_status!(stats, :accepted)
@test stats.step_status_reliable
set_time!(stats, 0.1)
@test stats.time_reliable
set_solver_specific!(stats, :bla, "boo!")
Expand Down
Loading