added CQWrite support for persistent message
[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
12 enum {nCycles = 10};
13 enum { maxMsgSize = 1 << 20 };
14
15 CpvDeclare(int,msgSize);
16 CpvDeclare(int,cycleNum);
17 CpvDeclare(int,exitHandler);
18 CpvDeclare(int,node0Handler);
19 CpvDeclare(int,node1Handler);
20 CpvStaticDeclare(double,startTime);
21 CpvStaticDeclare(double,endTime);
22
23 #define USE_PERSISTENT     1
24
25 #if USE_PERSISTENT
26 PersistentHandle h;
27 #endif
28
29 // Start the pingpong for each message size
30 void startRing()
31 {
32   CpvAccess(cycleNum) = 0;
33
34   //Increase message in powers of 4. Also add a converse header to that
35   CpvAccess(msgSize) = (CpvAccess(msgSize)-CmiMsgHeaderSizeBytes)*2 + 
36       CmiMsgHeaderSizeBytes;
37
38   char *msg = (char *)CmiAlloc(CpvAccess(msgSize));
39   *((int *)(msg+CmiMsgHeaderSizeBytes)) = CpvAccess(msgSize);
40   CmiSetHandler(msg,CpvAccess(node0Handler));
41   CmiSyncSendAndFree(0, CpvAccess(msgSize), msg);
42   CpvAccess(startTime) = CmiWallTimer();
43 }
44
45 //the pingpong has finished, record message time
46 void ringFinished(char *msg)
47 {
48   CmiFree(msg);
49
50   //Print the time for that message size
51   CmiPrintf("Size=%d bytes, time=%lf microseconds one-way\n", 
52              CpvAccess(msgSize)-CmiMsgHeaderSizeBytes, 
53              (1e6*(CpvAccess(endTime)-CpvAccess(startTime)))/(2.*nCycles));
54
55   
56   //Have we finished all message sizes?
57   if (CpvAccess(msgSize) < maxMsgSize)
58       //start the ring again
59       startRing();
60   else {
61       //exit
62       void *sendmsg = CmiAlloc(CmiMsgHeaderSizeBytes);
63       CmiSetHandler(sendmsg,CpvAccess(exitHandler));
64       CmiSyncBroadcastAllAndFree(CmiMsgHeaderSizeBytes,sendmsg);
65   }
66 }
67
68 //We finished for all message sizes. Exit now
69 CmiHandler exitHandlerFunc(char *msg)
70 {
71     CmiFree(msg);
72     CsdExitScheduler();
73     return 0;
74 }
75
76
77 //Handler on Node 0
78 CmiHandler node0HandlerFunc(char *msg)
79 {
80     CpvAccess(cycleNum)++;
81     
82     if (CpvAccess(cycleNum) == nCycles) {
83         CpvAccess(endTime) = CmiWallTimer();
84         ringFinished(msg);
85     }
86     else {
87         CmiSetHandler(msg,CpvAccess(node1Handler));
88         *((int *)(msg+CmiMsgHeaderSizeBytes)) = CpvAccess(msgSize);
89         
90 #if USE_PERSISTENT
91         CmiUsePersistentHandle(&h, 1);
92 #endif
93         CmiSyncSendAndFree(1,CpvAccess(msgSize),msg);
94 #if USE_PERSISTENT
95         CmiUsePersistentHandle(NULL, 0);
96 #endif
97     }
98     return 0;
99 }
100
101 CmiHandler node1HandlerFunc(char *msg)
102 {
103     CpvAccess(msgSize) = *((int *)(msg+CmiMsgHeaderSizeBytes));
104     CmiSetHandler(msg,CpvAccess(node0Handler));
105     
106 #if USE_PERSISTENT
107     CmiUsePersistentHandle(&h, 1);
108 #endif
109     CmiSyncSendAndFree(0,CpvAccess(msgSize),msg);
110 #if USE_PERSISTENT
111     CmiUsePersistentHandle(NULL, 0);
112 #endif
113     return 0;
114 }
115
116
117 //Converse main. Initialize variables and register handlers
118 CmiStartFn mymain()
119 {
120     CpvInitialize(int,msgSize);
121     CpvInitialize(int,cycleNum);
122     
123     CpvAccess(msgSize)= 8192 + CmiMsgHeaderSizeBytes;
124     
125     CpvInitialize(int,exitHandler);
126     CpvAccess(exitHandler) = CmiRegisterHandler((CmiHandler) exitHandlerFunc);
127     CpvInitialize(int,node0Handler);
128     CpvAccess(node0Handler) = CmiRegisterHandler((CmiHandler) node0HandlerFunc);
129     CpvInitialize(int,node1Handler);
130     CpvAccess(node1Handler) = CmiRegisterHandler((CmiHandler) node1HandlerFunc);
131     
132     CpvInitialize(double,startTime);
133     CpvInitialize(double,endTime);
134     
135     int otherPe = CmiMyPe() ^ 1;
136     
137 #if USE_PERSISTENT
138     if (CmiMyPe() < CmiNumPes())
139     h = CmiCreatePersistent(otherPe, maxMsgSize+1024);
140 #endif
141     
142     if (CmiMyPe() == 0)
143         startRing();
144     
145     return 0;
146 }
147
148 int main(int argc,char *argv[])
149 {
150     ConverseInit(argc,argv,(CmiStartFn)mymain,0,0);
151     return 0;
152 }