Verifying Compatibility in Compiling Extension Types, and Using Them with Cdef

What is this import_umath function?

There's a thread on the Cython mailing list that discusses this a little bit. I believe that the discussion was concerning the Cython test suite, but I think the same ideas can be applied to generated files.

In essence, the issue involved a hack that was done in order to avoid C compiler warnings about unused functions.

The code file in question currently looks like this:

cdef extern from *:
bint FALSE "0"
void import_array()
# void import_umath()

if FALSE:
import_array()
# import_umath()

In the past, the import_umath() portions were uncommented, but as it turns out, this was causing errors when building in C++ mode. So it appears that it was decided that a compiler warning is much better than a broken build.

In short, it seems this particular warning exists for the sake of C++ compatibility, and can be safely ignored. I suppose if you really dislike it, and if you're building in C mode, then you could try to do the same hack, by importing a similar .pxi file with a call to import_umath() inside of your Cython code.

When and how does cython do boundscheck?

http://docs.cython.org/src/reference/compilation.html#compiler-directives

"Cython is free to assume that indexing operations ([]-operator) in the code will not cause any IndexErrors to be raised. Lists, tuples, and strings are affected..."

I think in your code a C double array doesn't store its length anywhere, and so it's impossible for Cython to do any useful checks (except in your very trivial example). However, a built in Python type which can raise IndexErrors should be different (I'd assume numpy arrays, python arrays and cython memoryviews should also be affected since they all have a mechanism for Cython to tell if it's gone off the end).

Cython Speed Boost vs. Usability

The other answers have already explained how you were just compiling the Cython code, not executing it. However, I thought that you might want to know how much faster Cython can make your code. When I compiled the code you have (though I ran the function from from a different module) with distutils, I got very marginal speed gains over straight Python – about 1%. However, when I added a few small changes to your code:

def test(long long value):
cdef long long i
cdef long long z
for i in xrange(value):
z = i**2
if(i==1000000):
print i
if z < i:
print "yes"

and compiled it, I got the following times:

  • Pure Python code: 20.4553578737 seconds
  • Cython code: 0.199339860234 seconds

That’s a 100× speed-up. Not too shabby.

Trying to define a cython method results in `cdef statement not allowed here` error

The issue happens to be that When using a python class, one should also use cdef as well. This kind of class is called an Extension Type.

From Cython documentation:

... a Cython extension type definition looks a lot like a Python class
definition. Within it, you use the def statement to define methods
that can be called from Python code. You can even define many of the
special methods such as init() as you would in Python.

Note:

After doing so, in order to be able to use my class in Python, I had to inherit from it and instead use the inherited class. That is I had to do :

cdef class MyClass():
def __init__(self, args)
...

cpdef func1(self,...):
...

cpdef func2(self, ....):
...
...

class MyClass2(MyClass):
def __init__(self, args):
super().__init__(args)
pass

And in you client code :

# use MyClass2 from now on
obj = MyClass2(args)
...

Cython: Import definitions from .pyx file

It should be clearly described this way:

  • myclass.pyx is compiled into .so file
  • But there are 2 kinds of stuff in a .so file
    • Python definitions: Can be imported only with 'import'
    • Cython definitions: Can be imported only with 'cimport'

The problem is import myclass in another.pxd won't import myclass because it is cdef (Cython definition).

In another.pxd file, to import 'myclass', it must be either:

  • from myclass cimport myclass
    • myvar2 will be: cdef myclass myvar2
  • cimport myclass
    • myvar2 will be: cdef myclass.myclass myvar2
  • cimport some.path.to.myclass as myclass
    • myvar2 will be: cdef myclass myvar2

There may be a problem with exporting too, especially using Python build tool instead of cython3 and gcc directly:

  • __pyx_capi__ is not available in the .so file
  • myclass is not public and aren't seen after importing

Thus better put the myclass under public scope in myclass.pyx:

cdef public:
class myclass:
pass

Import non-integer constant in .pyx file

You could use a very short inline function (in the pxd file) that just returns the constant

cdef inline const char* GetFavouriteFood():
return "spam"

cdef inline float GetHowMuch():
return 4.5

The other option would be to define the constants in C in a header file then (in your pxd) do

cdef extern from "myconstants.h":
const char* FavouriteFood
float HowMuch

The C compiler (rather than Cython) enforces the constness so errors will appear at that stage if you try to change them. This does involve create an extra file so personally I prefer the inline function approach.


Edit (2018):

You can now include C code directly in Cython which makes the second approach easier:

cdef extern from *:
"""const char* FavouriteFood = "spam";
const float HowMuch = 4.5;"""
const char* FavouriteFood
float HowMuch

Cython: Trying to wrap SFML Window; getting ImportError: No module named 'ExprNodes'

Looking more closely at the traceback, I see that Cython fails inside it's own compiled code. It may be a bug indeed, sorry for missing it the first time.

What can you do:

  • Create a clean virtualenv, install Cython there and check if it works. (Version 0.19.1 is the latest).
  • Create another virtualenv, but this time install Cython using python setup.py install --no-cython-compile.

If either of these fails, please post your detailed configuration (linux distro and version, python version, gcc version, etc.) to the cython-devel mailing list.

BTW does your old successful project still compile?



Related Topics



Leave a reply



Submit