# Julia with Knitro

**URL:** <https://discourse.julialang.org/t/julia-with-knitro/81686>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [May 25, 2022, 10:00pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686 "2022-05-25T22:00:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![joyce\_azevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joyce_azevedo/32/36608_2.png) [@joyce\_azevedo](https://discourse.julialang.org/u/joyce_azevedo)\
**Post date:** [May 25, 2022, 10:00pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/1 "2022-05-25T22:00:20Z")

</div>

Hey everyone! I’m trying to set a time limit and a gap in Julia using Knitro, but not having success:

m = Model(KNITRO.Optimizer)  
set\_optimizer\_attribute(m, “maxtime\_cpu”, 3.6e+2)  
set\_optimizer\_attribute(m, “mip\_opt\_gap\_abs”, 1.0e+0)

**ERROR: MathOptInterface.UnsupportedAttribute**

Does anyone know how to set these parameters?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [May 26, 2022, 1:49am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/2 "2022-05-26T01:49:07Z")

</div>

Hello and welcome. I’ve moved this to the Optimization area to get more 👀 on it.

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [May 26, 2022, 2:10am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/3 "2022-05-26T02:10:24Z")

</div>

> [@joyce\_azevedo](#):
>
> set\_optimizer\_attribute(m, “maxtime\_cpu”, 3.6e+2)

This specifically can be set using a function from JuMP itself:  
`set_time_limit_sec(m, 3.6e+2)`  
where the value is in seconds.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [May 26, 2022, 3:22am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/4 "2022-05-26T03:22:40Z")

</div>

> **ERROR: MathOptInterface.UnsupportedAttribute**

What is the full error? Does it happen with `maxtime_cpu` or `mip_opt_gap_abs`?

---

<div class="post-metadata">

**Author:** ![joyce\_azevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joyce_azevedo/32/36608_2.png) [@joyce\_azevedo](https://discourse.julialang.org/u/joyce_azevedo)\
**Post date:** [May 26, 2022, 12:45pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/5 "2022-05-26T12:45:42Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![joyce\_azevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joyce_azevedo/32/36608_2.png) [@joyce\_azevedo](https://discourse.julialang.org/u/joyce_azevedo)\
**Post date:** [May 26, 2022, 12:46pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/6 "2022-05-26T12:46:42Z")

</div>

I tried to do it this way, but the runtime remains longer than what was set in parameter ☹

---

<div class="post-metadata">

**Author:** ![joyce\_azevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joyce_azevedo/32/36608_2.png) [@joyce\_azevedo](https://discourse.julialang.org/u/joyce_azevedo)\
**Post date:** [May 26, 2022, 12:49pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/7 "2022-05-26T12:49:04Z")

</div>

Sorry! It’s just happening with the _maxtime\_cpu_. For _mip\_opt\_gap\_abs_, model processing is not interrupted when it reaches the established gap.

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [September 26, 2023, 8:40am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/8 "2023-09-26T08:40:03Z")

</div>

Hi, I’m trying this but the `set_time_limit_sec` is completely ignored. I’m also using `InfiniteOpt.jl`, can this be the reason?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 26, 2023, 8:06pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/9 "2023-09-26T20:06:34Z")

</div>

> Hi, I’m trying this but the `set_time_limit_sec` is completely ignored

Do you have a reproducible example?

---

<div class="post-metadata">

**Author:** ![pulsipher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pulsipher/32/10461_2.png) [@pulsipher](https://discourse.julialang.org/u/pulsipher)\
**Post date:** [September 27, 2023, 1:43pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/10 "2023-09-27T13:43:09Z")

</div>

InfiniteOpt.jl just passes the `set_time_limit_sec` call directly to the underlying JuMP model (referred to as the `optimizer_model`): [https://github.com/infiniteopt/InfiniteOpt.jl/blob/f0929c6990c18b6bfe2adb2384146074072b9466/src/optimize.jl#L249-L263](https://github.com/infiniteopt/InfiniteOpt.jl/blob/f0929c6990c18b6bfe2adb2384146074072b9466/src/optimize.jl#L249-L263)

From my experience, KNITRO and other solvers will not exactly terminate at the time limit since they only check the wall-time in-between iterations. It is hard to say more without seeing the your code.

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [September 27, 2023, 4:29pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/11 "2023-09-27T16:29:56Z")

</div>

Sorry no MWE, the full program has like 2000 lines.  
Some pseudo-code goes like this:

```julia
using InfiniteOpt, JuMP, KNITRO

function solvePolicies(optimizer, # model optimizer
    sets::modelSettings, # number of EVs, discrete time supports, etc.
    data::Dict, # information for the model (mainly parameters), these are the devices (EV, BESS, PV, etc.), the costs (interests, capex, etc) and the revenues
    )
    # Sets
    tend=sets.dTime[end]
    t0=sets.dTime[1]; # initial time, can´t divide by 0

    model = InfiniteModel(optimizer) # create model
    # KNITRO attributes
    set_optimizer_attributes(model, 
                            "feastol" => 1e-3,
                            "mip_multistart"=> 1,
                            "mip_outlevel"=> 2,
                            "mip_method"=> 1, 
                            "mip_heuristic_maxit"=>800,
                            )
    set_time_limit_sec(model, 60*15);

    # define cont t
    @infinite_parameter(model, t in [t0, tend], supports = collect(sets.dTime), derivative_method = FiniteDifference(Forward(),true))

    # Add variables, constraints, obj
    model = build_model(model, sets, data); # <== this is were the magic happens
    # Solve model
    optimize!(model)
    results = getResults(model) # save results
    MOI.empty!(InfiniteOpt.backend(model)) # clean MOI
    return results;
end;

function getResults(model)
  x = all_variables(model)
  xdf=DataFrame(
      name = name.(x),
      value = value.(x),
  )
  idx=findall(x->x=="",name.(x)) # find point variables
  delete!(xdf, idx) # delete point variables
  xdict=Dict{Any,Any}(Pair.(xdf.name, xdf.value))
  merge!(xdict,Dict("t"=>supports(model[:t]), "γ_cont"=>value.(model[:γ_cont])))
  return xdict
end

function rollingHorizon(W, # weights
    Tw, # time window [days]
    steps, # number of steps to move the window
    Δt) # time length of each step [hr]
    # Build the data dictionary
    
    data=buildDict();
    # Initialize
    tend = 24*Tw; # [hr]
    Dt=0:Δt:tend; Dt=Dt*3600; # time array in seconds
    s=modelSettings(nEV=1:2, dTime=collect(Dt), costWeights=W);
    results=Vector{Dict}(undef, steps); # allocate memory
    for ts in 1:steps
        # build+solve model
        model=solvePolicies(KNITRO.Optimizer, s, data);
        # Print solution summary
        # solution_summary(optimizer_model(model))
        results[ts]=getResults(model);
        model=InfiniteModel();
        # update data, which contains the initial conditions
        data=update_measurements(results[ts], s, data);
        # move time window
        Dt = Dt .+ Δt*3600.0;
        # update_forecasts.(data, Dt)
        s.dTime=collect(Dt);
    end
    return results, data, s
end

Wgrid = 1;
Wloss = 2;
W=[Wgrid 1000 Wloss];
results, data, s=rollingHorizon(W, 1, 4, 1/4);

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 27, 2023, 8:19pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/12 "2023-09-27T20:19:00Z")

</div>

And what happens? Does each `solvePolicies` call take longer than 15 minutes to solve?

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [September 28, 2023, 7:04am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/13 "2023-09-28T07:04:51Z")

</div>

Yes, the call to `set_time_limit_sec` is ignored basically. I also tried `maxtime_cpu` and `maxtime_time` and same luck.  
I have calls that take like 500ms and calls that take hours, depending on the timestep.

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [December 4, 2023, 9:14pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/14 "2023-12-04T21:14:03Z")

</div>

Hi! any update on this topic?  
Should I raise an issue at the `KNITRO.jl` repo?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [December 4, 2023, 11:41pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/15 "2023-12-04T23:41:29Z")

</div>

Can you try with the latest version of KNITRO.jl (v0.14.1)?

I recently made a number of improvements.

If it still persists, can you provide the full output log? What is KNITRO doing after the time limit hits?

It’s going to be hard to debug this without a reproducible example.

> Should I raise an issue at the `KNITRO.jl` repo?

No need. It’ll just be me replying over there.

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [January 25, 2024, 9:22am UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/16 "2024-01-25T09:22:32Z")

</div>

Yeah sure, this is my `] status`

```julia
(myProject) pkg> status
Status `D:\OneDrive\Simulation\Project.toml`
  [336ed68f] CSV v0.10.12
  [13f3f980] CairoMakie v0.11.5
  [35d6a980] ColorSchemes v3.24.0
  [a93c6f00] DataFrames v1.6.1
  [31c24e10] Distributions v0.25.107
  [e9467ef8] GLMakie v0.9.5
  [cc18c42c] GaussianMixtures v0.3.8
  [87dc4568] HiGHS v1.8.0
  [20393b10] InfiniteOpt v0.5.8
⌅ [a98d9a8b] Interpolations v0.14.7
  [b6b21f68] Ipopt v1.6.0
  [c8e1da08] IterTools v1.10.0
  [0f8b85d8] JSON3 v1.14.0
  [4076af6c] JuMP v1.18.1
  [67920dd8] KNITRO v0.14.1
  [b964fa9f] LaTeXStrings v1.3.1
  [a5b28938] LiiBRA v0.3.4
  [23992714] MAT v0.10.6
  [ee78f7c6] Makie v0.20.4
  [b8f27783] MathOptInterface v1.25.1
  [01bcebdf] Nonconvex v2.1.3
  [bf347577] NonconvexIpopt v0.4.2
  [b43a31b8] NonconvexNLopt v0.1.8
  [d96e819e] Parameters v0.12.3
  [ccf2f8ad] PlotThemes v3.1.0
  [995b91a9] PlotUtils v1.4.0
  [f0f68f2c] PlotlyJS v0.18.12
  [91a5bcdd] Plots v1.40.0
  [c46f51b8] ProfileView v1.7.2
  [295af30f] Revise v3.5.13
  [99342f36] StateSpaceModels v0.6.7
⌅ [2913bbd2] StatsBase v0.33.21
  [f3b207a7] StatsPlots v0.15.6
  [9e3dc215] TimeSeries v0.24.1
  [fdbf4ff8] XLSX v0.10.1
  [37e2e46d] LinearAlgebra
  [9a3f8284] Random
  [10745b16] Statistics v1.10.0

```

and I´m running my model with the following model attributes

```julia
set_optimizer_attributes(model, 
                            "tuner"=>1,
                            "scale"=>1, # 
                            "feastol" => 1e-3,
                            "mip_multistart"=> 1,
                            "mip_outlevel"=> 2,
                            "mip_method"=> 1,
                            "mip_numthreads"=> 3,
                            "mip_heuristic_maxit"=>800,
                            "mip_maxnodes" => 700,
                            )
    set_time_limit_sec(model, 60);

```

The optimization violates the time limit of 60s.  
It does however respect my `"mip_maxnodes" => 700`.  
I don’t know what the issue might be.  
Sorry that I don’t have a MWE but the issue is hard to reproduce since I’m solving a MINLP in a rolling horizon window. So depending on the model inputs `optimize!` can take values between 10ms or 2hs (stopping due to the MIP node limit).

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [January 25, 2024, 8:25pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/17 "2024-01-25T20:25:43Z")

</div>

What happens if you set the time limit in `set_optimizer_attributes` instead of calling `set_time_limit_sec`?

`"maxtime_cpu" => 60.0` or `"maxtime_real" => 60.0`

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [January 26, 2024, 1:06pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/18 "2024-01-26T13:06:45Z")

</div>

well, weirdly enough, the first `"maxtime_cpu => 60.0"` got me the following error:

```julia
ERROR: MathOptInterface.UnsupportedAttribute{MathOptInterface.RawOptimizerAttribute}: Attribute MathOptInterface.RawOptimizerAttribute("maxtime_cpu") is not supported by the model.
Stacktrace:
  [1] set(model::KNITRO.Optimizer, attr::MathOptInterface.RawOptimizerAttribute, value::Float64)
    @ KNITRO C:\Users\user\.julia\packages\KNITRO\4sI4C\src\MOI_wrapper.jl:316
  [2] set
    @ C:\Users\user\.julia\packages\MathOptInterface\3JqTJ\src\Bridges\bridge_optimizer.jl:955 [inlined]
  [3] set(model::MathOptInterface.Utilities.CachingOptimizer{…}, attr::MathOptInterface.RawOptimizerAttribute, value::Float64)
    @ MathOptInterface.Utilities C:\Users\user\.julia\packages\MathOptInterface\3JqTJ\src\Utilities\cachingoptimizer.jl:1059
  [4] set(m::Model, attr::MathOptInterface.RawOptimizerAttribute, value::Float64)
    @ JuMP C:\Users\user\.julia\packages\JuMP\027Gt\src\optimizer_interface.jl:728
  [5] set_attribute
    @ C:\Users\user\.julia\packages\JuMP\027Gt\src\optimizer_interface.jl:957 [inlined]
  [6] set_attribute
    @ C:\Users\user\.julia\packages\JuMP\027Gt\src\optimizer_interface.jl:966 [inlined]
  [7] set_optimizer_attribute
    @ C:\Users\user\.julia\packages\JuMP\027Gt\src\optimizer_interface.jl:77 [inlined]
  [8] set_optimizer_attribute
    @ C:\Users\user\.julia\packages\InfiniteOpt\WWtLl\src\optimize.jl:309 [inlined]
  [9] set_optimizer_attributes
    @ C:\Users\user\.julia\packages\InfiniteOpt\WWtLl\src\optimize.jl:356 [inlined]
Some type information was truncated. Use `show(err)` to see complete types.

```

The second one is running now. Let’s see if I can trigger something

---

<div class="post-metadata">

**Author:** ![daro.slai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daro.slai/32/48757_2.png) [@daro.slai](https://discourse.julialang.org/u/daro.slai)\
**Post date:** [January 26, 2024, 3:37pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/19 "2024-01-26T15:37:39Z")

</div>

And unfortunately its also ignored.  
Here’s the report of one my runs:

```julia
=======================================
           Academic License
       (NOT FOR COMMERCIAL USE)
         Artelys Knitro 13.2.0
=======================================

MINLP solver shifted start point to satisfy bounds (291 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
feastol: 0.001
hessian_no_f: 1
maxtime_real: 1
numthreads: 1
outappend: 1
mip_method: 1
mip_multistart 1
mip_numthreads: 1
mip_terminate: 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 2.
Knitro changing mip_clique from AUTO to 0.
Knitro changing mip_zerohalf from AUTO to 0.
Knitro changing mip_liftproject from AUTO to 0.
Knitro changing mip_knapsack from AUTO to 1.
Knitro changing mip_gomory from AUTO to 0.
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: quadratic
Number of variables: 3880
    bounded below only: 388
    bounded above only: 388
    bounded below and above: 1358
    fixed: 0
    free: 1746
Number of binary variables: 388
Number of integer variables: 0
Number of constraints: 3589
    linear equalities: 2231
    quadratic equalities: 0
    gen. nonlinear equalities: 582
    linear one-sided inequalities: 776
    quadratic one-sided inequalities: 0
    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: 9911
Number of nonzeros in Hessian: 2328

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

       Nodes Best solution Best bound Gap Time
   Expl | Unexpl value value (secs)
   --------------- ------------- ---------- --- ------
      0 0 -inf 0.023
      1 2 5.83946e-07 0.146
      1 2 5.92848e-07 FP 5.83946e-07 0.00% 4.676

EXIT: Optimal solution found (assuming convexity).

Final Statistics for MIP
------------------------
Final objective value = 5.92847868574609e-07
Final bound value = 5.83945507059980e-07
Final optimality gap (abs / rel) = 8.90e-09 / 8.90e-09 (0.00%)
# of root cutting plane rounds = 0
# of restarts = 0
# of nodes processed = 1 (0.120s)
# of strong branching evaluations = 0 (0.000s)
# of function evaluations = 455 (0.444s)
# of gradient evaluations = 374 (0.355s)
# of hessian evaluations = 369 (0.595s)
# of hessian-vector evaluations = 0
# of subproblems processed = 8 (4.635s)
Total program time (secs) = 4.680 (4.563 CPU time)
Time spent in evaluations (secs) = 1.394

Cuts statistics (gen / add)
---------------------------
Knapsack cuts = 0 / 0
Mixed-integer rounding cuts = 0 / 0

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

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

```

with:

```julia
"maxtime_real" => 1.0,

```

so almost 4.7secs of total time in KNITRO violating the 1sec limit.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [January 28, 2024, 8:55pm UTC](https://discourse.julialang.org/t/julia-with-knitro/81686/20 "2024-01-28T20:55:54Z")

</div>

If I had to guess, it’s because the code spends 4.5 seconds in the feasibility pump heuristic. So it doesn’t check time limit termination until after, and then it return with the optimal solution.

Can you send me a copy of the model? I’ll send you a private message with my email. To write the model to file, do:

`JuMP.write_to_file(model, "bug_report.nl")`

[Next page](https://discourse.julialang.org/t/julia-with-knitro/81686.md?page=2)
