使用 Cython 的 Line Profiling 内部函数

     2023-03-06     151

关键词:

【中文标题】使用 Cython 的 Line Profiling 内部函数【英文标题】:Line Profiling inner function with Cython 【发布时间】:2016-06-28 21:14:01 【问题描述】:

我在使用this answer 分析我的 Cython 代码方面取得了相当大的成功,但它似乎不适用于嵌套函数。在this notebook 中,您可以看到在嵌套函数上使用线剖析器时配置文件不会出现。有没有办法让它工作?

【问题讨论】:

【参考方案1】:

tl,博士:

这似乎是Cython 的一个问题,有一种骇人听闻的方法可以解决问题,但不可靠,您可以将其用于一次性情况,直到此问题得到解决*支持>

更改line_profiler来源:

我不能 100% 确定这一点,但它确实有效,您需要做的是 download the source for line_profiler 并在 python_trace_callback 中摆弄。从当前执行帧(code = <object>py_frame.f_code)获取code对象后,添加以下内容:

if what == PyTrace_LINE or what == PyTrace_RETURN:
    code = <object>py_frame.f_code

    # Add entry for code object with different address if and only if it doesn't already
    # exist **but** the name of the function is in the code_map
    if code not in self.code_map and code.co_name in co.co_name for co in self.code_map:
        for co in self.code_map:
            # make condition as strict as necessary
            cond = co.co_name == code.co_name and co.co_code == code.co_code
            if cond:
                del self.code_map[co]
                self.code_map[code] = 

这会将self.code_map 中的代码对象替换为当前正在执行的与其名称和co.co_code 内容匹配的代码对象。 co.co_codeb''Cython,所以本质上匹配具有该名称的 Cython 函数。在这里它可以变得更加健壮并匹配code 对象的更多属性(例如,文件名)。

然后您可以继续使用python setup.py build_ext 构建它并使用sudo python setup.py install 进行安装。 我目前正在使用python setup.py build_ext --inplace 构建它,以便在本地使用它,我建议你也这样做。如果您确实使用--inplace 构建它,请确保在import 之前导航到包含line_profiler 源的文件夹。

因此,在包含为line_profiler 构建的共享库的文件夹中,我设置了一个包含您的函数的cyclosure.pyx 文件:

def outer_func(int n):
    def inner_func(int c):
        cdef int i
        for i in range(n):
             c+=i
        return c
    return inner_func

还有一个等效的 setup_cyclosure.py 脚本来构建它:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
from Cython.Compiler.Options import directive_defaults

directive_defaults['binding'] = True
directive_defaults['linetrace'] = True

extensions = [Extension("cyclosure", ["cyclosure.pyx"], define_macros=[('CYTHON_TRACE', '1')])]
setup(name = 'Testing', ext_modules = cythonize(extensions))

和之前一样,构建是使用python setup_cyclosure.py build_ext --inplace 执行的。

从当前文件夹启动您的解释器并发出以下命令会产生想要的结果:

>>> import line_profiler
>>> from cyclosure import outer_func
>>> f = outer_func(5)
>>> prof = line_profiler.LineProfiler(f)
>>> prof.runcall(f, 5)

15
>>> prof.print_stats()
Timer unit: 1e-06 s

Total time: 1.2e-05 s
File: cyclosure.pyx

Function: inner_func at line 2

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     2                                               def inner_func(int c):
     3                                                   cdef int i
     4         1            5      5.0     41.7          for i in range(n):
     5         5            6      1.2     50.0               c+=i
     6         1            1      1.0      8.3          return c  

IPython %%cython 的问题:

试图从IPython 运行它会导致不幸的情况。在执行时,code 对象不存储定义它的文件的路径,它只是存储文件名。由于我只是将code 对象放入self.code_map 字典中,并且由于代码对象具有只读属性,因此在使用IPython 时会丢失文件路径信息(因为它将%%cython 生成的文件存储在一个临时目录)。

因此,您确实获得了代码的分析统计信息,但您没有获得内容的内容。一个人可能能够在有问题的两个代码对象之间强制复制文件名,但这完全是另一个问题。

*问题:

这里的问题是,由于某种原因,在处理嵌套和/或封闭函数时,代码对象在创建时和在 Python 框架之一中解释时的地址存在异常。您遇到的问题是由以下condition not being satisfied引起的:

    if code in self.code_map:

这很奇怪。在IPython 中创建函数并将其添加到LineProfiler 确实将其添加到self.code_map 字典中:

prof = line_profiler.LineProfiler(f)

prof.code_map
Out[16]: <code object inner_func at 0x7f5c65418f60, file "/home/jim/.cache/ipython/cython/_cython_magic_1b89b9cdda195f485ebb96a104617e9c.pyx", line 2>: 

到了实际测试前一个条件的时候,当前代码对象被code = &lt;object&gt;py_frame.f_code从当前执行帧中抢走,代码对象的地址不同:

 # this was obtained with a basic print(code) in _line_profiler.pyx
 code object inner_func at 0x7f7a54e26150

表示它已被重新创建。这只发生在Cython 以及在另一个函数中定义一个函数时。无论是这个还是我完全想念的东西。

【讨论】:

Python Line_profiler 和 Cython 函数

...【发布时间】:2014-06-1015:27:30【问题描述】:所以我尝试使用line_profiler在我自己的python脚本中分析一个函数,因为我想要逐行计时。唯一的问题是该函数是Cython函数,而line_profiler无法正常工作。在第一次运行时,它只是因错误... 查看详情

运行 Cython 的问题

...【发布时间】:2012-09-1517:24:19【问题描述】:我正在尝试使用运行MountainLion的OSX安装Python2.7运行cython,但出现以下错误:Traceback(mostrecentcalllast):File"/usr/local/bin/cython",line5,in<module>frompkg_resourc 查看详情

zeromq操作抛出exc:[当前状态下无法完成操作](代码片段)

...deo2MQComparecZMQ.py",line17,insendself.socketC.send(data)File"zmq/backend/cython/socket.pyx",line636,inzmq.backend.cython.socket.Socket.send(zmqackendcythonsocket.c:7305)File"zmq/backend/cython/socket.pyx",line683,inzmq.backend.cython.socket.Socket.send(zmqackendcythonsocket.c:7048)File"zmq/backe... 查看详情

用 cython 和 mingw 编译会产生 gcc: error: unrecognized command line option '-mno-cygwin'

】用cython和mingw编译会产生gcc:error:unrecognizedcommandlineoption\\\'-mno-cygwin\\\'【英文标题】:Compilingwithcythonandmingwproducesgcc:error:unrecognizedcommandlineoption\'-mno-cygwin\'用cython和mingw编译会产生gcc:error:unrecognizedcommand 查看详情

在 Cython 的结构中使用指针数组

】在Cython的结构中使用指针数组【英文标题】:UsingapointerarraywithinastructinCython【发布时间】:2014-09-1216:06:05【问题描述】:我正在尝试围绕C库编写Cython包装器。我对Cython很陌生,所以如果问题很明显,我提前道歉。在文件wrapper.... 查看详情

在 Cython 中使用 C++ STL 映射

】在Cython中使用C++STL映射【英文标题】:UsingC++STLmapsinCython【发布时间】:2017-04-0520:43:31【问题描述】:我正在尝试在Cython类中使用地图,但Cython编译器引发错误。这是一个演示我的问题和Cython报告的错误的示例。Cython文件pyxfrom... 查看详情

使用 cuda 的 cython 扩展

】使用cuda的cython扩展【英文标题】:cythonextensionsusingcuda【发布时间】:2014-06-0422:08:46【问题描述】:我有一个作为C++类的convnet实现。该类构建在生成CUDA代码的模板库(mshadow)之上,因此它采用头文件的形式。因此,它只能在使... 查看详情

Cython:融合类型的使用无效,类型不能特化

】Cython:融合类型的使用无效,类型不能特化【英文标题】:Cython:Invaliduseoffusedtypes,typecannotbespecialized【发布时间】:2018-12-0713:07:45【问题描述】:我有以下MCVE:importnumpyasnpcimportnumpyasnpcimportcythonfromcythoncimportfloatingdeffunc1(floating[... 查看详情

Cython:如何使用 C++ 类的用户定义转换?

】Cython:如何使用C++类的用户定义转换?【英文标题】:Cython:Howuser-definedconversionofC++-classescanbeused?【发布时间】:2019-12-3023:13:09【问题描述】:Cython的documentation似乎对如何包装user-definedconversion保持沉默。例如,当下面的c++代码... 查看详情

使用 Cython 的 setup_requires?

】使用Cython的setup_requires?【英文标题】:setup_requireswithCython?【发布时间】:2016-09-2501:48:24【问题描述】:我正在为带有一些Cython扩展模块的项目创建一个setup.py文件。我已经让这个工作了:fromsetuptoolsimportsetup,ExtensionfromCython.Bui... 查看详情

使用 Cython 包装 C++ 类时处理指针

】使用Cython包装C++类时处理指针【英文标题】:HandlingpointerswhenwrappingC++classwithCython【发布时间】:2017-03-0211:44:22【问题描述】:我在使用cython处理指针时遇到问题。类的cython实现包含一个指向类Person的C++实例的指针。这是我的.p... 查看详情

在 jupyter 笔记本中使用 cython 进行行分析

】在jupyter笔记本中使用cython进行行分析【英文标题】:Lineprofilingwithcythoninjupyternotebook【发布时间】:2019-08-2112:46:33【问题描述】:我正在尝试在jupyternotebook中使用带有cython函数的liner_profiler库。它只工作了一半。我得到的结果... 查看详情

使用 Cython 启用并行性

】使用Cython启用并行性【英文标题】:EnablingParallelismwithCython【发布时间】:2018-04-0904:36:42【问题描述】:我正在尝试让Cython的parallel包的prange函数工作,似乎没有并行性生效。为了拥有一个MWE,我从Cython:AGuideforPythonProgrammers书... 查看详情

在cython中使用pyqt类(.pyx文件)(代码片段)

如何在Cython(.pyx文件)中使用pyqt类?实际上,如何在cython类中继承pyqt类?谢谢答案所有Python代码都应该是有效的Cython代码(有bug,所以这不太正确,但它很接近)。因此,使用PyQt的Python代码应该在Cython下工作,如果没有,那... 查看详情

如何手动编译使用 C++ 的 Cython 代码?

】如何手动编译使用C++的Cython代码?【英文标题】:HowcanImanuallycompileCythoncodethatusesC++?【发布时间】:2015-02-0612:47:13【问题描述】:我已经完全复制了CythondocumentationforwrappingC++classes中给出的示例代码。我可以使用distutils和cythonize... 查看详情

Cython 的功率谱

...【发布时间】:2012-05-2707:59:13【问题描述】:我正在尝试使用Cython优化我的代码。它正在做一个功率谱,而不是使用FFT,因为这是我们在课堂上被告知要做的。我尝试在Cython中编写代码,但没有发现任何区别。这是我的代码#!/usr... 查看详情

使用 Cython 和 C++ 组织项目

】使用Cython和C++组织项目【英文标题】:ProjectorganizationwithCythonandC++【发布时间】:2013-05-2311:14:07【问题描述】:我想为我的C++项目提供Python接口。从技术上讲,我决定使用Cython来包装C++代码。随着时间的推移,整个项目旨在成... 查看详情

如何在 Cython 中使用不同的 C++ 编译器?

】如何在Cython中使用不同的C++编译器?【英文标题】:HowtouseadifferentC++compilerinCython?【发布时间】:2019-12-0200:20:45【问题描述】:我正在开发一个从Python调用C++的项目。我们为此目的使用Cython。使用命令“python3.6setup.pybuild_ext--inp... 查看详情