Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cython: Inline Function not pure C

I have the following inline function for Cython

cpdef inline int c_rate2recs_2(int maxNN,int idx):
  cdef int out=idx%maxNN
  return out

However this translates into

/* 
 *   return out
 * 
 * cpdef inline int c_rate2recs_2(int maxNN,int idx):             # <<<<<<<<<<<<<<
 *   cdef int out=idx%maxNN
 *   return out
 */

static PyObject *__pyx_pw_6kmc_cy_5c_rate2recs_2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static CYTHON_INLINE int __pyx_f_6kmc_cy_c_rate2recs_2(int __pyx_v_maxNN, int __pyx_v_idx, CYTHON_UNUSED int __pyx_skip_dispatch) {
  int __pyx_v_out;
  int __pyx_r;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("c_rate2recs_2", 0);
  __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984);

/* 
 *   return out
 * 
 * cpdef inline int c_rate2recs_2(int maxNN,int idx):             # <<<<<<<<<<<<<<
 *   cdef int out=idx%maxNN
 *   return out
 */

static PyObject *__pyx_pf_6kmc_cy_4c_rate2recs_2(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_maxNN, int __pyx_v_idx) {
  PyObject *__pyx_r = NULL;
  __Pyx_TraceDeclarations
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("c_rate2recs_2", 0);
  __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = PyInt_FromLong(__pyx_f_6kmc_cy_c_rate2recs_2(__pyx_v_maxNN, __pyx_v_idx, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("kmc_cy.c_rate2recs_2", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_TraceReturn(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

As I am pretty new in the cython business, I would like to know how to get rid of most of the Python commands (cython -a flags this inline as pretty far away from pure C).

like image 902
bios Avatar asked Dec 17 '12 10:12

bios


1 Answers

As I am pretty new in the cython business, I would like to know how to get rid of most of the python commands (cython -a flags this inline as pretty far away from pure C)

The trick is that if you can call your function nogil;

cpdef inline int c_rate2recs_2(int maxNN,int idx) nogil:
  cdef int out=idx%maxNN
  return out

then whatever yellow you see isn't actually generally going to Python. It could be an error-case, for example, or it could just be other types of mild checking. In the case of a cpdef, not only is a pure-C function made, a Python alias is made for calling from a Python scope. This will not affect speeds.

In this case some timings against a manually inlined loop showed no slowdowns, and removing inline did nothing, either, to the time. I imagine a case harder to optimise may show different characteristics, but the key is to profile.

Finally, speed-ups and removal of some of the error-checking can be had by using compiler directives.

like image 105
Veedrac Avatar answered Oct 15 '22 05:10

Veedrac