@@ -131,3 +131,51 @@ non-global tree search solvers like
131131| Completed a non-global tree search (no solution found) | ` LOCALLY_INFEASIBLE ` | 0 | ` NO_SOLUTION ` | ` NO_SOLUTION ` |
132132| Iteration limit | ` ITERATION_LIMIT ` | 1 | * | * |
133133| Diverging iterates | ` NORM_LIMIT ` or ` OBJECTIVE_LIMIT ` | 1 | * | * |
134+
135+ ## Querying solution attributes
136+
137+ Some solvers will not implement every solution attribute. Therefore, a call like
138+ ` MOI.get(model, MOI.SolveTimeSec()) ` may throw an [ ` UnsupportedAttribute ` ] ( @ref )
139+ error.
140+
141+ If you need to write code that is agnostic to the solver (for example, you are
142+ writing a library that an end-user passes their choice of solver to), you can
143+ work-around this problem using a ` try-catch ` :
144+ ``` julia
145+ function get_solve_time (model)
146+ try
147+ return MOI. get (model, MOI. SolveTimeSec ())
148+ catch err
149+ if err isa MOI. UnsupportedAttribute
150+ return NaN # Solver doesn't support. Return a placeholder value.
151+ end
152+ rethrow (err) # Something else went wrong. Rethrow the error
153+ end
154+ end
155+ ```
156+
157+ If, _ after careful profiling_ , you find that the ` try-catch ` is taking a
158+ significant portion of your runtime, you can improve performance by caching the
159+ result of the ` try-catch ` :
160+ ``` julia
161+ mutable struct CachedSolveTime{M}
162+ model:: M
163+ supports_solve_time:: Bool
164+ CachedSolveTime (model:: M ) where {M} = new (model, true )
165+ end
166+
167+ function get_solve_time (model:: CachedSolveTime )
168+ if ! model. supports_solve_time
169+ return NaN
170+ end
171+ try
172+ return MOI. get (model, MOI. SolveTimeSec ())
173+ catch err
174+ if err isa MOI. UnsupportedAttribute
175+ model. supports_solve_time = false
176+ return NaN
177+ end
178+ rethrow (err) # Something else went wrong. Rethrow the error
179+ end
180+ end
181+ ```
0 commit comments