Numpy distutils无法识别Fortran文件类型

时间:2018-08-04 00:21:57

标签: python numpy fortran distutils

我正在尝试使用Anaconda3编写一个python软件包,其中包括一些已编译的Fortran库。根据在线给出的示例,我需要使用numpy.distutils.core.Extension来正确构建扩展名。这是我的最小工作示例目录:

MANIFEST.in
setup.py
bin
 └─── test_smat
mypkg
 ├─── __init__.py
 ├─── compiled
 |     ├─── __init__.py
 |     └─── gaussian.f90
 └─── pystuff
       ├─── __init__.py
       └─── buildmat.py

MANIFEST.in包含:

recursive-include mypkg *.f90

setup.py包含:

from setuptools import find_packages
from setuptools import setup
from numpy.distutils.core import Extension


ext_modules = [
    Extension('mypkg.compiled.gaussian',
              sources=['mypkg/compiled/gaussian.f90'])
               ]


setup(
    name='mypkg',
    version='0.1',
    description='This should work',
    packages=find_packages(),
    scripts=['bin/test_smat'],
    install_requires=['numpy>=1.7.0'],
    ext_modules = ext_modules
      )

gaussian.f90包含(编辑:简化):

!                                                                           
!  Calculates the overlap between two Gaussians                             
!                                                                           
subroutine overlap(x1, x2, a1, a2, S)                                       
    implicit none                                                           
    double precision, intent(in)  :: x1, x2, a1, a2                         
    double precision, intent(out) :: S                                      

    double precision, parameter   :: pi=atan(1.0_8)                         
    double precision              :: N1, N2, dist, expt                     

    N1 = (pi / (2*a1)) ** (-0.75)                                           
    N2 = (pi / (2*a2)) ** (-0.75)                                           
    dist = abs(x2 - x1)                                                     
    expt = a1*a2*dist**2 / (a1 + a2)                                        
    S = N1 * N2 * exp(-expt) * (pi / (a1 + a2)) ** 1.5                      

    return                                                                  
end subroutine overlap

buildmat.py包含:

"""                                                                         
Module for building matrices of Gaussian properties                         
"""                                                                         
import numpy as np                                                          
import mypkg.compiled.gaussian as gaussian                                  


def olap_matrix(x, a):                                                      
    """Builds an overlap matrix from a set of positions and widths."""      
    ngauss = len(x)                                                         
    Smat = np.empty((ngauss, ngauss))                                       

    for i in range(ngauss):                                                 
        for j in range(ngauss):                                             
            Smat[i,j] = gaussian.overlap(x[i], x[j], a[i], a[j])            

    return Smat

test_smat包含:

#!/usr/bin/env python                                                       
"""                                                                         
Script to test Python modules depending on Fortran libraries.               
"""                                                                         
import mypkg.pystuff.buildmat as buildmat                                   


def main():                                                                 
    """The main routine."""                                                 
    x = [-1, -0.9, -0.5, -0.1, 0.0, 0.0001, 0.001, 0.01, 0.1]               
    a = [1.2, 0.8, 0.3, 1.5, 3.2, 0.9, 0.8, 0.1, 1.6]                       
    mat = buildmat.olap_matrix(x, a)                                        

    print(mat)                                                              


if __name__ == '__main__':                                                  
    main()

理想情况下,我应该能够安装python setup.py install并运行test_smat以获得打印输出。但是,当我尝试安装时会得到:

running install                                                             
running bdist_egg                                                           
running egg_info                                                            
writing mypkg.egg-info/PKG-INFO                                             
writing dependency_links to mypkg.egg-info/dependency_links.txt             
writing requirements to mypkg.egg-info/requires.txt                         
writing top-level names to mypkg.egg-info/top_level.txt                     
reading manifest file 'mypkg.egg-info/SOURCES.txt'                          
reading manifest template 'MANIFEST.in'                                     
writing manifest file 'mypkg.egg-info/SOURCES.txt'                          
installing library code to build/bdist.linux-x86_64/egg                     
running install_lib                                                         
running build_py                                                            
creating build                                                              
creating build/lib.linux-x86_64-3.6                                         
creating build/lib.linux-x86_64-3.6/mypkg                                   
copying mypkg/__init__.py -> build/lib.linux-x86_64-3.6/mypkg               
creating build/lib.linux-x86_64-3.6/mypkg/pystuff                           
copying mypkg/pystuff/buildmat.py -> build/lib.linux-x86_64-3.6/mypkg/pystuff
copying mypkg/pystuff/__init__.py -> build/lib.linux-x86_64-3.6/mypkg/pystuff
creating build/lib.linux-x86_64-3.6/mypkg/compiled                          
copying mypkg/compiled/__init__.py -> build/lib.linux-x86_64-3.6/mypkg/compiled
running build_ext                                                           
building 'mypkg.compiled.gaussian' extension                                
C compiler: gcc -pthread -B /home/rymac/.anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC

error: unknown file type '.f90' (from 'mypkg/compiled/gaussian.f90')

我是否缺少告诉NumPy distutils扩展名是Fortran 90文件的信息?该网站上的其他示例似乎都有一个setup.py文件,它很简单,却没有遇到此错误。将Fortran扩展名更改为.f95.f会导致相同类型的错误。

1 个答案:

答案 0 :(得分:0)

问题出在试图将setuptools.setupnumpy.disutils.core.Extension一起使用。 Extension的Numpy版本包含f2py中未包含的有关setuptools.Extension的其他信息,但是如果还使用numpy.distutils.core.setup,则只能用于构建Fortran库

解决方案:将from setuptools import setup中的from numpy.distutils.core import setup替换为setup.py