Cython: How to print without GIL
Asked Answered
M

2

19

How should I use print in a Cython function with no gil? For example:

from libc.math cimport log, fabs
cpdef double f(double a, double b) nogil:
    cdef double c = log( fabs(a - b) )
    print c
    return c

gives this error when compiling:

Error compiling Cython file:
...
    print c
    ^
------------------------------------------------------------

Python print statement not allowed without gil
...

I know how to use C libraries instead of their python equivalent (math library for example here) but I couldn't find a similar way for print.

Mitten answered 21/1, 2018 at 3:31 Comment(4)
Why do you need this? You only really need to release the GIL to do multithreading. Using print from multiple threads can end easily just end up giving jumbled output.Selfness
@Selfness I'm not doing any multithreading. I thought releasing GIL would remove Python overhead (which it seems that I was wrong?). In my case, the core part of my code is a big for loop (with around 50 lines of code), but this was my guess and I didn't check if releasing GIL is helping in my big code.Mitten
It doesn't sound like you need to be so strict about it - simply having the GIL won't slow you down. The sort of code that doesn't need the GIL is often faster (as a general rule), but the occasional print statement is fine.Selfness
I think this helpful comment deserves to bee seen. I don't know what's best but please feel free to post it as an edit to my question or as an answer.Mitten
M
36

Use printf from stdio:

from libc.stdio cimport printf
...
printf("%f\n", c)
Motherland answered 21/1, 2018 at 3:52 Comment(0)
S
18

This is a follow-up to a discussion in the comments which suggested that this question was based on a slight misconception: it's always worth thinking about why you need to release the GIL and whether you actually need to do it.

Fundamentally the GIL is a flag that each thread holds to indicate whether it is allowed to call the Python API. Simply holding the flag doesn't cost you any performance. Cython is generally fastest when not using the Python API, but this is because of the sort of operations it is performing rather than because it holds the flag (i.e. printf is probably slightly faster than Python print, but printf runs the same speed with or without the GIL).

The only time you really need to worry about the GIL is when using multithreaded code, where releasing it gives other Python threads the opportunity to run. (Similarly, if you're writing a library and you don't need the Python API it's probably a good idea to release the GIL so your users can run other threads if they want).

Finally, if you are in a nogil block and you want to do a quick Python operation you can simply do:

with gil:
    print c

The chances are it won't cost you much performance and it may save a lot of programming effort.

Selfness answered 22/1, 2018 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.