about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/numpy/f2py/_backends
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/numpy/f2py/_backends
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/numpy/f2py/_backends')
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/f2py/_backends/__init__.py9
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_backend.py46
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_distutils.py75
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py205
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/f2py/_backends/meson.build.template54
5 files changed, 389 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/__init__.py b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/__init__.py
new file mode 100644
index 00000000..e91393c1
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/__init__.py
@@ -0,0 +1,9 @@
+def f2py_build_generator(name):
+    if name == "meson":
+        from ._meson import MesonBackend
+        return MesonBackend
+    elif name == "distutils":
+        from ._distutils import DistutilsBackend
+        return DistutilsBackend
+    else:
+        raise ValueError(f"Unknown backend: {name}")
diff --git a/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_backend.py b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_backend.py
new file mode 100644
index 00000000..a7d43d25
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_backend.py
@@ -0,0 +1,46 @@
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+
+
+class Backend(ABC):
+    def __init__(
+        self,
+        modulename,
+        sources,
+        extra_objects,
+        build_dir,
+        include_dirs,
+        library_dirs,
+        libraries,
+        define_macros,
+        undef_macros,
+        f2py_flags,
+        sysinfo_flags,
+        fc_flags,
+        flib_flags,
+        setup_flags,
+        remove_build_dir,
+        extra_dat,
+    ):
+        self.modulename = modulename
+        self.sources = sources
+        self.extra_objects = extra_objects
+        self.build_dir = build_dir
+        self.include_dirs = include_dirs
+        self.library_dirs = library_dirs
+        self.libraries = libraries
+        self.define_macros = define_macros
+        self.undef_macros = undef_macros
+        self.f2py_flags = f2py_flags
+        self.sysinfo_flags = sysinfo_flags
+        self.fc_flags = fc_flags
+        self.flib_flags = flib_flags
+        self.setup_flags = setup_flags
+        self.remove_build_dir = remove_build_dir
+        self.extra_dat = extra_dat
+
+    @abstractmethod
+    def compile(self) -> None:
+        """Compile the wrapper."""
+        pass
diff --git a/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_distutils.py b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_distutils.py
new file mode 100644
index 00000000..e9b22a39
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_distutils.py
@@ -0,0 +1,75 @@
+from ._backend import Backend
+
+from numpy.distutils.core import setup, Extension
+from numpy.distutils.system_info import get_info
+from numpy.distutils.misc_util import dict_append
+from numpy.exceptions import VisibleDeprecationWarning
+import os
+import sys
+import shutil
+import warnings
+
+
+class DistutilsBackend(Backend):
+    def __init__(sef, *args, **kwargs):
+        warnings.warn(
+            "distutils has been deprecated since NumPy 1.26.x"
+            "Use the Meson backend instead, or generate wrappers"
+            "without -c and use a custom build script",
+            VisibleDeprecationWarning,
+            stacklevel=2,
+        )
+        super().__init__(*args, **kwargs)
+
+    def compile(self):
+        num_info = {}
+        if num_info:
+            self.include_dirs.extend(num_info.get("include_dirs", []))
+        ext_args = {
+            "name": self.modulename,
+            "sources": self.sources,
+            "include_dirs": self.include_dirs,
+            "library_dirs": self.library_dirs,
+            "libraries": self.libraries,
+            "define_macros": self.define_macros,
+            "undef_macros": self.undef_macros,
+            "extra_objects": self.extra_objects,
+            "f2py_options": self.f2py_flags,
+        }
+
+        if self.sysinfo_flags:
+            for n in self.sysinfo_flags:
+                i = get_info(n)
+                if not i:
+                    print(
+                        f"No {repr(n)} resources found"
+                        "in system (try `f2py --help-link`)"
+                    )
+                dict_append(ext_args, **i)
+
+        ext = Extension(**ext_args)
+
+        sys.argv = [sys.argv[0]] + self.setup_flags
+        sys.argv.extend(
+            [
+                "build",
+                "--build-temp",
+                self.build_dir,
+                "--build-base",
+                self.build_dir,
+                "--build-platlib",
+                ".",
+                "--disable-optimization",
+            ]
+        )
+
+        if self.fc_flags:
+            sys.argv.extend(["config_fc"] + self.fc_flags)
+        if self.flib_flags:
+            sys.argv.extend(["build_ext"] + self.flib_flags)
+
+        setup(ext_modules=[ext])
+
+        if self.remove_build_dir and os.path.exists(self.build_dir):
+            print(f"Removing build directory {self.build_dir}")
+            shutil.rmtree(self.build_dir)
diff --git a/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py
new file mode 100644
index 00000000..f324e0f5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py
@@ -0,0 +1,205 @@
+from __future__ import annotations
+
+import os
+import errno
+import shutil
+import subprocess
+import sys
+from pathlib import Path
+
+from ._backend import Backend
+from string import Template
+from itertools import chain
+
+import warnings
+
+
+class MesonTemplate:
+    """Template meson build file generation class."""
+
+    def __init__(
+        self,
+        modulename: str,
+        sources: list[Path],
+        deps: list[str],
+        libraries: list[str],
+        library_dirs: list[Path],
+        include_dirs: list[Path],
+        object_files: list[Path],
+        linker_args: list[str],
+        c_args: list[str],
+        build_type: str,
+        python_exe: str,
+    ):
+        self.modulename = modulename
+        self.build_template_path = (
+            Path(__file__).parent.absolute() / "meson.build.template"
+        )
+        self.sources = sources
+        self.deps = deps
+        self.libraries = libraries
+        self.library_dirs = library_dirs
+        if include_dirs is not None:
+            self.include_dirs = include_dirs
+        else:
+            self.include_dirs = []
+        self.substitutions = {}
+        self.objects = object_files
+        self.pipeline = [
+            self.initialize_template,
+            self.sources_substitution,
+            self.deps_substitution,
+            self.include_substitution,
+            self.libraries_substitution,
+        ]
+        self.build_type = build_type
+        self.python_exe = python_exe
+
+    def meson_build_template(self) -> str:
+        if not self.build_template_path.is_file():
+            raise FileNotFoundError(
+                errno.ENOENT,
+                "Meson build template"
+                f" {self.build_template_path.absolute()}"
+                " does not exist.",
+            )
+        return self.build_template_path.read_text()
+
+    def initialize_template(self) -> None:
+        self.substitutions["modulename"] = self.modulename
+        self.substitutions["buildtype"] = self.build_type
+        self.substitutions["python"] = self.python_exe
+
+    def sources_substitution(self) -> None:
+        indent = " " * 21
+        self.substitutions["source_list"] = f",\n{indent}".join(
+            [f"{indent}'{source}'" for source in self.sources]
+        )
+
+    def deps_substitution(self) -> None:
+        indent = " " * 21
+        self.substitutions["dep_list"] = f",\n{indent}".join(
+            [f"{indent}dependency('{dep}')" for dep in self.deps]
+        )
+
+    def libraries_substitution(self) -> None:
+        self.substitutions["lib_dir_declarations"] = "\n".join(
+            [
+                f"lib_dir_{i} = declare_dependency(link_args : ['-L{lib_dir}'])"
+                for i, lib_dir in enumerate(self.library_dirs)
+            ]
+        )
+
+        self.substitutions["lib_declarations"] = "\n".join(
+            [
+                f"{lib} = declare_dependency(link_args : ['-l{lib}'])"
+                for lib in self.libraries
+            ]
+        )
+
+        indent = " " * 21
+        self.substitutions["lib_list"] = f"\n{indent}".join(
+            [f"{indent}{lib}," for lib in self.libraries]
+        )
+        self.substitutions["lib_dir_list"] = f"\n{indent}".join(
+            [f"{indent}lib_dir_{i}," for i in range(len(self.library_dirs))]
+        )
+
+    def include_substitution(self) -> None:
+        indent = " " * 21
+        self.substitutions["inc_list"] = f",\n{indent}".join(
+            [f"{indent}'{inc}'" for inc in self.include_dirs]
+        )
+
+    def generate_meson_build(self):
+        for node in self.pipeline:
+            node()
+        template = Template(self.meson_build_template())
+        return template.substitute(self.substitutions)
+
+
+class MesonBackend(Backend):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.dependencies = self.extra_dat.get("dependencies", [])
+        self.meson_build_dir = "bbdir"
+        self.build_type = (
+            "debug" if any("debug" in flag for flag in self.fc_flags) else "release"
+        )
+
+    def _move_exec_to_root(self, build_dir: Path):
+        walk_dir = Path(build_dir) / self.meson_build_dir
+        path_objects = chain(
+            walk_dir.glob(f"{self.modulename}*.so"),
+            walk_dir.glob(f"{self.modulename}*.pyd"),
+        )
+        # Same behavior as distutils
+        # https://github.com/numpy/numpy/issues/24874#issuecomment-1835632293
+        for path_object in path_objects:
+            dest_path = Path.cwd() / path_object.name
+            if dest_path.exists():
+                dest_path.unlink()
+            shutil.copy2(path_object, dest_path)
+            os.remove(path_object)
+
+    def write_meson_build(self, build_dir: Path) -> None:
+        """Writes the meson build file at specified location"""
+        meson_template = MesonTemplate(
+            self.modulename,
+            self.sources,
+            self.dependencies,
+            self.libraries,
+            self.library_dirs,
+            self.include_dirs,
+            self.extra_objects,
+            self.flib_flags,
+            self.fc_flags,
+            self.build_type,
+            sys.executable,
+        )
+        src = meson_template.generate_meson_build()
+        Path(build_dir).mkdir(parents=True, exist_ok=True)
+        meson_build_file = Path(build_dir) / "meson.build"
+        meson_build_file.write_text(src)
+        return meson_build_file
+
+    def _run_subprocess_command(self, command, cwd):
+        subprocess.run(command, cwd=cwd, check=True)
+
+    def run_meson(self, build_dir: Path):
+        setup_command = ["meson", "setup", self.meson_build_dir]
+        self._run_subprocess_command(setup_command, build_dir)
+        compile_command = ["meson", "compile", "-C", self.meson_build_dir]
+        self._run_subprocess_command(compile_command, build_dir)
+
+    def compile(self) -> None:
+        self.sources = _prepare_sources(self.modulename, self.sources, self.build_dir)
+        self.write_meson_build(self.build_dir)
+        self.run_meson(self.build_dir)
+        self._move_exec_to_root(self.build_dir)
+
+
+def _prepare_sources(mname, sources, bdir):
+    extended_sources = sources.copy()
+    Path(bdir).mkdir(parents=True, exist_ok=True)
+    # Copy sources
+    for source in sources:
+        if Path(source).exists() and Path(source).is_file():
+            shutil.copy(source, bdir)
+    generated_sources = [
+        Path(f"{mname}module.c"),
+        Path(f"{mname}-f2pywrappers2.f90"),
+        Path(f"{mname}-f2pywrappers.f"),
+    ]
+    bdir = Path(bdir)
+    for generated_source in generated_sources:
+        if generated_source.exists():
+            shutil.copy(generated_source, bdir / generated_source.name)
+            extended_sources.append(generated_source.name)
+            generated_source.unlink()
+    extended_sources = [
+        Path(source).name
+        for source in extended_sources
+        if not Path(source).suffix == ".pyf"
+    ]
+    return extended_sources
diff --git a/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/meson.build.template b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/meson.build.template
new file mode 100644
index 00000000..8e34fdc8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/f2py/_backends/meson.build.template
@@ -0,0 +1,54 @@
+project('${modulename}',
+        ['c', 'fortran'],
+        version : '0.1',
+        meson_version: '>= 1.1.0',
+        default_options : [
+                            'warning_level=1',
+                            'buildtype=${buildtype}'
+                          ])
+fc = meson.get_compiler('fortran')
+
+py = import('python').find_installation('${python}', pure: false)
+py_dep = py.dependency()
+
+incdir_numpy = run_command(py,
+  ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'],
+  check : true
+).stdout().strip()
+
+incdir_f2py = run_command(py,
+    ['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'],
+    check : true
+).stdout().strip()
+
+inc_np = include_directories(incdir_numpy)
+np_dep = declare_dependency(include_directories: inc_np)
+
+incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src'
+inc_f2py = include_directories(incdir_f2py)
+fortranobject_c = incdir_f2py / 'fortranobject.c'
+
+inc_np = include_directories(incdir_numpy, incdir_f2py)
+# gh-25000
+quadmath_dep = fc.find_library('quadmath', required: false)
+
+${lib_declarations}
+${lib_dir_declarations}
+
+py.extension_module('${modulename}',
+                     [
+${source_list},
+                     fortranobject_c
+                     ],
+                     include_directories: [
+                     inc_np,
+${inc_list}
+                     ],
+                     dependencies : [
+                     py_dep,
+                     quadmath_dep,
+${dep_list}
+${lib_list}
+${lib_dir_list}
+                     ],
+                     install : true)