Initializing help system before first use

raw: binary data format of the host application

The raw I/O driver provides an implementation of the initializations block in binary mode: instead of translating information from/to text format, data is kept in its raw representation. The following example shows how to use this driver in combination with the mem driver to exchange arrays of data between a model and an application through memory. As shown in the previous section, we may work with a separate model file (this example) or alternatively include the model source directly in the model.

#include <stdio.h>
#include "xprm_mc.h"

const struct
{                                 /* Initial values for array 'data': */
 const char *ind;                 /*   index name */
 double val,wght;                 /*   value and weight data entries */
} data[]={{"camera",15,2}, {"necklace",100,20}, {"vase",90,20},
          {"picture",60,30}, {"tv",40,40}, {"video",15,30},
          {"chest",10,60}, {"brick",1,10}};

double solution[8];               /* Array for solution values */

int main()
{
 XPRMmodel mod;
 int result;
 XPRMalltypes rvalue, itemname;
 XPRMset set;
 char bimfile[2000];              /* Buffer to store BIM file */
 size_t bimfile_size;             /* Buffer to store actual size of BIM file */
 char bimfile_name[64];           /* File name of BIM file */
 char data_name[40];              /* File name of initial values for 'data' */
 char solution_name[40];          /* File name of solution values */
 char params[96];                 /* Parameter string for model execution */

 XPRMinit();                      /* Initialize Mosel */

/* Prepare file name for compilation using 'mem' driver: */
/*   "mem:base address/size[/actual size pointer]"       */
 bimfile_size=0;
 sprintf(bimfile_name, "mem:%p/%d/%p",
         bimfile, (int)sizeof(bimfile), &bimfile_size);

                                  /* Compile model file to memory */
 XPRMcompmod(NULL, "burglar2r.mos", bimfile_name, "Knapsack example");
 printf("BIM file uses %lu bytes of memory.\n", bimfile_size);

                                  /* Load a BIM file from memory */
 mod=XPRMloadmod(bimfile_name, NULL);

/* Prepare file names for 'initializations' using the 'raw' driver:         */
/*   "rawoption[,...],filename"                                             */
/*   (Here, 'filename' uses the 'mem' driver, data is stored in memory)     */
/* Options for 'raw':                                                       */
/* 'slength=0': strings are represented by  pointers to null terminated     */
/*              arrays of characters (C-string) instead of fixed size arrays*/
/* 'noindex':   only array values are expected - no indices requested       */

 sprintf(data_name, "slength=0,mem:%p/%d", data, (int)sizeof(data));
 sprintf(solution_name, "noindex,mem:%p/%d", solution, (int)sizeof(solution));

                                  /* Pass file names as execution param.s */
 sprintf(params, "DATA='%s',SOL='%s'", data_name, solution_name);

 XPRMrunmod(mod, &result, params);   /* Run the model */

/* Display solutions values obtained from the model */
 printf("Objective: %g\n", XPRMgetobjval(mod));
 XPRMfindident(mod, "ITEMS", &rvalue);     /* Get the model object 'ITEMS' */
 set = rvalue.set;
 for(i=0;i<8;i++)
  printf(" take(%s): %g\n", XPRMgetelsetval(set, i+1, &itemname)->string,
         solution[i]);

 return 0;
}

The input data in the C code above is stored and communicated to the model in sparse format, that is, each data item with its index tuple. For retrieving and saving the solution data this example uses dense format, that is, just the data items without explicitly specifying the indices. To obtain a printout with the (string) index names, we retrieve separately the set of indices from the Mosel model. Alternatively, we could also use sparse format for the solution data similarly to the input data, in which case we did not have to retrieve the index set separately.

The model file burglar2r.mos of this example is very similar to the model versions for the odbc and diskdata I/O drivers in Section Data source access from Mosel models. The only changes made are to the name of the I/O driver and to the strings DATA and SOL for the data source and the destination of results respectively.

model Burglar2r
 uses 'mmxprs'

 parameters
  IODRV = 'raw:'
  DATA=''
  SOL=''
  WTMAX = 102                    ! Maximum weight allowed
 end-parameters

 declarations
  ITEMS: set of string           ! Index set for items
  VALUE: array(ITEMS) of real    ! Value of items
  WEIGHT: array(ITEMS) of real   ! Weight of items
  SOLTAKE: array(ITEMS) of real  ! Solution values
 end-declarations

 initialisations from IODRV
  [VALUE,WEIGHT] as DATA
 end-initialisations

 declarations
  take: array(ITEMS) of mpvar    ! 1 if we take item i; 0 otherwise
 end-declarations

! Objective: maximize total value
 MaxVal:= sum(i in ITEMS) VALUE(i)*take(i)

! Weight restriction
 sum(i in ITEMS) WEIGHT(i)*take(i) <= WTMAX

! All variables are 0/1
 forall(i in ITEMS) take(i) is_binary

 maximize(MaxVal)                ! Solve the problem

! Solution output
 forall(i in ITEMS) SOLTAKE(i):= getsol(take(i))

 initialisations to IODRV
  SOLTAKE as SOL
 end-initialisations

end-model

The example above uses sparse data format, that is, every data entry comprises its index (or index tuple) and the actual value (or list of values in our case). A model version using dense data format, so communicating just the data values without the indices, is described in Chapter 13.4.1 `Exchanging data between an application and a modelDense arrays' of the `Mosel User Guide'.

The raw format communicates data via fixed-size memory blocks. Greater flexibility through dynamic sizing of the data structures can be achieved by using the callback functionality provided through the driver cb (see Section cb: output to callback functions below and the examples of Chapters 13.4.3 and 14.1.7.3 `Exchanging data between an application and a model Dynamic data' of the `Mosel User Guide' for C and Java examples respectively).

Java version of the example

With the Mosel Java libraries, we replace the C driver raw by the Java binary format I/O driver jraw. Just as in the C version, we have stored the model data in a single structure containing the string index and the two data values for 'weight' and 'value' of every item. Mosel returns the solution into a second structure that also stores index and data values.

// Class to store initial values for array 'data'
 public static class MyData
 {
  public String ind;                // index name
  public double val,wght;           // value and weight data entries
  MyData(String i, double v, double w)
  { ind=i; val=v; wght=w; }
 }
                        // Class to receive solution values
 public static class MySol
 {
  public String ind;                // index name
  public double val;                // solution value
 }

 public static void main(String[] args) throws Exception
 {
  XPRM mosel;
  XPRMModel mod;
  MyData data[]={new MyData("camera",15,2), new MyData("necklace",100,20),
                 new MyData("vase",90,20), new MyData("picture",60,30),
		 new MyData("tv",40,40), new MyData("video",15,30),
                 new MyData("chest",10,60), new MyData("brick",1,10)};
  MySol[] solution=new MySol[8];

  for(int i=0;i<8;i++) solution[i] = new MySol();

  mosel = new XPRM();                 // Initialize Mosel

  mosel.compile("burglar2r.mos");     // Compile & load the model
  mod = mosel.loadModel("burglar2r.bim");

                        // Associate the Java objects with names in Mosel
  mosel.bind("dt", data);
  mosel.bind("sol", solution);
                        // File names are passed through execution parameters
  mod.execParams = "DATA='dt(ind,val,wght)',SOL='sol(ind,val)',IODRV='jraw:'";

  mod.run();                          // Run the model

  if(mod.getProblemStatus()!=mod.PB_OPTIMAL)
   System.exit(1);                    // Stop if no solution found

                        // Display solution values obtained from the model
  System.out.println("Objective value: " + mod.getObjectiveValue());
  for(int i=0;i<8;i++)
   System.out.println(" take(" + solution[i].ind + "): " + solution[i].val);

  mod.reset();                        // Reset the model
 }

A model version using dense data format is discussed in Chapter 14.1.7.1 `Exchanging data between an application and a modelDense arrays' of the `Mosel User Guide'.

.NET version of the example

The .NET version of our program is again very similar to its Java version. We now use the I/O driver dotnetraw in the place of jraw.

// Arrays containing initialization data for the model
 static double[] vdata = new double[] {15,100,90,60,40,15,10, 1};  // VALUE
 static double[] wdata = new double[] { 2, 20,20,30,40,30,60,10};  // WEIGHT

 // Structure to store initial values for the array 'data'
 class MyData {
  public string ind;
  public double val;
  public double wght;

  public MyData(string i, double v, double w) {
   this.ind = i;
   this.val = v;
   this.wght = w;
  }
 }

// Structure to receive solution values
 class MySol {
  public string ind;
  public double val;
 }

// The initial values for the array 'data'
 private static MyData[] data = new MyData[] {
                 new MyData("camera",15,2), new MyData("necklace",100,20),
                 new MyData("vase",90,20), new MyData("picture",60,30),
		 new MyData("tv",40,40), new MyData("video",15,30),
                 new MyData("chest",10,60), new MyData("brick",1,10) };

// Main entry point for the application
 static void Main(string[] args) {
  // Initialize Mosel
  XPRM mosel = XPRM.Init();

  // Compile and load the Mosel model
  XPRMModel model = mosel.CompileAndLoad("burglar2r.mos");

  // Associate the .NET object with a name in Mosel
  model.Bind("dt", data);

  // Create a new array for solution data and bind that to the name 'SOL'
  MySol[] solution=new MySol[8];
  for(int i=0;i<8;i++) solution[i] = new MySol();
  mosel.Bind("sol", solution);

  // Pass data location as a parameter to the model
  model.ExecParams =
      "DATA='dt(ind,val,wght)',SOL='sol(ind,val)',IODRV='dotnetraw:'";

  // Run the model
  model.Run();

  // Print the solution
  Console.WriteLine("Objective value: {0}", model.ObjectiveValue);
  for(int i=0;i<8;i++)
   Console.Write(" take({0}): {1}",  solution[i].ind, solution[i].val);
  Console.WriteLine();
 }

mmjobs version of the example

When running a Mosel model from another model, the two models can exchange data in memory using the binary format defined by raw. Given the restrictions of the raw format (each 'file' only contains a single data array, composite Mosel data structures are not supported) we recommend however to give preference to the more flexible binary format defined by the bin driver that supports the full set of data structures of initializations blocks (see Section bin: using Mosel's binary format below). Here is an example of a Mosel model reading and writing data to memory in binary format using bin.

model "Run model burglar IO"
 uses "mmjobs"

 declarations
  modBurg: Model                    ! Submodel
  ISet,SSet: set of string          ! Index set for data arrays
  V,W: array(ISet) of real          ! Data arrays
  Solution: array(SSet) of real     ! Solution values
 end-declarations

 V:: (["camera","necklace","vase","picture","tv","video","chest","brick"])
      [15, 100, 90, 60, 40, 15, 10,  1]
 W:: (["camera","necklace","vase","picture","tv","video","chest","brick"])
      [ 2,  20, 20, 30, 40, 30, 60, 10]

                                    ! Compile the model, save bim in memory
 if compile("burglar2r.mos")<>0 then exit(1); end-if
 load(modBurg, "burglar2r.bim")     ! Load the bim file

 setdefstream(modBurg, F_OUTPUT, "null:")   ! Disable output from submodel

! Save data in shared memory
 IODRV:="bin:shmem:burgdata"
 initializations to IODRV
  [V,W] as "Burgdata"
 end-initializations
                                    ! Start model execution, setting parameters
 run(modBurg, "IODRV='" +IODRV + "',DATA='Burgdata',SOL='Solution'")
 wait                               ! Wait for model termination
 dropnextevent                      ! Ignore termination event message

! Retrieve solution from shared memory
 initializations from IODRV
  Solution
 end-initializations

 forall(i in SSet)  writeln(" take(", i, "): ", Solution(i))

end-model 

The relevant part of the model above look as follows with the raw I/O driver.

! Save data in shared memory
 IODRV:="raw:"
 initializations to IODRV
  [V,W] as "shmem:Burgdata"
 end-initializations
                                    ! Start model execution, setting parameters
 run(modBurg, "IODRV='" +IODRV + "',DATA='shmem:Burgdata',SOL='shmem:SolTake'")
 wait                               ! Wait for model termination
 dropnextevent                      ! Ignore termination event message

! Retrieve solution from shared memory
 initializations from IODRV
  Solution as "shmem:SolTake"
 end-initializations

© 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.