![](/img/trans.png)
[英]How do I compile a Fortran library for use with Python? (f2py may not be an option)
[英]How do I use the avx flag when compiling Fortran code using f2py?
在Python中进行一些性能测试时,我比较了不同方法的计时,以计算坐标数组之间的欧几里得距离。 我发现用F2PY编译的Fortran代码比SciPy使用的C实现慢大约4倍。 将该C代码与我的Fortran代码进行比较,我发现没有根本的差异会导致4差异。 这是我的代码(带有一些解释其用法的注释):
subroutine distance(coor,dist,n)
double precision coor(n,3),dist(n,n)
integer n,i,j
double precision xij,yij,zij
cf2py intent(in):: coor,n
cf2py intent(in,out):: dist
cf2py intent(hide):: xij,yij,zij,
do 200,i=1,n-1
do 300,j=i+1,n
xij=coor(i,1)-coor(j,1)
yij=coor(i,2)-coor(j,2)
zij=coor(i,3)-coor(j,3)
dist(i,j)=dsqrt(xij*xij+yij*yij+zij*zij)
300 continue
200 continue
end
c 1 2 3 4 5 6 7
c123456789012345678901234567890123456789012345678901234567890123456789012
c
c to setup and incorporate into python (requires numpy):
c
c # python setup_distance.py build
c # cp build/lib*/distance.so ./
c
c to call this from python add the following lines:
c
c >>> import sys ; sys.path.append('./')
c >>> from distance import distance
c
c >>> dist = distance(coor, dist)
查看F2PY运行的编译命令,我发现没有avx
编译标志。 我尝试使用extra_compile_args=['-mavx
]`将其添加到Python设置文件中, extra_compile_args=['-mavx
运行的compile命令没有任何更改:
compiling Fortran sources
Fortran f77 compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran f90 compiler: /usr/bin/gfortran -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
Fortran fix compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
compile options: '-I/home/user/anaconda/lib/python2.7/site-packages/numpy/core/include -Ibuild/src.linux-x86_64-2.7 -I/home/user/anaconda/lib/python2.7/site-packages/numpy/core/include -I/home/user/anaconda/include/python2.7 -c'
gfortran:f77: ./distance.f
creating build/lib.linux-x86_64-2.7
/usr/bin/gfortran -Wall -g -Wall -g -shared build/temp.linux-x86_64-2.7/build/src.linux-x86_64-2.7/distancemodule.o build/temp.linux-x86_64-2.7/build/src.linux-x86_64-2.7/fortranobject.o build/temp.linux-x86_64-2.7/distance.o -L/home/user/anaconda/lib -lpython2.7 -lgfortran -o build/lib.linux-x86_64-2.7/distance.so
回答如何将avx
标志添加到编译器选项中。
在您的情况下,将选择f77编译器gfortran:f77: ./distance.f
<这是关键所在。
您可以尝试指定--f77flags=-mavx
Warren Weckesser在评论中解释说,Fortran数组相对于C数组已转置存储。 但是,没有提到一个重要的含义。 要以正确的顺序遍历数组,必须切换循环的顺序。 在C中,第一个索引是外部循环,在Fortran中,第一个索引应该是内部循环。 您索引为dist(i,j)
因此循环顺序错误。
但是,由于j
循环取决于i
循环值,因此您可能必须切换数组中索引的作用(转置它)。
一些编译器能够以足够高的优化水平为您纠正一些简单的循环顺序。
顺便说一句, -funroll-loops
通常过于激进,并且实际上是有害的。 通常应该设置一些限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.