Initializing help system before first use

Basic tasks: remote connection, coordination, communication, and parallelization


Type: Programming
Rating: 3 (intermediate)
Description: A series of examples of basic tasks that typically need to be performed when working with remote models in Mosel:
  • Check for available remote Mosel servers: findservers.*
  • Run a single model on a remote machine: runrtdistr.* (executing rtparams.mos)
  • Running parallel submodels in a distributed architecture: runrtpardistr.* (executing rtparams3.mos)
  • Queuing submodels for parallel execution in a distributed architecture with one or several models per node: runrtparqueued.* (executing rtparams3.mos)
File(s): findservers.c, findservers.java, runrtdistr.c, runrtdistr.java, rtparams.mos, runrtpardistr.c, runrtpardistr.java, rtparams3.mos, runrtparqueued.c, runrtparqueued.java


findservers.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file findservers.c
   ``````````````````
   Find Mosel servers that are able to accept remote model runs

   This file only produces output on the local node, 
   it does not start any remote runs.
       
   (c) 2013 Fair Isaac Corporation
       author: S. Heipcke, Jan. 2013
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "xprd.h"

#define M 20                   /* Max. number of servers to be sought */

int main(int argv,char *args[]) 
{
  XPRDcontext xprd;
  XPRDmosel mosInst;
  struct in_addr Hosts[M];
  char buf[200],*sysinfo;
  int hsize, i;

  xprd=XPRDinit();             /* Create an XPRD context */
 
  printf("Searching...\n"); fflush(stdout);
  hsize=XPRDfindxsrvs(xprd, 1,M, (unsigned int *)Hosts);
  printf("%d server(s) found.\n", hsize); fflush(stdout);
   
  for(i=0;i<hsize;i++) 
  {                            /* Open connection to a remote node */
    strcpy(buf,inet_ntoa(Hosts[i]));
    mosInst=XPRDconnect(xprd, buf, NULL, NULL, NULL, 0);
    if (mosInst!=NULL)
    {
      printf("Server %s: ", inet_ntoa(Hosts[i])); fflush(stdout);
      sysinfo=XPRDsysinfo(mosInst, XPRD_SYS_ALL, buf, sizeof(buf));
      printf("%s\n",sysinfo!=NULL?sysinfo:"?"); fflush(stdout);
      XPRDdisconnect(mosInst);     /* Disconnect remote instance */
    }
    else
    {
      printf("Connection to %s failed\n", inet_ntoa(Hosts[i]));
      fflush(stdout);
    }
  }
  
  XPRDfinish(xprd);            /* Terminate XPRD */
  return 0;
} 


findservers.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file findservers.java
   `````````````````````
   Find Mosel servers that are able to accept remote model runs

   This file only produces output on the local node, 
   it does not start any remote runs.
       
   (c) 2013 Fair Isaac Corporation
       author: S. Heipcke, Jan. 2013
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.io.*;
import java.util.*;


public class findservers
{
 static final int M=20;
 
 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDMosel mosInst=null;
  Set<String> Hosts=new HashSet<String>();

  xprd.findXsrvs(1, M, Hosts);
  System.out.println(Hosts.size() + " servers found.");
  
  for(Iterator<String> h=Hosts.iterator(); h.hasNext();)
  {
   String i=h.next();
                               // Open connection to a remote node
   try {
    mosInst=xprd.connect(i);
    
    System.out.println("Server " + i + ": " + mosInst.getSystemInformation());
    mosInst.disconnect();        // Disconnect remote instance
   }
   catch(IOException e) {
    System.out.println("Connection to " + i + " failed");
   }
  }
  
 }
} 

runrtdistr.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtdistr.c
   `````````````````
   Running a model on a remote machine,
   passing runtime parameters to the submodel.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Jan 2012
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "xprd.h"

int main(int argv,char *args[]) 
{
  XPRDcontext xprd;
  XPRDmosel mosInst;
  XPRDmodel modRP;
  char params[200];

       /* Use the name or IP address of a machine in
        * your local network, or "" for current node */
  char *NODENAME = "";

  xprd=XPRDinit();             /* Create an XPRD context */
                               /* Open connection to a remote node */
  mosInst=XPRDconnect(xprd, NODENAME, NULL, NULL, NULL, 0);
                               /* Compile the model file */
  XPRDcompmod(mosInst, "", "rmt:rtparams.mos", "tmp:rp.bim", "");
                               /* Load the bim file into the remote instance */
  modRP=XPRDloadmod(mosInst, "tmp:rp.bim"); 
                               /* Run-time parameters */
  sprintf(params, "PARAM1=%d,PARAM2=%g,PARAM3='a string',PARAM4=true", 2, 3.4);
  XPRDrunmod(modRP, params);   /* Run the model */
  XPRDwaitevent(xprd,-1);      /* Wait for model termination */
  XPRDdropevent(xprd);         /* Ignore termination event message */

  printf("`rtparams' returned: %d\n", XPRDgetexitcode(modRP));

  XPRDunloadmod(modRP);        /* Unload the model */
  XPRDdisconnect(mosInst);     /* Disconnect remote instance */
  XPRDfinish(xprd);            /* Terminate XPRD */
  return 0;
} 

runrtdistr.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtdistr.java
   ````````````````````
   Running a model on a remote machine,
   passing runtime parameters to the submodel.

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Jan 2012
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.io.*;

public class runrtdistr
{
 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDMosel mosInst=null;
  XPRDModel modRP=null;

       // Use the name or IP address of a machine in
       // your local network, or "" for current node
  String NODENAME = "";
                               // Open connection to a remote node
  mosInst=xprd.connect(NODENAME);
                               // Compile the model file
  mosInst.compile("", "rmt:rtparams.mos", "tmp:rp.bim"); 
                               // Load the bim file into the remote instance
  modRP=mosInst.loadModel("tmp:rp.bim"); 
                               // Run-time parameters
  modRP.execParams = "PARAM1=" + 2 + ",PARAM2=" + 3.4 + 
                     ",PARAM3='a string'" + ",PARAM4=true";
  modRP.run();                 // Run the model
  xprd.waitForEvent();         // Wait for model termination
  xprd.dropNextEvent();        // Ignore termination event message

  System.out.println("`rtparams' returned: " + modRP.getResult());

  mosInst.disconnect();        // Disconnect remote instance
 }
} 

rtparams.mos
(!*******************************************************
   Mosel Example Problems 
   ======================

   file rtparams.mos
   `````````````````
   Model with different runtime parameter types;
   can be run as submodel from models 'runrtpar*.mos'.
       
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, May 2006
*******************************************************!)

model "Runtime parameters"
 uses "mmjobs"
 parameters
  PARAM1 = 0
  PARAM2 = 0.5
  PARAM3 = ''
  PARAM4 = false
 end-parameters

 wait(round(5*random))
 writeln(PARAM1, "  ", PARAM2, "  ", PARAM3, "  ", PARAM4)
end-model 

runrtpardistr.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtpardistr.c
   ````````````````````
   Running several instances of a model remotely from
   a host program.
   - Parallel submodels in distributed architecture -

   Before running this model, you need to set up the 
   NODENAME with a machine name/address of your local network.
   The node that is used needs to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Apr 2012, rev. Jan. 2013
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "xprd.h"

#define A 10 
#define B 5

int main(int argv,char *args[]) 
{
  XPRDcontext xprd;
  XPRDmosel mosInst[B];
  XPRDmodel modRP[A];
  char params[200];
  char *NODENAME[B];
  int i,j;
  char bufd[200],bufn[200];

       /* Use the name or IP address of a machine in
        * your local network, or "" for current node */
  for(j=0;j<B;j++) NODENAME[j] = (j%2==0)?"localhost":"xssh:127.0.0.1";

  xprd=XPRDinit();             /* Create an XPRD context */
                               /* Open connection to a remote node */
  for(j=0;j<B;j++)
  {
    mosInst[j]=XPRDconnect(xprd, NODENAME[j], NULL, NULL, NULL, 0);
    if(mosInst[j]==NULL)
    {
     printf("Failed to connect to %s - aborting.\n",NODENAME[j]);
     exit(1);
    }
  }

  for(j=0;j<B;j++)
  {
    XPRDsysinfo(mosInst[j], XPRD_SYS_NODE, bufd, sizeof(bufd));
    XPRDsysinfo(mosInst[j], XPRD_SYS_NAME, bufn, sizeof(bufn));
    printf("Submodel node: %s on %s\n", bufd, bufn);
  }

                               /* Compile the model file */
  XPRDcompmod(mosInst[0], "", "rmt:rtparams3.mos", "rmt:rp3.bim", "");

  for(i=0;i<A;i++)
  {                             /* Load the bim file into the remote instance */
    modRP[i]=XPRDloadmod(mosInst[i%B], "rmt:rp3.bim"); 
                               /* Run-time parameters */
    sprintf(params, "PARAM1=%d,PARAM2=%g,PARAM3='a string',PARAM4=%s", i,
            0.1*i, (i%2==0)?"true":"false");
    XPRDrunmod(modRP[i], params);   /* Run the model */
  }

  for(i=0;i<A;i++)
  {
    XPRDwaitevent(xprd,-1);    /* Wait for model termination */
    XPRDdropevent(xprd);       /* Ignore termination event message */
  }

  for(i=0;i<A;i++)
    XPRDunloadmod(modRP[i]);   /* Unload the models */

  for(j=0;j<B;j++)
    XPRDdisconnect(mosInst[j]);   /* Disconnect remote instance */
  XPRDfinish(xprd);            /* Terminate XPRD */
  
  remove("rp3.bim");          /* Cleaning up */
  return 0;
} 

runrtpardistr.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtpardistr.java
   ```````````````````````
   Running several instances of a model remotely from
   a host program.
   - Parallel submodels in distributed architecture -

   Before running this model, you need to set up the 
   NODENAMES with a machine name/address of your local network.
   All nodes that are used need to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on this machine.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke, Feb 2012, rev. Jan. 2013
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.io.*;

public class runrtpardistr
{
 static final int A=10;
 static final int B=5;

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
  XPRDMosel[] mosInst=new XPRDMosel[B];
  XPRDModel[] modRP=new XPRDModel[A];
  String[] NODENAMES=new String[B];
  int i,j;

       // Use the name or IP address of a machine in
       // your local network, or "" for current node
  for(j=0;j<B;j++) NODENAMES[j] = (j%2==0)?"localhost":"xssh:localhost";
 // String[] NODENAMES={"localhost","","","rcmd:mosel -r","rcmd:mosel -r"};

                               // Open connection to remote nodes
  for(j=0;j<B;j++)
    mosInst[j]=xprd.connect(NODENAMES[j]);

  for(j=0;j<B;j++)
    System.out.println("Submodel node: " + 
		       mosInst[j].getSystemInformation(XPRDMosel.SYS_NODE) + " on " +
		       mosInst[j].getSystemInformation(XPRDMosel.SYS_NAME));

                               // Compile the model file on one instance
  mosInst[0].compile("", "rmt:rtparams3.mos", "rmt:rp3.bim");
 
  for(i=0;i<A;i++)
  {	                       // Load the bim file into remote instances
   modRP[i]=mosInst[i%B].loadModel("rmt:rp3.bim"); 
                               // Run-time parameters
    modRP[i].execParams = "PARAM1=" + i + ",PARAM2=" + (0.1*i) + 
                          ",PARAM3='a string " + i + "',PARAM4=" + (i%2==0);
    modRP[i].run();            // Run the model
  }

  for(i=0;i<A;i++)
  {
    xprd.waitForEvent();       // Wait for model termination
    xprd.dropNextEvent();      // Ignore termination event message
  }

  for(j=0;j<B;j++)
    mosInst[j].disconnect();   // Disconnect remote instance

  new File("rp3.bim").delete();           // Cleaning up
 }
} 

rtparams3.mos
(!*******************************************************
   Mosel Example Problems 
   ======================

   file rtparams3.mos
   ``````````````````
   Model with different runtime parameter types;
   can be run as submodel from models 'runrtpar*.mos'.
       
   (c) 2010 Fair Isaac Corporation
       author: S. Heipcke, May 2010
*******************************************************!)

model "Runtime parameters"
 uses "mmjobs", "mmsystem"
 parameters
  PARAM1 = 0
  PARAM2 = 0.5
  PARAM3 = ''
  PARAM4 = false
 end-parameters

 sleep(1000*round(5*random))
 writeln("Node: ", getparam("NODENUMBER"), " ", getsysinfo(SYS_NODE), 
         ". Parent: ", getparam("PARENTNUMBER"),
	 ". Model number: ", getparam("JOBID"), 
         ". Parameters: ", 
         PARAM1, "  ", PARAM2, "  ", PARAM3, "  ", PARAM4)
end-model 

runrtparqueued.c
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtparqueued.c
   `````````````````````
   Running several instances of a model from another
   Mosel model.
   - Queuing submodels for parallel execution in a
     distributed architecture (one or several models per node) -

   Before running this model, you need to set up the list
   NodeList with machine names/addresses of your local network.
   All nodes that are used need to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on these machines.

   The maximum number of models per node in array MaxMod needs
   to be adapted to the number of executions licensed on 
   the corresponding nodes.
   
   All files are local to the root node, no write access is
   required at remote nodes.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke & Y. Colombani, Apr. 2012
*******************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xprd.h"

#define J 10         /* Number of jobs to run */
#define NUMPAR 2     /* Number of parallel model executions */
                     /* (preferrably <= no. of processors) */

#define MAXQSIZE 20  /* Maximum number of elements in a queue (>=J) */

                     /* Use the name or IP address of a machine in
                        your local network, or "" for current node */
const char *NodeList[]={"localhost","localhost"};
#define NodeListSize (sizeof(NodeList)/sizeof(NodeList[0]))
#define nbNodes (NodeListSize<J?NodeListSize:J)

int *jobid,*modid;
const char **modNode;

typedef struct
	{
	 int head;
	 int tail;
	 int size;
	 int buf[MAXQSIZE];
	} s_queue;

void start_next_job(s_queue *jobList,XPRDmodel model);
void queue_init(s_queue *q);
int queue_add(s_queue *q,int e);
int queue_get(s_queue *q);
int queue_size(s_queue *q);

int main(int argv,char *args[]) 
{
 XPRDcontext xprd;
 XPRDmosel mosInst[nbNodes];
 int MaxMod[nbNodes];
 XPRDmodel modPar[nbNodes*NUMPAR];
 int i,j,m,n,nct;
 char bufd[200];
 s_queue JobList,JobsRun;
 XPRDmodel sender;
 double eventValue;
 int eventClass;
 int lastId=0;
 int JobSize;

 xprd=XPRDinit();                  /* Create an XPRD context */

 /**** Setting up remote Mosel instances ****/
 for(n=0;n<nbNodes;n++)
 {
  mosInst[n]=XPRDconnect(xprd,NodeList[n], NULL, NULL, NULL, 0);
  if(mosInst[n]==NULL)
  {
   printf("Failed to connect to %s - aborting.\n",NodeList[n]);
   exit(1);
  }
  MaxMod[n]= NUMPAR;
        /* Adapt this setting to number of processors and licences per node */
 }

                                   /* Compile the model file on first node */
 XPRDcompmod(mosInst[0], "", "rmt:rtparams.mos", "rmt:rtparams.bim", "");

 /**** Loading model instances ****/
 nct=0;
 for(n=0;(n<nbNodes) && (nct<J);n++)
  for(m=0;(m<MaxMod[n]) && (nct<J);m++)
  {                                /* Load the bim file */
   modPar[nct]=XPRDloadmod(mosInst[n], "rmt:rtparams.bim"); 
   if(XPRDgetnumber(modPar[nct])>lastId) lastId=XPRDgetnumber(modPar[nct]);
   nct++;
  }

 jobid=malloc(sizeof(int)*(lastId+1));
 modid=malloc(sizeof(int)*(lastId+1));
 modNode=malloc(sizeof(char *)*(lastId+1));

 for(j=0;j<nct;j++)
 {
  i=XPRDgetnumber(modPar[j]);
  modid[i]=j;                     /* Store the model ID */
  modNode[i]=strdup(XPRDsysinfo(XPRDgetmosel(modPar[j]),XPRD_SYS_NODE, bufd, sizeof(bufd)));
 }

 queue_init(&JobList);
 queue_init(&JobsRun);
 for(i=0;i<J;i++)                 /* Define the list of jobs (instances) */
  queue_add(&JobList,i);
 JobSize=queue_size(&JobList);    /* Store the number of jobs */

 /**** Start initial lot of model runs ****/
 for(j=0;j<nct;j++)
  start_next_job(&JobList,modPar[j]);

 /**** Run all remaining jobs ****/
 while(queue_size(&JobsRun)<JobSize)
 {
  XPRDwaitevent(xprd,-1);         /* Wait for model termination */
  XPRDgetevent(xprd,&sender,&eventClass,&eventValue);
  if(eventClass==XPRD_EVENT_END)  /* We are only interested in "end" events */
  {                               /* Keep track of job termination */
   queue_add(&JobsRun,jobid[XPRDgetnumber(sender)]);
   printf("End of job %d (model %d)\n", jobid[XPRDgetnumber(sender)] ,
                             modid[XPRDgetnumber(sender)]);
   if(queue_size(&JobList)>0)     /* Start a new run if queue not empty */
    start_next_job(&JobList,sender);
  }
 }

 for(n=0;n<nbNodes;n++)
   XPRDdisconnect(mosInst[n]);   /* Disconnect remote instances */
 XPRDfinish(xprd);               /* Terminate XPRD */
 
 remove("rtparams.bim");         /* Cleaning up */

 return 0;
}

/*****************************/
/* Start next job in a queue */
/*****************************/
void start_next_job(s_queue *jobList,XPRDmodel model)
{
 char params[200];
 int i;

 i=queue_get(jobList);      /* Retrieve and remove first entry from queue */
 printf("Start job %d (model %d) on %s\n", i , modid[XPRDgetnumber(model)],
                         modNode[XPRDgetnumber(model)]);
 sprintf(params, "PARAM1=%d,PARAM2=%g,PARAM3='a string',PARAM4=%s", i,
           0.1*i, (i%2==0)?"true":"false");
 XPRDrunmod(model, params);
 jobid[XPRDgetnumber(model)]=i;
}

/**********************/
/* Initialize a queue */
/**********************/
void queue_init(s_queue *q)
{ memset(q,0,sizeof(s_queue)); }

/*****************************/
/* Add an element to a queue */
/*****************************/
int queue_add(s_queue *q,int e)
{
 if(q->size>=MAXQSIZE) return -1;
 else
 {
  q->buf[q->head++]=e;
  if(q->head>=MAXQSIZE) q->head=0;
  return ++q->size;
 }
}

/**********************************/
/* Remove an element from a queue */
/**********************************/
int queue_get(s_queue *q)
{
 int rts;

 if(q->size<1) return -1;
 else
 {
  rts=q->buf[q->tail++];
  if(q->tail>=MAXQSIZE) q->tail=0;
  q->size--;
  return rts;
 }
}

/***************************/
/* Get the size of a queue */
/***************************/
int queue_size(s_queue *q)
{ return q->size; }

runrtparqueued.java
/*******************************************************
   Mosel Example Problems 
   ======================

   file runrtparqueued.java
   ````````````````````````
   Running several instances of a model from another
   Mosel model.
   - Queuing submodels for parallel execution in a
     distributed architecture (one or several models per node) -

   Before running this model, you need to set up the list
   NodeList with machine names/addresses of your local network.
   All nodes that are used need to have the same version of
   Xpress installed and suitably licensed, and the server 
   "xprmsrv" must have been started on these machines.

   The maximum number of models per node in array MaxMod needs
   to be adapted to the number of executions licensed on 
   the corresponding nodes.
   
   All files are local to the root node, no write access is
   required at remote nodes.
       
   (c) 2012 Fair Isaac Corporation
       author: S. Heipcke & Y. Colombani, Apr. 2012
*******************************************************/

import com.dashoptimization.*;
import java.lang.*;
import java.util.*;
import java.io.*;

public class runrtparqueued
{
 static final int J=10;             // Number of jobs to run
 static final int NUMPAR=2;         // Number of parallel model executions
                                    // (preferrably <= no. of processors)
 static int[] jobid;
 static int[] modid;
 static String[] modNode;

 public static void main(String[] args) throws Exception
 {
  XPRD xprd=new XPRD();
                            // Use the name or IP address of a machine in
                            // your local network, or "" for current node
  String[] NodeList={"localhost","localhost"};
  final int nbNodes=(NodeList.length<J?NodeList.length:J);
  XPRDMosel[] mosInst=new XPRDMosel[nbNodes];
  int[] MaxMod=new int[nbNodes];
  XPRDModel[] modPar=new XPRDModel[nbNodes*NUMPAR];
  int nct;
  List<Integer> JobList=new ArrayList<Integer>();
  List<Integer> JobsRun=new ArrayList<Integer>();
  int JobSize;
  XPRDEvent event;
  int lastId=0;

  //**** Setting up remote Mosel instances ****
  for(int n=0;n<nbNodes;n++)
  {
   mosInst[n]=xprd.connect(NodeList[n]);
   MaxMod[n]= NUMPAR;
         // Adapt this setting to number of processors and licences per node
  }

                                    // Compile the model file on first node
  mosInst[0].compile("", "rmt:rtparams.mos", "rmt:rtparams.bim");

  //**** Loading model instances ****
  nct=0;
  for(int n=0;(n<nbNodes) && (nct<J);n++)
   for(int m=0;(m<MaxMod[n]) && (nct<J);m++)
   {                               // Load the bim file
    modPar[nct]=mosInst[n].loadModel("rmt:rtparams.bim");
    if(modPar[nct].getNumber()>lastId) lastId=modPar[nct].getNumber();
    nct++;
   }

  jobid=new int[lastId+1];
  modid=new int[lastId+1];
  modNode=new String[lastId+1];
  for(int j=0;j<nct;j++)
  {
   int i=modPar[j].getNumber();
   modid[i]=j;                    // Store the model ID
   modNode[i]=modPar[j].getMosel().getSystemInformation(XPRDMosel.SYS_NODE);
  }

  for(int i=0;i<J;i++)            // Define the list of jobs (instances)
   JobList.add(new Integer(i));
  JobSize=JobList.size();         // Store the number of jobs
  JobsRun.clear();                // List of terminated jobs is empty

  //**** Start initial lot of model runs ****
  for(int j=0;j<nct;j++)
   startNextJob(JobList,modPar[j]);

  //**** Run all remaining jobs ****
  while(JobsRun.size()<JobSize)
  {
   xprd.waitForEvent();           // Wait for model termination
   event=xprd.getNextEvent();     // We are only interested in "end" events
   if(event.eventClass==XPRDEvent.EVENT_END)
   {                              // Keep track of job termination
    JobsRun.add(new Integer(jobid[event.sender.getNumber()]));
    System.out.println("End of job "+ jobid[event.sender.getNumber()] +
                              " (model "+ modid[event.sender.getNumber()]+ ")");
    if(!JobList.isEmpty())        // Start a new run if queue not empty
     startNextJob(JobList,event.sender);
   }
  }

  for(int n=0;n<nbNodes;n++)
   mosInst[n].disconnect();                 // Terminate remote instances

  new File("rtparams.bim").delete();        // Cleaning up
 }

//******** Start the next job in a queue ********
 static void startNextJob(List<Integer> jobList,XPRDModel model) throws Exception
 {
  Integer job;
  int i;

  job=jobList.remove(0);      // Retrieve and remove first entry from job list
  i=job.intValue();
  System.out.println("Start job "+ job + " (model " + modid[model.getNumber()]+
                          ") on "+ modNode[model.getNumber()] );
  model.execParams = "PARAM1=" + i + ",PARAM2=" + (0.1*i) + 
                          ",PARAM3='a string " + i + "',PARAM4=" + (i%2==0);
  model.run();
  jobid[model.getNumber()]=i;
 }

}