How to declare a c++ tuple in cython - cython

I have a C++ method declared as follow:
std::tuple<std::vector<int>, std::size_t, std::size_t> get_state(); // Should I use a struct and expose the struct instead?
And I would like to declare a cython extension to interface it in Python
cdef extern from "cpp_sources/CClass.hpp":
cdef cppclass CClass nogil:
tuple[vector[int], size_t, size_t] get_state()
Unfortunately, I don't see an easy import to make to have access to a C++ tuple.
I also checked here with no success.
My question is, is there an easy way to have access to a c++ tuple? Or maybe there is a better way to have access to some elements?
(We don't care about performances for this exact method)

Unfortunately this is not supported. More generally variadic templates are not supported - that's why you have pair for example, but not a generic tuple.
In the github issue I linked they have their own version of a workaround, which is what I would come up with first - for every amount of N arguments I will actually use,
template<typename T_1, ... typename T_N>
using tupleN = std::tuple<T_1, ..., TN>;
and exporting each tupleN individually. There is no magic I'm aware of to make a general variadic template here.

Related

What are prototypes in programming?

This isn't a specific question about a language, but more about programming in general. The question came after I started an argument with a friend about "Function prototypes" which I learnt about recently from my C++ course. I mentioned to him that prototypes are function headers that you have to create at the beginning of your code so the compiler allocates some space at runtime before getting to the actual function. We then started rambling about whether other programming languages (Like java or python) which do not utilize function prototypes -- so far as we're concerned -- actually had a system similar to that of C++, just that they handled it themselves rather than having the user create them.
So we're curious to know, what are function prototypes after all? Are they only accountable on C/C++, or do other programming languages make use of them? And is it something I'd need to develop more on as a future programmer? Thanks for the help!
With respect to C and C++, the word "prototype" refers to a specific declaration syntax.
In the earliest versions of C, function definitions were written as
int func( arg1, arg2, arg3 ) // no types in argument list, just identifiers
int arg1;
double arg2;
char *arg3;
{
// function body
}
and declarations were written as
int func( ); // no argument list
The function argument list only contained identifiers and no type information - that was supplied separately. Function declarations didn't include arguments, just the return type.
C++ introduced and C later adopted the concept of prototype syntax, where the type information is included in the parameter list in both the definition:
int func( int arg1, double arg2, char *arg3 )
{
// function body
}
and the declaration
int func( int, double, char * );
This allowed compilers to check the number and types of arguments in a function call and issue diagnostics if they didn't match, rather than waiting until runtime to find out if there's a problem.
While the old-style function declaration and definition syntax is still supported, it should not be used for new code development - we're almost to the point where the word "prototype" is kind of redundant, since prototype syntax is the norm rather than the exception.
Statically-typed languages like Fortran and Pascal and Ada all have separate function declarations, but they don't refer to those declarations as prototypes. And again with C, "prototype" refers to a specific style of function declaration and definition, not just a declaration in and of itself.
This is greatly oversimplified, but the reason for function prototypes is "one-pass compilers."
If your compiler only makes one pass through the code, it needs to know what functions are available to it, before the function implementation is called. This is where prototypes come in.
Compilers that make multiple passes through the code build jump tables that tell it where all the functions are, so there's no need for function prototypes.
In C compilers, prototypes are used to check the type and number of function parameters (i.e. the function signature). This program:
#include <stdio.h>
int main()
{
printf("%d\n",add(3));
}
int add(int i, int j)
{
return i+j;
}
compiles and executes in Clang 7 with a warning, even though the result is meaningless (i.e. undefined behavior).
Whereas this program, incorporating a function prototype:
#include <stdio.h>
int add (int, int); /* function prototype for add */
void main()
{
printf("%d\n",add(3));
}
int add(int i, int j)
{
return i+j;
}
fails to compile.
C and C++ are compiled to native code and support calling between compilation units (files). To call a function XYZ from a neighboring compilation unit the compiler inserts a reference "calling XYZ" which is later resolved by the linker. But you need to know what to prepare on the stack for the function. The prototype supplies that information without having to compile the whole function.
Early C treated everything as int and as the C calling convention is caller-cleans-up, you as the caller know how many ints to remove from the stack after a function returns. If you call printf with three arguments without explaining what it is, the C compiler can still figure out what code to generate. If you misspelled it to vrintf it will compile but fail to link. So plain C worked (still works?) to some extent without prototypes (or treats missing prototypes as just a warning).
As C++ can pass all kinds of crazy stuff as function arguments, if you try to call something without explaining its argument types first, the compiler does not know what code to generate and you get an error.
This outside article is reasonably nice: http://www.cplusplus.com/articles/yAqpX9L8/

How to use C complex numbers in 'language=c++' mode?

Most of my library is written with Cython in the "normal" C mode. Up to now I rarely needed any C++ functionality, but always assumed (and sometimes did!) I could just switch to C++-mode for one module if I wanted to.
So I have like 10+ modules in C-mode and 1 module in C++-mode.
The problem is now how Cython seems to handle complex numbers definitions. In C-mode it assumes I think C complex numbers, and in C++-mode it assumes I think C++ complex numbers. I've read they might be even the same by now, but in any case Cython complains that they are not:
openChargeState/utility/cheb.cpp:2895:35: error: cannot convert ‘__pyx_t_double_complex {aka std::complex<double>}’ to ‘__complex__ double’ for argument ‘1’ to ‘double cabs(__complex__ double)’
__pyx_t_5 = ((cabs(__pyx_v_num) == INFINITY) != 0);
In that case I'm trying to use cabs defined in a C-mode module, and calling it from the C++-mode module.
I know there are some obvious workarounds (right now I'm just not using C++-mode; I'd like to use vectors and instead use the slower Python lists for now).
Is there maybe a way to tell my C++-mode module to use C complex numbers, or tell it that they are the same? If there is I couldn't find a working way to ctypedef C complex numbers in my C++-mode module... Or are there any other solutions?
EDIT: Comments of DavidW and ead suggested some reasonable things. First the minimum working example.
setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
extra_compile_args=['-O3']
compdir = {'language_level' : '3'}
extensions = cythonize([
Extension("cmod", ["cmod.pyx"]),
Extension("cppmod", ["cppmod.pyx"], language='c++')
],
compiler_directives = compdir
)
setup(cmdclass = {'build_ext': build_ext},
ext_modules = extensions
)
import cppmod
cmod.pyx
cdef double complex c_complex_fun(double complex xx):
return xx**2
cmod.pxd
cdef double complex c_complex_fun(double complex xx)
cdef extern from "complex.h":
double cabs(double complex zz) nogil
cppmod.pyx
cimport cmod
cdef double complex cpp_complex_fun(double complex xx):
return cmod.c_complex_fun(xx)*abs(xx) # cmod.cabs(xx) doesn't work here
print(cpp_complex_fun(5.5))
Then just compile with python3 setup.py build_ext --inplace.
Now the interesting part is that (as written in the code) only "indirectly" imported c functions have a problem, in my case cabs. So the suggestion to just use abs actually does help, but I still don't understand the underlying logic. I hope I don't encounter this in another problem. I'm leaving the question up for now. Maybe somebody knows what's happening.
Your problem has nothing to do with the fact, that one module is compiled as a C-extension and the other as a C++-extension - one can easily reproduce the issue in a C++-extension alone:
%%cython -+
cdef extern from "complex.h":
double cabs(double complex zz) nogil
def cpp_complex_fun(double complex xx):
return cabs(xx)
results in your error-message:
error: cannot convert __pyx_t_double_complex {aka
std::complex<double>} to __complex__ double for argument 1 to
double cabs(__complex__ double)
The problem is that the complex numbers are ... well, complex. Cython's strategy (can be looked up here and here) to handle complex numbers is to use an available implementation from C/CPP and if none is found a hand-written fallback is used:
#if !defined(CYTHON_CCOMPLEX)
#if defined(__cplusplus)
#define CYTHON_CCOMPLEX 1
#elif defined(_Complex_I)
#define CYTHON_CCOMPLEX 1
#else
#define CYTHON_CCOMPLEX 0
#endif
#endif
....
#if CYTHON_CCOMPLEX
#ifdef __cplusplus
typedef ::std::complex< double > __pyx_t_double_complex;
#else
typedef double _Complex __pyx_t_double_complex;
#endif
#else
typedef struct { double real, imag; } __pyx_t_double_complex;
#endif
In case of a C++-extension, Cython's double complex is translated to std::complex<double> and thus cannot be called with cabs( double complex z ) because std::complex<double> isn't double complex.
So actually, it is your "fault": you lied to Cython and told him, that cabs has the signature double cabs(std::complex<double> z), but it was not enough to fool the c++-compiler.
That means, in c++-module std::abs(std::complex<double>) could be used, or just Cython's/Python's abs, which is automatically translated to the right function (this is however not possible for all standard-function).
In case of the C-extension, because you have included complex.h as an so called "early include" with cdef extern from "complex.h", thus for the above defines _Complex_I becomes defined and Cython's complex becomes an alias for double complex and thus cabs can be used.
Probably the right thing for Cython would be to always use the fallback per default and that the user should be able to choose the desired implementation (double complex or std::complex<double>) explicitly.

cython ctypedef syntax: quoted string at end?

I am working at understanding the petsc4py sources. In them one finds many ctypedef declarations of the following form:
ctypedef <type> <typename> "<C typename>"
for instance the following:
ctypedef char* PetscMatType "const char*"
or
ctypedef struct PetscMatStencil "MatStencil":
PetscInt k,j,i,c
(In this second case MatStencil is a type that will be known to C at compile time because of its definition in a PETSc header file.)
I have not been able to find any explanation in the Cython documentation that explains this use of a quoted string in a ctypedef statement. (I gather from context that it is a hint to cythonize to implement the Cython type being defined with the named C type.) Can anyone tell me where to find this documented?
More generally, is there anywhere a comprehensive Cython reference? The main documentation I know of is that at cython.readthedocs.io. This is helpful, but it is not a comprehensive reference. For instance, if you search it for ctypedef, you find a bunch of examples, but none of the syntax I asked about above. What you do not find there is a comprehensive definition of ctypedef syntax.
There isn't a document that's a more comprehensive reference than the documentation you linked. It actually does have what you're asking about in it, although I suspect you need to know what you're looking for to find it (unfortunately): https://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#resolving-naming-conflicts-c-name-specifications:
For special cases where namespacing or renaming on import is not enough, e.g. when a name in C conflicts with a Python keyword, you can use a C name specification to give different Cython and C names to the C function at declaration time. Suppose, for example, that you want to wrap an external C function called yield(). If you declare it as:
cdef extern from "myheader.h":
void c_yield "yield" (float speed)```
It then goes on to show other examples of structs and variables being renamed (but not specifically typedefs).
Essentially the assumption is that usually when you wrap something in Cython you want to use the same name in Cython as you do in C. However sometimes that doesn't work and this "quoted string" syntax lets you specify a different name that matches your C code.
It's a useful trick to know about because it often lets you work round Cython limitations - for example when wrapping a single variant of a heavily templated C++ class without exposing the whole template hierarchy. In these cases I suspect that the const in const char was confusing Cython, and that the author wanted to use MatStencil as the name in the Python interface (so needed a different name for the C interface). Lying to Cython about small details is often helpful...

Cython: declare a PyCapsule_Destructor in pyx file

I don't know python and trying to wrap an existing C library that provides 200 init functions for some objects and 200 destructors with help of PyCapsule. So my idea is to return a PyCapsule from init functions` wrappers and forget about destructors that shall be called automatically.
According to documentation PyCapsule_New() accepts:
typedef void (*PyCapsule_Destructor)(PyObject *);
while C-library has destructors in a form of:
int foo(void*);
I'm trying to generate a C function in .pyx file with help of cdef that would generate a C-function that will wrap library destructor, hide its return type and pass a pointer taken with PyCapsule_GetPointer to destructor. (pyx file is programmatically generated for 200 functions).
After a few experiments I end up with following .pyx file:
from cpython.ref cimport PyObject
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer
cdef void stateFree( PyObject *capsule ):
cdef:
void * _state
# some code with PyCapsule_GetPointer
def stateInit():
cdef:
void * _state
return PyCapsule_New(_state, "T", stateFree)
And when I'm trying to compile it with cython I'm getting:
Cannot assign type 'void (PyObject *)' to 'PyCapsule_Destructor'
using PyCapsule_New(_state, "T", &stateFree) doesn't help.
Any idea what is wrong?
UPD:
Ok, I think I found a solution. At least it compiles. Will see if it works. I'll bold the places I think I made a mistake:
from cpython.ref cimport PyObject
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer, PyCapsule_Destructor
cpdef void stateFree( object capsule ):
cdef:
void* _state
_state = PyCapsule_GetPointer(capsule, "T")
print('destroyed')
def stateInit():
cdef:
int _state = 1
print ("initialized")
return PyCapsule_New(_state, "T", < PyCapsule_Destructor >stateFree)
The issue is that Cython distinguishes between
object - a Python object that it knows about and handles the reference-counting for, and
PyObject*, which as far as it's concerned is a mystery type that it basically nothing about except that it's a pointer to a struct.
This is despite the fact that the C code generated for Cython's object ends up written in terms of PyObject*.
The signature used by the Cython cimport is ctypedef void (*PyCapsule_Destructor)(object o) (which isn't quite the same as the C definition. Therefore, define the destructor as
cdef void stateFree( object capsule ):
Practically in this case the distinction makes no difference. It matters more in cases where a function steals a reference or returns a borrowed reference. Here capsule has the same reference count on both the input and output of the function whether Cython manages it or not.
In terms of your edited-in solution:
cpdef is wrong for stateFree. Use cdef since it is not a function that should be exposed in a Python interface (and if you use cpdef it isn't obvious whether the Python or C version is passed as a function pointer).
You shouldn't need the cast to PyCapsule_Destructor and should avoid it because casts can easily hide bugs.
Can I just take a moment to express my general dislike for PyCapsule (it's occasionally useful for passing an opaque type through Python code without touching it, but for anything more I think it's usually better to wrap it properly in a cdef class). It's possible you've thought about it and it is the right tool for the job, but I'm putting this warning in to try to discourage people in the future who might be trying to use it on a more "copy-and-paste" basis.

non-member operator in Cython

I'm currently doing a Cython wrapper for an existing C++ library. I have an overloaded non-member operator in C++ like
Data operator+(Data const& a, Data const& b)
And in the pxd file describing the header, I wrote
cdef extern from 'blabla.h':
Data operator+(const Data&, const Data&)
Now how can I use this operator+ in another pyx file?
For very simple cases, like in your example you can lie to Cython and tell it that the operator is a member function:
cdef extern from 'blabla.h':
cdef cppclass Data:
# the rest of the data definitions
Data operator+(const Data&)
It only uses this information to know that it can translate the code a+b (where a and b are data objects) to __pyx_v_a + __pyx_v_b and let the c++ compiler do the rest (which it knows how to because of the import from "blabla.h"). Therefore, the distinction between member and non-member is irrelevant.
However: one of the main reasons to use nonmember operators is to allow things like
Data operator+(int a, const Data& b);
You can make this work, but it's very slightly messy. In your pxd file do
cdef extern from 'blabla.h':
Data operator+(int, const Data&) # i.e. do nothing special
In your pyx file
from my_pxd_file import * # works fine
## but this isn't accepted unfortunately:
from my_pxd_file import operator+
If you wanted to avoid too much namespace pollution from doing import *, you could probably create a pxd file that only contains operators and not the class definitions (I haven't tested this though)
In conclusion - two methods depending on how complicated your use-case is...