reverting to previous version
[charm.git] / examples / converse / pingpong / pingpong.C
1
2 /**********************************************************
3       Converse Ping-pong to test the message latency and bandwidth
4       Modified from Milind's ping-pong
5       
6       Sameer Kumar 02/07/05
7 ***************************************************/
8
9 #include <stdlib.h>
10 #include <converse.h>
11 #include <unistd.h>
12
13 enum {nCycles =4096};
14 enum { maxMsgSize = 1 << 16 };
15
16 CpvDeclare(int,msgSize);
17 CpvDeclare(int,cycleNum);
18 CpvDeclare(int,exitHandler);
19 CpvDeclare(int,node0Handler);
20 CpvDeclare(int,node1Handler);
21 CpvStaticDeclare(double,startTime);
22 CpvStaticDeclare(double,endTime);
23
24 // Start the pingpong for each message size
25 void startRing()
26 {
27   CpvAccess(cycleNum) = 0;
28
29   //Increase message in powers of 4. Also add a converse header to that
30   CpvAccess(msgSize) = (CpvAccess(msgSize)-CmiMsgHeaderSizeBytes)*4 + 
31       CmiMsgHeaderSizeBytes;
32
33   char *msg = (char *)CmiAlloc(CpvAccess(msgSize));
34   *((int *)(msg+CmiMsgHeaderSizeBytes)) = CpvAccess(msgSize);
35   CmiSetHandler(msg,CpvAccess(node0Handler));
36   CmiSyncSendAndFree(0, CpvAccess(msgSize), msg);
37   CpvAccess(startTime) = CmiWallTimer();
38 }
39
40 //the pingpong has finished, record message time
41 void ringFinished(char *msg)
42 {
43   CmiFree(msg);
44
45   //Print the time for that message size
46   CmiPrintf("Size=%d bytes, time=%lf microseconds one-way\n", 
47              CpvAccess(msgSize)-CmiMsgHeaderSizeBytes, 
48              (1e6*(CpvAccess(endTime)-CpvAccess(startTime)))/(2.*nCycles));
49
50   
51   //Have we finished all message sizes?
52   if (CpvAccess(msgSize) < maxMsgSize)
53       //start the ring again
54       startRing();
55   else {
56       //exit
57       void *sendmsg = CmiAlloc(CmiMsgHeaderSizeBytes);
58       CmiSetHandler(sendmsg,CpvAccess(exitHandler));
59       CmiSyncBroadcastAllAndFree(CmiMsgHeaderSizeBytes,sendmsg);
60   }
61 }
62
63 //We finished for all message sizes. Exit now
64 CmiHandler exitHandlerFunc(char *msg)
65 {
66     CmiFree(msg);
67     CsdExitScheduler();
68     return 0;
69 }
70
71
72 //Handler on Node 0
73 CmiHandler node0HandlerFunc(char *msg)
74 {
75     CpvAccess(cycleNum)++;
76     
77     if (CpvAccess(cycleNum) == nCycles) {
78         CpvAccess(endTime) = CmiWallTimer();
79         ringFinished(msg);
80     }
81     else {
82         CmiSetHandler(msg,CpvAccess(node1Handler));
83         *((int *)(msg+CmiMsgHeaderSizeBytes)) = CpvAccess(msgSize);
84         
85         CmiSyncSendAndFree(1,CpvAccess(msgSize),msg);
86     }
87     return 0;
88 }
89
90 CmiHandler node1HandlerFunc(char *msg)
91 {
92     CpvAccess(msgSize) = *((int *)(msg+CmiMsgHeaderSizeBytes));
93     CmiSetHandler(msg,CpvAccess(node0Handler));
94     
95     CmiSyncSendAndFree(0,CpvAccess(msgSize),msg);
96     return 0;
97 }
98
99
100 //Converse main. Initialize variables and register handlers
101 CmiStartFn mymain()
102 {
103     CpvInitialize(int,msgSize);
104     CpvInitialize(int,cycleNum);
105     
106     CpvAccess(msgSize)= 4 + CmiMsgHeaderSizeBytes;
107     
108     CpvInitialize(int,exitHandler);
109     CpvAccess(exitHandler) = CmiRegisterHandler((CmiHandler) exitHandlerFunc);
110     CpvInitialize(int,node0Handler);
111     CpvAccess(node0Handler) = CmiRegisterHandler((CmiHandler) node0HandlerFunc);
112     CpvInitialize(int,node1Handler);
113     CpvAccess(node1Handler) = CmiRegisterHandler((CmiHandler) node1HandlerFunc);
114     
115     CpvInitialize(double,startTime);
116     CpvInitialize(double,endTime);
117     
118     int otherPe = CmiMyPe() ^ 1;
119     
120     
121     if (CmiMyPe() == 0)
122         startRing();
123     
124     return 0;
125 }
126
127 int main(int argc,char *argv[])
128 {
129     ConverseInit(argc,argv,(CmiStartFn)mymain,0,0);
130     return 0;
131 }