From d0571fa7f829ac96ab95ddbbbb7126b6ea51f2eb Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 1 Feb 2022 09:34:53 +1300 Subject: [PATCH] [docs] Add try-catch section on querying attributes --- docs/src/manual/solutions.md | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/src/manual/solutions.md b/docs/src/manual/solutions.md index cd559bfc14..2b48be57df 100644 --- a/docs/src/manual/solutions.md +++ b/docs/src/manual/solutions.md @@ -131,3 +131,51 @@ non-global tree search solvers like | Completed a non-global tree search (no solution found) | `LOCALLY_INFEASIBLE` | 0 | `NO_SOLUTION` | `NO_SOLUTION` | | Iteration limit | `ITERATION_LIMIT` | 1 | * | * | | Diverging iterates | `NORM_LIMIT` or `OBJECTIVE_LIMIT` | 1 | * | * | + +## Querying solution attributes + +Some solvers will not implement every solution attribute. Therefore, a call like +`MOI.get(model, MOI.SolveTimeSec())` may throw an [`UnsupportedAttribute`](@ref) +error. + +If you need to write code that is agnostic to the solver (for example, you are +writing a library that an end-user passes their choice of solver to), you can +work-around this problem using a `try-catch`: +```julia +function get_solve_time(model) + try + return MOI.get(model, MOI.SolveTimeSec()) + catch err + if err isa MOI.UnsupportedAttribute + return NaN # Solver doesn't support. Return a placeholder value. + end + rethrow(err) # Something else went wrong. Rethrow the error + end +end +``` + +If, _after careful profiling_, you find that the `try-catch` is taking a +significant portion of your runtime, you can improve performance by caching the +result of the `try-catch`: +```julia +mutable struct CachedSolveTime{M} + model::M + supports_solve_time::Bool + CachedSolveTime(model::M) where {M} = new(model, true) +end + +function get_solve_time(model::CachedSolveTime) + if !model.supports_solve_time + return NaN + end + try + return MOI.get(model, MOI.SolveTimeSec()) + catch err + if err isa MOI.UnsupportedAttribute + model.supports_solve_time = false + return NaN + end + rethrow(err) # Something else went wrong. Rethrow the error + end +end +```