Использование 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