Initializing help system before first use

Approximating PI number


Type: Programming
Rating: 3 (intermediate)
Description: This example shows how to approximate the PI number by executing Mosel models on a remote nodes. The C or Java XPRD program (piap.c or piap.java) connects to a remote node, there compiles the model piapprox.mos, loads it several times, runs all models instances in parallel and retrieves the result via an event message.
File(s): piap.c, piap.java, piapprox.mos

piap.c
/********************************************************/
/*  XPRD library example                                */
/*  ====================                                */
/*                                                      */
/*  file piap.c                                         */
/*  ```````````                                         */
/* Example of use of XPRD: C version of piapprox.mos    */
/*       Calculations are performed by the Mosel models */
/*                                                      */
/*  (c) 2011 Fair Isaac Corporation                     */
/*      author: S. Heipcke, 2011, rev. Nov. 2018        */
/********************************************************/

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

#define N 1000000
#define K 20
#define NEWSUM 2

const char *nodelist[]={"","localhost"};
#define M (sizeof(nodelist)/sizeof(nodelist[0]))

int main()
{
 char msg[256];
 XPRDcontext xprd;
 XPRDmosel moselInst[M];
 XPRDmodel modPar[K],sender;
 int modct,nbfinished,i,j;
 int cls;
 double val;
 double mypi;

 xprd=XPRDinit();
 for(i=0;i<M;i++)
 {
  moselInst[i]=XPRDconnect(xprd,nodelist[i],NULL,NULL,msg,sizeof(msg));
  if(moselInst[i]==NULL)
  {
   printf("Connection failed: %s\n",msg);
   return 2;
  }
 }

 if((i=XPRDcompmod(moselInst[0],"","rmt:piapprox.mos","rmt:p.bim",""))!=0)
 {
  printf("Compilation failed - error %d\n",i);
  return 3;
 }

 for(j=0;j<K;j++)
 {
  sprintf(msg,"NUM=%d,N=%d",j+1,N);
  modPar[j]=XPRDloadmod(moselInst[j%M],"rmt:p.bim");
  if(modPar[j]==NULL)
  {
   printf("Failed to load model %d\n",i);
   return 4;
  }
  XPRDrunmod(modPar[j],msg);
 }

 modct=0;
 mypi=0;
 nbfinished=0;
 while (nbfinished<K)
 {
  XPRDwaitevent(xprd,-1);
  XPRDgetevent(xprd,&sender,&cls,&val);
  if(cls==NEWSUM)
  {
   mypi+=val;
   modct+=1;
  }
  else
   nbfinished++;
 }
 printf("pi approximation: %.19f\n",mypi);
 
 for(i=0;i<M;i++)
  XPRDdisconnect(moselInst[i]);
 
 XPRDfinish(xprd);
 return 0;
}


piap.java
/********************************************************/
/*  XPRD library example                                */
/*  ====================                                */
/*                                                      */
/*  file piap.java                                      */
/*  ``````````````                                      */
/* Example of use of XPRD: Java version of piapprox.mos */
/*       Calculations are performed by the Mosel models */
/*                                                      */
/*  (c) 2011 Fair Isaac Corporation                     */
/*      author: S. Heipcke, 2011, rev. Nov. 2018        */
/********************************************************/

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

public class piap
{
 static final int N=1000000;
 static final int K=20;
 static final int NEWSUM=2;
 static final String nodelist[]={"","localhost"};

 public static void main(String[] args) throws Exception
 {
  int M=nodelist.length;
  XPRD xprd=new XPRD();
  XPRDMosel moselInst[]=new XPRDMosel[M];
  XPRDModel modPar[]=new XPRDModel[K];
  XPRDEvent ev;
  int modct,nbfinished;
  double mypi;

  for(int i=0;i<M;i++)
   moselInst[i]=xprd.connect(nodelist[i]);

  try
  {
   moselInst[0].compile("","rmt:piapprox.mos","rmt:p.bim");
  }
  catch(Exception e)
  {
   System.out.println("Compilation failed:"+e);
   System.exit(1);
  }

  for(int j=0;j<K;j++)
  {
   modPar[j]=moselInst[j%M].loadModel("rmt:p.bim");
   modPar[j].setExecParam("N",N);
   modPar[j].setExecParam("NUM",j+1);
   modPar[j].run();
  }

  modct=0;
  mypi=0;
  nbfinished=0;
  while (nbfinished<K)
  {
   xprd.waitForEvent();
   ev=xprd.getNextEvent();
   if(ev.eventClass==NEWSUM)
   {
    mypi+=ev.value;
    modct+=1;
   }
   else
    nbfinished++;
  }
  System.out.println("pi approximation: "+mypi);
  
  for(int i=0;i<M;i++)
   moselInst[i].disconnect();
 }
}

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

   file piapprox.mos
   `````````````````
   Approximating the value of pi by integrating the
   function 1/(1+x^2) over the interval [0,1].
   The integral is approximated by dividing the interval [0,1]
   into N subintervals and calculating the sum of their areas.   
   
   integral 0 to 1  1/(1+x^2)dx
   = arctan(1)-arctan(0)
   = arctan(1)
   = pi/4   
   
   (c) 2010 Fair Isaac Corporation
       author: S. Heipcke, June 2010, rev. Nov. 2018
  *******************************************************!)

model "approximating pi"
 uses "mmjobs"
 
 parameters
  N = 1000000                  ! Number of intervals
  K = 20                       ! Number of submodels to run
  NUM = 0                      ! 0 in master model, else >=1
 end-parameters
 
 if N<1 then exit(1); end-if

!!! Configure this list with machines in your local network, 
!!! there must be at least 1 entry in this list.
  NODELIST:=["","localhost"]
 
 declarations
  A = 1..K
  B: range
  modPar: array(A) of Model
  moselInst: array(B) of Mosel
  NODES: array(B) of string

  h,res: real
  M: integer
  
  NEWSUM = 2
  ev: Event
 end-declarations 
 
! Start child nodes
 if NUM=0 then
  forall(n in NODELIST, ct as counter) NODES(ct):=n
  M:= getsize(B)

  forall(i in B) do
    create(moselInst(i))            
    if connect(moselInst(i), NODES(i))<>0 then exit(2); end-if
  end-do
  
  if compile("piapprox.mos")<>0 then exit(3); end-if
  forall(j in A) do
    load(moselInst(j mod M + 1), modPar(j), "rmt:piapprox.bim")  
                                   ! Start remote model execution
    run(modPar(j), "NUM="+j+",N="+N)
  end-do
 
 else
 ! Calculate a part of pi
   h:=1/N
   i:=NUM
   while(i <= N) do
     x:=h*(i-0.5)
     pisum+= 4/(1+x^2)
     i+=K
   end-do 
   mypi:=h*pisum

   writeln(NUM, "(", getparam("NODENUMBER"), ",", getparam("JOBID"), "): ",
     strfmt(mypi,20,19))
 end-if
 
 if NUM>0 then
 ! Return the solution value
   send(NEWSUM, mypi)
 else 
 ! Add up values for parts returned by child models
   modct:=0
   while (modct<K) do
     ev:=getnextevent
     if getclass(ev)=NEWSUM then
       mypi+=getvalue(ev)
       modct+=1 
     end-if  
   end-do

 ! Solution output
   writeln("pi approximation: ", strfmt(mypi,20,19))
   writeln("pi (built-in):    ", strfmt(M_PI,20,19))
   writeln("difference   :    ", strfmt(abs(mypi-M_PI),20,19))
 end-if
 
end-model