restructure gauss-seidel
[charm.git] / tests / charm++ / jacobi3d-gausssiedel / main.cc
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /** \file jacobi3d Gauss-Seidel to measure openMP, ckLoop
9  *  Author: Yanhua Sun 
10  *  This does a topological placement for a 3d jacobi.
11  *
12  *      
13  *            *****************
14  *         *               *  *
15  *   ^  *****************     *
16  *   |  *               *     *
17  *   |  *               *     *
18  *   |  *               *     *
19  *   Y  *               *     *
20  *   |  *               *     *
21  *   |  *               *     *
22  *   |  *               *  * 
23  *   ~  *****************    Z
24  *      <------ X ------> 
25  *
26  *   X: left, right --> wrap_x
27  *   Y: top, bottom --> wrap_y
28  *   Z: front, back --> wrap_z
29  */
30
31 #include "main.decl.h"
32 #include "jacobi3d.decl.h"
33 #include "jacobi3d.h"
34 #include "defines.h"
35 #include "TopoManager.h"
36
37 #include "CkLoopAPI.h"
38 CProxy_FuncCkLoop ckLoopProxy;
39 #include <omp.h>
40
41 /*readonly*/ int gaussIter;  
42 /*readonly*/ double convergeDelta;
43 /*readonly*/ int threadNums;
44
45 /*readonly*/ CProxy_Main mainProxy;
46 /*readonly*/ int arrayDimX;
47 /*readonly*/ int arrayDimY;
48 /*readonly*/ int blockDimX;
49 /*readonly*/ int arrayDimZ;
50 /*readonly*/ int blockDimY;
51 /*readonly*/ int blockDimZ;
52
53 // specify the number of worker chares in each dimension
54 /*readonly*/ int num_chare_x;
55 /*readonly*/ int num_chare_y;
56 /*readonly*/ int num_chare_z;
57
58 /*readonly*/ int globalBarrier;
59
60 static unsigned long next = 1;
61
62 double startTime;
63 double endTime;
64
65 class Main : public CBase_Main {
66 public:
67     CProxy_Jacobi array;
68     CProxy_TraceControl _traceControl;
69     int iterations;
70
71     void processCommandlines(int argc, char** argv)
72     {
73         gaussIter = 1;
74         convergeDelta = 0.01;
75         threadNums = 1;
76         for (int i=0; i<argc; i++) {
77             if (argv[i][0]=='-') {
78                 switch (argv[i][1]) {
79                 case 'X': arrayDimX = atoi(argv[++i]); break;
80                 case 'Y': arrayDimY = atoi(argv[++i]); break;
81                 case 'Z': arrayDimZ = atoi(argv[++i]); break;
82                 case 'x': blockDimX = atoi(argv[++i]); break;
83                 case 'y': blockDimY = atoi(argv[++i]); break;
84                 case 'z': blockDimZ = atoi(argv[++i]); break;
85                 case 'g': gaussIter =  atoi(argv[++i]); break;
86                 case 't': convergeDelta = atof(argv[++i]); break;
87                 case 'r': threadNums = atoi(argv[++i]); break;
88                 }   
89             }       
90         }       
91         if (arrayDimX < blockDimX || arrayDimX % blockDimX != 0)
92             CkAbort("array_size_X % block_size_X != 0!");
93         if (arrayDimY < blockDimY || arrayDimY % blockDimY != 0)
94             CkAbort("array_size_Y % block_size_Y != 0!");
95         if (arrayDimZ < blockDimZ || arrayDimZ % blockDimZ != 0)
96             CkAbort("array_size_Z % block_size_Z != 0!");
97
98         num_chare_x = arrayDimX / blockDimX;
99         num_chare_y = arrayDimY / blockDimY;
100         num_chare_z = arrayDimZ / blockDimZ;
101
102         // print info
103         CkPrintf("\nSTENCIL COMPUTATION WITH NO BARRIERS\n");
104         CkPrintf("Running Jacobi on %d processors with (%d, %d, %d) chares threshold=%f\n", CkNumPes(), num_chare_x, num_chare_y, num_chare_z, convergeDelta);
105         CkPrintf("Array Dimensions: %d %d %d\n", arrayDimX, arrayDimY, arrayDimZ);
106         CkPrintf("Block Dimensions: %d %d %d\n", blockDimX, blockDimY, blockDimZ);
107     } 
108     
109     Main(CkArgMsg* m) {
110         iterations = 0;
111         mainProxy = thisProxy;
112         processCommandlines(m->argc, m->argv);
113         delete m;
114 #if USE_TOPOMAP
115         CProxy_JacobiMap map = CProxy_JacobiMap::ckNew(num_chare_x, num_chare_y, num_chare_z);
116         CkPrintf("Topology Mapping is being done ... \n");
117         CkArrayOptions opts(num_chare_x, num_chare_y, num_chare_z);
118         opts.setMap(map);
119         array = CProxy_Jacobi::ckNew(opts);
120 #else
121 #if CKLOOP
122         //map one chare to one node instead of one thread 
123         CProxy_JacobiNodeMap map = CProxy_JacobiNodeMap::ckNew();
124         CkArrayOptions opts(num_chare_x, num_chare_y, num_chare_z);
125         opts.setMap(map);
126         array = CProxy_Jacobi::ckNew(opts);
127 #else
128         array = CProxy_Jacobi::ckNew(num_chare_x, num_chare_y, num_chare_z);
129 #endif
130 #endif
131
132 #if USE_TOPOMAP
133         TopoManager tmgr;
134         CkArray *jarr = array.ckLocalBranch();
135         int jmap[num_chare_x][num_chare_y][num_chare_z];
136
137         int hops=0, p;
138         for(int i=0; i<num_chare_x; i++)
139             for(int j=0; j<num_chare_y; j++)
140                 for(int k=0; k<num_chare_z; k++) {
141                     jmap[i][j][k] = jarr->procNum(CkArrayIndex3D(i, j, k));
142                 }
143
144         for(int i=0; i<num_chare_x; i++)
145             for(int j=0; j<num_chare_y; j++)
146                 for(int k=0; k<num_chare_z; k++) {
147                     p = jmap[i][j][k];
148                     hops += tmgr.getHopsBetweenRanks(p, jmap[wrap_x(i+1)][j][k]);
149                     hops += tmgr.getHopsBetweenRanks(p, jmap[wrap_x(i-1)][j][k]);
150                     hops += tmgr.getHopsBetweenRanks(p, jmap[i][wrap_y(j+1)][k]);
151                     hops += tmgr.getHopsBetweenRanks(p, jmap[i][wrap_y(j-1)][k]);
152                     hops += tmgr.getHopsBetweenRanks(p, jmap[i][j][wrap_z(k+1)]);
153                     hops += tmgr.getHopsBetweenRanks(p, jmap[i][j][wrap_z(k-1)]);
154                 }
155         CkPrintf("Total Hops: %d\n", hops);
156 #endif 
157         //only trace some steps instead of all steps
158         _traceControl = CProxy_TraceControl::ckNew();
159 #if CKLOOP
160         ckLoopProxy = CkLoop_Init(CkMyNodeSize());
161 #endif
162         array.doStep();
163     }
164
165     void converge(double maxDiff)
166     {
167         iterations++;
168         if(iterations == START_ITER)
169             _traceControl.startTrace();
170         if(iterations == END_ITER)
171             _traceControl.endTrace();
172
173         if(iterations == WARM_ITER)
174             startTime = CmiWallTimer();                
175         //if(maxDiff <= convergeDelta || iterations > 20)
176         if(maxDiff <= convergeDelta )
177         {
178             endTime = CmiWallTimer();
179             CkPrintf("Completed:\t[PEs:nodes] <char_x,y,z> \t\t chares  \t\t msgbytes \t\t iterations, \t\t  times,\t\t timeperstep(ms)\n benchmark\t[%d:%d] [ %d %d %d ] \t\t %d \t\t %d \t\t %d\t\t %.3f \t\t %.3f %d\n", CkNumPes(), CkNumNodes(), num_chare_x, num_chare_y, num_chare_z, num_chare_x *num_chare_y * num_chare_z, sizeof(double) * blockDimX*blockDimY, iterations*gaussIter, endTime - startTime, (endTime - startTime)/(iterations-WARM_ITER)/gaussIter*1000, arrayDimX*arrayDimY/CmiNumNodes()*arrayDimZ/1000000*8 );
180             //array.print();
181             CkExit();
182         }else
183         {
184             if(iterations % PRINT_FREQ== 0)
185                 CkPrintf("iteration %d  diff=%e\n", iterations, maxDiff); 
186                         array.doStep();
187         }
188     }
189 };
190
191 #include "jacobi3d.cc"
192
193 #include "main.def.h"
194 #include "jacobi3d.def.h"