restored
[charm.git] / tests / converse / commbench / pingpong.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,      256},
14   {256,     256},
15   {2048,    64},
16   {4096,    64},
17   {65536,   10},
18   {1048576, 10},
19   {-1,      -1},
20 };
21
22 typedef struct message_{
23   char core[CmiMsgHeaderSizeBytes];
24   int srcpe;
25   int idx;
26   int data[1];
27 } Message;
28
29 static void fillMessage(Message *msg)
30 {
31   int i, size, items;
32   size = sizes[msg->idx].size + sizeof(double);
33   items = size/sizeof(double);
34   for(i=0;i<items;i++)
35     msg->data[i] = i+0x1234;
36 }
37
38 static void checkMessage(Message *msg)
39 {
40   int i, size, items;
41   size = sizes[msg->idx].size + sizeof(double);
42   items = size/sizeof(double);
43   for(i=0;i<items;i++) {
44     if(msg->data[i] != (i+0x1234))
45       CmiAbort("[pingpong] Data corrupted. Run megacon !!\n");
46   }
47 }
48
49 typedef struct Time_{
50   char core[CmiMsgHeaderSizeBytes];
51   int srcNode;
52   double data[1];
53 } TimeMessage;
54
55 pvd(int, nextIter);
56 pvd(int, nextSize);
57 pvd(int, nextNbr); 
58
59 pvd(double, starttime);
60 pvd(double, endtime);
61 pvd(double **, times);/* stores times for all nbrs and sizes */
62 pvd(int *, nodeList); /* stores nums of pes rank 0 on all nodes*/
63 pvd(double *, gavg);
64 pvd(double *, gmax);
65 pvd(double *, gmin);
66 pvd(int *, gmaxSrc);
67 pvd(int *, gmaxDest);
68 pvd(int *, gminSrc);
69 pvd(int *, gminDest);
70
71 pvd(int, numSizes);    /* how many test sizes exist */
72 pvd(int, numRecv);
73
74 pvd(int, timeHandler);
75 pvd(int, nodeHandler);
76 pvd(int, nbrHandler);
77 pvd(int, sizeHandler);
78 pvd(int, iterHandler);
79 pvd(int, bounceHandler);
80
81 static void recvTime(TimeMessage *msg)
82 {
83   EmptyMsg m;
84   int i, j;
85   double time;
86
87   pva(numRecv)++;
88   for(i=0;i<CmiNumNodes();i++) {
89     if(i==msg->srcNode)
90       continue;
91     for(j=0;j<pva(numSizes);j++) {
92       time = *(msg->data+i*pva(numSizes)+j);
93       pva(gavg)[j] += time;
94       if(time > pva(gmax)[j]) {
95         pva(gmax)[j] = time;
96         pva(gmaxSrc)[j] = msg->srcNode;
97         pva(gmaxDest)[j] = i;
98       }
99       if(time < pva(gmin)[j]) {
100         pva(gmin)[j] = time;
101         pva(gminSrc)[j] = msg->srcNode;
102         pva(gminDest)[j] = i;
103       }
104     }
105   }
106   if(pva(numRecv)==CmiNumNodes()){
107     for(j=0;j<pva(numSizes);j++)
108       pva(gavg)[j] /= (CmiNumNodes()*(CmiNumNodes()-1));
109     CmiPrintf("[pingpong] CmiSyncSend\n");
110     for(j=0;j<pva(numSizes);j++) {
111       CmiPrintf("[pingpong] size=%d\taverageTime=%le seconds\n",
112                             sizes[j].size, pva(gavg)[j]);
113       CmiPrintf("[pingpong] size=%d\tmaxTime=%le seconds\t[%d->%d]\n",
114                   sizes[j].size, pva(gmax)[j],pva(gmaxSrc)[j],pva(gmaxDest)[j]);
115       CmiPrintf("[pingpong] size=%d\tminTime=%le seconds\t[%d->%d]\n",
116                   sizes[j].size, pva(gmin)[j],pva(gminSrc)[j],pva(gminDest)[j]);
117     }
118     CmiSetHandler(&m, pva(ack_handler));
119     CmiSyncSend(0, sizeof(EmptyMsg), &m);
120   }
121   CmiFree(msg);
122 }
123
124 static void startNextNode(EmptyMsg *msg)
125 {
126   EmptyMsg m;
127   CmiFree(msg);
128   if((CmiMyNode()+1) != CmiNumNodes()) {
129     CmiSetHandler(&m, pva(nbrHandler));
130     CmiSyncSend(pva(nodeList)[CmiMyNode()+1], sizeof(EmptyMsg), &m);
131   }
132 }
133
134 static void startNextNbr(EmptyMsg *msg)
135 {
136   EmptyMsg m;
137   TimeMessage *tm;
138   int i, size;
139
140   CmiFree(msg);
141   pva(nextNbr)++;
142   if(pva(nextNbr) == CmiMyNode()) {
143     CmiSetHandler(&m, pva(nbrHandler));
144     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
145     return;
146   }
147   if(pva(nextNbr) == CmiNumNodes()) {
148     pva(nextNbr) = -1;
149     CmiSetHandler(&m, pva(nodeHandler));
150     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
151     size = sizeof(TimeMessage)+pva(numSizes)*CmiNumNodes()*sizeof(double);
152     tm = (TimeMessage *) CmiAlloc(size);
153     for(i=0;i<CmiNumNodes();i++)
154       memcpy(tm->data+i*pva(numSizes),pva(times)[i],
155              sizeof(double)*pva(numSizes));
156     tm->srcNode = CmiMyNode();
157     CmiSetHandler(tm, pva(timeHandler));
158     CmiSyncSendAndFree(0, size, tm);
159   } else {
160     CmiSetHandler(&m, pva(sizeHandler));
161     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
162   }
163 }
164
165 static void startNextSize(EmptyMsg *msg)
166 {
167   EmptyMsg m;
168   Message *mm;
169
170   pva(nextSize)++;
171   if(pva(nextSize) == pva(numSizes)) {
172     pva(nextSize) = -1;
173     CmiSetHandler(&m, pva(nbrHandler));
174     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
175   } else {
176     int size = sizeof(Message)+sizes[pva(nextSize)].size;
177     mm = (Message *) CmiAlloc(size);
178     mm->srcpe = CmiMyPe();
179     mm->idx = pva(nextSize);
180     CmiSetHandler(mm, pva(iterHandler));
181     fillMessage(mm);
182     CmiSyncSendAndFree(CmiMyPe(), size, mm);
183     pva(starttime) = CmiWallTimer();
184   }
185   CmiFree(msg);
186 }
187
188 static void startNextIter(Message *msg)
189 {
190   EmptyMsg m;
191
192   pva(nextIter)++;
193   if(pva(nextIter) > sizes[pva(nextSize)].numiter) {
194     pva(endtime) = CmiWallTimer();
195     checkMessage(msg);
196     pva(times)[pva(nextNbr)][pva(nextSize)] =
197       (pva(endtime) - pva(starttime))/(2.0*sizes[pva(nextSize)].numiter);
198     pva(nextIter) = -1;
199     CmiSetHandler(&m, pva(sizeHandler));
200     CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
201     CmiFree(msg);
202   } else {
203     CmiSetHandler(msg, pva(bounceHandler));
204     CmiSyncSendAndFree(pva(nextNbr), sizeof(Message)+sizes[msg->idx].size, msg);
205   }
206 }
207
208 static void bounceMessage(Message *msg)
209 {
210   CmiSetHandler(msg, pva(iterHandler));
211   CmiSyncSendAndFree(msg->srcpe, sizeof(Message)+sizes[msg->idx].size, msg);
212 }
213
214 void pingpong_init(void)
215 {
216   EmptyMsg m;
217
218   if(CmiNumNodes()==1) {
219     CmiPrintf("[pingpong] This benchmark requires > 1 nodes.\n");
220     CmiSetHandler(&m, pva(ack_handler));
221     CmiSyncSend(0, sizeof(EmptyMsg), &m);
222     return;
223   }
224   CmiSetHandler(&m, pva(nbrHandler));
225   CmiSyncSend(0, sizeof(EmptyMsg), &m);
226 }
227
228 void pingpong_moduleinit(void)
229 {
230   int i,j;
231   pvi(int, numRecv);
232   pva(numRecv) = 0;
233   pvi(int, nextIter);
234   pva(nextIter) = -1;
235   pvi(int, nextSize);
236   pva(nextSize) = -1;
237   pvi(int, nextNbr);
238   pva(nextNbr) = -1;
239   pvi(double, starttime);
240   pva(starttime) = 0.0;
241   pvi(double, endtime);
242   pva(endtime) = 0.0;
243   pvi(int, numSizes);
244   for(i=0; sizes[i].size != (-1); i++);
245   pva(numSizes) = i;
246   pvi(double **, times);
247   pva(times) = (double **) malloc(CmiNumNodes()*sizeof(double *));
248   for(i=0;i<CmiNumNodes();i++)
249     pva(times)[i] = (double *) malloc(pva(numSizes)*sizeof(double));
250   for(i=0;i<CmiNumNodes();i++)
251     for(j=0;j<pva(numSizes);j++)
252       pva(times)[i][j] = 0.0;
253   pvi(int *, nodeList);
254   pva(nodeList) = (int *) malloc(CmiNumNodes()*sizeof(int));
255   for(i=0;i<CmiNumNodes();i++)
256     pva(nodeList)[i] = CmiNodeFirst(i);
257   pvi(double *, gavg);
258   pva(gavg) = (double *) malloc(sizeof(double)*pva(numSizes));
259   pvi(double *, gmax);
260   pva(gmax) = (double *) malloc(sizeof(double)*pva(numSizes));
261   pvi(double *, gmin);
262   pva(gmin) = (double *) malloc(sizeof(double)*pva(numSizes));
263   pvi(int *, gmaxSrc);
264   pva(gmaxSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
265   pvi(int *, gmaxDest);
266   pva(gmaxDest) = (int *) malloc(sizeof(int)*pva(numSizes));
267   pvi(int *, gminSrc);
268   pva(gminSrc) = (int *) malloc(sizeof(int)*pva(numSizes));
269   pvi(int *, gminDest);
270   pva(gminDest) = (int *) malloc(sizeof(int)*pva(numSizes));
271   for(i=0;i<pva(numSizes);i++) {
272     pva(gavg)[i] = 0.0;
273     pva(gmax)[i] = 0.0;
274     pva(gmin)[i] = 1000000000.0;
275     pva(gmaxSrc)[i] = 0;
276     pva(gmaxDest)[i] = 0;
277     pva(gminSrc)[i] = 0;
278     pva(gminDest)[i] = 0;
279   }
280   pvi(int, timeHandler);
281   pva(timeHandler) = CmiRegisterHandler((CmiHandler)recvTime);
282   pvi(int, nodeHandler);
283   pva(nodeHandler) = CmiRegisterHandler((CmiHandler)startNextNode);
284   pvi(int, nbrHandler);
285   pva(nbrHandler) = CmiRegisterHandler((CmiHandler)startNextNbr);
286   pvi(int, sizeHandler);
287   pva(sizeHandler) = CmiRegisterHandler((CmiHandler)startNextSize);
288   pvi(int, iterHandler);
289   pva(iterHandler) = CmiRegisterHandler((CmiHandler)startNextIter);
290   pvi(int, bounceHandler);
291   pva(bounceHandler) = CmiRegisterHandler((CmiHandler)bounceMessage);
292 }