Initializing help system before first use

Communication of data between different models

Runtime parameters are a means of communicating single data values to a submodel but they are not suited, for instance, to pass data tables or sets to a submodel. Also, they cannot be employed to retrieve any information from a submodel or to exchange data between models during their execution. All these tasks are addressed by the two I/O drivers defined by the module mmjobs: the shmem driver and the mempipe driver. As was already stated earlier, the shmem driver is meant for one-to-many communication (one model writing, many reading) and the mempipe driver serves for many-to-one communication. In the case of one model writing and one model reading we may use either, where shmem is conceptionally probably the easier to use.

Using the shared memory driver

With the shmem shared memory driver we write and read data blocks from/to memory. The use of this driver is quite similar to the way we would work with physical files. We have already encountered an example of its use in Section Compilation to memory: the filename is replaced by a label, prefixed by the name of the driver, such as "mmjobs.shmem:aLabel". If the module mmjobs is loaded by the model (or another model held in memory at the same time, such as its master model) we may use the short form "shmem:aLabel". Another case where we would have to explicitly add the name of a module to a driver occurs when we need to distinguish between several shmem drivers defined by different modules.

The exchange of data between different models is carried out through initializations blocks. In general, the shmem driver will be combined with the bin driver to save data in binary format (an alternative, somewhat more restrictive binary format is generated by the raw driver).

Let us now take a look at a modified version testsubshm.mos of our initial test submodel (Section Executing a submodel). This model reads in the index range from memory and writes back the resulting array to memory:

model "Test submodel"
 declarations
  A: range
  B: array(A) of real
 end-declarations

 initializations from "bin:shmem:indata"
  A
 end-initializations

 forall(i in A) B(i):= i^2

 initializations to "bin:shmem:resdata"
  B
 end-initializations

end-model 

The master model runsubshm.mos to run this submodel may look as follows:

model "Run model testsubshm"
 uses "mmjobs"

 declarations
  modSub: Model
  A = 30..40
  B: array(A) of real
 end-declarations
                                   ! Compile the model file
 if compile("testsubshm.mos")<>0 then exit(1); end-if
 load(modSub, "testsubshm.bim")    ! Load the bim file

 initializations to "bin:shmem:indata"
  A
 end-initializations

 run(modSub)                       ! Start model execution
 wait                              ! Wait for model termination
 dropnextevent                     ! Ignore termination event message

 initializations from "bin:shmem:resdata"
  B
 end-initializations

 writeln(B)

end-model 

Before the submodel run is started the index range is written to memory and after its end we retrieve the result array to print it out from the master model.

If memory blocks are no longer used it is recommended to free up these blocks by calling fdelete (subroutine provided by module mmsystem), especially if the data blocks are large, since the data blocks survive the termination of the model that has created them, even if the model is unloaded explicitly, until the module mmjobs is unloaded (explicitly or by the termination of the Mosel session). At the end of our master model we might thus add the lines

 fdelete("shmem:A")
 fdelete("shmem:B") 

Using the memory pipe driver

The memory pipe I/O driver mempipe works in the opposite way to what we have seen for the shared memory driver: a pipe first needs to be opened before it can be written to. That means we need to call initializations from before initializations to. The submodel (file testsubpip.mos) now looks as follows:

model "Test submodel"
 declarations
  A: range
  B: array(A) of real
 end-declarations

 initializations from "mempipe:indata"
  A
 end-initializations

 forall(i in A) B(i):= i^2

 initializations to "mempipe:resdata"
  B
 end-initializations

end-model 

This is indeed not very different from the previous submodel. However, there are more changes to the master model (file runsubpip.mos): the input data is now written by the master model after the submodel run has started. The master model then opens a new pipe to read the result data before the submodel terminates its execution.

model "Run model testsubpip"
 uses "mmjobs"

 declarations
  modSub: Model
  A = 30..40
  B: array(A) of real
 end-declarations
                                   ! Compile the model file
 if compile("testsubpip.mos")<>0 then exit(1); end-if
 load(modSub, "testsubpip.bim")    ! Load the bim file

 run(modSub)                       ! Start model execution

 initializations to "mempipe:indata"
  A
 end-initializations

 initializations from "mempipe:resdata"
  B
 end-initializations

 wait                              ! Wait for model termination
 dropnextevent                     ! Ignore termination event message

 writeln(B)

end-model 

Once a file has opened a pipe for reading it remains blocked in this state until it has received the requested data through this pipe. The program control flow is therefore the following in the present case:

  1. The master model starts the submodel.
  2. The submodel opens the input data pipe and waits for the master to write to it.
  3. Once the input data has been communicated the submodel continues its execution while the master model opens the result data pipe and waits for the results.
  4. When the result data pipe is open, the submodel writes to the result data pipe and then terminates.
  5. The master model prints out the result.

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.