Skip to content

Commit

Permalink
Fix invalid return code in MOI.TerminationStatus (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Feb 3, 2023
1 parent b000abe commit 7146792
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
23 changes: 15 additions & 8 deletions src/Interfaces/MOI_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ function MOI.optimize!(model::Optimizer)
end

# From Ipopt/src/Interfaces/IpReturnCodes_inc.h
const _STATUS_CODES = Dict(
const _STATUS_CODES = Dict{Status,MOI.TerminationStatusCode}(
SOLVE_SUCCEEDED => MOI.LOCALLY_SOLVED,
SOLVED_TO_ACCEPTABLE_LEVEL => MOI.ALMOST_LOCALLY_SOLVED,
SEARCH_DIRECTION_BECOMES_TOO_SMALL => MOI.SLOW_PROGRESS,
Expand All @@ -706,12 +706,20 @@ const _STATUS_CODES = Dict(
MAXIMUM_ITERATIONS_EXCEEDED => MOI.ITERATION_LIMIT,
MAXIMUM_WALLTIME_EXCEEDED => MOI.TIME_LIMIT,
INITIAL => MOI.OPTIMIZE_NOT_CALLED,
# REGULAR
# RESTORE
# ROBUST
RESTORATION_FAILED => MOI.NUMERICAL_ERROR,
INVALID_NUMBER_DETECTED => MOI.INVALID_MODEL,
ERROR_IN_STEP_COMPUTATION => MOI.NUMERICAL_ERROR,
NOT_ENOUGH_DEGREES_OF_FREEDOM => MOI.INVALID_MODEL,
USER_REQUESTED_STOP => MOI.INTERRUPTED,
INTERNAL_ERROR => MOI.OTHER_ERROR,
INVALID_NUMBER_OBJECTIVE => MOI.INVALID_MODEL,
INVALID_NUMBER_GRADIENT => MOI.INVALID_MODEL,
INVALID_NUMBER_CONSTRAINTS => MOI.INVALID_MODEL,
INVALID_NUMBER_JACOBIAN => MOI.INVALID_MODEL,
INVALID_NUMBER_HESSIAN_LAGRANGIAN => MOI.INVALID_MODEL,
)

### MOI.ResultCount
Expand All @@ -729,9 +737,12 @@ function MOI.get(model::Optimizer, ::MOI.RawStatusString)
return "The model has no variable"
elseif model.solver === nothing
return "Optimize not called"
else
return string(_STATUS_CODES[model.result.status])
end
return get(
STATUS_OUTPUT_DICT,
model.result.status,
"Unknown result status: $(model.result.status)",
)
end

### MOI.TerminationStatus
Expand All @@ -742,11 +753,7 @@ function MOI.get(model::Optimizer, ::MOI.TerminationStatus)
elseif model.solver === nothing
return MOI.OPTIMIZE_NOT_CALLED
end
if haskey(_STATUS_CODES, model.result.status)
return _STATUS_CODES[model.result.status]
else
return MOI.UNKNOWN_RESULT_STATUS
end
return get(_STATUS_CODES, model.result.status, MOI.OTHER_ERROR)
end

### MOI.PrimalStatus
Expand Down
23 changes: 20 additions & 3 deletions test/MOI_interface_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,31 @@ end
function test_extra()
model = MadNLP.Optimizer()
MOI.set(model, MOI.RawOptimizerAttribute("linear_solver"), UmfpackSolver)

@test MOI.supports(model, MOI.Name())
@test MOI.get(model, MOI.Name()) == ""
MOI.set(model, MOI.Name(), "Model")
@test MOI.get(model, MOI.Name()) == "Model"

@test MOI.get(model, MOI.BarrierIterations()) == 0


return
end

function test_invalid_number_in_hessian_lagrangian()
model = MadNLP.Optimizer()
x = MOI.add_variable(model)
y = MOI.add_variable(model)
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
nlp = MOI.Nonlinear.Model()
MOI.Nonlinear.set_objective(nlp, :(($x - 5)^2 + ($y - 8)^2))
MOI.Nonlinear.add_constraint(nlp, :($x * $y), MOI.EqualTo(5.0))
ev = MOI.Nonlinear.Evaluator(nlp, MOI.Nonlinear.SparseReverseMode(), [x, y])
MOI.set(model, MOI.NLPBlock(), MOI.NLPBlockData(ev))
MOI.optimize!(model)
@test MOI.get(model, MOI.TerminationStatus()) == MOI.INVALID_MODEL
@test MOI.get(model, MOI.RawStatusString()) ==
"Invalid number in NLP Hessian Lagrangian detected."
return
end

Expand Down

0 comments on commit 7146792

Please sign in to comment.