b00b18cb93b298ecea9f7089fa458edbe632e214
[charm.git] / examples / converse / pingpong / pingpong.C
1 #include <stdlib.h>
2 #include <converse.h>
3
4 enum {nCycles = 1 << 8 };
5 enum { maxMsgSize = 1 << 18 }; 
6
7 CpvDeclare(int,msgSize);
8 CpvDeclare(int,cycleNum);
9 CpvDeclare(int,sizeNum);
10 CpvDeclare(int,exitHandler);
11 CpvDeclare(int,node0Handler);
12 CpvDeclare(int,node1Handler);
13 CpvStaticDeclare(double,startTime);
14 CpvStaticDeclare(double,endTime);
15 CpvStaticDeclare(double,startCTime);
16 CpvStaticDeclare(double,endCTime);
17
18 void startRing()
19 {
20   CpvAccess(cycleNum) = 0;
21   CpvAccess(msgSize) = (1 << CpvAccess(sizeNum)) + CmiMsgHeaderSizeBytes;
22   //CmiPrintf("PE %d startRing allocating %d bytes, header=%d bytes\n",
23             //CmiMyPe(),CpvAccess(msgSize),CmiMsgHeaderSizeBytes);
24   CmiPrintf(
25   "       cycles       bytes         Total(ms)     One-way (us/msg)\n"
26   );
27   char *msg = (char *)CmiAlloc(CpvAccess(msgSize));
28   *((int *)(msg+CmiMsgHeaderSizeBytes)) = CpvAccess(msgSize);
29   CmiPrintf("PE %d startRing starting clock\n",CmiMyPe());
30   CpvAccess(startTime) = CmiWallTimer();
31   CpvAccess(startCTime) = CmiTimer();
32   CmiSetHandler(msg,CpvAccess(node0Handler));
33   CmiSyncSendAndFree(0, CpvAccess(msgSize), msg);
34 }
35
36 void ringFinished(char *msg)
37 {
38   // CmiPrintf("PE %d ringFinished\n",CmiMyPe());
39   CmiFree(msg);
40   CpvAccess(endTime) = CmiWallTimer();
41   CpvAccess(endCTime) = CmiTimer();
42   CmiPrintf("WALL: %4d \t%8d \t%8.4g \t%8.4g\n",
43             nCycles, CpvAccess(msgSize)-CmiMsgHeaderSizeBytes,
44             (CpvAccess(endTime)-CpvAccess(startTime))*1e3,
45             1e6*(CpvAccess(endTime)-CpvAccess(startTime))/(2.*nCycles)
46   );
47   CmiPrintf(" CPU: %4d \t%8d \t%8.4g \t%8.4g\n",
48             nCycles,CpvAccess(msgSize)-CmiMsgHeaderSizeBytes,
49             (CpvAccess(endCTime)-CpvAccess(startCTime))*1e3, 
50             1e6*(CpvAccess(endCTime)-CpvAccess(startCTime))/(2.*nCycles)
51     );
52   CpvAccess(sizeNum)++;
53   if (CpvAccess(msgSize) < maxMsgSize)
54     startRing();
55   else 
56   {
57     void *sendmsg = CmiAlloc(CmiMsgHeaderSizeBytes);
58     CmiSetHandler(sendmsg,CpvAccess(exitHandler));
59     CmiSyncBroadcastAllAndFree(CmiMsgHeaderSizeBytes,sendmsg);
60   }
61 }
62
63 CmiHandler exitHandlerFunc(char *msg)
64 {
65   CmiFree(msg);
66   CsdExitScheduler();
67   return 0;
68 }
69
70 CmiHandler node0HandlerFunc(char *msg)
71 {
72   CpvAccess(cycleNum)++;
73
74   if (CpvAccess(cycleNum) == nCycles)
75     ringFinished(msg);
76   else
77   {
78     CmiSetHandler(msg,CpvAccess(node1Handler));
79     CmiSyncSendAndFree(1,CpvAccess(msgSize),msg);
80   }
81   return 0;
82 }
83
84 CmiHandler node1HandlerFunc(char *msg)
85 {
86   CpvAccess(msgSize) = *((int *)(msg+CmiMsgHeaderSizeBytes));
87   CmiSetHandler(msg,CpvAccess(node0Handler));
88   CmiSyncSendAndFree(0,CpvAccess(msgSize),msg);
89   return 0;
90 }
91
92 CmiStartFn mymain()
93 {
94   CmiPrintf("PE %d of %d starting\n",CmiMyPe(),CmiNumPes());
95
96   CpvInitialize(int,msgSize);
97   CpvInitialize(int,cycleNum);
98   CpvInitialize(int,sizeNum);
99   CpvAccess(sizeNum) = 1;
100
101   CpvInitialize(int,exitHandler);
102   CpvAccess(exitHandler) = CmiRegisterHandler((CmiHandler) exitHandlerFunc);
103   CpvInitialize(int,node0Handler);
104   CpvAccess(node0Handler) = CmiRegisterHandler((CmiHandler) node0HandlerFunc);
105   CpvInitialize(int,node1Handler);
106   CpvAccess(node1Handler) = CmiRegisterHandler((CmiHandler) node1HandlerFunc);
107
108   CpvInitialize(double,startTime);
109   CpvInitialize(double,endTime);
110   CpvInitialize(double,startCTime);
111   CpvInitialize(double,endCTime);
112
113   if (CmiMyPe() == 0)
114     startRing();
115
116   return 0;
117 }
118
119 int main(int argc,char *argv[])
120 {
121   ConverseInit(argc,argv,(CmiStartFn)mymain,0,0);
122   return 0;
123 }