16

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.

Behzad Jamali
  • 884
  • 2
  • 10
  • 23
  • 2
    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. – DavidW Jan 21 '18 at 09:52
  • @DavidW 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. – Behzad Jamali Jan 21 '18 at 21:29
  • 1
    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. – DavidW Jan 21 '18 at 22:01
  • 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. – Behzad Jamali Jan 21 '18 at 22:12

2 Answers2

31

Use printf from stdio:

from libc.stdio cimport printf
...
printf("%f\n", c)
a spaghetto
  • 1,072
  • 2
  • 14
  • 22
19

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.

DavidW
  • 29,336
  • 6
  • 55
  • 86
  • This Ans Like ChatGTP –  Jul 26 '23 at 07:00
  • 1
    @HardikSindhav I know you're pissed off because I pointed out your bulk posting of ChatGPT answers. However this answer predates ChatGPT by about 5 years – DavidW Jul 26 '23 at 07:03
  • i am not good in content writing so i use ChatGPT But solutions code written by me i don’t use ChatGPT if you don’t like My answer then don’t read my answer but please stop give down-vote . –  Jul 26 '23 at 07:06