[Python] Numpy distutils not recognizing Fortran file types

Discussão em 'Python' iniciado por Stack, Maio 6, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to write a python package with Anaconda3 which includes some compiled Fortran libraries. Based on the examples given online, I need to use numpy.distutils.core.Extension to have the extension build correctly. Here is my somewhat-minimal working example directory:

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


    MANIFEST.in contains:

    recursive-include mypkg *.f90


    setup.py contains:

    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 contains (EDIT: simplified):

    !
    ! 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 contains:

    """
    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, x[j], a, a[j])

    return Smat


    test_smat contains:

    #!/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()


    Ideally, I should be able to install with python setup.py install and run test_smat to get a printed output. However, when I try to install I get:

    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')


    Am I missing something that tells NumPy distutils that the extension is a Fortran 90 file? Other examples on this website seem to have a setup.py file that is just as simple without encountering this error. Changing the Fortran extension to .f95 or .f leads to the same type of error.

    Continue reading...

Compartilhe esta Página