.. _sec-ccode:

Generating C-code
=================

.. include:: defs.rst

The numerical evaluation of function objects in |casadi| normally takes place in *virtual machines*,
implemented as part of |casadi|'s symbolic framework. But |casadi| also supports the generation of
self-contained C-code for a large subset of function objects.

C-code generation is interesting for a number of reasons:

* Speeding up the evaluation time. As a rule of thumb, the numerical evaluation of autogenerated code, compiled with code optimization flags, can be between 4 and 10 times faster than the same code executed in |casadi|'s virtual machines.
* Allowing code to be compiled on a system where |casadi| is not installed, such as an embedded system. All that is needed to compile the generated code is a C compiler.
* Debugging and profiling functions. The generated code is essentially a mirror of the evaluation that takes place in the virtual machines and if a particular operation is slow, this is likely to show up when analyzing the generated code with a profiling tool such as ``gprof``. By looking at the code, it is also possible to detect what is potentially done in a suboptimal way. If the code is very long and takes a long time to compile, it is an indication that some functions need to be broken up in smaller, but nested functions.

.. _sec-codegen_syntax:

Syntax for generating code
--------------------------

Generated C code can be as simple as calling the ``generate`` member function for a |Function| instance.

.. side-by-side::
    .. exec-block:: python

        x = MX.sym('x',2)
        y = MX.sym('y')
        f = Function('f',[x,y],\
              [x,sin(y)*x],\
              ['x','y'],['r','q'])
        f.generate('gen.c')
        print(open('gen.c','r').read())
    &&

    .. exec-block:: octave

        x = MX.sym('x',2);
        y = MX.sym('y');
        f = Function('f',{x,y},...
              {x,sin(y)*x},...
              {'x','y'},{'r','q'});
        f.generate('gen.c');

This will create a C file ``gen.c`` containing the function ``f`` and all its dependencies and required helper functions.
We will return to how this file can be used in :numref:`sec-codegen_syntax` and the structure of the generated code is
described in :numref:`sec-c_api` below.

You can generate a C file containing multiple |casadi| functions by working with |casadi|'s :class:`CodeGenerator` class:

.. side-by-side::
    .. exec-block:: python

        x = MX.sym('x') [hidden]
        f = Function('f',[x],[sin(x)])
        g = Function('g',[x],[cos(x)])
        C = CodeGenerator('gen.c')
        C.add(f)
        C.add(g)
        C.generate()
    &&

    .. exec-block:: octave

        x = MX.sym('x'); [hidden]
        f = Function('f',{x},{sin(x)});
        g = Function('g',{x},{cos(x)});
        C = CodeGenerator('gen.c');
        C.add(f);
        C.add(g);
        C.generate();

Both the ``generate`` function and the :class:`CodeGenerator` constructor take an optional
options dictionary as an argument, allowing customization of the code generation. Two useful
options are ``main``, which generates a *main* entry point, and ``mex``,
which generates a *mexFunction* entry point:

.. side-by-side::
    .. exec-block:: python

        x = MX.sym('x') [hidden]
        f = Function('f',[x],[sin(x)])
        opts = dict(main=True, \
                    mex=True)
        f.generate('gen.c',opts)
    &&

    .. exec-block:: octave

        x = MX.sym('x'); [hidden]
        f = Function('f',{x},{sin(x)});
        opts = struct('main', true,...
                      'mex', true);
        f.generate('gen.c',opts);

This enables executing the function from the command line and MATLAB, respectively,
as described in :numref:`sec-using_codegen` below.

If you plan to link directly against the generated code in some C/C++ application,
a useful option is ``with_header``, which controls the creation of a header file
containing declarations of the functions with external linkage, i.e. the API of
the generated code, described in :numref:`sec-c_api` below.

Here is a list of available options for the :class:`CodeGenerator` class:

================= =================== ======================
Option            Default value       Description
================= =================== ======================
``verbose``       true                Include comments in generated code
``mex``           false               Generate an MATLAB/Octave MEX entry point
``cpp``           false               Generated code is C++ instead of C
``main``          false               Generate a command line interface
``casadi_real``   ``double``          Floating point type
``casadi_int``    ``long long int``   Integer type
``with_header``   false               Generate a header file
``with_mem``      false               Generate a simplified C API
``indent``        2                   Number of spaces per indentation level
================= =================== ======================


.. _sec-using_codegen:

Using the generated code
------------------------
The generated C code can be used in a number of different ways:

* The code can be compiled into a dynamically linked library (DLL), from which a |Function| instance can be created using |casadi|'s ``external`` function. Optionally, the user can rely on |casadi| to carry out the compilation *just-in-time*.
* The generated code can be compiled into MEX function and executed from MATLAB.
* The generated code can be executed from the command line.
* The user can link, statically or dynamically, the generated code to his or her C/C++ application, accessing the C API of the generated code.
* The code can be compiled into a dynamically linked library and the user can then manually access the C API using ``dlopen`` on Linux/OS X or ``LoadLibrary`` on Windows.


This is elaborated in the following.

|casadi|'s ``external`` function
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``external`` command allows the user to create a |Function| instance
from a dynamically linked library with the entry points described by the
C API described in :numref:`sec-c_api`. Since the autogenerated files are
self-contained [#f2]_, the compilation -- on Linux/OSX -- can be as easy as issuing:

.. code-block:: none

      gcc -fPIC -shared gen.c -o gen.so

from the command line. Or, equivalently using MATLAB's ``system`` command
or Python's ``os.system`` command. Assuming ``gen.c`` was created as
described in the previous section, we can then create a |Function|
``f`` as follows:

.. side-by-side::
    .. exec-block:: python

        from os import system [hidden]

        x = MX.sym('x') [hidden]
        f = Function('f',[x],[sin(x)]) [hidden]
        f.generate('gen.c') [hidden]
        system('gcc -fPIC -shared gen.c -o gen.so') [hidden]
        f = external('f', './gen.so')
        print(f(3.14))
    &&

    .. exec-block:: octave

        x = MX.sym('x'); [hidden]
        f = Function('f',{x},{sin(x)}); [hidden]
        f.generate('gen.c'); [hidden]
        system('gcc -fPIC -shared gen.c -o gen.so'); [hidden]
        f = external('f', './gen.so');
        disp(f(3.14))

We can also rely on |casadi| performing the compilation *just-in-time*
using |casadi|'s :class:`Importer` class. This is a plugin class, which at the
time of writing had two supported plugins, namely ``'clang'``, which invokes
the *LLVM/Clang* compiler framework (distributed with |casadi|), and ``'shell'``,
which invokes the system compiler via the command line:

.. side-by-side::
    .. exec-block:: python

        x = MX.sym('x') [hidden]
        f = Function('f',[x],[sin(x)]) [hidden]
        f.generate('gen.c') [hidden]
        C = Importer('gen.c','shell')
        f = external('f',C)
        print(f(3.14))
    &&

    .. exec-block:: octave

        x = MX.sym('x'); [hidden]
        f = Function('f',{x},{sin(x)}); [hidden]
        f.generate('gen.c'); [hidden]

        C = Importer('gen.c','shell');
        f = external('f',C);
        disp(f(3.14))

We will return to the ``external`` function in :numref:`sec-external`.

Calling generated code from MATLAB
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
An alternative way of executing generated code is to compile the code into a
MATLAB MEX function and call from MATLAB. This assumes that the ``mex`` option
was set to "true" during the code generation, cf. :numref:`sec-codegen_syntax`.
The generated MEX function takes the function name as its first argument,
followed by the function inputs:

.. exec-block:: octave

    x = MX.sym('x'); [hidden]
    f = Function('f',{x},{sin(x)}); [hidden]
    f.generate('gen.c',struct('mex',true)); [hidden]

    %mex gen.c -largeArrayDims  % Matlab
    mex gen.c -DMATLAB_MEX_FILE % Octave

    disp(gen('f', 3.14))

Note that the result of the execution is always a MATLAB sparse matrix by default. Compiler flags ``-DCASASI_MEX_ALWAYS_DENSE`` and ``-DCASASI_MEX_ALLOW_DENSE`` may be set to influence this behaviour.

Calling generated code from the command line
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Another option is to execute the generated code from the Linux/OSX command line.
This is possible if the ``main`` option was set to "true" during the code
generation, cf. :numref:`sec-codegen_syntax`. This is useful if you e.g. want
to profile the generated with a tool such as ``gprof``.

When executing the generated code, the function name is passed
as a command line argument. The nonzero entries of all the inputs
need to be passed via standard input and the function will return the output
nonzeros for all the outputs via standard output:

.. code-block:: none

    # Command line
    echo 3.14 3.14 > gen_in.txt
    gcc gen.c -o gen
    ./gen f < gen_in.txt > gen_out.txt
    cat gen_out.txt # returns 0.00159265 0.00159265

Linking against generated code from a C/C++ application
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The generated code is written so that it can be linked with directly from a C/C++
application. If the ``with_header`` option was set to "true" during the
code generation, a header file with declarations of all the exposed entry points
of the file. Using this header file requires an understanding of |casadi|'s
codegen API, as described in :numref:`sec-c_api` below. Symbols that are
*not* exposed are prefixed with a file-specific prefix, allowing an
application to link against multiple generated functions without risking
symbol conflicts.

Dynamically loading generated code from a C/C++ application
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A variant of above is to compile the generated code into a shared library,
but directly accessing the exposed symbols rather than relying on |casadi|'s
``external`` function. This also requires an understanding of the structure
of the generated code.

In |casadi|'s example collection, ``codegen_usage.cpp`` demonstrates how this
can be done.

.. _sec-c_api:

API of the generated code
-------------------------
The API of the generated code consists of a number of functions with external
linkage. In addition to the actual execution, there are functions for memory
management as well as meta information about the inputs and outputs.
These functions are described in the following. Below, assume that the name of
function we want to access is ``fname``. To see what these functions actually
look like in code and when they are called, we refer to the
``codegen_usage.cpp`` example.

Reference counting
^^^^^^^^^^^^^^^^^^

.. code-block:: c

    void fname_incref(void);
    void fname_decref(void);

A generated function may need to e.g. read in some data or initialize some data
structures before first call. This is typically not needed for functions generated
from |casadi| expressions, but may be required e.g. when the generated code contains
calls to external functions. Similarly, memory might need to be deallocated
after usage.

To keep track of the ownership, the generated code contains two functions for
increasing and decreasing a reference counter.
They are named ``fname_incref`` and ``fname_decref``, respectively. These
functions have no input argument and return void.

Typically, some initialization may take place upon the first call to
``fname_incref`` and subsequent calls will only increase some internal counter.
The ``fname_decref``, on the other hand, decreases the internal counter and
when the counter hits zero, a deallocation -- if any -- takes place.

Number of inputs and outputs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: c

    casadi_int fname_n_in(void);
    casadi_int fname_n_out(void);

The number of function inputs and outputs can be obtained by calling the
``fname_n_in`` and ``fname_n_out`` functions, respectively. These functions
take no inputs and return the number of input or outputs (``casadi_int`` is an alias for ``long long int``).

Names of inputs and outputs
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: c

    const char* fname_name_in(casadi_int ind);
    const char* fname_name_out(casadi_int ind);

The functions ``fname_name_in`` and ``fname_name_out`` return the name
of a particular input or output. They take the index of the input or output,
starting with index 0, and return a ``const char*`` with the name as a
null-terminated C string. Upon failure, these functions will return a null
pointer.

Sparsity patterns of inputs and outputs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: c

    const casadi_int* fname_sparsity_in(casadi_int ind);
    const casadi_int* fname_sparsity_out(casadi_int ind);


The sparsity pattern for a given input or output is obtained by calling
``fname_sparsity_in`` and ``fname_sparsity_out``, respectively.
These functions take the input or output index and return a pointer to a field
of constant integers (``const casadi_int*``). This is a compact representation
of the *compressed column storage* (CCS) format that |casadi| uses,
cf. :numref:`sec-sparsity_class`.
The integer field pointed to is structured as follows:

* The first two entries are the number of rows and columns, respectively. In the following referred to as ``nrow`` and ``ncol``.
* If the third entry is ``1``, the pattern is dense and any remaining entries are discarded.
* If the third entry is ``0``, that entry plus subsequent ``ncol`` entries form the nonzero offsets for each column, ``colind`` in the following. E.g. column :math:`i` will consist of the nonzero indices ranging from ``colind[i]`` to ``colind[i+1]``. The last entry, ``colind[ncol]``, will be equal to the number of nonzeros, ``nnz``.
* Finally, *if* the sparsity pattern is *not dense*, i.e. if ``nnz`` :math:`\ne` ``nrow`` * ``ncol``, then the last ``nnz`` entries will contain the row indices.

Upon failure, these functions will return a null pointer.

Memory objects
^^^^^^^^^^^^^^
A function may contain some mutable memory, e.g. for caching the latest
factorization or keeping track of evaluation statistics. When multiple functions
need to call the same function without conflicting, they each need to work with
a different memory object. This is especially important for evaluation in
parallel on a shared memory architecture, in which case each thread should access
a different memory object.

.. code-block:: c

    void* fname_alloc_mem(void);


Allocates a memory object which will be passed to the numerical evaluation.

.. code-block:: c

    int fname_init_mem(void* mem);

(Re)initializes a memory object. Returns 0 upon successful return;

.. code-block:: c

    int fname_free_mem(void* mem);

Frees a memory object. Returns 0 upon successful return;

Work vectors
^^^^^^^^^^^^

.. code-block:: c

    int fname_work(casadi_int* sz_arg, casadi_int* sz_res, casadi_int* sz_iw, casadi_int* sz_w);


To allow the evaluation to be performed efficiently with a small memory
footprint, the user is expected to pass four work arrays. The function
``fname_work`` returns the length of these arrays, which have entries
of type ``const double*``, ``double*``, ``casadi_int`` and ``double``,
respectively.

The return value of the function is nonzero upon failure.

Numerical evaluation
^^^^^^^^^^^^^^^^^^^^

.. code-block:: c


    int fname(const double** arg, double** res,
              casadi_int* iw, double* w, void* mem);

Finally, the function ``fname``, performs the actual evaluation. It takes
as input arguments the four work vectors and a memory object created using ``fname_alloc_mem``
(or NULL if absent).
The length of the work vectors must be at least the lengths provided
by the ``fname_work`` command and the index of the memory object must be strictly
smaller than the value returned by ``fname_n_mem``.

The nonzeros of the function inputs are pointed to by the
first entries of the ``arg`` work vector and are unchanged by the evaluation.
Similarly, the output nonzeros are pointed to by the first entries of the
``res`` work vector and are also unchanged (i.e. the pointers are unchanged,
not the actual values).

The return value of the function is nonzero upon failure.


.. rubric:: Footnotes

.. [#f2] An exception is when code is generated for a function that in turn contains calls to external functions.
