Python与Fortran混合编程

简介:Fortran程序在地球物理学中并不少见,90年代Fortran十分流行,386时代计算机时很珍贵,Fortran作为当时的高级语言,具有运行速度快,语法简单等诸多优点。现在虽然Fortran已经成为小众游戏,但过去曾经的那些基础计算程序还是有价值的,如果全要重新改写,不但耗时耗力还容易出错。因此,今天我们讨论一下如何在Python里面调用Fortran的函数。

1、认识f2py

混合编程方法有很多,但是f2py可以作为众多方法的首选。f2py是NumPy的一部分,不需要独立安装配置。f2py简单来说就是 Fortran to Python的接口生成器。使用它可以实现Python和Fortran语言之间提供的连接。

在安装了NumPy之后,它还可以作为独立的命令行工具f2py使用,它可以方便地创建/构建Python C/API扩展模块。支持调用Fortran 77/90/95外部子程序和Fortran 90/95模块子程序以及C函数; 支持访问Fortran 77通用块和Fortran 90/95模块数据,包括可分配数组。

f2py通过创建一个可在Python中使用import关键字导入的扩展模块来工作。该模块包含可以从Python调用的自动生成的包装器函数,充当Python和编译后的Fortran例程之间的接口。

编译后的fortran程序依据平台的不同,在磁盘上会产生一个以pyd为扩展名的文件,可以在python程序中被import。

MATLAB和Python这样的脚本语言虽然容易上手,但是对于大规模的循环和数值计算速度还是逊色于C/ c++和Fortran这样的编译语言。要实现两全其美,混合编程是一个好的选择,而Numpy这种大型的python包,其底层也是要通过混合编程来加速的。

2、Fortran的函数接口设计

我们从一个简单的例子开始,Fortran代码保存在fortran.f95中。一般作为接口函数的代码都放到一个subroutine中,这里面在fortran代码里面通过intent关键字来定义输入/输出变量和类型。

下面是fortran代码中的subroutine的典型写法:

subroutine logical_to_integer(prime_numbers, is_prime, num_primes, n)
! =====================================================
! Translates the logical array from sieve to an array
! of size num_primes of prime numbers.
! =====================================================
    integer                 :: i, j=0
    integer, intent(in)     :: n
    logical, intent(in)     :: is_prime(n)
    integer, intent(in)     :: num_primes
    integer, intent(out)    :: prime_numbers(num_primes)
    do i = 1, size(is_prime)
        if (is_prime(i)) then
            j = j + 1
            prime_numbers(j) = i
        end if
    end do
end subroutine

需要注意的是在接口函数中不要使用动态数组,与python交换数据一定要指定数组大小。

3、Python的函数调用方法

Python要调用fortran的函数,必须对fortran函数进行编译。
可以在虚拟环境中,使用下面的命令:

f2py -c fortran.f95 -m fortran

或者:

python -m numpy.f2py -c fortran.f95 -m fortran

在Python中,可以直接import上面的函数名

import fortran
print(fortran.__doc__)
print(fortran.logical_to_integer.__doc__)

注意上面的__doc __是f2py自动生成的,可以看到fortran模块里面包含几个函数,每个函数里面还可以再调用doc看到接口参数类型。

在实践中更常见的做法是在python中在设计一个与fortran函数同名的wrapper函数,并设计新的docstring,这样用起来更像一个python函数。

4、Setup.py中的编译

如果您在程序包里面用到了混合编程方法,还需要编写setup.py,这样软件包安装后,自动会完成fortran代码的编译。方法如下:

# Fortran extension
from numpy.distutils.core import Extension 
from numpy.distutils.core import setup 
ext_for1 = Extension(name='geoist.name.for1',
                sources=['geoist/name/for1.f90'])
setup(
  ext_modules         = [ext_for1],
)

上面代码在setup.py中添加后,当geoist这个软件包安装时,for1.f90就会被自动的根据平台类型进行编译。

5、什么时候使用混合编程

如果想问什么时候要用到混合编程,我想这永远不会有没有明确的答案。然而,一个好的经验法则是,当在(嵌套的)循环中执行多个操作/-计算时,可以使用f2py或编译语言。最典型的例子可能是对多维矩阵中的元素进行操作。也就是一般的线性代数。其他好的例子可以是计算积分的程序或进行蒙特卡罗模拟。此时,您可能想知道是否已经有人为您的特定问题制作了免费的模块。

答案很可能是肯定的!

NumPy和SciPy中的大多数函数和例程实际上都是用Fortran(或C/ c++)例程编译的,它们为解决多个问题提供了高效和快速的解决方案。

一句话总结:如果您是从fortran阵营转到python来的,并且希望使用更多python生态工具,或者您期望通过fortran来加速python程序运行速度,我想这篇文章是有帮助的。对于一些经典的数值计算算法,我们建议您经常检查这Numpy和Scipy这两个包中是否已经提供了解决方案。如果没有,您可以尝试通过混合编程的方法,继承原来的程序框架,而f2py可能会为您的问题提供最佳解决方案。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342