Other programmatic interfaces
This chapter discusses interfaces to C++, C#, Java, Fortran and Python offered by the Knitro callable library.
Knitro in a C++ application
C++ driver-based interface has been superseded by C++ object-oriented interface, see Object-oriented interface reference. The C++ driver and examples are not available anymore since Knitro 10.0.
Calling Knitro from a C++ application follows the same outline
as a C application. The distribution provides a C++ general test harness
in the directory
examples/C++. In the example, optimization problems
are coded as subclasses of an abstract interface and compiled as separate shared
objects. A main driver program dynamically loads a problem and sets up
callback mode so Knitro can invoke the
particular problem’s evaluation methods. The main driver can also use
Knitro to conveniently check partial derivatives against
It is easy to add more test problems to the test environment.
Knitro in a C# application
Calling Knitro from a C# application is similar to using the
object-oriented interface in C++. The primary difference between the C++
and C# version of the object-oriented interface is in the syntax and function
name capitalization. The C# function names are capitalized, and the functions
IList<> (implemented as
List<>) for function arguments and return values.
The C# object-oriented interface requires .NET Version 4.0 and up.
The interface uses P/Invoke to call the C Knitro callable library and
convert data and function signatures between C# and C,
knitro.h and the
knitro.dll dynamic library.
Examples of problem definitions and Knitro callbacks in C# can be found in the example folders distributed with Knitro, and the source code for the interface is provided for informational purposes.
Knitro in a Java application
Calling Knitro from a Java application is similar to using the object-oriented interface in C++. The primary difference between the C++ and Java version of the object-oriented interface is in the syntax. The Java function names are capitalized, and the functions use List<> (implemented as ArrayList<>) for function arguments and return values.
The Java object-oriented interface requires Java 1.6 and up.
The interface uses JNA (Java Native Access) to call the C Knitro callable
library and convert data and function signatures between Java and C,
knitro.h and the
knitro.dll dynamic library
libknitro.so on Linux;
libknitro.dylib on Mac OS X).
Examples of problem definitions and Knitro callbacks in Java can be found in the example folders distributed with Knitro, and the source code for the interface is provided for informational purposes.
Knitro in a Fortran application
Calling Knitro from a Fortran application follows the same outline
as a C application. The optimization problem must be defined in terms of
arrays and constants that follow the old pre-Knitro 11.0 API, and then the
Fortran version of
KTR_init_problem() is called. Fortran
integer and double precision types map directly to
C int and double types.
Fortran applications require wrapper functions written in C to (1) isolate the KTR_context structure, which has no analog in unstructured Fortran, (2) convert C function names into names recognized by the Fortran linker, and (3) renumber array indices to start from zero (the C convention used by Knitro) for applications that follow the Fortran convention of starting from one. The wrapper functions can be called from Fortran with exactly the same arguments as their C language counterparts, except for the omission of the KTR_context argument.
An example Fortran program and set of C wrappers is provided in
The example loads the matrix
sparsity of the optimization problem with indices that start numbering
from zero, and therefore requires no conversion from the Fortran convention
of numbering from one. The C wrappers provided are sufficient for the
simple example, but do not implement all the functionality of the Knitro
callable library. Users are free to write their own C wrapper routines, or
extend the example wrappers as needed.
Knitro in a Python application
Knitro provides a Python interface for the Knitro callable library functions defined
knitro.h. The Python API loads directly the Knitro library (
knitro.dll on Windows;
libknitro.so on Unix;
libknitro.dylib on Mac OS X). With this interface, Python
applications can create a Knitro solver instance and call Python methods that execute the
corresponding Knitro functions. The Python form of Knitro is thread-safe, which means that a
Python application can create multiple instances of a Knitro solver in different threads, each
instance solving a different problem. This feature might be important in an application
that is deployed on a web server. However, please note that Python interpreters are usually not
thread safe so callbacks cannot be evaluated in parallel. Thus
always initialized to 0/’no’ in the Python interface, but may still be set to 1/’yes’ by the user.
Calling Knitro from a Python application follows the same outline as a C application, with the same methods. C int and double types are automatically mapped into their Python counterparts (int and float). C arrays are automatically mapped into Python list types. C pointers to native C types are automatically mapped into the corresponding Python native type. Methods that accept NULL values in C also accept None values in Python.
The definition of the optimization problem is similar to the Knitro C API, building a model in pieces
while providing specific structures to Knitro (e.g. linear or quadratic structures), while providing
callbacks to handle general nonlinear structures.
The call sequence for using Knitro is almost exactly the same as C applications that call
knitro.h functions with a KN_context_ptr object.
A typical sequence of function calls is as follows:
KN_new(): create a new Knitro solver context pointer, allocating resources.
KN_set_*bnds(): add basic problem information to Knitro.
KN_add_*_quadratic_struct(): add specific problem structures.
KN_add_eval_callback(): add callback for nonlinear evaluations if needed.
KN_set_cb_*(): set properties for nonlinear evaluation callbacks.
KN_set_*_param(): set user options/parameters.
KN_solve(): solve the problem.
KN_free(): delete the Knitro context pointer, releasing allocated resources.
A major difference between the C and Python APIs is the handling of function return codes.
In C, Knitro functions always return an integer code, which is 0 in case of success and non-zero
in case of error. C users have to check the return code to make sure that each function was executed
In Python, Knitro functions raise Python errors in case of failure to execute the function. Some
functions do not return anything (such as
KN_set_*_param()) and some return the expected
output (such as
Python functions can be provided as callbacks for Knitro as long as they follow
the corresponding callback function prototypes (defined in
Although the Python language makes it unnecessary, Python objects may be passed to the
callback function through the userParams argument.
To write a Python application, take a look at the sample programs in
The sample programs can be run directly from the command line after installing
knitro.py (or making sure that
knitro.py is in the folder containing
the example source file). The sample programs provided closely mirror the structural
form of the C examples.
The Numpy module is also supported by the additional module
knitroNumPy.py file and allows
the use of Numpy arrays instead of Python lists. Take a look at sample program
exampleNLP1NumPy.py that illustrates the use of Numpy.
The Knitro Python API supports Python versions 2.7 and 3.6.