KNITRO.jl is a wrapper for the Artelys Knitro solver.
It has two components:
- a thin wrapper around the C API
- an interface to MathOptInterface.
This wrapper is maintained by the JuMP community with help from Artelys.
Contact Artelys support if you encounter any problem with this interface or the solver.
KNITRO.jl is licensed under the MIT License.
The underlying solver is a closed-source commercial product for which you must purchase a license.
Install KNITRO.jl as follows:
import Pkg
Pkg.add("KNITRO")In addition to installing the KNITRO.jl package, this will also download and install the KNITRO binaries from KNITRO_jll.jl. You do not need to install the KNITRO binaries separately.
To install a particular version of KNITRO, install the corresponding version of KNITRO_jll.jl. For example:
import Pkg; Pkg.pkg"add [email protected]"This section explains how to opt-out of using the KNITRO_jll binaries.
First, obtain a license and install a copy of KNITRO from Artelys.
Once installed, set the KNITRODIR environment variable to point to the
directory of your KNITRO installation, so that the file
${KNITRODIR}/lib/libknitro exists.
Then, set the KNITRO_JL_USE_KNITRO_JLL environment variable to "false" and
run Pkg.add("KNITRO"). For example:
ENV["KNITRODIR"] = "/path/to/knitro"
ENV["KNITRO_JL_USE_KNITRO_JLL"] = "false"
import Pkg
Pkg.add("KNITRO")
using KNITRO
KNITRO.has_knitro() # true if installed correctlyTo change the location of a manual install, change the value of KNITRODIR,
call Pkg.build("KNITRO"), and then restart Julia.
To revert to the KNITRO_jll binaries, do:
ENV["KNITRO_JL_USE_KNITRO_JLL"] = "true"
import Pkg
Pkg.build("KNITRO")then restart Julia.
To use KNITRO with JuMP, use KNITRO.Optimizer:
using JuMP, KNITRO
model = Model(KNITRO.Optimizer)
set_attribute(model, "outlev", 1)
set_attribute(model, "algorithm", 4)To use KNITRO's license manager, do:
using JuMP, KNITRO
manager = KNITRO.LMcontext()
model_1 = Model(() -> KNITRO.Optimizer(; license_manager = manager))
model_2 = Model(() -> KNITRO.Optimizer(; license_manager = manager))To release the license manager, do KNITRO.KN_release_license(manager).
KNITRO.jl v0.14.7 moved the KNITRO.Optimizer object to a package extension. As
a consequence, KNITRO.Optimizer is now type unstable, and it will be inferred
as KNITRO.Optimizer()::Any.
In most cases, this should not impact performance. If it does, there are two work-arounds.
First, you can use a function barrier:
using JuMP, KNITRO
function main(optimizer::T) where {T}
model = Model(optimizer)
return
end
main(KNITRO.Optimizer)Although the outer KNITRO.Optimizer is type unstable, the optimizer inside
main will be properly inferred.
Second, you may explicitly get and use the extension module:
using JuMP, KNITRO
const KNITROMathOptInterfaceExt =
Base.get_extension(KNITRO, :KNITROMathOptInterfaceExt)
model = Model(KNITROMathOptInterfaceExt.Optimizer)To use KNITRO with AmplNLWriter.jl,
use KNITRO.amplexe:
using JuMP
import AmplNLWriter
import KNITRO
model = Model(() -> AmplNLWriter.Optimizer(KNITRO.amplexe, ["outlev=3"]))A variety of packages extend KNITRO.jl to support other optimization modeling systems. These include:
The Knitro optimizer supports the following constraints and attributes.
List of supported objective functions:
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}MOI.ObjectiveFunction{MOI.ScalarNonlinearFunction}MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}}MOI.ObjectiveFunction{MOI.VariableIndex}
List of supported variable types:
List of supported constraint types:
MOI.ScalarAffineFunction{Float64}inMOI.EqualTo{Float64}MOI.ScalarAffineFunction{Float64}inMOI.GreaterThan{Float64}MOI.ScalarAffineFunction{Float64}inMOI.Interval{Float64}MOI.ScalarAffineFunction{Float64}inMOI.LessThan{Float64}MOI.ScalarNonlinearFunctioninMOI.EqualTo{Float64}MOI.ScalarNonlinearFunctioninMOI.GreaterThan{Float64}MOI.ScalarNonlinearFunctioninMOI.Interval{Float64}MOI.ScalarNonlinearFunctioninMOI.LessThan{Float64}MOI.ScalarQuadraticFunction{Float64}inMOI.EqualTo{Float64}MOI.ScalarQuadraticFunction{Float64}inMOI.GreaterThan{Float64}MOI.ScalarQuadraticFunction{Float64}inMOI.Interval{Float64}MOI.ScalarQuadraticFunction{Float64}inMOI.LessThan{Float64}MOI.VariableIndexinMOI.EqualTo{Float64}MOI.VariableIndexinMOI.GreaterThan{Float64}MOI.VariableIndexinMOI.IntegerMOI.VariableIndexinMOI.Interval{Float64}MOI.VariableIndexinMOI.LessThan{Float64}MOI.VariableIndexinMOI.ZeroOneMOI.VectorAffineFunction{Float64}inMOI.SecondOrderConeMOI.VectorOfVariablesinMOI.ComplementsMOI.VectorOfVariablesinMOI.SecondOrderCone
List of supported model attributes:
A list of available options is provided in the KNITRO reference manual.
The complete C API can be accessed via KNITRO.KN_xx functions, where the names
and arguments are identical to the C API.
See the KNITRO documentation for details.
As general rules when converting from Julia to C:
- When KNITRO requires a
Ptr{T}that holds one element, likedouble *, use aRef{T}(). - When KNITRO requires a
Ptr{T}that holds multiple elements, use aVector{T}. - When KNITRO requires a
double, useCdouble - When KNITRO requires an
int, useCint - When KNITRO requires a
NULL, useC_NULL
Extensive examples using the C wrapper can be found in examples/.
KNITRO.jl v0.14.0 introduced a number of breaking changes to the low-level C API. The main changes were:
- removing Julia-specific functions like
KN_set_param. Use the C API functions likeKN_set_int_paramandKN_set_double_param_by_name. - removing intermediate methods that tried to make the C API more Julia-like.
For example, we have removed the
KN_add_varmethod that returned the index of the variable. There is now only the method from the C API.
If you have trouble updating, please open a GitHub issue.
Due to limitations in the interaction between Julia and C, KNITRO.jl disables
multi-threading if the problem is nonlinear. This will override any options such
as par_numthreads that you may have set.
If you are using the low-level API, opt-in to enable multi-threading by calling
KN_solve(model.env) instead of KN_solve(model), where model is the value
returned by model = KN_new(). Note that calling KN_solve(model.env) is an
advanced operation because it requires all callbacks you provide to be threadsafe.
Read GitHub issue #93 for more details.