added mpi pingpong with all cache miss result
[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 Message *msg_pointers;
33 static  int     buffered_messages;
34
35 typedef struct message_{
36   char core[CmiMsgHeaderSizeBytes];
37   int srcpe;
38   int idx;
39   int data[1];
40 } Message;
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
94 static void recvTime(TimeMessage *msg)
95 {
96   EmptyMsg m;
97   int i, j;
98   double time;
99
100   pva(numRecv)++;
101   for(i=0;i<CmiNumNodes();i++) {
102     if(i==msg->srcNode)
103       continue;
104     for(j=0;j<pva(numSizes);j++) {
105       time = *(msg->data+i*pva(numSizes)+j);
106       pva(gavg)[j] += time;
107       if(time > pva(gmax)[j]) {
108         pva(gmax)[j] = time;
109         pva(gmaxSrc)[j] = msg->srcNode;
110         pva(gmaxDest)[j] = i;
111       }
112       if(time < pva(gmin)[j]) {
113         pva(gmin)[j] = time;
114         pva(gminSrc)[j] = msg->srcNode;
115         pva(gminDest)[j] = i;
116       }
117     }
118   }
119   if(pva(numRecv)==CmiNumNodes()){
120     for(j=0;j<pva(numSizes);j++)
121       pva(gavg)[j] /= (CmiNumNodes()*(CmiNumNodes()-1));
122     CmiPrintf("[pingpong] CmiSyncSend\n");
123     for(j=0;j<pva(numSizes);j++) {
124       CmiPrintf("%d\t\t%le\n",
125                             sizes[j].size, pva(gavg)[j]);
126       //CmiPrintf("[pingpong] size=%d\tmaxTime=%le seconds\t[%d->%d]\n",
127       //            sizes[j].size, pva(gmax)[j],pva(gmaxSrc)[j],pva(gmaxDest)[j]);
128       //CmiPrintf("[pingpong] size=%d\tminTime=%le seconds\t[%d->%d]\n",
129       //            sizes[j].size, pva(gmin)[j],pva(gminSrc)[j],pva(gminDest)[j]);
130     }
131     CmiSetHandler(&m, pva(ack_handler));
132     CmiSyncSend(0, sizeof(EmptyMsg), &m);
133   }
134   CmiFree(msg);
135 }
136
137 static void startNextNode(EmptyMsg *msg)
138 {
139   EmptyMsg m;
140   CmiFree(msg);
141   if((CmiMyNode()+1) != CmiNumNodes()) {
142     CmiSetHandler(&m, pva(nbrHandler));
143     CmiSyncSend(pva(nodeList)[CmiMyNode()+1], sizeof(EmptyMsg), &m);
144   }
145 }
146
147 static void startNextNbr(EmptyMsg *msg)
148 {
149   EmptyMsg m;
150   TimeMessage *tm;
151   int i, size;
152
153   CmiFree(msg);
154   pva(nextNbr)++;
155   if(pva(nextNbr) == CmiMyNode()) {
156     CmiSetHandler(&m, pva(nbrHandler));
157     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
158     return;
159   }
160   if(pva(nextNbr) == CmiNumNodes()) {
161     pva(nextNbr) = -1;
162     CmiSetHandler(&m, pva(nodeHandler));
163     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
164     size = sizeof(TimeMessage)+pva(numSizes)*CmiNumNodes()*sizeof(double);
165     tm = (TimeMessage *) CmiAlloc(size);
166     for(i=0;i<CmiNumNodes();i++)
167       memcpy(tm->data+i*pva(numSizes),pva(times)[i],
168              sizeof(double)*pva(numSizes));
169     tm->srcNode = CmiMyNode();
170     CmiSetHandler(tm, pva(timeHandler));
171     CmiSyncSendAndFree(0, size, tm);
172   } else {
173     CmiSetHandler(&m, pva(sizeHandler));
174     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
175   }
176 }
177
178 static void startNextSize(EmptyMsg *msg)
179 {
180   EmptyMsg m;
181   Message *mm;
182
183   pva(nextSize)++;
184   if(pva(nextSize) == pva(numSizes)) {
185     pva(nextSize) = -1;
186     CmiSetHandler(&m, pva(nbrHandler));
187     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
188   } else {
189     int size = sizeof(Message)+sizes[pva(nextSize)].size;
190     mm = (Message *) CmiAlloc(size);
191     mm->srcpe = CmiMyPe();
192     mm->idx = pva(nextSize);
193     CmiSetHandler(mm, pva(iterHandler));
194     fillMessage(mm);
195     CmiSyncSendAndFree(CmiMyPe(), size, mm);
196     pva(starttime) = CmiWallTimer();
197   }
198   CmiFree(msg);
199 }
200
201 static void startNextIter(Message *msg)
202 {
203   EmptyMsg m;
204
205   pva(nextIter)++;
206   if(pva(nextIter) > sizes[pva(nextSize)].numiter) {
207     pva(endtime) = CmiWallTimer();
208     checkMessage(msg);
209     pva(times)[pva(nextNbr)][pva(nextSize)] =
210       (pva(endtime) - pva(starttime))/(2.0*sizes[pva(nextSize)].numiter);
211     pva(nextIter) = -1;
212     CmiSetHandler(&m, pva(sizeHandler));
213     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
214     CmiFree(msg);
215   } else {
216
217     CmiSetHandler(msg, pva(bounceHandler));
218     CmiSyncSendAndFree(pva(nextNbr), sizeof(Message)+sizes[msg->idx].size, msg);
219   }
220 }
221
222 static void bounceMessage(Message *msg)
223 {
224
225     mm = (Message *) CmiAlloc( sizeof(Message)+sizes[msg->idx].size);
226     CmiSetHandler(msg, pva(iterHandler));
227     CmiSyncSendAndFree(msg->srcpe, sizeof(Message)+sizes[msg->idx].size, msg);
228 }
229
230 void pingpong_init(void)
231 {
232   EmptyMsg m;
233
234   if(CmiNumNodes()==1) {
235     CmiPrintf("[pingpong] This benchmark requires > 1 nodes.\n");
236     CmiSetHandler(&m, pva(ack_handler));
237     CmiSyncSend(0, sizeof(EmptyMsg), &m);
238     return;
239   }
240   CmiSetHandler(&m, pva(nbrHandler));
241   CmiSyncSend(0, sizeof(EmptyMsg), &m);
242 }
243
244 void pingpong_moduleinit(void)
245 {
246   int i,j;
247   pvi(int, numRecv);
248   pva(numRecv) = 0;
249   pvi(int, nextIter);
250   pva(nextIter) = -1;
251   pvi(int, nextSize);
252   pva(nextSize) = -1;
253   pvi(int, nextNbr);
254   pva(nextNbr) = -1;
255   pvi(double, starttime);
256   pva(starttime) = 0.0;
257   pvi(double, endtime);
258   pva(endtime) = 0.0;
259   pvi(int, numSizes);
260   for(i=0; sizes[i].size != (-1); i++);
261   pva(numSizes) = i;
262   pvi(double **, times);
263   pva(times) = (double **) malloc(CmiNumNodes()*sizeof(double *));
264   for(i=0;i<CmiNumNodes();i++)
265     pva(times)[i] = (double *) malloc(pva(numSizes)*sizeof(double));
266   for(i=0;i<CmiNumNodes();i++)
267     for(j=0;j<pva(numSizes);j++)
268       pva(times)[i][j] = 0.0;
269   pvi(int *, nodeList);
270   pva(nodeList) = (int *) malloc(CmiNumNodes()*sizeof(int));
271   for(i=0;i<CmiNumNodes();i++)
272     pva(nodeList)[i] = CmiNodeFirst(i);
273   pvi(double *, gavg);
274   pva(gavg) = (double *) malloc(sizeof(double)*pva(numSizes));
275   pvi(double *, gmax);
276   pva(gmax) = (double *) malloc(sizeof(double)*pva(numSizes));
277   pvi(double *, gmin);
278   pva(gmin) = (double *) malloc(sizeof(double)*pva(numSizes));
279   pvi(int *, gmaxSrc);
280   pva(gmaxSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
281   pvi(int *, gmaxDest);
282   pva(gmaxDest) = (int *) malloc(sizeof(int)*pva(numSizes));
283   pvi(int *, gminSrc);
284   pva(gminSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
285   pvi(int *, gminDest);
286   pva(gminDest) = (int *) malloc(sizeof(int)*pva(numSizes));
287   for(i=0;i<pva(numSizes);i++) {
288     pva(gavg)[i] = 0.0;
289     pva(gmax)[i] = 0.0;
290     pva(gmin)[i] = 1000000000.0;
291     pva(gmaxSrc)[i] = 0;
292     pva(gmaxDest)[i] = 0;
293     pva(gminSrc)[i] = 0;
294     pva(gminDest)[i] = 0;
295   }
296   pvi(int, timeHandler);
297   pva(timeHandler) = CmiRegisterHandler((CmiHandler)recvTime);
298   pvi(int, nodeHandler);
299   pva(nodeHandler) = CmiRegisterHandler((CmiHandler)startNextNode);
300   pvi(int, nbrHandler);
301   pva(nbrHandler) = CmiRegisterHandler((CmiHandler)startNextNbr);
302   pvi(int, sizeHandler);
303   pva(sizeHandler) = CmiRegisterHandler((CmiHandler)startNextSize);
304   pvi(int, iterHandler);
305   pva(iterHandler) = CmiRegisterHandler((CmiHandler)startNextIter);
306   pvi(int, bounceHandler);
307   pva(bounceHandler) = CmiRegisterHandler((CmiHandler)bounceMessage);
308 }