PythonBridge.F90 Source File


This file depends on

sourcefile~~pythonbridge.f90~~EfferentGraph sourcefile~pythonbridge.f90 PythonBridge.F90 sourcefile~base_base.f90 Base_Base.F90 sourcefile~pythonbridge.f90->sourcefile~base_base.f90 sourcefile~mapl_generic.f90 MAPL_Generic.F90 sourcefile~pythonbridge.f90->sourcefile~mapl_generic.f90 sourcefile~maplshared.f90 MaplShared.F90 sourcefile~pythonbridge.f90->sourcefile~maplshared.f90

Files dependent on this one

sourcefile~~pythonbridge.f90~~AfferentGraph sourcefile~pythonbridge.f90 PythonBridge.F90 sourcefile~mapl.f90 MAPL.F90 sourcefile~mapl.f90->sourcefile~pythonbridge.f90 sourcefile~capdriver.f90 CapDriver.F90 sourcefile~capdriver.f90->sourcefile~mapl.f90 sourcefile~extdataroot_gridcomp.f90 ExtDataRoot_GridComp.F90 sourcefile~capdriver.f90->sourcefile~extdataroot_gridcomp.f90 sourcefile~comp_testing_driver.f90 Comp_Testing_Driver.F90 sourcefile~comp_testing_driver.f90->sourcefile~mapl.f90 sourcefile~driver.f90 driver.F90 sourcefile~driver.f90->sourcefile~mapl.f90 sourcefile~gridcomp.f90 GridComp.F90 sourcefile~driver.f90->sourcefile~gridcomp.f90 sourcefile~extdatadriver.f90 ExtDataDriver.F90 sourcefile~extdatadriver.f90->sourcefile~mapl.f90 sourcefile~extdatadrivergridcomp.f90 ExtDataDriverGridComp.F90 sourcefile~extdatadriver.f90->sourcefile~extdatadrivergridcomp.f90 sourcefile~extdatadrivermod.f90 ExtDataDriverMod.F90 sourcefile~extdatadriver.f90->sourcefile~extdatadrivermod.f90 sourcefile~extdatadriver.f90->sourcefile~extdataroot_gridcomp.f90 sourcefile~extdatadrivergridcomp.f90->sourcefile~mapl.f90 sourcefile~extdatadrivermod.f90->sourcefile~mapl.f90 sourcefile~extdatadrivermod.f90->sourcefile~extdatadrivergridcomp.f90 sourcefile~extdatadrivermod.f90->sourcefile~extdataroot_gridcomp.f90 sourcefile~extdataroot_gridcomp.f90->sourcefile~mapl.f90 sourcefile~varspecdescription.f90 VarspecDescription.F90 sourcefile~extdataroot_gridcomp.f90->sourcefile~varspecdescription.f90 sourcefile~gridcomp.f90->sourcefile~mapl.f90 sourcefile~mapl_demo_fargparse.f90 MAPL_demo_fargparse.F90 sourcefile~mapl_demo_fargparse.f90->sourcefile~mapl.f90 sourcefile~pfio_mapl_demo.f90 pfio_MAPL_demo.F90 sourcefile~pfio_mapl_demo.f90->sourcefile~mapl.f90 sourcefile~regrid_util.f90 Regrid_Util.F90 sourcefile~regrid_util.f90->sourcefile~mapl.f90 sourcefile~time_ave_util.f90 time_ave_util.F90 sourcefile~time_ave_util.f90->sourcefile~mapl.f90 sourcefile~varspecdescription.f90->sourcefile~mapl.f90

Source Code

#include "MAPL_Generic.h"

module MAPL_PythonBridge

   ! -----------------------------
   ! Generic bridge mechanism to pull MAPL down to the python level
   !
   ! WARNING: All functional code should be #ifdef with PYTHONBRIDGE_INTEGRATION
   !          in order to keep the functionality as a deliberate opt-in
   !
   ! -----------------------------
   use ESMF
   use MAPL_BaseMod
   use MAPL_GenericMod
   use MaplShared
#ifdef PYTHONBRIDGE_INTEGRATION
   use mapl_fortran_python_bridge, only: mapl_fortran_python_bridge_global_initialize
   use mapl_fortran_python_bridge, only: mapl_fortran_python_bridge_user_init
   use mapl_fortran_python_bridge, only: mapl_fortran_python_bridge_user_run
   use mapl_fortran_python_bridge, only: mapl_fortran_python_bridge_user_run_with_internal
   use mapl_fortran_python_bridge, only: mapl_fortran_python_bridge_user_finalize
   use mapl_fortran_python_bridge, only: pygeosbridge_name_buffer
   use ieee_exceptions, only: ieee_get_halting_mode, ieee_set_halting_mode
   use ieee_exceptions, only: ieee_overflow, ieee_support_halting
   use iso_c_binding, only: c_loc, C_NULL_CHAR
#endif

   implicit none
   private

   public initialize_python_bridge
   public MAPL_pybridge_gcrun
   public MAPL_pybridge_gcrun_with_internal
   public MAPL_pybridge_gcinit
   public MAPL_pybridge_gcfinalize

contains

   subroutine initialize_python_bridge(im, jm, lm)
      ! -----------------------------
      ! Initialize the underlying python tools with a grid size.
      ! It will spin a central CFFI-handled python interpreter
      ! It also gives us a hook to do pre-load of common packages (numpy, tf, etc.)
      !
      ! TODO | Dev Note : this works for a single GRID. A much powerful system
      !                   would not get the dimensions upfront but have them part
      !                   of the backward fetch from python to MAPL
      ! -----------------------------
      integer, intent(in), value :: im, jm, lm

      character(len=ESMF_MAXSTR) :: IAm
      integer :: STATUS
      integer :: RC

#ifdef PYTHONBRIDGE_INTEGRATION
      logical :: halting_mode(5)
      logical :: set_halting_allowed

      ! Spin the interface - we have to deactivate the ieee error
      ! to be able to load numpy, scipy and other numpy packages
      ! that generate an overflow during init

      set_halting_allowed = ieee_support_halting(ieee_overflow)

      if (set_halting_allowed) then
         call ieee_get_halting_mode(ieee_overflow, halting_mode)
         call ieee_set_halting_mode(ieee_overflow, .false.)
      end if
      call mapl_fortran_python_bridge_global_initialize(im, jm, lm)
      if (set_halting_allowed) then
         call ieee_set_halting_mode(ieee_overflow, halting_mode)
      end if
#endif

   end subroutine initialize_python_bridge

   subroutine MAPL_pybridge_gcinit(pypkg_name, mapl, import, export)
      ! -----------------------------
      ! Call the python integration by marhshalling Fortran object/memory
      ! into C compatible memory
      ! Will trigger the `GEOSInterfaceCode.init` python function on the user code
      ! -----------------------------
      character(len=*), intent(in) :: pypkg_name
      type(MAPL_MetaComp), intent(inout), target :: mapl ! MAPL state
      type(ESMF_State), intent(inout), target :: import ! Import state
      type(ESMF_State), intent(inout), target :: export ! Export state

#ifdef PYTHONBRIDGE_INTEGRATION
      pygeosbridge_name_buffer = pypkg_name // C_NULL_CHAR
      call mapl_fortran_python_bridge_user_init( &
           c_loc(pygeosbridge_name_buffer), &
           c_loc(mapl), c_loc(import), c_loc(export))
#endif
   end subroutine MAPL_pybridge_gcinit

   subroutine MAPL_pybridge_gcrun(pypkg_name, mapl, import, export)
      ! -----------------------------
      ! Call the python integration by marhshalling Fortran object/memory
      ! into C compatible memory
      ! Will trigger the `GEOSInterfaceCode.run` python function on the user code
      ! -----------------------------
      character(len=*), intent(in) :: pypkg_name
      type(MAPL_MetaComp), intent(inout), target :: mapl ! MAPL state
      type(ESMF_State), intent(inout), target :: import ! Import state
      type(ESMF_State), intent(inout), target :: export ! Export state

#ifdef PYTHONBRIDGE_INTEGRATION
      pygeosbridge_name_buffer = pypkg_name // C_NULL_CHAR
      call mapl_fortran_python_bridge_user_run( &
           c_loc(pygeosbridge_name_buffer), &
           c_loc(mapl), c_loc(import), c_loc(export))
#endif
   end subroutine MAPL_pybridge_gcrun

   subroutine MAPL_pybridge_gcrun_with_internal(pypkg_name, mapl, import, export, internal)
      ! -----------------------------
      ! Call the python integration by marhshalling Fortran object/memory
      ! into C compatible memory. Variation of `gcrun` with an INTERNAL state
      ! Will trigger the `GEOSInterfaceCode.run_with_internal` python function on the user code
      ! -----------------------------
      character(len=*), intent(in) :: pypkg_name
      type(MAPL_MetaComp), intent(inout), target :: mapl ! MAPL state
      type(ESMF_State), intent(inout), target :: import ! Import state
      type(ESMF_State), intent(inout), target :: export ! Export state
      type(ESMF_State), intent(inout), target :: internal ! Internal state

#ifdef PYTHONBRIDGE_INTEGRATION
      pygeosbridge_name_buffer = pypkg_name // C_NULL_CHAR
      call mapl_fortran_python_bridge_user_run_with_internal( &
           c_loc(pygeosbridge_name_buffer), &
           c_loc(mapl), c_loc(import), c_loc(export), c_loc(internal))
#endif
   end subroutine MAPL_pybridge_gcrun_with_internal

   subroutine MAPL_pybridge_gcfinalize(pypkg_name, mapl, import, export)
      ! -----------------------------
      ! Call the python integration by marhshalling Fortran object/memory
      ! into C compatible memory.
      ! Will trigger the `GEOSInterfaceCode.finalize` python function on the user code
      ! -----------------------------
      character(len=*), intent(in) :: pypkg_name
      type(MAPL_MetaComp), intent(inout), target :: mapl ! MAPL state
      type(ESMF_State), intent(inout), target :: import ! Import state
      type(ESMF_State), intent(inout), target :: export ! Export state

#ifdef PYTHONBRIDGE_INTEGRATION
      pygeosbridge_name_buffer = pypkg_name // C_NULL_CHAR
      call mapl_fortran_python_bridge_user_finalize( &
           c_loc(pygeosbridge_name_buffer), &
           c_loc(mapl), c_loc(import), c_loc(export))
#endif
   end subroutine MAPL_pybridge_gcfinalize

end module MAPL_PythonBridge