Fortran - Cython Workflow(Fortran - Cython 工作流程)
问题描述
我想设置一个工作流,以便在 Windows 机器上使用 Cython 从 Python 访问 fortran 例程
I would like to set up a workflow to reach fortran routines from Python using Cython on a Windows Machine
经过一番搜索,我发现:http://www.fortran90.org/src/best-practices.html#interfacing-with-c 和 https://stackoverflow.com/tags/fortran-iso-c-binding/信息
after some searching I found : http://www.fortran90.org/src/best-practices.html#interfacing-with-c and https://stackoverflow.com/tags/fortran-iso-c-binding/info
还有一些代码图片:
Fortran 端:
pygfunc.h:
pygfunc.f90
pygfunc.f90
gfunc.f90
Cython 方面:
pygfunc.pyx
pygfunc.pyx
和设置文件:
所有文件都在一个目录中
all the files ar in one directory
fortran 文件编译(使用 NAG Fortran Builder)pygfunc 编译
the fortran files compile ( using NAG Fortran Builder ) pygfunc compiles
但链接它们会引发:
错误 LNK2019:引用了未解析的外部符号 _c_gfunc在函数___pyx_pf_7pygfunc_f
error LNK2019: unresolved external symbol _c_gfunc referenced in function ___pyx_pf_7pygfunc_f
当然还有:
致命错误 LNK1120:1 个未解决的外部问题
fatal error LNK1120: 1 unresolved externals
我错过了什么?还是这种在 Python 和 Fortran 之间建立工作流的方式从一开始就该死?
What am I missing ? or is this way to set up a workflow between Python and Fortran damned from the beginning ?
THX马丁
推荐答案
这是一个最小的工作示例.我使用 gfortran 并将编译命令直接写入安装文件.
Here's a minimum working example. I used gfortran and wrote the compile commands directly into the setup file.
gfunc.f90
pygfunc.f90
pygfunc.h
pygfunc.pyx
setup.py
test.py
我所做的大部分更改都不是非常根本.以下是重要的.
Most of the changes I made aren't terribly fundamental. Here are the important ones.
您混合了双精度和单精度浮点数.不要那样做. 同时使用 real (Fortran)、float (Cython) 和 float32 (NumPy),同时使用双精度 (Fortran)、double (Cyton) 和 float64 (NumPy).尽量不要无意中混合它们.我假设你在我的例子中想要双打.
You were mixing double precision and single precision floating point numbers. Don't do that. Use real (Fortran), float (Cython), and float32 (NumPy) together and use double precision (Fortran), double (Cyton), and float64 (NumPy) together. Try not to mix them unintentionally. I assumed you wanted doubles in my example.
您应该将所有变量作为指针传递给 Fortran.在这方面,它与 C 调用约定不匹配.Fortran 中的 iso_c_binding 模块仅匹配 C 命名约定.将数组作为指针传递,其大小作为单独的值.可能还有其他方法可以做到这一点,但我不知道.
You should pass all variables to Fortran as pointers. It does not match the C calling convention in that regard. The iso_c_binding module in Fortran only matches the C naming convention. Pass arrays as pointers with their size as a separate value. There may be other ways of doing this, but I don't know any.
我还在设置文件中添加了一些内容,以显示在构建时可以在哪里添加一些更有用的额外参数.
I also added some stuff in the setup file to show where you can add some of the more useful extra arguments when building.
要编译,请运行 python setup.py build_ext --inplace
.要验证它是否有效,请运行测试脚本.
To compile, run python setup.py build_ext --inplace
. To verify that it works, run the test script.
这是 fortran90.org 上显示的示例:mesh_exp
Here is the example shown on fortran90.org: mesh_exp
这是我前段时间整理的另外两个:ftridiag,fssor我当然不是这方面的专家,但这些示例可能是一个很好的起点.
Here are two more that I put together some time ago: ftridiag, fssor I'm certainly not an expert at this, but these examples may be a good place to start.
这篇关于Fortran - Cython 工作流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!