Examples: 3D Jacobi using SDAG and Parameter marshalling, from Bigsim
[charm.git] / tests / charm++ / loadbalancing / jacobi2D / Jacobi2D.C
1
2 #include "Jacobi2D.h"
3
4 #define ITERATIONS 30
5
6   TheMain::TheMain(CkArgMsg *)
7   {
8    CkPrintf("ChareArray %d sq, data array %d sq, iterations %d\n", TheMain::NUM_CHUNKS, TheMain::CHUNK_SIZE, ITERATIONS);
9    int i;
10    int j;
11    CProxy_JacobiChunk jc = CProxy_JacobiChunk::ckNew();
12    for(i = 0;(i < TheMain::NUM_CHUNKS);(i++))   for(j = 0;(j < TheMain::NUM_CHUNKS);(j++))      jc(i,j).insert();
13    jc.doneInserting();
14    jc(0,0).setStartTime(CmiWallTimer());
15    jc.startNextIter();
16   }
17   void TheMain::pup(PUP::er &p) {
18    CBase_TheMain::pup(p);
19   }
20
21   JacobiChunk::JacobiChunk() {
22    int i;
23    int j;
24    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   for(j = 1;(j <= TheMain::CHUNK_SIZE);(j++))   data[i][j] = (100.0 + (((i + j) % 2)?(-1):1));
25    numGot = 0;
26    numIters = 0;
27    numDone = 0;
28    numNeighbors = 4;
29    if (((thisIndex.x == 0) || (thisIndex.x == (TheMain::NUM_CHUNKS - 1))))
30    (--numNeighbors);
31    if (((thisIndex.y == 0) || (thisIndex.y == (TheMain::NUM_CHUNKS - 1))))
32    (--numNeighbors);
33    maxDelta = 0.0;
34    numIters = ITERATIONS;
35    usesAtSync = true;
36    usesAutoMeasure = true;
37   }
38
39   void JacobiChunk::setStartTime(double t)
40   {
41      CkPrintf("Start time = %f\n", t);
42      startTime = t;
43   }
44
45   void JacobiChunk::startNextIter()
46   {
47     int i;
48     if (thisIndex.x == 0 && thisIndex.y == 0) CmiPrintf("startNextIter: %d\n", numIters);
49     if ((thisIndex.x > 0))
50     thisProxy((thisIndex.x - 1),thisIndex.y).getBottom(data[1]);
51     if ((thisIndex.x < (TheMain::NUM_CHUNKS - 1)))
52     thisProxy((thisIndex.x + 1),thisIndex.y).getTop(data[TheMain::CHUNK_SIZE]);
53     float tmp[TheMain::CHUNK_SIZE + 2];
54     if ((thisIndex.y > 0))
55     {
56      for(i = 0;(i <= (TheMain::CHUNK_SIZE + 1));(i++))     tmp[i] = data[i][1];
57      thisProxy(thisIndex.x,(thisIndex.y - 1)).getRight(tmp);
58     }
59     if ((thisIndex.y < (TheMain::NUM_CHUNKS - 1)))
60     {
61      for(i = 0;(i <= (TheMain::CHUNK_SIZE + 1));(i++))     tmp[i] = data[i][TheMain::CHUNK_SIZE];
62      thisProxy(thisIndex.x,(thisIndex.y + 1)).getLeft(tmp);
63     }
64   }
65
66   void JacobiChunk::getLeft(float left[])
67   {
68    int i;
69    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[i][0] = left[i];
70    if (((++numGot) == numNeighbors))
71    {
72     numGot = 0;
73     refine();
74    }
75   }
76   void JacobiChunk::getRight(float right[])
77   {
78    int i;
79    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[i][(TheMain::CHUNK_SIZE + 1)] = right[i];
80    if (((++numGot) == numNeighbors))
81    {
82     numGot = 0;
83     refine();
84    }
85   }
86   void JacobiChunk::getTop(float top[])
87   {
88    int i;
89    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[0][i] = top[i];
90    if (((++numGot) == numNeighbors))
91    {
92     numGot = 0;
93     refine();
94    }
95   }
96   void JacobiChunk::getBottom(float bottom[])
97   {
98    int i;
99    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[(TheMain::CHUNK_SIZE + 1)][i] = bottom[i];
100    if (((++numGot) == numNeighbors))
101    {
102     numGot = 0;
103     refine();
104    }
105   }
106   void JacobiChunk::refine()
107   {
108 //      double t = CmiWallTimer();
109    int i;
110    int j;
111    if ((thisIndex.y == 0))
112    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[i][0] = data[i][1];
113    else
114    if ((thisIndex.y == (TheMain::NUM_CHUNKS - 1)))
115    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   data[i][(TheMain::CHUNK_SIZE + 1)] = data[i][TheMain::CHUNK_SIZE];
116    if ((thisIndex.x == 0))
117    for(i = 0;(i <= TheMain::CHUNK_SIZE);(i++))   data[0][i] = data[1][i];
118    else
119    if ((thisIndex.x == (TheMain::NUM_CHUNKS - 1)))
120    for(i = 0;(i <= TheMain::CHUNK_SIZE);(i++))   data[(TheMain::CHUNK_SIZE + 1)][i] = data[TheMain::CHUNK_SIZE][i];
121    for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))   for(j = 1;(j <= TheMain::CHUNK_SIZE);(j++))   data[i][j] = (((((data[(i - 1)][j] + data[i][j]) + data[(i + 1)][j]) + data[i][(j - 1)]) + data[i][(j + 1)]) / 5.0);
122 //     CkPrintf("Iteration time in microsecs = %d\n", (int )((CmiWallTimer() - t) * 1.0e6));
123    if (false)
124    {
125      int i,j;
126      maxDelta = 0;
127      for(i = 1;(i <= TheMain::CHUNK_SIZE);(i++))    for(j = 1;(j <= TheMain::CHUNK_SIZE);(j++))    {
128       float delta = (data[i][j] - data[(i - 1)][j]);
129       if ((delta < 0))
130       delta *= (-1);
131       if ((delta > maxDelta))
132       maxDelta = delta;
133      }
134    }
135
136      // reduction
137    CkCallback cb(CkIndex_JacobiChunk::stepping(NULL), thisProxy(0,0));
138    contribute(sizeof(float), &maxDelta, CkReduction::sum_float, cb);
139   }
140
141   void JacobiChunk::done(float delta)
142   {
143    if ((delta > maxDelta))
144      maxDelta = delta;
145    double t = CmiWallTimer();
146    CkPrintf("From %d %d: %f\n", thisIndex.x, thisIndex.y, maxDelta);
147    CkPrintf("End time = %f, Total time in microsecs = %u\n", t, (unsigned long)((t - startTime) * 1.0e6));
148    CkExit();
149   }
150   void JacobiChunk::pup(PUP::er &p) {
151    CBase_JacobiChunk::pup(p);
152    p|startTime;
153    p|numNeighbors;
154    p|numDone;
155    p|numGot;
156    p|numIters;
157    p|maxDelta;
158    p((char*)data, (TheMain::CHUNK_SIZE+2)*(TheMain::CHUNK_SIZE+2)*sizeof(float));
159   }
160
161   void JacobiChunk::ResumeFromSync() {
162    startNextIter();
163   }
164
165   // a callback function to set object load
166   void JacobiChunk::UserSetLBLoad() {
167     setObjTime(1.0);
168   }
169
170   void JacobiChunk::stepping(CkReductionMsg *m) {   // on PE 0
171    float max_delta = *(float*)m->getData();
172    delete m;
173    numIters --;
174    if (numIters > 0) {
175      if (numIters % MIGRATE_STEPS == 3) {
176        thisProxy.AtSync();
177      }
178      else
179        thisProxy.startNextIter();
180    }
181    else
182        done(max_delta);
183   }
184
185
186 #include "Jacobi2D.def.h"