working version. needs small amount of placing tweaking to put
[charm.git] / examples / charm++ / integrateArray / pgm.C
1 /***************************************************************************
2   This "integration" program calculates the integral value of function
3   f(x)=1.0/x for the range of [1.0, 2.0].
4
5   The idea is to divide the range into "numSlices" of slices, and create 
6   "numChares" of parallel objects, or Chares, each taking care of 
7   numSlices/numChares of slices. 
8   After each chare finishes its portion of computation, a global reduction 
9   is performed to sum up the local values and get the final result.
10 ***************************************************************************/
11
12 #include "pgm.h"
13
14 CProxy_main mainProxy;
15
16 // program starts from here
17 main::main(CkArgMsg *m)
18
19   if(m->argc < 3) CmiAbort("./pgm slices numChares.");
20   int numSlices = atoi(m->argv[1]); 
21   int numChares = atoi(m->argv[2]);
22   mainProxy = thishandle;       // readonly initialization
23
24   // calculate the number of slices for each chare
25   int slicesPerChare=numSlices/numChares;
26   numSlices=slicesPerChare*numChares;   //Make slices an even multiple of numChares
27
28   double xLeft=1.0;                     //Left end of integration domain
29   double xRight=2.0;                    //Right end of integration domain
30   double dx=(xRight-xLeft)/numSlices;   //range between slides
31
32   // create array of chares to do the actual computation
33   CProxy_integrate integrateArray = CProxy_integrate::ckNew();
34   for (int i=0; i<numChares; i++) {
35     int nSlices=slicesPerChare;     // must be a divisor
36     double x=xLeft+i*slicesPerChare*dx; // Chare i takes slices starting at [i*slicesPerChare]
37     // create chare i that takes slices starting from x for nSlices
38     integrateArray[i].insert(x, dx, nSlices); 
39   }
40   integrateArray.doneInserting();       // done with creation
41
42   // set up reduction handler for sum up the integrals across all chares.
43   CkCallback *cb = new CkCallback(CkIndex_main::results(NULL), mainProxy);
44   integrateArray.ckSetReductionClient(cb);
45 }
46
47 // reduction handler, it prints out the result and exits.
48 void main::results(CkReductionMsg *msg) 
49
50   double integral = *(double *)msg->getData();
51   CkPrintf("With all results, integral is: %.15f \n", integral);
52   CkExit();
53 }
54
55 integrate::integrate(double xStart,double dx, int nSlices)
56
57   // calculate the partialIntegral for this chare for
58   // range of [xStart, xStart+(nSlices-1)*dx]
59   double partialIntegral = 0.0;
60   for (int i=0; i<nSlices; i++) {
61     double x = xStart+(i+0.5)*dx;
62     double f_x=(1.0/x);
63     partialIntegral += f_x*dx;
64   }
65
66   // reduction to sum the partialIntegral across all chares
67   contribute(sizeof(double), &partialIntegral, CkReduction::sum_double);
68 }
69
70 #include "pgm.def.h"