|
| 1 | +'''This Python code is an automatically generated wrapper |
| 2 | +for Fortran code made by 'fmodpy'. The original documentation |
| 3 | +for the Fortran source code follows. |
| 4 | +
|
| 5 | +
|
| 6 | +''' |
| 7 | + |
| 8 | +import os |
| 9 | +import ctypes |
| 10 | +import platform |
| 11 | +import numpy |
| 12 | + |
| 13 | +# -------------------------------------------------------------------- |
| 14 | +# CONFIGURATION |
| 15 | +# |
| 16 | +_verbose = True |
| 17 | +_fort_compiler = "gfortran" |
| 18 | +_shared_object_name = "compute." + platform.machine() + ".so" |
| 19 | +_this_directory = os.path.dirname(os.path.abspath(__file__)) |
| 20 | +_path_to_lib = os.path.join(_this_directory, _shared_object_name) |
| 21 | +_compile_options = ['-fPIC', '-shared', '-O3'] |
| 22 | +_ordered_dependencies = ['compute.f90', 'compute_c_wrapper.f90'] |
| 23 | +_symbol_files = []# |
| 24 | +# -------------------------------------------------------------------- |
| 25 | +# AUTO-COMPILING |
| 26 | +# |
| 27 | +# Try to import the prerequisite symbols for the compiled code. |
| 28 | +for _ in _symbol_files: |
| 29 | + _ = ctypes.CDLL(os.path.join(_this_directory, _), mode=ctypes.RTLD_GLOBAL) |
| 30 | +# Try to import the existing object. If that fails, recompile and then try. |
| 31 | +try: |
| 32 | + # Check to see if the source files have been modified and a recompilation is needed. |
| 33 | + if (max(max([0]+[os.path.getmtime(os.path.realpath(os.path.join(_this_directory,_))) for _ in _symbol_files]), |
| 34 | + max([0]+[os.path.getmtime(os.path.realpath(os.path.join(_this_directory,_))) for _ in _ordered_dependencies])) |
| 35 | + > os.path.getmtime(_path_to_lib)): |
| 36 | + print() |
| 37 | + print("WARNING: Recompiling because the modification time of a source file is newer than the library.", flush=True) |
| 38 | + print() |
| 39 | + if os.path.exists(_path_to_lib): |
| 40 | + os.remove(_path_to_lib) |
| 41 | + raise NotImplementedError(f"The newest library code has not been compiled.") |
| 42 | + # Import the library. |
| 43 | + clib = ctypes.CDLL(_path_to_lib) |
| 44 | +except: |
| 45 | + # Remove the shared object if it exists, because it is faulty. |
| 46 | + if os.path.exists(_shared_object_name): |
| 47 | + os.remove(_shared_object_name) |
| 48 | + # Compile a new shared object. |
| 49 | + _command = " ".join([_fort_compiler] + _compile_options + ["-o", _shared_object_name] + _ordered_dependencies) |
| 50 | + if _verbose: |
| 51 | + print("Running system command with arguments") |
| 52 | + print(" ", _command) |
| 53 | + # Run the compilation command. |
| 54 | + import subprocess |
| 55 | + subprocess.run(_command, shell=True, cwd=_this_directory) |
| 56 | + # Import the shared object file as a C library with ctypes. |
| 57 | + clib = ctypes.CDLL(_path_to_lib) |
| 58 | +# -------------------------------------------------------------------- |
| 59 | + |
| 60 | + |
| 61 | +class compute_module: |
| 62 | + '''''' |
| 63 | + |
| 64 | + |
| 65 | + # ---------------------------------------------- |
| 66 | + # Wrapper for the Fortran subroutine COMPUTE1 |
| 67 | + |
| 68 | + def compute1(self, x, y): |
| 69 | + '''''' |
| 70 | + |
| 71 | + # Setting up "x" |
| 72 | + if ((not issubclass(type(x), numpy.ndarray)) or |
| 73 | + (not numpy.asarray(x).flags.f_contiguous) or |
| 74 | + (not (x.dtype == numpy.dtype(ctypes.c_double)))): |
| 75 | + import warnings |
| 76 | + warnings.warn("The provided argument 'x' was not an f_contiguous NumPy array of type 'ctypes.c_double' (or equivalent). Automatically converting (probably creating a full copy).") |
| 77 | + x = numpy.asarray(x, dtype=ctypes.c_double, order='F') |
| 78 | + x_dim_1 = ctypes.c_long(x.shape[0]) |
| 79 | + x_dim_2 = ctypes.c_long(x.shape[1]) |
| 80 | + |
| 81 | + # Setting up "y" |
| 82 | + if ((not issubclass(type(y), numpy.ndarray)) or |
| 83 | + (not numpy.asarray(y).flags.f_contiguous) or |
| 84 | + (not (y.dtype == numpy.dtype(ctypes.c_double)))): |
| 85 | + import warnings |
| 86 | + warnings.warn("The provided argument 'y' was not an f_contiguous NumPy array of type 'ctypes.c_double' (or equivalent). Automatically converting (probably creating a full copy).") |
| 87 | + y = numpy.asarray(y, dtype=ctypes.c_double, order='F') |
| 88 | + y_dim_1 = ctypes.c_long(y.shape[0]) |
| 89 | + y_dim_2 = ctypes.c_long(y.shape[1]) |
| 90 | + |
| 91 | + # Call C-accessible Fortran wrapper. |
| 92 | + clib.c_compute1(ctypes.byref(x_dim_1), ctypes.byref(x_dim_2), ctypes.c_void_p(x.ctypes.data), ctypes.byref(y_dim_1), ctypes.byref(y_dim_2), ctypes.c_void_p(y.ctypes.data)) |
| 93 | + |
| 94 | + # Return final results, 'INTENT(OUT)' arguments only. |
| 95 | + return y |
| 96 | + |
| 97 | +compute_module = compute_module() |
| 98 | + |
0 commit comments