Использование line-profiler (в ipython) в скомпилированном коде Cython

Я прочитал ответ на этот вопрос Как построчно профилировать функции Cython, но я не могу заставить его работать с моей настройкой.

у меня есть cumsum.pyx файл:

# cython: profile=True
# cython: linetrace=True
# cython: binding=True
DEF CYTHON_TRACE = 1

def cumulative_sum(int n):
    cdef int s=0, i
    for i in range(n):
        s += i

    return s

Я скомпилировал это с:

cython cumsum.pyx
gcc cumsum.c $(pkg-config --cflags --libs python3) -o cumsum.so -shared -fPIC

Затем я попытался профилировать его в ipython:

%load_ext line_profiler
from cumsum import cumulative_sum
%lprun -f cumulative_sum cumulative_sum(100)

Я не получаю сообщение об ошибке, только пустой профиль:

Timer unit: 1e-06 s

Total time: 0 s
File: cumsum.pyx
Function: cumulative_sum at line 6

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     6                                           def cumulative_sum(int n):
     7                                               cdef int s=0, i
     8                                               for i in range(n):
     9                                                   s += i
    10                                           
    11                                               return s

Как я могу заставить это работать?

PS: я использую CMake, а не setup.py, поэтому я был бы признателен за решение системы построения системы

2 ответа

Решение

Оказывается, проблема была в том, что DEF CYTHON_TRACE = 1 на самом деле не устанавливает правильную константу.

Обходные пути включают в себя:

1. Ответ М.Сейферта с использованием distutils

2. Изменение строки gcc на

gcc cumsum.c $(pkg-config --cflags --libs python3) -o cumsum.so -shared -fPIC -DCYTHON_TRACE=1

3. Создание дополнительного заголовка trace.h и установив там константу

 #define CYTHON_TRACE 1

наряду с добавлением следующего к cumsum.pyx

cdef extern from "trace.h":
    pass

4. С CMake, добавив

add_definitions(-DCYTHON_TRACE)

В документации по Cythons "Profiling" уже есть пример того, как установить CYTHON_TRACE макрос:

# distutils: define_macros=CYTHON_TRACE_NOGIL=1

вместо вашего DEF CYTHON_TRACE = 1,

Это сработало, когда я скомпилировал его, используя %%cython:

%load_ext cython
%%cython

# cython: profile=True
# cython: linetrace=True
# cython: binding=True
# distutils: define_macros=CYTHON_TRACE_NOGIL=1

def cumulative_sum(int n):
    cdef int s=0, i
    for i in range(n):
        s += i
    return s

И показал профилирование:

%load_ext line_profiler
%lprun -f cumulative_sum cumulative_sum(100)
[...]
Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     7                                           def cumulative_sum(int n):
     8         1            8      8.0      3.5      cdef int s=0, i
     9         1            3      3.0      1.3      for i in range(n):
    10       100          218      2.2     94.4          s += i
    11         1            2      2.0      0.9      return s
Другие вопросы по тегам