将 python 回调函数传递给 Fortran 子例程的开销是多少?

2024-01-03

我刚刚使用 F2PY 将 Fortran 90 子例程包装到 python 中。这里的微妙之处在于 Fortran 子例程也采用 python 回调函数作为其参数之一:

SUBROUTINE f90foo(pyfunc, a)
real(kind=8),intent(in) :: a
!f2py intent(callback) pyfunc
external pyfunc
!f2py real*8 y,x
!f2py y = pyfunc(x)

!*** debug begins***
print *, 'Start Loop'
do i=1,1000
  p = pyfunc(a)
end do
total = etime(elapsed)
print *, 'End: total=', total, ' user=', elapsed(1), ' system=', elapsed(2)
stop
!*** debug ends  ***

The pyfunc是我的 python 代码中其他地方定义的 python 函数。包装器工作正常,但是运行上面的包装版本,我得到的运行时间比使用纯 python 得到的运行时间长大约 5 倍,如下所示,

def pythonfoo(k):
    """ k: scalar 
        returns: scalar
    """
    print('Pure Python: Start Loop')
    start = time.time()
    for i in xrange(1000):
        p = pyfunc(k)
    elapsed = (time.time() - start)
    print('End: total=%20f'% elapsed)

那么问题来了,开销从何而来?我真的很想离开pyfunc因为重新编码成纯fortran函数是极其耗时的,那么有没有办法提高wrapper模块的速度呢?


在您发布的代码中,a是双精度浮点数。将它从 Fortran 传递到 Python 意味着将 Fortran double 包装到 PyFloat 对象,这确实有成本。在纯Python版本中,k是一个PyFloat,你不需要为包装它1000次而付出代价。

另一个问题是函数调用本身。从 C 调用 Python 函数在性能方面已经很糟糕,但从 Fortran 调用它们更糟糕,因为有额外的代码层将 Fortran 函数调用约定(关于堆栈等)转换为 C 函数调用约定。当从 C 调用 Python 函数时,需要将参数准备为 Python 对象,通常创建一个 PyTuple 对象作为 Python 函数的 *args 参数,在模块的表中查找以获取函数指针。 ..

最后但并非最不重要的一点是:在 Fortran 和 Numpy 之间传递 2D 数组时需要注意数组顺序。 F2py 和 numpy 在这方面可能很聪明,但如果您的 Python 代码不是为了按 Fortran 顺序操作数组而编写的,那么您的性能将会受到影响。

我不知道 pyfunc 的用途是什么,但如果它与您发布的内容接近,那么用 Python 编写循环,并且仅调用该函数一次将节省您的时间。如果您需要中间值(p),让你的 Python 函数返回一个包含所有中间值的 Numpy 数组。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 python 回调函数传递给 Fortran 子例程的开销是多少? 的相关文章

  • scipy 将一个稀疏矩阵的所有行附加到另一个稀疏矩阵

    我有一个 numpy 矩阵 想在其中附加另一个矩阵 这两个矩阵的形状为 m1 shape 2777 5902 m2 shape 695 5902 我想将 m2 附加到 m1 以便新矩阵的形状为 m new shape 3472 5902 当
  • 如何在 Windows 64 上安装 NumPy?

    NumPy 安装程序在注册表中找不到 python 路径 无法安装 需要 Python 2 5 版本 但在注册表中未找到该版本 OK 我必须修改注册表吗 我已经修改了 PATH 以指向Python25安装目录 我可以检查一下您使用的是什么安
  • Python - 来自 .进口

    我第一次尝试图书馆 我注意到解决图书馆内导入问题的最简单方法是使用如下结构 from import x from some module import y 我觉得这件事有些 糟糕 也许只是因为我不记得经常看到它 尽管公平地说我还没有深入研究
  • Python 中的流式传输管道

    我正在尝试使用 Python 将 vmstat 的输出转换为 CSV 文件 因此我使用类似的方法转换为 CSV 并将日期和时间添加为列 vmstat 5 python myscript py gt gt vmstat log 我遇到的问题是
  • 如果未引发异常,则通过 Python 单元测试

    在Python中unittest框架 是否有一种方法可以在未引发异常的情况下通过单元测试 否则会因 AssertRaise 而失败 如果我正确理解你的问题 你could做这样的事情 def test does not raise on va
  • Pandas:如果单元格包含特定文本则删除行

    pandas 中的这段代码不起作用 如果该列包含提供的任何文本 数字 我希望它删除该行 目前 我只能在单元格与我的代码中传递的确切文本匹配时才能使其工作 因为它只删除显示 Fin 的单元格不是金融或金融 df2 df df Team Fin
  • 如何在 Python 中加密并在 Java 中解密?

    我正在尝试在 Python 程序中加密一些数据并将其保存 然后在 Java 程序中解密该数据 在Python中 我像这样加密它 from Crypto Cipher import AES KEY 1234567890123456789012
  • 一段时间后终止线程的最 Pythonic 方法

    我想在线程中运行一个进程 它正在迭代一个大型数据库表 当线程运行时 我只想让程序等待 如果该线程花费的时间超过 30 秒 我想终止该线程并执行其他操作 通过终止线程 我的意思是我希望它停止活动并优雅地释放资源 我认为最好的方法是通过Thre
  • Python新式类和__subclasses__函数

    有人可以向我解释为什么这有效 在 Python 2 5 中 class Foo object pass class Bar Foo pass print Foo subclasses 但这不是 class Foo pass class Ba
  • 在 Windows 上使用 apache mod_wsgi 运行 Flask 应用程序时导入冲突

    我允许您询问我在 Windows 上使用您的 mod wsgi portage 托管 Flask 应用程序时遇到的问题 我有两个烧瓶应用程序 由于导入冲突 只有一个可以同时存在 IE 如果请求申请 1 我有回复 然后 如果我请求应用程序 2
  • .pyx 文件出现未知文件类型错误

    我正在尝试构建一个包含 pyx 文件的 Python 包 pyregion 但在构建过程中出现错误 检查以下输出 python setup py build running build running build py creating b
  • 用 python 编写的数学语法检查器

    我需要的只是使用 python 检查字符串是否是有效的数学表达式 为了简单起见 假设我只需要 运算符 也作为一元 带有数字和嵌套括号 为了完整性 我还添加了简单的变量名称 所以我可以这样测试 test 3 2 1 valid test 3
  • Anaconda 无法导入 ssl 但 Python 可以

    Anaconda 3 Jupyter笔记本无法导入ssl 但使用Atom终端导入ssl没有问题 我尝试在 Jupyter 笔记本中导入 ssl 但出现以下错误 C ProgramData Anaconda3 lib ssl py in
  • Elasticsearch 通过搜索返回拼音标记

    我用语音分析插件 https www elastic co guide en elasticsearch plugins current analysis phonetic html由于语音转换 从弹性搜索中进行一些字符串匹配 我的问题是
  • 混淆矩阵不支持多标签指示符

    multilabel indicator is not supported是我在尝试运行时收到的错误消息 confusion matrix y test predictions y test is a DataFrame其形状为 Horse
  • Django 与谷歌图表

    我试图让谷歌图表显示在我的页面上 但我不知道如何将值从 django 视图传递到 javascript 以便我可以绘制图表 姜戈代码 array Year Sales Expenses 2004 1000 400 2005 1170 460
  • 如何根据第一列创建新列,同时考虑Python Pandas中字母和列表的大小? [复制]

    这个问题在这里已经有答案了 我在 Python Pandas 中有 DataFrame 如下所示 col1 John Simon prd agc Ann White BeN and Ann bad list Ben Wayne 我需要这样做
  • 从 pandas DataFrame 中删除少于 K 个连续 NaN

    我正在处理时间序列数据 我在从数据帧列中删除小于或等于阈值的连续 NaN 时遇到问题 我尝试查看一些链接 例如 标识连续 NaN 出现的位置以及计数 Pandas NaN 孔的游程长度 https stackoverflow com que
  • 多个对象以某种方式相互干扰[原始版本]

    我有一个神经网络 NN 当应用于单个数据集时 它可以完美地工作 但是 如果我想在一组数据上运行神经网络 然后创建一个新的神经网络实例以在不同的数据集 甚至再次同一组数据 上运行 那么新实例将产生完全错误的预测 例如 对 XOR 模式进行训练
  • Apache Beam Pipeline 写表后查询表

    我有一个 Apache Beam Dataflow 管道 它将结果写入 BigQuery 表 然后我想查询该表以获取管道的单独部分 但是 我似乎无法弄清楚如何正确设置此管道依赖性 我编写的新表 然后想要查询 与一个单独的表连接以进行某些过滤

随机推荐