Tests: Add CmiInitMsgHeader calls for non-CmiAlloc message allocations
[charm.git] / tests / converse / commbench / pingpong.c
blobd59bd9b9c3d368c734aaa057300afc176414c9ca
1 #include <stdlib.h>
2 #include <converse.h>
3 #include "commbench.h"
5 #define pva CpvAccess
6 #define pvd CpvStaticDeclare
7 #define pvi CpvInitialize
9 static struct testdata {
10 int size;
11 int numiter;
12 } sizes[] = {
13 {16, 1},
14 {128, 400},
15 {512, 100},
16 {2048, 100},
17 {8192, 100},
18 {32768, 100},
19 {131072, 20},
20 {1048576, 10},
21 {8388608, 4},
22 {-1, -1},
25 typedef struct message_ {
26 char core[CmiMsgHeaderSizeBytes];
27 int srcpe;
28 int idx;
29 int data[1];
30 } Message;
32 static void fillMessage(Message* msg) {
33 int i, size, items;
34 size = sizes[msg->idx].size + sizeof(double);
35 items = size / sizeof(double);
36 for (i = 0; i < items; i++) msg->data[i] = i + 0x1234;
39 static void checkMessage(Message* msg) {
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");
49 typedef struct Time_ {
50 char core[CmiMsgHeaderSizeBytes];
51 int srcNode;
52 double data[1];
53 } TimeMessage;
55 pvd(int, nextIter);
56 pvd(int, nextSize);
57 pvd(int, nextNbr);
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);
71 pvd(int, numSizes); /* how many test sizes exist */
72 pvd(int, numRecv);
74 pvd(int, timeHandler);
75 pvd(int, nodeHandler);
76 pvd(int, nbrHandler);
77 pvd(int, sizeHandler);
78 pvd(int, iterHandler);
79 pvd(int, bounceHandler);
81 static void recvTime(TimeMessage* msg) {
82 EmptyMsg m;
83 int i, j;
84 double time;
86 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
87 pva(numRecv)++;
88 for (i = 0; i < CmiNumPes(); i++) {
89 if (i == msg->srcNode) continue;
90 for (j = 0; j < pva(numSizes); j++) {
91 time = *(msg->data + i * pva(numSizes) + j);
92 pva(gavg)[j] += time;
93 if (time > pva(gmax)[j]) {
94 pva(gmax)[j] = time;
95 pva(gmaxSrc)[j] = msg->srcNode;
96 pva(gmaxDest)[j] = i;
98 if (time < pva(gmin)[j]) {
99 pva(gmin)[j] = time;
100 pva(gminSrc)[j] = msg->srcNode;
101 pva(gminDest)[j] = i;
105 if (pva(numRecv) == CmiNumPes()) {
106 for (j = 0; j < pva(numSizes); j++)
107 pva(gavg)[j] /= (CmiNumPes() * (CmiNumPes() - 1));
108 CmiPrintf("[pingpong] CmiSyncSend\n");
109 for (j = 0; j < pva(numSizes); j++) {
110 CmiPrintf("[pingpong] size=%d\taverageTime=%le seconds\n", sizes[j].size,
111 pva(gavg)[j]);
112 CmiPrintf("[pingpong] size=%d\tmaxTime=%le seconds\t[%d->%d]\n",
113 sizes[j].size, pva(gmax)[j], pva(gmaxSrc)[j], pva(gmaxDest)[j]);
114 CmiPrintf("[pingpong] size=%d\tminTime=%le seconds\t[%d->%d]\n",
115 sizes[j].size, pva(gmin)[j], pva(gminSrc)[j], pva(gminDest)[j]);
117 CmiSetHandler(&m, pva(ack_handler));
118 CmiSyncSend(0, sizeof(EmptyMsg), &m);
120 CmiFree(msg);
123 static void startNextNode(EmptyMsg* msg) {
124 EmptyMsg m;
125 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
126 CmiFree(msg);
127 if ((CmiMyPe() + 1) != CmiNumPes()) {
128 CmiSetHandler(&m, pva(nbrHandler));
129 CmiSyncSend(pva(nodeList)[CmiMyPe() + 1], sizeof(EmptyMsg), &m);
133 static void startNextNbr(EmptyMsg* msg) {
134 EmptyMsg m;
135 TimeMessage* tm;
136 int i, size;
138 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
139 CmiFree(msg);
140 pva(nextNbr)++;
141 if (pva(nextNbr) == CmiMyPe()) {
142 CmiSetHandler(&m, pva(nbrHandler));
143 CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
144 return;
146 if (pva(nextNbr) == CmiNumPes()) {
147 pva(nextNbr) = -1;
148 CmiSetHandler(&m, pva(nodeHandler));
149 CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
150 size = sizeof(TimeMessage) + pva(numSizes) * CmiNumPes() * sizeof(double);
151 tm = (TimeMessage*)CmiAlloc(size);
152 for (i = 0; i < CmiNumPes(); i++)
153 memcpy(tm->data + i * pva(numSizes), pva(times)[i],
154 sizeof(double) * pva(numSizes));
155 tm->srcNode = CmiMyPe();
156 CmiSetHandler(tm, pva(timeHandler));
157 CmiSyncSendAndFree(0, size, tm);
158 } else {
159 CmiSetHandler(&m, pva(sizeHandler));
160 CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
164 static void startNextSize(EmptyMsg* msg) {
165 EmptyMsg m;
166 Message* mm;
168 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
169 pva(nextSize)++;
170 if (pva(nextSize) == pva(numSizes)) {
171 pva(nextSize) = -1;
172 CmiSetHandler(&m, pva(nbrHandler));
173 CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
174 } else {
175 int size = sizeof(Message) + sizes[pva(nextSize)].size;
176 mm = (Message*)CmiAlloc(size);
177 mm->srcpe = CmiMyPe();
178 mm->idx = pva(nextSize);
179 CmiSetHandler(mm, pva(iterHandler));
180 fillMessage(mm);
181 CmiSyncSendAndFree(CmiMyPe(), size, mm);
182 pva(starttime) = CmiWallTimer();
184 CmiFree(msg);
187 static void startNextIter(Message* msg) {
188 EmptyMsg m;
190 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
191 pva(nextIter)++;
192 if (pva(nextIter) > sizes[pva(nextSize)].numiter) {
193 pva(endtime) = CmiWallTimer();
194 checkMessage(msg);
195 pva(times)[pva(nextNbr)][pva(nextSize)] =
196 (pva(endtime) - pva(starttime)) / (2.0 * sizes[pva(nextSize)].numiter);
197 pva(nextIter) = -1;
198 CmiSetHandler(&m, pva(sizeHandler));
199 CmiSyncSend(CmiMyPe(), sizeof(EmptyMsg), &m);
200 CmiFree(msg);
201 } else {
202 CmiSetHandler(msg, pva(bounceHandler));
203 CmiSyncSendAndFree(pva(nextNbr), sizeof(Message) + sizes[msg->idx].size,
204 msg);
208 static void bounceMessage(Message* msg) {
209 CmiSetHandler(msg, pva(iterHandler));
210 CmiSyncSendAndFree(msg->srcpe, sizeof(Message) + sizes[msg->idx].size, msg);
213 void pingpong_init(void) {
214 EmptyMsg m;
216 CmiInitMsgHeader(m.core, sizeof(EmptyMsg));
217 if (CmiNumPes() == 1) {
218 CmiPrintf("[pingpong] This benchmark requires > 1 nodes.\n");
219 CmiSetHandler(&m, pva(ack_handler));
220 CmiSyncSend(0, sizeof(EmptyMsg), &m);
221 return;
223 CmiSetHandler(&m, pva(nbrHandler));
224 CmiSyncSend(0, sizeof(EmptyMsg), &m);
227 void pingpong_moduleinit(void) {
228 int i, j;
229 pvi(int, numRecv);
230 pva(numRecv) = 0;
231 pvi(int, nextIter);
232 pva(nextIter) = -1;
233 pvi(int, nextSize);
234 pva(nextSize) = -1;
235 pvi(int, nextNbr);
236 pva(nextNbr) = -1;
237 pvi(double, starttime);
238 pva(starttime) = 0.0;
239 pvi(double, endtime);
240 pva(endtime) = 0.0;
241 pvi(int, numSizes);
242 for (i = 0; sizes[i].size != (-1); i++)
244 pva(numSizes) = i;
245 pvi(double**, times);
246 pva(times) = (double**)malloc(CmiNumPes() * sizeof(double*));
247 for (i = 0; i < CmiNumPes(); i++)
248 pva(times)[i] = (double*)malloc(pva(numSizes) * sizeof(double));
249 for (i = 0; i < CmiNumPes(); i++)
250 for (j = 0; j < pva(numSizes); j++) pva(times)[i][j] = 0.0;
251 pvi(int*, nodeList);
252 pva(nodeList) = (int*)malloc(CmiNumPes() * sizeof(int));
253 for (i = 0; i < CmiNumPes(); i++) pva(nodeList)[i] = i; /*CmiNodeFirst(i);*/
254 pvi(double*, gavg);
255 pva(gavg) = (double*)malloc(sizeof(double) * pva(numSizes));
256 pvi(double*, gmax);
257 pva(gmax) = (double*)malloc(sizeof(double) * pva(numSizes));
258 pvi(double*, gmin);
259 pva(gmin) = (double*)malloc(sizeof(double) * pva(numSizes));
260 pvi(int*, gmaxSrc);
261 pva(gmaxSrc) = (int*)malloc(sizeof(int) * pva(numSizes));
262 pvi(int*, gmaxDest);
263 pva(gmaxDest) = (int*)malloc(sizeof(int) * pva(numSizes));
264 pvi(int*, gminSrc);
265 pva(gminSrc) = (int*)malloc(sizeof(int) * pva(numSizes));
266 pvi(int*, gminDest);
267 pva(gminDest) = (int*)malloc(sizeof(int) * pva(numSizes));
268 for (i = 0; i < pva(numSizes); i++) {
269 pva(gavg)[i] = 0.0;
270 pva(gmax)[i] = 0.0;
271 pva(gmin)[i] = 1000000000.0;
272 pva(gmaxSrc)[i] = 0;
273 pva(gmaxDest)[i] = 0;
274 pva(gminSrc)[i] = 0;
275 pva(gminDest)[i] = 0;
277 pvi(int, timeHandler);
278 pva(timeHandler) = CmiRegisterHandler((CmiHandler)recvTime);
279 pvi(int, nodeHandler);
280 pva(nodeHandler) = CmiRegisterHandler((CmiHandler)startNextNode);
281 pvi(int, nbrHandler);
282 pva(nbrHandler) = CmiRegisterHandler((CmiHandler)startNextNbr);
283 pvi(int, sizeHandler);
284 pva(sizeHandler) = CmiRegisterHandler((CmiHandler)startNextSize);
285 pvi(int, iterHandler);
286 pva(iterHandler) = CmiRegisterHandler((CmiHandler)startNextIter);
287 pvi(int, bounceHandler);
288 pva(bounceHandler) = CmiRegisterHandler((CmiHandler)bounceMessage);