Exchanging data with the model
An application that processes a Mosel model typically needs to retrieve some (result) data from the model for reporting or further treatment. Besides exchanging data via external sources (e.g. databases), Mosel offers a number of possibilities for directly retrieving data into an XPRD program. The choice of the method for exchanging data usually depends on the particular system setup (write access rights) and the volume of data to be communicated (memory usage). Data in Mosel format written in an initializations block can be output
- on the remote machine running Mosel
- in memory
- as a physical file
- on the local machine running XPRD
- in memory
- as a physical file
Case 1a is implemented in the program version runprimeiodistr.java printed below. Case 1b is obtained by removing the shmem: prefix from the file name, for example, the setting
OUTPUTFILE=bin:tmp:resdata
will create a file resdata in Mosel's temporary directory. Cases 2a and 2b could use the setting
OUTPUTFILE=bin:rmt:resdata
For the implementation of case 2b we simply replace the XPRD remote file access by standard Java file access, for example
resdata=new FileInputStream("resdata");Somewhat more work is required for the implementation of case 2a: the program needs to define an XPRD file manager to handle the data in memory—an example implementation is provided in the file runprimeiodistr2.java.
All implementation versions share the use of the bin: I/O driver and they all define the same function showSolution that decodes Mosel's binary format and displays the solution values. Using Mosel's binary format is recommended (though not a necessity) in distributed applications—it is platform-independent and uses less space than the standard text format.
The program version printed below introduces two user events to achieve more precise time measures for the remote process: the hard stop of the Mosel model is replaced by sending the user event `STOPMOD' to the submodel: instead of immediately terminating the submodel this event is intercepted by the submodel and makes it interrupt its calculations and write out the current solution. To make sure that the submodel is actually running at the point where we sent the `STOPMOD' event, we have also introduced a 'MODREADY' event sent from the submodel to the master to indicate the point of time when it starts the calculations (with heavy operating system loads the actual submodel start may be delayed).
We work with the Mosel model primeio.mos from Section Exchanging data between models.
import com.dashoptimization.*; import java.lang.*; import java.util.*; import java.io.*; public class runprimeiodistr { static final int STOPMOD = 2; // Identifier for "Stop submodel" user event static final int MODREADY = 3; // Identifier for "Submodel ready" user event public static void main(String[] args) throws Exception { XPRD xprd=new XPRD(); // Initialize XPRD XPRDMosel moselInst; XPRDModel modPrime; XPRDEvent event; InputStream resdata; moselInst=xprd.connect(""); // Open connection to remote nodes // "" means the node running this program // Compile the model file on remote instance moselInst.compile("", "rmt:primeio.mos", "tmp:primeio.bim"); // Load the bim file into remote instance modPrime=moselInst.loadModel("tmp:primeio.bim"); // Disable submodel output modPrime.setDefaultStream(modPrime.F_OUTPUT, "null:"); modPrime.execParams = "LIMIT=50000,OUTPUTFILE=bin:shmem:resdata"; modPrime.run(); // Start execution and xprd.waitForEvent(); // ...wait for an event event=xprd.getNextEvent(); // Retrieve the event if (event.eventClass != MODREADY) // Check the event class { System.out.println("Problem with submodel run"); System.exit(1); } xprd.waitForEvent(2); // Let the submodel run for 2 seconds if (xprd.isQueueEmpty()) // No event has been sent... { System.out.println("Model too slow: stopping it!"); modPrime.sendEvent(STOPMOD, 0); // ... stop the model, then xprd.waitForEvent(); // wait for its termination } // Open the output file, retrieve and display the solution data resdata=moselInst.openForReading("shmem:resdata", moselInst.F_BINARY); showSolution(resdata); resdata.close(); moselInst.unloadModel(modPrime); // Unload the submodel moselInst.disconnect(); // Terminate the connection } }
After termination of the model run, the XPRD application reads the solution data from the location specified in the model parameter OUTPUTFILE and displays the results. Below follows the implementation of the function showSolution that uses an instance of BinDrvReader to decode Mosel's binary format (the bindrv library is provided with XPRD). A binary format files has the same structure as the correponding text file in Mosel format, for example:
NumP: 6 SPrime: [ 2 3 5 7 11 13 ]
Each data entry starts with a label (string followed by a colon), followed either by a single, scalar data value, or a list of data values surrounded by square brackets.
// **** Decode the binary stream and display its contents **** static void showSolution(InputStream inbuf) throws Exception { BinDrvReader bdrv=new BinDrvReader(inbuf); // Initialize binreader String label; ArrayList<Integer> setP=new ArrayList<Integer>(); while(bdrv.nextToken()>=0) { bdrv.getControl(); // 'label' (marker) label=bdrv.getString(); // Read a string if(label.equals("NumP")) { // Read an integer System.out.println("(" + bdrv.getInt() + " prime numbers.)"); } else if(label.equals("SPrime")) { bdrv.getControl(); // [ (start marker) while(bdrv.nextToken()==BinDrvReader.TYP_INT) // or ] at end of list { // Read integers setP.add(new Integer(bdrv.getInt())); } bdrv.getControl(); // ] (end marker) } else { System.out.println("Unexpected label: "+label); System.exit(0); } } // Display the contents of the set 'SPrime' Iterator<Integer> iprime=setP.iterator(); System.out.print("Prime numbers={"); while(iprime.hasNext()) { Integer p=iprime.next(); System.out.print(" "+p); } System.out.println(" }"); }
© 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.