From b5b6cf29d91f3bce5ed72cafb9490b4ee3af1fbf Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 09:33:51 -0700 Subject: [PATCH 01/10] add xpress patch --- src/core/optimization_container.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index 2953aac2ad..1a1452a63a 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -677,7 +677,13 @@ function solve_impl!(container::OptimizationContainer, system::PSY.System) optimizer_stats.sec_in_gc = @timed JuMP.optimize!(jump_model) model_status = JuMP.primal_status(jump_model) if model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode - @error "Optimizer returned $model_status" + @error "Optimizer returned $model_status trying again" + JuMP.optimize!(jump_model) + model_status = JuMP.primal_status(jump_model) + end + + if model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode + @error "Optimizer returned $model_status getting conflict" if get_calculate_conflict(get_settings(container)) compute_conflict!(container) end @@ -706,6 +712,8 @@ function compute_conflict!(container::OptimizationContainer) JuMP.compute_conflict!(jump_model) if MOI.get(jump_model, MOI.ConflictStatus()) != MOI.CONFLICT_FOUND @error "No conflict could be found for the model. $(MOI.get(jump_model, MOI.ConflictStatus()))" + + return end for (key, field_container) in get_constraints(container) From fff6433dc5ca33c27d9401c473711425f673d636 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:20:41 -0700 Subject: [PATCH 02/10] use while loop to re-try to solve --- src/core/optimization_container.jl | 44 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index 1a1452a63a..6d9ae80fbb 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -671,23 +671,34 @@ function solve_impl!(container::OptimizationContainer, system::PSY.System) optimizer_stats = get_optimizer_stats(container) jump_model = get_jump_model(container) - _, - optimizer_stats.timed_solve_time, - optimizer_stats.solve_bytes_alloc, - optimizer_stats.sec_in_gc = @timed JuMP.optimize!(jump_model) - model_status = JuMP.primal_status(jump_model) - if model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode - @error "Optimizer returned $model_status trying again" - JuMP.optimize!(jump_model) + + model_status = MOI.NO_SOLUTION::MOI.ResultStatusCode + conflict_status = MOI.COMPUTE_CONFLICT_NOT_CALLED + + MAX_TRIES = 2 + try_count = 0 + while model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode + _, + optimizer_stats.timed_solve_time, + optimizer_stats.solve_bytes_alloc, + optimizer_stats.sec_in_gc = @timed JuMP.optimize!(jump_model) model_status = JuMP.primal_status(jump_model) - end - if model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode - @error "Optimizer returned $model_status getting conflict" if get_calculate_conflict(get_settings(container)) - compute_conflict!(container) + @error "Optimizer returned $model_status computing conflict" + conflict_status = compute_conflict!(container) + if conflict_status == MOI.CONFLICT_FOUND + return RunStatus.FAILED + end + else + @error "Optimizer returned $model_status trying again" + end + + try_count += 1 + if try_count > MAX_TRIES + @error "Optimizer returned $model_status after $try_count solve tries" + return RunStatus.FAILED end - return RunStatus.FAILED end status = RunStatus.SUCCESSFUL @@ -712,8 +723,7 @@ function compute_conflict!(container::OptimizationContainer) JuMP.compute_conflict!(jump_model) if MOI.get(jump_model, MOI.ConflictStatus()) != MOI.CONFLICT_FOUND @error "No conflict could be found for the model. $(MOI.get(jump_model, MOI.ConflictStatus()))" - - return + return MOI.get(jump_model, MOI.ConflictStatus()) end for (key, field_container) in get_constraints(container) @@ -726,6 +736,8 @@ function compute_conflict!(container::OptimizationContainer) end end @error "$(conflict)" + + return MOI.get(jump_model, MOI.ConflictStatus()) catch e jump_model.is_model_dirty = true if isa(e, MethodError) @@ -735,7 +747,7 @@ function compute_conflict!(container::OptimizationContainer) end end - return + return MOI.NO_CONFLICT_EXISTS end function write_optimizer_stats!(container::OptimizationContainer) From 90b900d82146ebb5f172b714e22345e5314829b9 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:42:34 -0700 Subject: [PATCH 03/10] add mipgap to caputred stats (#1049) --- src/utils/jump_utils.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/jump_utils.jl b/src/utils/jump_utils.jl index c3360c5da5..e610a91ae5 100644 --- a/src/utils/jump_utils.jl +++ b/src/utils/jump_utils.jl @@ -243,6 +243,7 @@ function _summary_to_dict!(optimizer_stats::OptimizerStats, jump_model::JuMP.Mod :objective_bound, # Union{Missing,Float64} :dual_objective_value, # Union{Missing,Float64} # Work counters + :relative_gap, # Union{Missing,Int} :barrier_iterations, # Union{Missing,Int} :simplex_iterations, # Union{Missing,Int} :node_count, # Union{Missing,Int} From c296555dc852917728227d036f8c4f49f7381e6f Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:42:45 -0700 Subject: [PATCH 04/10] improve retry logic --- src/core/optimization_container.jl | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index 6d9ae80fbb..4c3389c88b 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -684,20 +684,22 @@ function solve_impl!(container::OptimizationContainer, system::PSY.System) optimizer_stats.sec_in_gc = @timed JuMP.optimize!(jump_model) model_status = JuMP.primal_status(jump_model) - if get_calculate_conflict(get_settings(container)) - @error "Optimizer returned $model_status computing conflict" - conflict_status = compute_conflict!(container) - if conflict_status == MOI.CONFLICT_FOUND - return RunStatus.FAILED + if model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode + if get_calculate_conflict(get_settings(container)) + @warn "Optimizer returned $model_status computing conflict" + conflict_status = compute_conflict!(container) + if conflict_status == MOI.CONFLICT_FOUND + return RunStatus.FAILED + end + else + @warn "Optimizer returned $model_status trying optimize! again" end - else - @error "Optimizer returned $model_status trying again" - end - try_count += 1 - if try_count > MAX_TRIES - @error "Optimizer returned $model_status after $try_count solve tries" - return RunStatus.FAILED + try_count += 1 + if try_count > MAX_TRIES + @error "Optimizer returned $model_status after $MAX_TRIES optimize! attempts" + return RunStatus.FAILED + end end end From 0d6f377a4a3c9f6f5c9be1a49acf75dfff94d793 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:44:19 -0700 Subject: [PATCH 05/10] add missing fields to optimizer stats --- src/core/optimizer_stats.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/optimizer_stats.jl b/src/core/optimizer_stats.jl index 19475381c6..dfac5c3cce 100644 --- a/src/core/optimizer_stats.jl +++ b/src/core/optimizer_stats.jl @@ -10,6 +10,7 @@ mutable struct OptimizerStats has_duals::Bool # Candidate solution objective_bound::Union{Missing, Float64} + relative_gap::Union{Missing, Float64} # Use missing instead of nothing so that CSV writting doesn't fail dual_objective_value::Union{Missing, Float64} # Work counters @@ -37,6 +38,7 @@ function OptimizerStats() false, missing, missing, + missing, NaN, missing, missing, From a4f28d354944d7aad3f99883f9d659f09d5a2d0d Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:54:28 -0700 Subject: [PATCH 06/10] move constant to definitions --- src/core/definitions.jl | 2 ++ src/core/optimization_container.jl | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/definitions.jl b/src/core/definitions.jl index 142967f063..4244243985 100644 --- a/src/core/definitions.jl +++ b/src/core/definitions.jl @@ -61,6 +61,8 @@ const NO_SERVICE_NAME_PROVIDED = "" const CONTAINER_KEY_EMPTY_META = "" const UPPER_BOUND = "ub" const LOWER_BOUND = "lb" +const MAX_OPTIMIZE_TRIES = 2 + # File Names definitions const PROBLEM_SERIALIZATION_FILENAME = "operation_problem.bin" diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index 4c3389c88b..775cb233d5 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -675,7 +675,6 @@ function solve_impl!(container::OptimizationContainer, system::PSY.System) model_status = MOI.NO_SOLUTION::MOI.ResultStatusCode conflict_status = MOI.COMPUTE_CONFLICT_NOT_CALLED - MAX_TRIES = 2 try_count = 0 while model_status != MOI.FEASIBLE_POINT::MOI.ResultStatusCode _, @@ -696,8 +695,8 @@ function solve_impl!(container::OptimizationContainer, system::PSY.System) end try_count += 1 - if try_count > MAX_TRIES - @error "Optimizer returned $model_status after $MAX_TRIES optimize! attempts" + if try_count > MAX_OPTIMIZE_TRIES + @error "Optimizer returned $model_status after $MAX_OPTIMIZE_TRIES optimize! attempts" return RunStatus.FAILED end end From 28596baaeda85685581bd7ab6c5d010b453cea5e Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 17:56:36 -0700 Subject: [PATCH 07/10] Update src/core/definitions.jl Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/core/definitions.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/definitions.jl b/src/core/definitions.jl index 4244243985..52af4c8103 100644 --- a/src/core/definitions.jl +++ b/src/core/definitions.jl @@ -63,7 +63,6 @@ const UPPER_BOUND = "ub" const LOWER_BOUND = "lb" const MAX_OPTIMIZE_TRIES = 2 - # File Names definitions const PROBLEM_SERIALIZATION_FILENAME = "operation_problem.bin" const PROBLEM_LOG_FILENAME = "operation_problem.log" From 11229b873cd55e7924db59eb68b5539ce32d4b38 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 18:30:38 -0700 Subject: [PATCH 08/10] use variable for conflict_status --- src/core/optimization_container.jl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/optimization_container.jl b/src/core/optimization_container.jl index 775cb233d5..133a439595 100644 --- a/src/core/optimization_container.jl +++ b/src/core/optimization_container.jl @@ -717,14 +717,19 @@ end function compute_conflict!(container::OptimizationContainer) jump_model = get_jump_model(container) + settings = get_settings(container) JuMP.unset_silent(jump_model) jump_model.is_model_dirty = false conflict = container.infeasibility_conflict try JuMP.compute_conflict!(jump_model) - if MOI.get(jump_model, MOI.ConflictStatus()) != MOI.CONFLICT_FOUND - @error "No conflict could be found for the model. $(MOI.get(jump_model, MOI.ConflictStatus()))" - return MOI.get(jump_model, MOI.ConflictStatus()) + conflict_status = MOI.get(jump_model, MOI.ConflictStatus()) + if conflict_status != MOI.CONFLICT_FOUND + @error "No conflict could be found for the model. Status: $conflict_status" + if !get_optimizer_solve_log_print(settings) + JuMP.set_silent(jump_model) + end + return conflict_status end for (key, field_container) in get_constraints(container) @@ -738,7 +743,7 @@ function compute_conflict!(container::OptimizationContainer) end @error "$(conflict)" - return MOI.get(jump_model, MOI.ConflictStatus()) + return conflict_status catch e jump_model.is_model_dirty = true if isa(e, MethodError) From 4065707e7ae5c11812fcf122cb781cc584bbbf1e Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 20:33:58 -0700 Subject: [PATCH 09/10] always serialize infeasible problem version --- src/operation/decision_model.jl | 3 ++- src/operation/operation_model_interface.jl | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/operation/decision_model.jl b/src/operation/decision_model.jl index a0cde57e3d..9a60a0669c 100644 --- a/src/operation/decision_model.jl +++ b/src/operation/decision_model.jl @@ -473,7 +473,6 @@ function solve!( @info "\n$(RUN_OPERATION_MODEL_TIMER)\n" catch e @error "Decision Problem solve failed" exception = (e, catch_backtrace()) - # TODO: Run IIS here if the solve called failed set_run_status!(model, RunStatus.FAILED) end end @@ -514,6 +513,8 @@ function solve!( write_results!(store, model, start_time, start_time; exports = exports) write_optimizer_stats!(store, model, start_time) advance_execution_count!(model) + else + serialize_problem(model, ) end return get_run_status(model) end diff --git a/src/operation/operation_model_interface.jl b/src/operation/operation_model_interface.jl index faa323ae6b..1ddd992f1b 100644 --- a/src/operation/operation_model_interface.jl +++ b/src/operation/operation_model_interface.jl @@ -88,6 +88,10 @@ function solve_impl!(model::OperationModel) settings = get_settings(model) model_name = get_name(model) ts = get_current_timestamp(model) + output_dir = get_output_dir(model) + infeasible_opt_path = joinpath(output_dir, "infeasible_$(model_name)_$(ts).json") + serialize_optimization_model(container, infeasible_opt_path) + @error("Infeasible Problem Serialized at $(infeasible_opt_path)") if !get_allow_fails(settings) error("Solving model $(model_name) failed at $(ts)") else From 0a15ae659021d14f6d76e4926ed37b1053ddb427 Mon Sep 17 00:00:00 2001 From: Jose Daniel Lara Date: Thu, 8 Feb 2024 23:05:53 -0700 Subject: [PATCH 10/10] remove incorrect conditional --- src/operation/decision_model.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/operation/decision_model.jl b/src/operation/decision_model.jl index 9a60a0669c..e5d61a2fea 100644 --- a/src/operation/decision_model.jl +++ b/src/operation/decision_model.jl @@ -513,8 +513,6 @@ function solve!( write_results!(store, model, start_time, start_time; exports = exports) write_optimizer_stats!(store, model, start_time) advance_execution_count!(model) - else - serialize_problem(model, ) end return get_run_status(model) end