BaM-tools / BaM

BaM (Bayesian Modeling) is a framework aimed at estimating a model using a bayesian approach and using it for prediction, with a particular focus on uncertainty quantification.
Other
2 stars 0 forks source link

Strategies for piloting a model not available in Fortran (e.g. external executable, Python or R script, etc.) #12

Open benRenard opened 5 months ago

benRenard commented 5 months ago

Problem statement

When BaM controls a model that is not implemented in Fortran (e.g. by calling an exe or a Python script), the communication between BaM and the model MDL during MCMC-based parameter estimation can be roughly described as follows:

0. MDL setup

do many times:
1. BaM proposes candidate  parameters and writes them
2. MDL reads parameters, runs model and writes simulated outputs
3. BAM reads simulated outputs, computes posterior and accept or reject parameters

This requires setting up some sort of 2-way communication between BaM and MDL so that BaM can tell MDL to run, then MDL can let BaM know when it's done, etc. There exist several approaches to implement this.

Approach 1: the easy way

Implements step 2 in a script or an executable that will be called in the XXX_run subroutine of BaM, e.g.: call execute_command_line(cmdString,wait=.true.,exitStat=err,cmdMsg=mess) It's the simplest approach and corresponds to what is implemented for MAGE. The main drawback is that any action performed as part of this script/exe will be repeated every time the script/exe is called. Such actions may include importing modules or reading large data files that do not change across iterations. It's not a big issue if the CPU time of such actions is small compared with the CPU time of running the model (such as in MAGE), but it's problematic otherwise (e.g. SMASH which requires importing big modules and reading large input files, while the CPU time to run the model is comparably quite small).

Approach 2: the "two infinite loops" approach

This is the approach used for SMASH, and it is based on the the idea that the MDL script should be called only once to avoid re-importing modules and re-reading inputs at each iteration. From the MDL side, this can be achieved by a script that looks like what follows and that should be called AT STEP 0 (and not at step 2!)

import modules
read input files
# file used as a way for MDL to let BaM know that initialization is done:
create file 'initDone.MDL' 
# start infinite loop running MDL when BaM asks for it:
keepGoing=True
while keepGoing:
    if  file 'run.BAM' exists: # BaM is asking for a run
        read parameters
                run model
        delete file 'run.BAM' # cleanup
        write file 'runDone.MDL' # tell BaM it's done
    if file 'stop.BAM' exists # BaM says it's all done
        keepGoing=False
        delete file 'stop.BAM' # cleanup

Likewise, an infinite loop should be implemented in the XXX_run subroutine of BaM as follows:

write parameters
write file 'run.BAM' # tell MDL to run
! wait-for-it infinite loop
runDone=.false.
do while (.not. runDone) ! wait for signal from MDL
    INQUIRE(FILE='runDone.MDL',EXIST=runDone)
enddo
delete file 'runDone.MDL' # cleanup
Read simulated outputs

In a nutshell, 2-way communication is achieved by writing/deleting empty files as messengers. This looks a bit rudimentary, even sketchy, but it does work !

Approaches 3, 4, 5, etc.: to be evaluated

There exist several approaches that may be candidate to perform the 2-way communication of approach 2 in a less rudimentary way. Here are a few directions suggested by a specialist in programming (thanks Arnaud !) that need to be considered :

  1. Remote Procedure Call: unclear whether there is a Fortran library for this (there is a C one: RPCGEN)
  2. Linux Signals: there are Fortran utilities for this, but whether it's portable on Windows in unclear.
  3. Use network sockets - Fortran utilities?
  4. Solutions when MDL is a Python script: a. start a http server in python and send/receive messages as URLs (urllib, Fortran utilities?) b. explore the notify() function in Python (here or here?)
  5. [some more options following discussion with Apolline] expect command. Wiki. See this post.