fixed pingpong cache miss bug
[charm.git] / tests / converse / commbench / pingpong-cachemiss.c
1 #include <stdlib.h>
2 #include <converse.h>
3 #include "commbench.h"
4
5 #define pva CpvAccess
6 #define pvd CpvStaticDeclare
7 #define pvi CpvInitialize
8
9 static struct testdata {
10   int size;
11   int numiter;
12 } sizes[] = {
13  {16,      4000},
14  {32,      4000},
15  {128,      4000},
16  {256,     1000},
17  {512,     1000},
18  {1024,    1000},
19  {2048,    1000},
20  {4096,    1000},
21  {8192,    1000},
22  {16384,   1000},
23  {32768,   1000},
24  {65536,   1000},
25  {131072,   400},
26  {524288,   400},
27  {1048576, 100},
28  {4194304, 40},
29   {-1,      -1},
30 };
31
32 typedef struct message_{
33   char core[CmiMsgHeaderSizeBytes];
34   int srcpe;
35   int idx;
36   int iter;
37   int data[1];
38 } Message;
39
40 char     *buffer_msgs;
41
42 static void fillMessage(Message *msg)
43 {
44   int i, size, items;
45   size = sizes[msg->idx].size + sizeof(double);
46   items = size/sizeof(double);
47   for(i=0;i<items;i++)
48     msg->data[i] = i+0x1234;
49 }
50
51 static void checkMessage(Message *msg)
52 {
53   int i, size, items;
54   size = sizes[msg->idx].size + sizeof(double);
55   items = size/sizeof(double);
56   for(i=0;i<items;i++) {
57     if(msg->data[i] != (i+0x1234))
58       CmiAbort("[pingpong] Data corrupted. Run megacon !!\n");
59   }
60 }
61
62 typedef struct Time_{
63   char core[CmiMsgHeaderSizeBytes];
64   int srcNode;
65   double data[1];
66 } TimeMessage;
67
68 pvd(int, nextIter);
69 pvd(int, nextSize);
70 pvd(int, nextNbr); 
71
72 pvd(double, starttime);
73 pvd(double, endtime);
74 pvd(double **, times);/* stores times for all nbrs and sizes */
75 pvd(int *, nodeList); /* stores nums of pes rank 0 on all nodes*/
76 pvd(double *, gavg);
77 pvd(double *, gmax);
78 pvd(double *, gmin);
79 pvd(int *, gmaxSrc);
80 pvd(int *, gmaxDest);
81 pvd(int *, gminSrc);
82 pvd(int *, gminDest);
83
84 pvd(int, numSizes);    /* how many test sizes exist */
85 pvd(int, numRecv);
86
87 pvd(int, timeHandler);
88 pvd(int, nodeHandler);
89 pvd(int, nbrHandler);
90 pvd(int, sizeHandler);
91 pvd(int, iterHandler);
92 pvd(int, bounceHandler);
93 pvd(int, setupHandler);
94 pvd(int, startHandler);
95
96 static void recvTime(TimeMessage *msg)
97 {
98   EmptyMsg m;
99   int i, j;
100   double time;
101
102   pva(numRecv)++;
103   for(i=0;i<CmiNumNodes();i++) {
104     if(i==msg->srcNode)
105       continue;
106     for(j=0;j<pva(numSizes);j++) {
107       time = *(msg->data+i*pva(numSizes)+j);
108       pva(gavg)[j] += time;
109       if(time > pva(gmax)[j]) {
110         pva(gmax)[j] = time;
111         pva(gmaxSrc)[j] = msg->srcNode;
112         pva(gmaxDest)[j] = i;
113       }
114       if(time < pva(gmin)[j]) {
115         pva(gmin)[j] = time;
116         pva(gminSrc)[j] = msg->srcNode;
117         pva(gminDest)[j] = i;
118       }
119     }
120   }
121   if(pva(numRecv)==CmiNumNodes()){
122     for(j=0;j<pva(numSizes);j++)
123       pva(gavg)[j] /= (CmiNumNodes()*(CmiNumNodes()-1));
124     CmiPrintf("[pingpong] CmiSyncSend\n");
125     for(j=0;j<pva(numSizes);j++) {
126       CmiPrintf("%d\t\t%le\n",
127                             sizes[j].size, pva(gavg)[j]);
128       //CmiPrintf("[pingpong] size=%d\tmaxTime=%le seconds\t[%d->%d]\n",
129       //            sizes[j].size, pva(gmax)[j],pva(gmaxSrc)[j],pva(gmaxDest)[j]);
130       //CmiPrintf("[pingpong] size=%d\tminTime=%le seconds\t[%d->%d]\n",
131       //            sizes[j].size, pva(gmin)[j],pva(gminSrc)[j],pva(gminDest)[j]);
132     }
133     CmiSetHandler(&m, pva(ack_handler));
134     CmiSyncSend(0, sizeof(EmptyMsg), &m);
135   }
136   CmiFree(msg);
137 }
138
139 static void startNextNode(EmptyMsg *msg)
140 {
141   EmptyMsg m;
142   CmiFree(msg);
143   if((CmiMyNode()+1) != CmiNumNodes()) {
144     CmiSetHandler(&m, pva(nbrHandler));
145     CmiSyncSend(pva(nodeList)[CmiMyNode()+1], sizeof(EmptyMsg), &m);
146   }
147 }
148
149 static void startNextNbr(EmptyMsg *msg)
150 {
151   EmptyMsg m;
152   TimeMessage *tm;
153   int i, size;
154
155   CmiFree(msg);
156   pva(nextNbr)++;
157   if(pva(nextNbr) == CmiMyNode()) {
158     CmiSetHandler(&m, pva(nbrHandler));
159     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
160     return;
161   }
162   if(pva(nextNbr) == CmiNumNodes()) {
163     pva(nextNbr) = -1;
164     CmiSetHandler(&m, pva(nodeHandler));
165     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
166     size = sizeof(TimeMessage)+pva(numSizes)*CmiNumNodes()*sizeof(double);
167     tm = (TimeMessage *) CmiAlloc(size);
168     for(i=0;i<CmiNumNodes();i++)
169       memcpy(tm->data+i*pva(numSizes),pva(times)[i],
170              sizeof(double)*pva(numSizes));
171     tm->srcNode = CmiMyNode();
172     CmiSetHandler(tm, pva(timeHandler));
173     CmiSyncSendAndFree(0, size, tm);
174   } else {
175     CmiSetHandler(&m, pva(sizeHandler));
176     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
177   }
178 }
179
180 static void startNextSize(EmptyMsg *msg)
181 {
182   EmptyMsg m;
183   Message *mm;
184   int i;
185
186   pva(nextSize)++;
187   if(pva(nextSize) == pva(numSizes)) {
188     pva(nextSize) = -1;
189     CmiSetHandler(&m, pva(nbrHandler));
190     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
191   } else {
192     int size = sizeof(Message)+sizes[pva(nextSize)].size;
193     
194     buffer_msgs = (char*)malloc((sizes[pva(nextSize)].numiter) * sizeof(Message*));
195     for(i=0; i<sizes[pva(nextSize)].numiter; i++)
196     {
197         mm = CmiAlloc(size);
198         mm->srcpe = CmiMyPe();
199         mm->idx = pva(nextSize);
200         CmiSetHandler(mm, pva(bounceHandler));
201         *((Message**)(buffer_msgs+i*sizeof(char*))) = mm;
202     }
203     mm = (Message *) CmiAlloc(size);
204     mm->srcpe = CmiMyPe();
205     mm->idx = pva(nextSize);
206     CmiSetHandler(mm, pva(setupHandler));
207     //fillMessage(mm);
208     CmiSyncSendAndFree(pva(nextNbr), size, mm);
209   }
210   CmiFree(msg);
211 }
212
213 static void startNextIter(Message *msg)
214 {
215   EmptyMsg m;
216   Message *mm;
217   pva(nextIter)++;
218   if(pva(nextIter) > sizes[pva(nextSize)].numiter) {
219     pva(endtime) = CmiWallTimer();
220     //checkMessage(msg);
221     pva(times)[pva(nextNbr)][pva(nextSize)] =
222       (pva(endtime) - pva(starttime))/(2.0*sizes[pva(nextSize)].numiter);
223     pva(nextIter) = -1;
224     CmiSetHandler(&m, pva(sizeHandler));
225     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
226     CmiFree(msg);
227   } else {
228       mm = *((Message**)(buffer_msgs + pva(nextIter)*sizeof(char*))); 
229       mm->iter = pva(nextIter);
230       //CmiSetHandler(mm, pva(bounceHandler));
231       CmiSyncSendAndFree(pva(nextNbr), sizeof(Message)+sizes[mm->idx].size, mm);
232       CmiFree(msg);
233   }
234 }
235
236 static void bounceMessage(Message *msg)
237 {
238     Message *mm;
239     int iter = msg->iter;  
240     mm = *((Message**)(buffer_msgs + iter*sizeof(char*))); 
241     CmiSetHandler(mm, pva(iterHandler));
242     CmiSyncSendAndFree(msg->srcpe, sizeof(Message)+sizes[msg->idx].size, mm);
243     CmiFree(msg);
244 }
245 static void setupMessage(Message *msg)
246 {
247     Message *mm;
248     int     i, size;
249
250     int nextSize =  msg->idx; 
251     size = sizeof(Message)+sizes[nextSize].size; 
252     buffer_msgs = (char*)malloc((sizes[nextSize].numiter) * sizeof(Message*));
253     //CmiPrintf("[%d] set up iter=%d, idx=%d\n", CmiMyPe(), msg->iter, msg->idx;
254     CmiFree(msg);
255
256     for(i=0; i<sizes[nextSize].numiter; i++)
257     {
258         mm = (Message*)CmiAlloc(size);
259         mm->srcpe = CmiMyPe();
260         CmiSetHandler(mm, pva(iterHandler));
261         //mm->idx = pva(nextSize);
262         *((Message**)buffer_msgs+i*sizeof(char*)) = mm;
263     }
264     mm = (Message *) CmiAlloc(size);
265     mm->srcpe = CmiMyPe();
266     mm->idx = nextSize;
267     CmiSetHandler(mm, pva(startHandler));
268     //fillMessage(mm);
269     CmiSyncSendAndFree(pva(nextNbr), size, mm);
270 }
271 static void startMessage(Message *msg)
272 {
273     Message *mm;
274    
275     CmiFree(msg);
276
277     mm = *((Message**)buffer_msgs);
278     mm->srcpe = CmiMyPe();
279     mm->idx = pva(nextSize);
280     CmiSetHandler(mm, pva(iterHandler));
281     //fillMessage(mm);
282     pva(starttime) = CmiWallTimer();
283     CmiSyncSendAndFree(mm->srcpe, sizeof(Message)+sizes[pva(nextSize)].size, mm);
284   
285 }
286
287
288 void pingpong_init(void)
289 {
290   EmptyMsg m;
291
292   if(CmiNumNodes()==1) {
293     CmiPrintf("[pingpong] This benchmark requires > 1 nodes.\n");
294     CmiSetHandler(&m, pva(ack_handler));
295     CmiSyncSend(0, sizeof(EmptyMsg), &m);
296     return;
297   }
298   CmiSetHandler(&m, pva(nbrHandler));
299   CmiSyncSend(0, sizeof(EmptyMsg), &m);
300 }
301
302 void pingpong_moduleinit(void)
303 {
304   int i,j;
305   pvi(int, numRecv);
306   pva(numRecv) = 0;
307   pvi(int, nextIter);
308   pva(nextIter) = -1;
309   pvi(int, nextSize);
310   pva(nextSize) = -1;
311   pvi(int, nextNbr);
312   pva(nextNbr) = -1;
313   pvi(double, starttime);
314   pva(starttime) = 0.0;
315   pvi(double, endtime);
316   pva(endtime) = 0.0;
317   pvi(int, numSizes);
318   for(i=0; sizes[i].size != (-1); i++);
319   pva(numSizes) = i;
320   pvi(double **, times);
321   pva(times) = (double **) malloc(CmiNumNodes()*sizeof(double *));
322   for(i=0;i<CmiNumNodes();i++)
323     pva(times)[i] = (double *) malloc(pva(numSizes)*sizeof(double));
324   for(i=0;i<CmiNumNodes();i++)
325     for(j=0;j<pva(numSizes);j++)
326       pva(times)[i][j] = 0.0;
327   pvi(int *, nodeList);
328   pva(nodeList) = (int *) malloc(CmiNumNodes()*sizeof(int));
329   for(i=0;i<CmiNumNodes();i++)
330     pva(nodeList)[i] = CmiNodeFirst(i);
331   pvi(double *, gavg);
332   pva(gavg) = (double *) malloc(sizeof(double)*pva(numSizes));
333   pvi(double *, gmax);
334   pva(gmax) = (double *) malloc(sizeof(double)*pva(numSizes));
335   pvi(double *, gmin);
336   pva(gmin) = (double *) malloc(sizeof(double)*pva(numSizes));
337   pvi(int *, gmaxSrc);
338   pva(gmaxSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
339   pvi(int *, gmaxDest);
340   pva(gmaxDest) = (int *) malloc(sizeof(int)*pva(numSizes));
341   pvi(int *, gminSrc);
342   pva(gminSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
343   pvi(int *, gminDest);
344   pva(gminDest) = (int *) malloc(sizeof(int)*pva(numSizes));
345   for(i=0;i<pva(numSizes);i++) {
346     pva(gavg)[i] = 0.0;
347     pva(gmax)[i] = 0.0;
348     pva(gmin)[i] = 1000000000.0;
349     pva(gmaxSrc)[i] = 0;
350     pva(gmaxDest)[i] = 0;
351     pva(gminSrc)[i] = 0;
352     pva(gminDest)[i] = 0;
353   }
354   pvi(int, timeHandler);
355   pva(timeHandler) = CmiRegisterHandler((CmiHandler)recvTime);
356   pvi(int, nodeHandler);
357   pva(nodeHandler) = CmiRegisterHandler((CmiHandler)startNextNode);
358   pvi(int, nbrHandler);
359   pva(nbrHandler) = CmiRegisterHandler((CmiHandler)startNextNbr);
360   pvi(int, sizeHandler);
361   pva(sizeHandler) = CmiRegisterHandler((CmiHandler)startNextSize);
362   pvi(int, iterHandler);
363   pva(iterHandler) = CmiRegisterHandler((CmiHandler)startNextIter);
364   pvi(int, bounceHandler);
365   pva(bounceHandler) = CmiRegisterHandler((CmiHandler)bounceMessage);
366   pvi(int, setupHandler);
367   pva(setupHandler) = CmiRegisterHandler((CmiHandler)setupMessage);
368   pvi(int, startHandler);
369   pva(startHandler) = CmiRegisterHandler((CmiHandler)startMessage);
370 }