Skip to content

Instantly share code, notes, and snippets.

@jdfr
Created May 1, 2015 08:05
Show Gist options
  • Save jdfr/a791f1fbf70042cc5abb to your computer and use it in GitHub Desktop.
Save jdfr/a791f1fbf70042cc5abb to your computer and use it in GitHub Desktop.
Cython: using C++ templates inside "with nogil" sections

Let's suppose you have implemented a templated function with two template arguments fun<A,B> in the files cside.cpp and cside.hpp. Now, you want to use it in cython, so you declare it:

cdef extern from "cside.hpp" nogil:
  void fun[A,B](A *arg1, B *arg2)

and you can use it:

def test():
  cdef int arg
  fun[int,int](&arg, &arg)

However, if you try to use it inside a with nogil block:

def test():
  cdef int arg
  with nogil:
    fun[int,int](&arg, &arg)

Cython will fail to compile with a message hinting at problems to parse the syntax:

  with nogil:
    fun[int,int](&arg, &arg)
      ^
------------------------------------------------------------

cythonside2.pyx:9:7: Constructing Python tuple not allowed without gil

fortunately, there is an easy (if rather cumbersome) workaround: in the cython cdef extern declaration, replace the templated declaration by any needed instantiation:

cdef extern from "cside.hpp" nogil:
  void fun(int *arg1, int *arg2)
#include <stdio.h>
#include "cside.hpp"
template<typename A, typename B> void fun(A *arg1, B *arg2) {
printf("In fun\n");
}
template void fun(int *arg1, int *arg2);
template<typename A, typename B> void fun(A *arg1, B *arg2);
cdef extern from "cside.hpp" nogil:
void fun[A,B](A *arg1, B *arg2)
#this fails to compile
def test():
cdef int arg
with nogil:
fun[int,int](&arg, &arg)
cdef extern from "cside.hpp" nogil:
void fun(int *arg1, int *arg2)
#this compiles and runs as intended
def test():
cdef int arg
with nogil:
fun(&arg, &arg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment