Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XPRS_OPTIMIZETYPEUSED instead of is_mip #256

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions src/Lib/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ const XPRS_CPUSDETECTED = 1259
const XPRS_CORESDETECTED = 1260
const XPRS_PHYSICALCORESDETECTED = 1261
const XPRS_PHYSICALCORESPERCPUDETECTED = 1262
const XPRS_OPTIMIZETYPEUSED = 1268
const XPRS_BARSING = 1281
const XPRS_BARSINGR = 1282
const XPRS_PRESOLVEINDEX = 1284
Expand Down
85 changes: 50 additions & 35 deletions src/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -976,15 +976,17 @@
::ForwardSensitivityOutputVariable,
vi::MOI.VariableIndex,
)
if is_mip(model) && model.moi_warnings
@warn "The problem is a MIP, it might fail to get correct sensitivities."
end
if MOI.get(model, MOI.TerminationStatus()) != MOI.OPTIMAL
error("Model not optimized. Cannot get sensitivities.")
end
if model.forward_sensitivity_cache === nothing
elseif model.forward_sensitivity_cache === nothing
error("Forward sensitivity cache not initiliazed correctly.")
end
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP && model.moi_warnings
@warn "The problem is a MIP, it might fail to get correct sensitivities."

Check warning on line 988 in src/MOI/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/MOI/MOI_wrapper.jl#L988

Added line #L988 was not covered by tests
end
if model.forward_sensitivity_cache.is_updated != true
forward(model)
model.forward_sensitivity_cache.is_updated = true
Expand Down Expand Up @@ -1016,15 +1018,17 @@
::BackwardSensitivityOutputConstraint,
ci::MOI.ConstraintIndex,
)
if is_mip(model) && model.moi_warnings
@warn "The problem is a MIP, it might fail to get correct sensitivities."
end
if MOI.get(model, MOI.TerminationStatus()) != MOI.OPTIMAL
error("Model not optimized. Cannot get sensitivities.")
end
if model.backward_sensitivity_cache === nothing
elseif model.backward_sensitivity_cache === nothing
error("Backward sensitivity cache not initiliazed correctly.")
end
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP && model.moi_warnings
@warn "The problem is a MIP, it might fail to get correct sensitivities."

Check warning on line 1030 in src/MOI/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/MOI/MOI_wrapper.jl#L1030

Added line #L1030 was not covered by tests
end
if model.backward_sensitivity_cache.is_updated != true
backward(model)
model.backward_sensitivity_cache.is_updated = true
Expand Down Expand Up @@ -2824,16 +2828,6 @@
return
end

function is_mip(model::Optimizer)
n = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_ORIGINALMIPENTS, _)::Int,
)
nsos = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_ORIGINALSETS, _)::Int,
)
return !model.solve_relaxation && n + nsos > 0
end

function _set_MIP_start(model)
colind, solval = Cint[], Cdouble[]
for info in values(model.variable_info)
Expand Down Expand Up @@ -2871,15 +2865,17 @@
)::Int
rhs = Vector{Float64}(undef, ncons)
@checked Lib.XPRSgetrhs(model.inner, rhs, Cint(0), Cint(ncons - 1))
if !model.ignore_start && is_mip(model)
if !model.ignore_start
_set_MIP_start(model)
end
start_time = time()
if is_mip(model)
@checked Lib.XPRSmipoptimize(model.inner, model.solve_method)
else
@checked Lib.XPRSlpoptimize(model.inner, model.solve_method)
end
solvestatus, solstatus = Ref{Cint}(), Ref{Cint}()
@checked Lib.XPRSoptimize(
model.inner,
model.solve_method,
solvestatus,
solstatus,
)
model.cached_solution.solve_time = time() - start_time
check_cb_exception(model)
# Should be almost a no-op if not needed. Might have minor overhead due to
Expand All @@ -2890,9 +2886,10 @@
model.termination_status = _cache_termination_status(model)
model.primal_status = _cache_primal_status(model)
model.dual_status = _cache_dual_status(model)
# TODO: add @checked here - must review statuses
if is_mip(model)
# TODO @checked (only works if not in [MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, MOI.INFEASIBLE_POINT])
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP
Lib.XPRSgetmipsol(
model.inner,
model.cached_solution.variable_primal,
Expand All @@ -2901,6 +2898,7 @@
fill!(model.cached_solution.linear_dual, NaN)
fill!(model.cached_solution.variable_dual, NaN)
else
@assert optimize_type == Lib.XPRS_OPTIMIZETYPE_LP
Lib.XPRSgetlpsol(
model.inner,
model.cached_solution.variable_primal,
Expand Down Expand Up @@ -3020,14 +3018,18 @@
_throw_if_optimize_in_progress(model, attr)
stop =
@_invoke Lib.XPRSgetintattrib(model.inner, Lib.XPRS_STOPSTATUS, _)::Int
if is_mip(model)
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP
stat = @_invoke Lib.XPRSgetintattrib(
model.inner,
Lib.XPRS_MIPSTATUS,
_,
)::Int
return _MIPSTATUS[stat][1] * " - " * _STOPSTATUS[stop][1]
else
@assert optimize_type == Lib.XPRS_OPTIMIZETYPE_LP
stat = @_invoke Lib.XPRSgetintattrib(
model.inner,
Lib.XPRS_LPSTATUS,
Expand All @@ -3042,11 +3044,16 @@
@_invoke Lib.XPRSgetintattrib(model.inner, Lib.XPRS_STOPSTATUS, _)::Int
if stop != Lib.XPRS_STOP_NONE && stop != Lib.XPRS_STOP_MIPGAP
return _STOPSTATUS[stop][2]
elseif is_mip(model)
end
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP
mipstatus = Lib.XPRS_MIPSTATUS
stat = @_invoke Lib.XPRSgetintattrib(model.inner, mipstatus, _)::Int
return _MIPSTATUS[stat][2]
else
@assert optimize_type == Lib.XPRS_OPTIMIZETYPE_LP
lpstatus = Lib.XPRS_LPSTATUS
stat = @_invoke Lib.XPRSgetintattrib(model.inner, lpstatus, _)::Int
return _LPSTATUS[stat][2]
Expand Down Expand Up @@ -3099,7 +3106,10 @@
end

function _cache_dual_status(model)
if is_mip(model)
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
if optimize_type != Lib.XPRS_OPTIMIZETYPE_LP
return MOI.NO_SOLUTION
end
term_stat = MOI.get(model, MOI.TerminationStatus())
Expand Down Expand Up @@ -3352,8 +3362,9 @@
function MOI.get(model::Optimizer, attr::MOI.ObjectiveValue)
_throw_if_optimize_in_progress(model, attr)
MOI.check_result_index_bounds(model, attr)
attr = is_mip(model) ? Lib.XPRS_MIPOBJVAL : Lib.XPRS_LPOBJVAL
return @_invoke Lib.XPRSgetdblattrib(model.inner, attr, _)::Float64
return @_invoke(
Lib.XPRSgetdblattrib(model.inner, Lib.XPRS_OBJVAL, _)::Float64
)
end

#=
Expand All @@ -3362,7 +3373,11 @@

function MOI.get(model::Optimizer, attr::MOI.ObjectiveBound)
_throw_if_optimize_in_progress(model, attr)
attr = is_mip(model) ? Lib.XPRS_BESTBOUND : Lib.XPRS_LPOBJVAL
optimize_type = @_invoke(
Lib.XPRSgetintattrib(model.inner, Lib.XPRS_OPTIMIZETYPEUSED, _)::Int
)
is_mip = optimize_type == Lib.XPRS_OPTIMIZETYPE_MIP
attr = ifelse(is_mip, Lib.XPRS_BESTBOUND, Lib.XPRS_OBJVAL)
return @_invoke Lib.XPRSgetdblattrib(model.inner, attr, _)::Float64
end

Expand Down
8 changes: 4 additions & 4 deletions test/test_MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1799,11 +1799,11 @@ function test_BackwardSensitivityOutputConstraint_error()
c = MOI.add_constraint(model, 0.5 * x, MOI.EqualTo(0.0))
attr = Xpress.BackwardSensitivityOutputConstraint()
err = ErrorException("Model not optimized. Cannot get sensitivities.")
@test_logs (:warn,) @test_throws(err, MOI.get(model, attr, c))
@test_throws err MOI.get(model, attr, c)
MOI.optimize!(model)
err =
ErrorException("Backward sensitivity cache not initiliazed correctly.")
@test_logs (:warn,) @test_throws(err, MOI.get(model, attr, c))
@test_throws err MOI.get(model, attr, c)
return
end

Expand All @@ -1814,10 +1814,10 @@ function test_ForwardSensitivityOutputVariable_error()
MOI.add_constraint(model, x, MOI.ZeroOne())
attr = Xpress.ForwardSensitivityOutputVariable()
err = ErrorException("Model not optimized. Cannot get sensitivities.")
@test_logs (:warn,) @test_throws(err, MOI.get(model, attr, x))
@test_throws err MOI.get(model, attr, x)
MOI.optimize!(model)
err = ErrorException("Forward sensitivity cache not initiliazed correctly.")
@test_logs (:warn,) @test_throws(err, MOI.get(model, attr, x))
@test_throws err MOI.get(model, attr, x)
return
end

Expand Down
Loading