Fortran and Stata for Sequential Tasks


Our tasks are best done by utilizing the comparative advantage of different tools. As an example, we might want to use Stata for data processing and Fortran for optimization. Yet sometimes, the Stata task and the Fortran task have to be done sequentially. And we do not want to sit still and wait for the Stata task to end and manually begin the Fortran task. 

Consider for example the following set of tasks:
  1. Data processing, generate some data moments (Stata)
  1. Optimization using the data moments (Fortran)
  1. More manipulation of data using the optimization results from the previous step (Stata)

Step 2 can not start until step 1 is finished; and step 3 can not start until step 2 is finished. If we do this manually, we would have to run Stata code for step 1, wait for it to end; and start the Fortran code, wait for it to end; and start another Stata code again.

In this notes, I introduce a very simple way to deal with this problem, so that we can free ourselves from the computer. 

The basic ideas is that, we ask Stata to send a “go ahead” message to Fortran when step 1 is finished; and ask Fortran to send a “go ahead” message to Stata when step 2 is finished. 

More specifically, we maintain two “signal” files (simple text files would do). The first file deals with the sequentiality between step 1 and 2: Stata writes signal into this file and Fortran reads signal from the file. Once Stata finishes step 1, it opens this file and writes a signal into it. At the same time, we tell Fortran to wait while repeatedly read the same file until it receives a signal to move on. The wait process can be implemented by a simple “do while” loop. 

Similarly, the second file deals with sequentiality between step 2 and 3. The only difference is now Fortran writes and Stata reads. Stata is asked to wait until the signal says to move ahead. The wait process can be implemented using a simple “while” loop. 

Note: See the next page for the Fortran and Stata code. Run the Fortran code first, because it initializes the signal files. 

Fortran file

  INTEGER :: iwait
  REAL :: sig_ok                !<- sig_ok = 0 means wait; sig_ok = 1 means go ahead

!***Initializing the signal files
  sig_ok = 0
  OPEN(UNIT = 1, FILE='sig_ok_1.txt')
    WRITE(1,*) sig_ok
  OPEN(UNIT = 2, FILE='sig_ok_2.txt')
    WRITE(2,*) sig_ok
!******Wait for the signal from STATA to proceed
  iwait = 0
  sig_ok = 0
  DO WHILE(sig_ok .EQ. 0)
    CALL SLEEP(5)               !<-Ask Fortran to read the signal file once every 5 seconds
    OPEN(UNIT = 1, FILE='sig_ok_1.txt')
      READ(1,*) sig_ok
    PRINT *, "iwait", iwait
    PRINT *, "Step two finished"