1. 不要这样做
我知道你想把Python代码放在Fortran程序里,而不是使用带有Fortran扩展的Python程序。我的第一条建议是不要这样做。Fortran在数组运算方面比Python更快,但Python比Fortran更容易编写,使用OOP技术扩展Python代码更容易,并且Python可能可以访问对你很重要的库。你提到在Fortran中有一个超级优化的主循环;Fortran非常适合超级优化的内部循环。在Python程序中使用Numpy传递Fortran数组的逻辑比在Fortran中正确处理Python对象所需做的事情要简单得多。
当我从头开始启动科学计算项目时,我总是先用Python编写,找出性能瓶颈,然后将其转换为Fortran。能够针对经过验证的Python代码测试更快的Fortran代码,使得更容易展示代码是否正确工作。
由于您已经有现有的代码,将Python代码扩展为用Fortran制作的模块需要重构,但这个过程应该很简单。将初始化代码与主循环分离,将循环分解成逻辑部分,将每个例程包装在Python函数中,然后您的主Python代码可以调用Fortran子例程,并根据需要与Python函数交错使用。在此过程中,您可能能够保留Fortran主循环中大量的优化。F2PY是一个相当标准的工具,因此不难找到可以帮助您解决任何问题的人。
2. 系统调用
如果您一定要让Fortran代码调用Python代码,而不是相反,最简单的方法就是让Fortran代码将一些数据写入磁盘,并使用
SYSTEM
或
EXECUTE_COMMAND_LINE
运行Python代码。如果您使用
EXECUTE_COMMAND_LINE
,则可以让Python代码将其结果输出到标准输出,然后Fortran代码可以将其作为字符数据读取;如果输出很多(例如,一个大矩阵),则更合理的做法是让Python代码输出一个文件,然后Fortran代码再读取它。但是,磁盘读写开销可能会变得非常高,这可能会成为限制因素。此外,您还需要编写Fortran代码来输出数据,Python代码来读取数据,Python代码再次输出数据,以及Fortran代码重新输入数据。编写和测试这些代码应该很简单,但是在编辑代码时保持这四个部分同步可能会变成一个头疼的问题。
(这种方法已经在
this Stack Overflow question中尝试过)
3. 在Fortran中嵌入C中的Python
我不知道有什么直接将Python对象传递到Fortran的方法。然而,Fortran代码可以调用C代码,而C代码可以嵌入Python。(请参见
扩展和嵌入Python教程。)通常情况下,扩展Python(如我在第1点中推荐的)比将其嵌入C/C++更可取。(请参见
扩展与嵌入:只有一个正确的决定。)让这个工作起来将是一场噩梦,因为Python和Fortran之间的任何通信问题可能发生在Python和C之间,或者在C和Fortran之间。我不知道是否有人实际上在Fortran中嵌入了Python,因此获得帮助将会很困难。