diff options
author | Rohit Goswami <rgoswami@quansight.com> | 2022-04-29 16:04:04 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-29 16:04:04 +0000 |
commit | cec19d76586c7861f3c636cddadb75431494ae4e (patch) | |
tree | eefcaaac48d1fb2a856414c7923843397bdae6c7 | |
parent | 91a3e3a500aa121cf53223b1cc75adb46979bb15 (diff) | |
parent | 691db8b812a793c2d5f467b98ec1e049524cf963 (diff) | |
download | numpy-cec19d76586c7861f3c636cddadb75431494ae4e.tar.gz |
Merge pull request #21187 from HaoZeke/f2pyDeterminism
ENH: F2PY build output determinism
-rw-r--r-- | doc/release/upcoming_changes/21187.new_feature.rst | 8 | ||||
-rw-r--r-- | doc/source/f2py/buildtools/index.rst | 5 | ||||
-rw-r--r-- | doc/source/f2py/buildtools/meson.rst | 7 | ||||
-rw-r--r-- | doc/source/f2py/code/meson.build | 6 | ||||
-rw-r--r-- | doc/source/f2py/code/meson_upd.build | 6 | ||||
-rw-r--r-- | doc/source/f2py/usage.rst | 5 | ||||
-rwxr-xr-x | numpy/f2py/f2py2e.py | 6 | ||||
-rwxr-xr-x | numpy/f2py/rules.py | 17 |
8 files changed, 52 insertions, 8 deletions
diff --git a/doc/release/upcoming_changes/21187.new_feature.rst b/doc/release/upcoming_changes/21187.new_feature.rst new file mode 100644 index 000000000..3781cfd04 --- /dev/null +++ b/doc/release/upcoming_changes/21187.new_feature.rst @@ -0,0 +1,8 @@ +deterministic output files for F2PY +----------------------------------- +For F77 inputs, ``f2py`` will generate ``modname-f2pywrappers.f`` +unconditionally, though these may be empty. For free-form inputs, +``modname-f2pywrappers.f``, ``modname-f2pywrappers2.f90`` will both be generated +unconditionally, and may be empty. This allows writing generic output rules in +``cmake`` or ``meson`` and other build systems. Older behavior can be restored +by passing ``--skip-empty-wrappers`` to ``f2py``. :ref:`f2py-meson` details usage. diff --git a/doc/source/f2py/buildtools/index.rst b/doc/source/f2py/buildtools/index.rst index e7492f191..48ff927df 100644 --- a/doc/source/f2py/buildtools/index.rst +++ b/doc/source/f2py/buildtools/index.rst @@ -80,7 +80,10 @@ Signature files .. note:: - The signature file output situation is being reconsidered in `issue 20385`_ . + From NumPy ``1.22.4`` onwards, ``f2py`` will deterministically generate + wrapper files based on the input file Fortran standard (F77 or greater). + ``--skip-empty-wrappers`` can be passed to ``f2py`` to restore the previous + behaviour of only generating wrappers when needed by the input . In theory keeping the above requirements in hand, any build system can be diff --git a/doc/source/f2py/buildtools/meson.rst b/doc/source/f2py/buildtools/meson.rst index d98752e65..502d3e211 100644 --- a/doc/source/f2py/buildtools/meson.rst +++ b/doc/source/f2py/buildtools/meson.rst @@ -83,6 +83,13 @@ A major pain point in the workflow defined above, is the manual tracking of inputs. Although it would require more effort to figure out the actual outputs for reasons discussed in :ref:`f2py-bldsys`. +.. note:: + + From NumPy ``1.22.4`` onwards, ``f2py`` will deterministically generate + wrapper files based on the input file Fortran standard (F77 or greater). + ``--skip-empty-wrappers`` can be passed to ``f2py`` to restore the previous + behaviour of only generating wrappers when needed by the input . + However, we can augment our workflow in a straightforward to take into account files for which the outputs are known when the build system is set up. diff --git a/doc/source/f2py/code/meson.build b/doc/source/f2py/code/meson.build index b756abf8f..b84bf52a9 100644 --- a/doc/source/f2py/code/meson.build +++ b/doc/source/f2py/code/meson.build @@ -21,10 +21,10 @@ incdir_f2py = run_command(py3, ).stdout().strip() fibby_source = custom_target('fibbymodule.c', - input : ['fib1.f'], - output : ['fibbymodule.c'], + input : ['fib1.f'], # .f so no F90 wrappers + output : ['fibbymodule.c', 'fibby-f2pywrappers.f'], command : [ py3, '-m', 'numpy.f2py', '@INPUT@', - '-m', 'fibby', '--lower' ] + '-m', 'fibby', '--lower'] ) inc_np = include_directories(incdir_numpy, incdir_f2py) diff --git a/doc/source/f2py/code/meson_upd.build b/doc/source/f2py/code/meson_upd.build index 97bd8d175..44d69d182 100644 --- a/doc/source/f2py/code/meson_upd.build +++ b/doc/source/f2py/code/meson_upd.build @@ -21,10 +21,10 @@ incdir_f2py = run_command(py3, ).stdout().strip() fibby_source = custom_target('fibbymodule.c', - input : ['fib1.f'], - output : ['fibbymodule.c'], + input : ['fib1.f'], # .f so no F90 wrappers + output : ['fibbymodule.c', 'fibby-f2pywrappers.f'], command : [ py3, '-m', 'numpy.f2py', '@INPUT@', - '-m', 'fibby', '--lower' ]) + '-m', 'fibby', '--lower']) inc_np = include_directories(incdir_numpy, incdir_f2py) diff --git a/doc/source/f2py/usage.rst b/doc/source/f2py/usage.rst index 332cc5bce..dbd33e36e 100644 --- a/doc/source/f2py/usage.rst +++ b/doc/source/f2py/usage.rst @@ -224,6 +224,9 @@ Other options Run quietly. ``--verbose`` Run with extra verbosity. + ``--skip-empty-wrappers`` + Do not generate wrapper files unless required by the inputs. + This is a backwards compatibility flag to restore pre 1.22.4 behavior. ``-v`` Print the F2PY version and exit. @@ -289,4 +292,4 @@ packages directory for the version of Python you are using. For the resulting package to work, you need to create a file named ``__init__.py`` (in the same directory as ``add.pyf``). Notice the extension module is defined entirely in terms of the ``add.pyf`` and ``add.f`` files. The -conversion of the .pyf file to a .c file is handled by `numpy.distutils`.
\ No newline at end of file +conversion of the .pyf file to a .c file is handled by `numpy.distutils`. diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py index 5bc9113af..5732c1e19 100755 --- a/numpy/f2py/f2py2e.py +++ b/numpy/f2py/f2py2e.py @@ -18,6 +18,7 @@ import sys import os import pprint import re +from pathlib import Path from . import crackfortran from . import rules @@ -121,6 +122,7 @@ Options: --quiet Run quietly. --verbose Run with extra verbosity. + --skip-empty-wrappers Only generate wrapper files when needed. -v Print f2py version ID and exit. @@ -178,6 +180,7 @@ def scaninputline(inputline): files, skipfuncs, onlyfuncs, debug = [], [], [], [] f, f2, f3, f5, f6, f7, f8, f9, f10 = 1, 0, 0, 0, 0, 0, 0, 0, 0 verbose = 1 + emptygen = True dolc = -1 dolatexdoc = 0 dorestdoc = 0 @@ -249,6 +252,8 @@ def scaninputline(inputline): f7 = 1 elif l[:15] in '--include-paths': f7 = 1 + elif l == '--skip-empty-wrappers': + emptygen = False elif l[0] == '-': errmess('Unknown option %s\n' % repr(l)) sys.exit() @@ -298,6 +303,7 @@ def scaninputline(inputline): 'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile)) sys.exit() + options['emptygen'] = emptygen options['debug'] = debug options['verbose'] = verbose if dolc == -1 and not signsfile: diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py index feb181bcb..c56225032 100755 --- a/numpy/f2py/rules.py +++ b/numpy/f2py/rules.py @@ -53,6 +53,7 @@ Pearu Peterson import os, sys import time import copy +from pathlib import Path # __version__.version is now the same as the NumPy version from . import __version__ @@ -1217,6 +1218,22 @@ def buildmodule(m, um): # requiresf90wrapper must be called before buildapi as it # rewrites assumed shape arrays as automatic arrays. isf90 = requiresf90wrapper(nb) + # options is in scope here + if options['emptygen']: + b_path = options['buildpath'] + m_name = vrd['modulename'] + outmess(' Generating possibly empty wrappers"\n') + Path(f"{b_path}/{vrd['coutput']}").touch() + if isf90: + # f77 + f90 wrappers + outmess(f' Maybe empty "{m_name}-f2pywrappers2.f90"\n') + Path(f'{b_path}/{m_name}-f2pywrappers2.f90').touch() + outmess(f' Maybe empty "{m_name}-f2pywrappers.f"\n') + Path(f'{b_path}/{m_name}-f2pywrappers.f').touch() + else: + # only f77 wrappers + outmess(f' Maybe empty "{m_name}-f2pywrappers.f"\n') + Path(f'{b_path}/{m_name}-f2pywrappers.f').touch() api, wrap = buildapi(nb) if wrap: if isf90: |