====== Cython ====== Overview ~~~~~~~~ Cython is an hybrid language between python and c/cpp that allows the libMuscat.so and python modules to communicate. In Muscat, cython files are mixed with pure python files under the ``src`` directory. The main type of **cython file** you might encounter when browsing the sources are: * ``pyx``: these are the *".cpp"* equivalents. They contain implentation of * ``pxd``: these are the *".h"* equivalents. They hold information used .. note:: | To import a cython file from another cython file, please use the ``cimport`` instruction. | It first tries to find a pxd file or its pyx equivalent if it does not exist. These files contain mixed cython and python code that allow interfacing the two languages. Interfacing with Cpp ~~~~~~~~~~~~~~~~~~~~ In order to interface with the cpp code base, you can simply use the ``cdef extern from`` instruction: .. code-block:: cython cdef extern from "LinAlg/Kokkos/Utils.h" namespace "Muscat::KK" : cdef int MyFunction(int arg) nogil .. note:: A lot of cpp types are not natively available in cython but you can simply import them using ``from libcpp import xxx`` (xxx denoting the type). For example, **bool** is one of them ! .. warning:: Templates in cython are denoted as ``method[T]`` or ``class[T]`` Numpy and Eigency ~~~~~~~~~~~~~~~~~ In cython, you can import numpy using: .. code-block:: cython import numpy as np cimport numpy as cnp cnp.import_array() You can specify requirements for the matrices defined as parameter of your cython function .. code-block:: cython def mymethod(cnp.ndarray[CMuscatIndex, ndim=2, mode="c"] array): Please refer to the `cython documentation` for further information about it. However, the numpy arrays' pointers will not be available to cpp. The ``Eigency`` library is used to make the bridge between numpy and cpp. Therefore, it is first necessary to turn the numpy array into an ``Eigen::Map`` type by calling: .. code-block:: cython GetSharedMMatrixTYY(myNumpyArray).get()[0] .. note:: The pointer is just wrapped by eigency and **no copy** is made ! Where: * ``T`` denotes the type of the matrix: **D** for floating/double or **I** for integers. * ``X`` denotes the first dimensionality of the matrix: **D** for dynamic or **1** for single dimension. * ``Y`` denotes the second dimensionality of the matrix: **D** for dynamic or **1** for single dimension. All of this function return a pointer to **MapMaptrixTXY** type that need to be dereferenced using ``.get()[0]`` to retrieve a pointer to the first element. .. note:: Please refer to the ``CythonTypes.pxd`` and ``EigenTypes.h`` files to check every single types defined. Compilation ~~~~~~~~~~~ Compilation is done by the :ref:`cmake` build system and generate sequentially: #. ``.cpp`` file from the ``pyx`` #. ``.cpp.o`` file from the ``cpp`` #. ``.libXXX-cythonXXX.so`` file from the ``cpp.o`` In other words, cython generates a cpp file for every single cython module. Then, the cpp source file is compiled to create a shared library. .. warning:: You need to launch the program with the same cython version than you compiled it with.