From f75c1d0493640adab700d916c1d293cfa6f1f306 Mon Sep 17 00:00:00 2001 From: Michael Lange Date: Sun, 22 Dec 2024 05:55:38 +0000 Subject: [PATCH] Transpile: Improved docstrings for the ISO-C wrapper sub-package --- .../transpile/fortran_iso_c_wrapper.py | 80 ++++++++++++++++++- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/loki/transformations/transpile/fortran_iso_c_wrapper.py b/loki/transformations/transpile/fortran_iso_c_wrapper.py index a087ae3fd..803fbd173 100644 --- a/loki/transformations/transpile/fortran_iso_c_wrapper.py +++ b/loki/transformations/transpile/fortran_iso_c_wrapper.py @@ -190,7 +190,24 @@ def c_struct_typedef(derived, use_c_ptr=False): def generate_iso_c_interface(routine, bind_name, c_structs, scope, use_c_ptr=False, language='c'): """ - Generate the ISO-C subroutine interface + Generate the ISO-C subroutine :any:`Interface` object for a given :any:`Subroutine`. + + Parameters + ---------- + routine : :any:`Subroutine` + The subroutine for which to generate the interface + bind_name : str + Name of the C-function to which this interface corresponds. + c_structs : dict of str to str + Map from Fortran derived type name to C-struct type name + scope : :any:`Scope` + Parent scope in which to create the :any:`Interface` + use_c_ptr : bool, optional + Use ``c_ptr`` for array declarations and ``c_loc(...)`` to + pass the corresponding argument. Default is ``False``. + language : string + C-style language to generate; if this is ``'c'``, we resolve + non-C imports. """ intf_name = f'{routine.name}_iso_c' intf_routine = Subroutine(name=intf_name, body=None, args=(), parent=scope, bind=bind_name) @@ -237,6 +254,34 @@ def generate_iso_c_interface(routine, bind_name, c_structs, scope, use_c_ptr=Fal def generate_iso_c_wrapper_routine(routine, c_structs, bind_name=None, use_c_ptr=False, language='c'): + """ + Generate Fortran ISO-C wrapper :any:`Subroutine` that corresponds + to a transpiled C method. + + The new wrapper subroutine will have the suffix ``'_fc'`` appended + to the name original subroutine name and bind to a C function with + the suffix ``'_c'``. + + This method will call :meth:`generate_iso_c_interface` to generate + the ISO-C compatible interface for the C function and generate a + wrapper :any:`Subroutine` that converts the native Fortran arguments + to a call to the C function with ISO-C compatible arguments. + + Parameters + ---------- + routine : :any:`Subroutine` + The subroutine for which to generate the interface + c_structs : dict of str to str + Map from Fortran derived type name to C-struct type name + bind_name : str + Name of the C-function to which this interface corresponds. + use_c_ptr : bool, optional + Use ``c_ptr`` for array declarations and ``c_loc(...)`` to + pass the corresponding argument. Default is ``False``. + language : string + C-style language to generate; if this is ``'c'``, we resolve + non-C imports. + """ wrapper = Subroutine(name=f'{routine.name}_fc') if bind_name is None: @@ -323,9 +368,28 @@ def generate_iso_c_wrapper_module(module, use_c_ptr=False, language='c'): """ Generate the ISO-C wrapper module for a raw Fortran module. - Note, we only create getter functions for module variables here, - since certain type definitions cannot be used in ISO-C interfaces - due to pointer variables, etc. + The new wrapper module will have the suffix ``'_fc'`` appended to + the name and contain ISO-C function interfaces for contained + :any:`Subroutine` objects. This method will call + :meth:`generate_iso_c_routine` to generate the ISO-C compatible + procedure interfaces. + + Note + ---- + If the module contains global variables, we generate templated + getter functions here, as global Fortran variables are not + accessible via ISO-C interfaces. + + Parameters + ---------- + module : :any:`Module` + The module for which to generate the interface module + use_c_ptr : bool, optional + Use ``c_ptr`` for array declarations and ``c_loc(...)`` to + pass the corresponding argument. Default is ``False``. + language : string + C-style language to generate; if this is ``'c'``, we resolve + non-C imports. """ modname = f'{module.name}_fc' wrapper_module = Module(name=modname) @@ -392,6 +456,14 @@ def generate_c_header(module): """ Re-generate the C header as a module with all pertinent nodes, but not Fortran-specific intrinsics (eg. implicit none or save). + + The new header module will have the suffix ``'_c'`` appended to + the original module name. + + Parameters + ---------- + module : :any:`Module` + The module for which to generate the C header """ header_module = Module(name=f'{module.name}_c')