jump-dev / KNITRO.jl

A Julia interface to the Artelys Knitro solver
https://www.artelys.com/knitro
Other
78 stars 23 forks source link

maxtime_cpu is not respected #295

Closed chengg04 closed 2 months ago

chengg04 commented 3 months ago

This bug is similar to the one mentioned here: https://discourse.julialang.org/t/julia-with-knitro/81686.

A MWE is as follows:

using JuMP, KNITRO, PowerModels

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "maxtime_cpu" => 30)

solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)

The data file pglib_opf_case24_ieee_rts__sad.m is attached below (drop the extension .txt before running).

The code runs fine if one does not set the maxtime_cpu parameter in attributes, so it seems to be an issue with KNITRO.jl/MOI not being able to talk the parameter.

pglib_opf_case24_ieee_rts__sad.m.txt

odow commented 3 months ago

Use:

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, MOI.TimeLimitSec() => 30)

We don't do anything special with parameters, so this might depend on the version of KNITRO that you have installed.

chengg04 commented 2 months ago

Thank you for the prompt response, Oscar!

I included the time limit via MOI as you suggested. Here is the code I use now:

using JuMP, KNITRO, PowerModels

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, MOI.TimeLimitSec() => 30)

solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)

However, it seems the 30-second time limit is not taken by the solver. I include the solver log below. And here is my versions information: Knitro: 13.0.1, KNITRO.jl: v0.11.1, JuMP.jl: v0.22.3, PowerModels.jl: v 0.19.10. Operating system: macOS Sonoma with M1 chip.

MINLP solver shifted start point to satisfy bounds (32 variables).
WARNING: Problem appears to have nonlinear equalities and be non-convex.
         The Knitro mixed integer solver is designed for convex problems.
         For non-convex problems it is only a heuristic, and the reported
         bounds and optimality claims cannot be verified.

datacheck:               0
hessian_no_f:            1
numthreads:              1
mip_numthreads:          1
Knitro changing mip_method from AUTO to 1.
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_mir from AUTO to 1.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic_strategy from AUTO to 1.
Knitro changing mip_heuristic_feaspump from AUTO to 1.
Knitro changing mip_heuristic_mpec from AUTO to 1.
Knitro changing mip_heuristic_diving from AUTO to 0.
Knitro changing mip_heuristic_lns from AUTO to 0.
Knitro changing mip_pseudoinit from AUTO to 1.

Problem Characteristics
-----------------------
Objective goal:  Minimize
Objective type:  quadratic
Number of variables:                                304
    bounded below only:                               0
    bounded above only:                               0
    bounded below and above:                        279
    fixed:                                            1
    free:                                            24
Number of binary variables:                          38
Number of integer variables:                          0
Number of constraints:                              353
    linear equalities:                               48
    quadratic equalities:                             1
    gen. nonlinear equalities:                      152
    linear one-sided inequalities:                    0
    quadratic one-sided inequalities:               152
    gen. nonlinear one-sided inequalities:            0
    linear two-sided inequalities:                    0
    quadratic two-sided inequalities:                 0
    gen. nonlinear two-sided inequalities:            0
Number of nonzeros in Jacobian:                    1588
Number of nonzeros in Hessian:                      572

Knitro detected 0 GUB constraints
Knitro derived 0 knapsack covers after examining 0 constraints
Knitro using Branch and Bound method with 1 thread.

       Nodes        Best solution   Best bound      Gap       Time 
   Expl  |  Unexpl      value         value                  (secs)
   ---------------  -------------   ----------      ---      ------
      1       0                        73133.8                2.122
      1       0      76747.8   FP      73133.8      4.71%     2.769
    100       9      76747.8           76590.0      0.21%    86.050
    163      20      76630.6 LEAF      76609.5      0.03%   102.989
    168      17      76613.0 LEAF      76613.3     -0.00%   103.300

EXIT: Optimal solution found (assuming convexity).

HINT: The problem may be a non-convex mixed-integer problem.  Set
      mip_multistart=1 to enable a mixed-integer multistart heuristic,
      which may improve the chances of finding the global solution.

Final Statistics for MIP
------------------------
Final objective value               =  7.66130083679263e+04
Final bound value                   =  7.66132742057831e+04
Final optimality gap (abs / rel)    =  -2.66e-01 / -3.47e-06 (-0.00%)
# of nodes processed                =  168 (40.469s)
# of strong branching evaluations   =  63 (34.181s)
# of function evaluations           =  152284 (8.629s)
# of gradient evaluations           =  70783 (1.115s)
# of hessian evaluations            =  71618 (18.889s)
# of hessian-vector evaluations     =  0
# of subproblems processed          =  301 (102.627s)
Total program time (secs)           =  103.30029 (102.676 CPU time)
Time spent in evaluations (secs)    =  0.51630

Cuts statistics (computed / added)
----------------------------------
Knapsack cuts                       =  0 / 0
Mixed-Integer Rounding cuts         =  0 / 0

Heuristics statistics (calls / successes / time)
------------------------------------------------
Feasibility pump                    =  1 / 1 / 0.647s
Rounding heuristic                  =  0 / 0 / 0.017s
MPEC heuristic                      =  2 / 1 / 27.364s

===========================================================================

Dict{String, Any} with 8 entries:
  "solve_time"         => 102.676
  "optimizer"          => "Knitro"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 76613.0
  "solution"           => Dict{String, Any}("baseMVA"=>100.0, "branch"=>Dict{String, Any}("24"=>Dict{String, Any}("qf"=>-0.291815, "qt"=>0.255001, "br_status"=…
  "objective_lb"       => 76613.3
odow commented 2 months ago

Interesting. It's useful to have an example that fails.

This looks like an issue in the upstream KNITRO solver, because all we do here is pass the options.

I'll take a look

odow commented 2 months ago

KNITRO.jl: v0.11.1

Wait. The most recent version of KNITRO.jl is v0.14.2. Can you try updating???

odow commented 2 months ago

Ah. I can't test this locally because I only have a limited size license

I think this is just a bug in KNITRO

julia> model = KNITRO.Optimizer();
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####

julia> p = Ref{Cint}(0)
Base.RefValue{Int32}(0)

julia> KN_get_param_id(model.inner, "maxtime_cpu", p)
-521

julia> p
Base.RefValue{Int32}(0)

julia> KN_get_param_id(model.inner, "maxtimecpu", p)
0

julia> p
Base.RefValue{Int32}(1024)

julia> KN_set_double_param_by_name(model.inner, "maxtime_cpu", 30.0)
0

julia> KN_set_double_param_by_name(model.inner, "maxtimecpu", 30.0)
-516

KN_get_param_id requires maxtimecpu but KN_set_double_param_by_name requires maxtime_cpu.

chengg04 commented 2 months ago

Thank you, Oscar! Is there a way to fix this bug in KNITRO.jl source code?

odow commented 2 months ago

Can you try

using JuMP, KNITRO, PowerModels
minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, MOI.TimeLimitSec() => 30.0)
solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)
chengg04 commented 2 months ago

It seems the time limit is still not taken, after using the most updated KNITRO.jl version.

After updating, I am now using the following packages: KNITRO.jl: v0.14.2, JuMP.jl: v1.22.2, PowerModels.jl: v0.21.2.

I ran the following code (I reduced the time limit to 15 seconds):

using JuMP, KNITRO, PowerModels

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, MOI.TimeLimitSec() => 15)

solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)

And here is the solver log, which does not seem to indicate that the time limit is taken:

MINLP solver shifted start point to satisfy bounds (32 variables).
WARNING: Problem appears to have nonlinear equalities and be non-convex.
         The Knitro mixed integer solver is designed for convex problems.
         For non-convex problems it is only a heuristic, and the reported
         bounds and optimality claims cannot be verified.

datacheck:               0
hessian_no_f:            1
numthreads:              1
mip_numthreads:          1
Knitro changing mip_method from AUTO to 1.
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_mir from AUTO to 1.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic_strategy from AUTO to 1.
Knitro changing mip_heuristic_feaspump from AUTO to 1.
Knitro changing mip_heuristic_mpec from AUTO to 1.
Knitro changing mip_heuristic_diving from AUTO to 0.
Knitro changing mip_heuristic_lns from AUTO to 0.
Knitro changing mip_pseudoinit from AUTO to 1.

Problem Characteristics
-----------------------
Objective goal:  Minimize
Objective type:  quadratic
Number of variables:                                304
    bounded below only:                               0
    bounded above only:                               0
    bounded below and above:                        279
    fixed:                                            1
    free:                                            24
Number of binary variables:                          38
Number of integer variables:                          0
Number of constraints:                              353
    linear equalities:                               48
    quadratic equalities:                             1
    gen. nonlinear equalities:                      152
    linear one-sided inequalities:                    0
    quadratic one-sided inequalities:               152
    gen. nonlinear one-sided inequalities:            0
    linear two-sided inequalities:                    0
    quadratic two-sided inequalities:                 0
    gen. nonlinear two-sided inequalities:            0
Number of nonzeros in Jacobian:                    1588
Number of nonzeros in Hessian:                      572

Knitro detected 0 GUB constraints
Knitro derived 0 knapsack covers after examining 0 constraints
Knitro using Branch and Bound method with 1 thread.

       Nodes        Best solution   Best bound      Gap       Time 
   Expl  |  Unexpl      value         value                  (secs)
   ---------------  -------------   ----------      ---      ------
      1       0                        73133.8                0.079
      1       0      76747.8   FP      73133.8      4.71%     0.419
     48      26      75892.1 FCRD      75763.2      0.17%    21.038
     52      26      75762.0 LEAF      75769.0     -0.01%    21.284

EXIT: Optimal solution found (assuming convexity).

HINT: The problem may be a non-convex mixed-integer problem.  Set
      mip_multistart=1 to enable a mixed-integer multistart heuristic,
      which may improve the chances of finding the global solution.

Final Statistics for MIP
------------------------
Final objective value               =  7.57620054342590e+04
Final bound value                   =  7.57690388360681e+04
Final optimality gap (abs / rel)    =  -7.03e+00 / -9.28e-05 (-0.01%)
# of nodes processed                =  52 (6.501s)
# of strong branching evaluations   =  33 (14.176s)
# of function evaluations           =  39322 (2.381s)
# of gradient evaluations           =  25722 (0.359s)
# of hessian evaluations            =  26025 (4.023s)
# of hessian-vector evaluations     =  0
# of subproblems processed          =  125 (21.244s)
Total program time (secs)           =  21.28451 (21.284 CPU time)
Time spent in evaluations (secs)    =  0.00017

Cuts statistics (computed / added)
----------------------------------
Knapsack cuts                       =  0 / 0
Mixed-Integer Rounding cuts         =  0 / 0

Heuristics statistics (calls / successes / time)
------------------------------------------------
Feasibility pump                    =  1 / 1 / 0.340s
Rounding heuristic                  =  1 / 1 / 0.018s
MPEC heuristic                      =  1 / 0 / 0.226s

===========================================================================

Dict{String, Any} with 8 entries:
  "solve_time"         => 21.284
  "optimizer"          => "Knitro"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 75762.0
  "solution"           => Dict{String, Any}("baseMVA"=>100.0, "branch"=>Dict{String, Any}("24"=>Dict{String, Any}("qf"=>-0.414671, "qt"=>0.379171, "br_status"=…
  "objective_lb"       => 75769.0
odow commented 2 months ago

What about:

using JuMP, KNITRO, PowerModels
minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "maxtime_real" => 15.0)

We should probably contact Artelys support about this.

odow commented 2 months ago

Can you check that any options work?

julia> using JuMP, KNITRO, PowerModels

julia> minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "outlev" => 0)
MathOptInterface.OptimizerWithAttributes(KNITRO.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("outlev") => 0])

julia> solve_ots("pglib_opf_case14_ieee__api.m", ACPPowerModel, minlp_solver)
[info | PowerModels]: removing 3 cost terms from generator 4: Float64[]
[info | PowerModels]: removing 1 cost terms from generator 1: [792.0951, 0.0]
[info | PowerModels]: removing 3 cost terms from generator 5: Float64[]
[info | PowerModels]: removing 1 cost terms from generator 2: [2326.9494, 0.0]
[info | PowerModels]: removing 3 cost terms from generator 3: Float64[]
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####
Dict{String, Any} with 8 entries:
  "solve_time"         => 0.000871
  "optimizer"          => "Knitro"
  "termination_status" => INTERRUPTED
  "dual_status"        => UNKNOWN_RESULT_STATUS
  "primal_status"      => UNKNOWN_RESULT_STATUS
  "objective"          => 0.0
  "solution"           => Dict{String, Any}("baseMVA"=>100.0, "branch"=>Dict{String, Any}("4"=>Dict{…
  "objective_lb"       => -1.79769e308
chengg04 commented 2 months ago

The outlev=>0 option works.

For maxtime_real, the log shows that this option is taken. However, the solver still does not stop at the time limit. I guess maxtime_cpu is needed to impose the time limit, and KNITRO.jl has trouble just for this one option...Here is the code I use:

using JuMP, KNITRO, PowerModels

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "maxtime_real" => 5.0)

solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)

And here is the log. The maxtime_real option is shown in line 3 of the log:

datacheck:               0
hessian_no_f:            1
maxtime_real:            5
numthreads:              1
mip_numthreads:          1
Knitro changing mip_method from AUTO to 1.
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_mir from AUTO to 1.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic_strategy from AUTO to 1.
Knitro changing mip_heuristic_feaspump from AUTO to 1.
Knitro changing mip_heuristic_mpec from AUTO to 1.
Knitro changing mip_heuristic_diving from AUTO to 0.
Knitro changing mip_heuristic_lns from AUTO to 0.
Knitro changing mip_pseudoinit from AUTO to 1.

Problem Characteristics
-----------------------
Objective goal:  Minimize
Objective type:  quadratic
Number of variables:                                304
    bounded below only:                               0
    bounded above only:                               0
    bounded below and above:                        279
    fixed:                                            1
    free:                                            24
Number of binary variables:                          38
Number of integer variables:                          0
Number of constraints:                              353
    linear equalities:                               48
    quadratic equalities:                             1
    gen. nonlinear equalities:                      152
    linear one-sided inequalities:                    0
    quadratic one-sided inequalities:               152
    gen. nonlinear one-sided inequalities:            0
    linear two-sided inequalities:                    0
    quadratic two-sided inequalities:                 0
    gen. nonlinear two-sided inequalities:            0
Number of nonzeros in Jacobian:                    1588
Number of nonzeros in Hessian:                      572

Knitro detected 0 GUB constraints
Knitro derived 0 knapsack covers after examining 0 constraints
Knitro using Branch and Bound method with 1 thread.

       Nodes        Best solution   Best bound      Gap       Time 
   Expl  |  Unexpl      value         value                  (secs)
   ---------------  -------------   ----------      ---      ------
      1       0                        73133.8                0.079
      1       0      76747.8   FP      73133.8      4.71%     0.421
     48      26      75892.1 FCRD      75763.2      0.17%    21.045
     52      26      75762.0 LEAF      75769.0     -0.01%    21.291

EXIT: Optimal solution found (assuming convexity).

HINT: The problem may be a non-convex mixed-integer problem.  Set
      mip_multistart=1 to enable a mixed-integer multistart heuristic,
      which may improve the chances of finding the global solution.

Final Statistics for MIP
------------------------
Final objective value               =  7.57620054342590e+04
Final bound value                   =  7.57690388360681e+04
Final optimality gap (abs / rel)    =  -7.03e+00 / -9.28e-05 (-0.01%)
# of nodes processed                =  52 (6.518s)
# of strong branching evaluations   =  33 (14.166s)
# of function evaluations           =  39322 (2.340s)
# of gradient evaluations           =  25722 (0.356s)
# of hessian evaluations            =  26025 (4.085s)
# of hessian-vector evaluations     =  0
# of subproblems processed          =  125 (21.250s)
Total program time (secs)           =  21.29098 (21.292 CPU time)
Time spent in evaluations (secs)    =  0.00015

Cuts statistics (computed / added)
----------------------------------
Knapsack cuts                       =  0 / 0
Mixed-Integer Rounding cuts         =  0 / 0

Heuristics statistics (calls / successes / time)
------------------------------------------------
Feasibility pump                    =  1 / 1 / 0.341s
Rounding heuristic                  =  1 / 1 / 0.018s
MPEC heuristic                      =  1 / 0 / 0.225s

===========================================================================

Dict{String, Any} with 8 entries:
  "solve_time"         => 21.292
  "optimizer"          => "Knitro"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 75762.0
  "solution"           => Dict{String, Any}("baseMVA"=>100.0, "branch"=>Dict{String, Any}("24"=>Dict{String, Any}("qf"=>-0.414671, "qt"=>0.379171, "br_status"=…
  "objective_lb"       => 75769.0
odow commented 2 months ago

KNITRO.jl has trouble just for this one option

To clarify: this appears to be a problem with the upstream solver and not with KNITRO.jl. We don't do anything other than pass options straight through.

Bougron commented 2 months ago

I'm a member of Knitro development team, do not hesitate to contact us at support when you encounter an issue with Knitro itself. If you are trying to solve a MINLP problem, you should use mip_maxtime_cpu and mip_maxtime_real (all options are described in online documentation). Let me know how it goes.

chengg04 commented 2 months ago

Thank you very much for the follow up.

I tried both options, and for both of them, I encountered the error MathOptInterface.UnsupportedAttribute. More specifically, if I run the following:

using JuMP, KNITRO, PowerModels

minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "mip_maxtime_cpu" => 5.0)

solve_ots("pglib_opf_case24_ieee_rts__sad.m", ACPPowerModel, minlp_solver)

then I will get the error:

ERROR: LoadError: MathOptInterface.UnsupportedAttribute{MathOptInterface.RawOptimizerAttribute}: Attribute MathOptInterface.RawOptimizerAttribute("mip_maxtime_cpu") is not supported by the model.
Stacktrace:
  [1] set(model::KNITRO.Optimizer, attr::MathOptInterface.RawOptimizerAttribute, value::Float64)
    @ KNITRO ~/.julia/packages/KNITRO/FWSi0/src/MOI_wrapper.jl:316
  [2] _instantiate_and_check(optimizer_constructor::MathOptInterface.OptimizerWithAttributes)
    @ MathOptInterface ~/.julia/packages/MathOptInterface/aJZbq/src/instantiate.jl:120
  [3] instantiate(optimizer_constructor::Any; with_bridge_type::Type{Float64}, with_cache_type::Nothing)
    @ MathOptInterface ~/.julia/packages/MathOptInterface/aJZbq/src/instantiate.jl:175
  [4] set_optimizer(model::Model, optimizer_constructor::Any; add_bridges::Bool)
    @ JuMP ~/.julia/packages/JuMP/7rBNn/src/optimizer_interface.jl:493
  [5] set_optimizer(model::Model, optimizer_constructor::Any)
    @ JuMP ~/.julia/packages/JuMP/7rBNn/src/optimizer_interface.jl:491
  [6] optimize_model!(aim::ACPPowerModel; relax_integrality::Bool, optimizer::MathOptInterface.OptimizerWithAttributes, solution_processors::Vector{Any})
    @ InfrastructureModels ~/.julia/packages/InfrastructureModels/C2xBM/src/core/base.jl:387
  [7] solve_model(data::Dict{String, Any}, model_type::Type, optimizer::MathOptInterface.OptimizerWithAttributes, build_method::typeof(build_ots); ref_extensions::Vector{typeof(ref_add_on_off_va_bounds!)}, solution_processors::Vector{Any}, relax_integrality::Bool, multinetwork::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PowerModels ~/.julia/packages/PowerModels/Dhfhc/src/core/base.jl:37
  [8] solve_model(file::String, model_type::Type, optimizer::MathOptInterface.OptimizerWithAttributes, build_method::Function; kwargs::Base.Iterators.Pairs{Symbol, Vector{typeof(ref_add_on_off_va_bounds!)}, Tuple{Symbol}, NamedTuple{(:ref_extensions,), Tuple{Vector{typeof(ref_add_on_off_va_bounds!)}}}})
    @ PowerModels ~/.julia/packages/PowerModels/Dhfhc/src/core/base.jl:18
  [9] #solve_ots#1043
    @ ~/.julia/packages/PowerModels/Dhfhc/src/prob/ots.jl:9 [inlined]
 [10] solve_ots(file::String, model_type::Type, optimizer::MathOptInterface.OptimizerWithAttributes)
    @ PowerModels ~/.julia/packages/PowerModels/Dhfhc/src/prob/ots.jl:9

And the same for mip_maxtime_real.

odow commented 2 months ago

@Bougron, there does seem to be an issue with the C API:

When getting the param ID, it requires mip_maxtimecpu, and when setting, it requires mip_maxtime_cpu:

julia> using KNITRO

julia> model = KNITRO.Optimizer();
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####

julia> kc = model.inner;

julia> param_id = Ref{Cint}(0);

julia> KN_get_param_id(kc, "mip_maxtime_cpu", param_id)
-521

julia> param_id
Base.RefValue{Int32}(0)

julia> KN_get_param_id(kc, "mip_maxtimecpu", param_id)
0

julia> param_id
Base.RefValue{Int32}(2006)

julia> KN_set_double_param_by_name(kc, "mip_maxtime_cpu", 3.0)
0

julia> KN_set_double_param_by_name(kc, "mip_maxtimecpu", 3.0)
-516

297 works around this by using only the id version, so once merged, "mip_maxtimecpu" should work.

odow commented 2 months ago

Using #297, I get:

julia> using JuMP, KNITRO, PowerModels

julia> minlp_solver = JuMP.optimizer_with_attributes(KNITRO.Optimizer, "mip_maxtimereal" => 0.0)
MathOptInterface.OptimizerWithAttributes(KNITRO.Optimizer, Pair{MathOptInterface.AbstractOptimizerAttribute, Any}[MathOptInterface.RawOptimizerAttribute("mip_maxtimereal") => 0.0])

julia> solve_ots("pglib_opf_case14_ieee__api.m", ACPPowerModel, minlp_solver)
[info | PowerModels]: removing 3 cost terms from generator 4: Float64[]
[info | PowerModels]: removing 1 cost terms from generator 1: [792.0951, 0.0]
[info | PowerModels]: removing 3 cost terms from generator 5: Float64[]
[info | PowerModels]: removing 1 cost terms from generator 2: [2326.9494, 0.0]
[info | PowerModels]: removing 3 cost terms from generator 3: Float64[]
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####
##### This license is only intended for use by JuMP dev. #####
##### License is valid until Dec 31, 2024 #####

=======================================
            Student License
       (NOT FOR COMMERCIAL USE)
         Artelys Knitro 13.1.0
=======================================

WARNING: Problem appears to have nonlinear equalities and be non-convex.
         The Knitro mixed integer solver is designed for convex problems.
         For non-convex problems it is only a heuristic, and the reported
         bounds and optimality claims cannot be verified.

datacheck:               0
hessian_no_f:            1
numthreads:              1
mip_maxtime_real:        0
mip_numthreads:          1
Knitro changing mip_method from AUTO to 1.
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_mir from AUTO to 1.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic_strategy from AUTO to 1.
Knitro changing mip_heuristic_feaspump from AUTO to 1.
Knitro changing mip_heuristic_misqp from AUTO to 0.
Knitro changing mip_heuristic_mpec from AUTO to 1.
Knitro changing mip_heuristic_diving from AUTO to 0.
Knitro changing mip_heuristic_lns from AUTO to 0.
Knitro changing mip_pseudoinit from AUTO to 1.

Problem Characteristics
-----------------------
Objective goal:  Minimize
Objective type:  linear
Number of variables:                                138
    bounded below only:                               0
    bounded above only:                               0
    bounded below and above:                        121
    fixed:                                            3
    free:                                            14
Number of binary variables:                          20
Number of integer variables:                          0
Number of constraints:                              189
    linear equalities:                               28
    quadratic equalities:                             1
    gen. nonlinear equalities:                       80
    linear one-sided inequalities:                    0
    quadratic one-sided inequalities:                80
    gen. nonlinear one-sided inequalities:            0
    linear two-sided inequalities:                    0
    quadratic two-sided inequalities:                 0
    gen. nonlinear two-sided inequalities:            0
Number of nonzeros in Jacobian:                     812
Number of nonzeros in Hessian:                      302

Knitro detected 0 GUB constraints
Knitro derived 0 knapsack covers after examining 0 constraints
Knitro using Branch and Bound method with 1 thread.

       Nodes        Best solution   Best bound      Gap       Time 
   Expl  |  Unexpl      value         value                  (secs)
   ---------------  -------------   ----------      ---      ------

EXIT: Time limit reached. No integer feasible point found.

HINT: The problem may be a non-convex mixed-integer problem.  Set
      mip_multistart=1 to enable a mixed-integer multistart heuristic,
      which may improve the chances of finding the global solution.

Final Statistics for MIP
------------------------
Final objective value               =
Final bound value                   =  0.00000000000000e+00
Final optimality gap (abs / rel)    =  Infinity
# of nodes processed                =  0 (0.000s)
# of strong branching evaluations   =  0 (0.000s)
# of function evaluations           =  2 (0.000s)
# of gradient evaluations           =  1 (0.000s)
# of hessian evaluations            =  0 (0.000s)
# of hessian-vector evaluations     =  0
# of subproblems processed          =  0 (0.000s)
Total program time (secs)           =  0.00067 (0.001 CPU time)
Time spent in evaluations (secs)    =  0.00016

Cuts statistics (computed / added)
----------------------------------
Knapsack cuts                       =  0 / 0
Mixed-Integer Rounding cuts         =  0 / 0

Heuristics statistics (calls / successes / time)
------------------------------------------------
Feasibility pump                    =  0 / 0 / 0.000s
Rounding heuristic                  =  0 / 0 / 0.000s
MPEC heuristic                      =  0 / 0 / 0.000s

===========================================================================

Dict{String, Any} with 8 entries:
  "solve_time"         => 0.00072
  "optimizer"          => "Knitro"
  "termination_status" => TIME_LIMIT
  "dual_status"        => INFEASIBLE_POINT
  "primal_status"      => INFEASIBLE_POINT
  "objective"          => 0.0
  "solution"           => Dict{String, Any}("baseMVA"=>100.0, "branch"=>Dict{String, Any}("4"=>Dict{…
  "objective_lb"       => 0.0

so it is working.

@Bougron, as a secondary request then, shouldn't "maxtime_real" set the time limit regardless of which method is used to solve? The docs do not make it clear that this doesn't apply to MIP solves.

Bougron commented 2 months ago

Yes this is expected (even though I understand it is confusing), the documentation mentions it in the description: When solving a mip, the maxtime_real is solved to limit time on subproblems.

Bougron commented 2 months ago

Regarding the naming, we are checking it out (mip_maxtimecpu vs mip_maxtime_cpu).

odow commented 2 months ago

Ah, then perhaps all that is needed is that for the documentation of maxtime_real it clarifies that this applies to subproblems, and to use the various xxx_maxtime_real depending on the algorithm used to solve.

I see that other options have this wording, but it is missing from the maxtime_real and maxtime_cpu options.

odow commented 2 months ago

This will be fixed when I release #301