Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

compiling fortran file in python

The module f2py no longer has the compile command, and I can't get mesonbuild to import this fortran code as a module. I rarely use python and have already spent a few hours searching and troubleshooting. Please help!

I am having trouble compiling a fortran code to use as a module in pythonc3.9 on a MAC OS intel. The published code is a few years old (https://github.com/lisllain/EAP-model/blob/main/EAP_MODEL_CODE.ipynb), but the following lines are the problem.

sourcefile = open('Dmmex_R14B_4.f','rb') 
sourcecode = sourcefile.read()
f2py.compile(sourcecode, modulename='Dmmex_R14B_4') 
like image 251
Catherine Garcia Avatar asked Oct 14 '25 03:10

Catherine Garcia


1 Answers

This happens because distutils, the build system that f2py.compile() relied on, was officially deprecated in Python 3.10, and completely removed in Python 3.12 (PEP 632).

However, you can still make things work. The script below works as long as you have numpy installed and a version of gfortran on the path. (I installed it from conda-forge) I also needed to install meson and ninja for a complete build system stack.

conda create -n testenv -c conda-forge python=3.13 gfortran numpy meson ninja -y

The example code:

import os
import sys
import tempfile
import subprocess


def compile_fortran(code: str, module_name: str):
    try:
        with tempfile.NamedTemporaryFile(mode="w", suffix=".f", delete=False) as temp_source_file:
            temp_source_file.write(code)
            temp_source_file.flush()
            src_path = temp_source_file.name
        # compile using f2py
        subprocess.run(
            [sys.executable, "-m", "numpy.f2py", "-c", "-m", module_name, src_path],
            check=True
        )
    finally:
        os.remove(src_path)


code = """
      DOUBLE PRECISION FUNCTION ADD_NUMBERS(A, B)
      DOUBLE PRECISION A, B
      ADD_NUMBERS = A + B
      RETURN
      END
"""

compile_fortran(code, 'minimal')

import minimal
print(minimal.add_numbers(1.0, 2.0))  # will print 3.0

You did not share your Fortran code, so there may be some additional compilation issues based on the specific code, but this example shows that you can still use f2py and import the result.

The main thing is that you can't pass in-memory code directly to the system, so it writes a temporary file, calls f2py in a subprocess, and then cleans up the temp file at the end.

Once the function returns, there's a module in the working directory, which can be imported and used.

Note: your question states you are on Python 3.9, but the results you're getting suggests that's not the Python that's being used, or otherwise the wrong version of Numpy. Are you sure you're not running in some environment that has a newer version of Python?

If you are indeed on Python 3.9, the problem is likely that you upgraded your numpy beyond version 1.25.2. If I install python=3.9 and numpy=1.25.2, your code works, but it's a bit trickier to then get the module loaded, but you may have that working in your code already.

like image 166
Grismar Avatar answered Oct 16 '25 17:10

Grismar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!