doc: Add serial to list of ci file reserved words
[charm.git] / examples / pose / PatternGen / Worker.C
1 #include "defs.h"
2
3 /// Worker constructor
4 Worker::Worker(WorkerInitMsg *initMsg) {
5   myPID = initMsg->myPID;
6   totalNumWorkers = initMsg->totalNumWorkers;
7   patternNum = initMsg->patternNum;
8   msgCount = 0;
9   iterNum = 0;
10   msgNum = 0;
11
12   dbPrintf("Worker %d constructed\n", myPID);
13
14   // send the first message(s) of the simulation
15   WorkMsg *wm;
16   switch (patternNum) {
17   case 0:  // ring
18     if (myPID == 0) {
19       wm = new WorkMsg(myPID, 0);
20       msgCount++;
21       POSE_invoke(recvMessage(wm), Worker, (totalNumWorkers > 1) ? 1 : 0, (POSE_TimeType)P0_MSG_TRANSIT_TIME);
22     }
23     break;
24   case 1: {  // short communication burst, long message send, repeat
25     POSE_srand(time(NULL));
26     wm = new WorkMsg(myPID, 0);
27     POSE_local_invoke(pattern1Iter(wm), 1);
28     break;
29   }
30   case 2: {  // simultaneous ring with elapse
31     wm = new WorkMsg(myPID, 0);
32     msgCount++;
33     POSE_invoke(recvMessage(wm), Worker, (myPID + 1) % totalNumWorkers, (POSE_TimeType)0);
34     break;
35   }
36   case 3: {  // simultaneous ring without elapse
37     wm = new WorkMsg(myPID, 0);
38     msgCount++;
39     POSE_invoke(recvMessage(wm), Worker, (myPID + 1) % totalNumWorkers, (POSE_TimeType)0);
40     break;
41   }
42   default:
43     CkPrintf("Invalid pattern number: %d\n", patternNum);
44     CkAbort("");
45     break;
46   }
47 }
48
49 /// Send a message to a Worker
50 void Worker::sendMessage() {
51   dbPrintf("[ID=%d][ovt=%lld] sendMessage msgCount=%d iterNum=%d msgNum=%d\n", myPID, ovt, msgCount, iterNum, msgNum);
52
53   int destWorker;
54   POSE_TimeType msgTransitTime;
55   WorkMsg *wm;
56
57   // set message parameters based on the pattern
58   switch (patternNum) {
59   case 0:  // ring
60     destWorker = (myPID + 1) % totalNumWorkers;
61     msgTransitTime = (POSE_TimeType)P0_MSG_TRANSIT_TIME;
62     wm = new WorkMsg(myPID, msgCount);
63     msgCount++;
64     break;
65   case 1:  // short communication burst, long message send, repeat
66     //destWorker = POSE_rand() % totalNumWorkers;
67     destWorker = myPID;
68     msgTransitTime = (POSE_TimeType)(P1_BASE_MSG_TRANSIT_TIME + (POSE_rand() % P1_MSG_TRANSIT_TIME_RANGE));
69     wm = new WorkMsg(myPID, msgCount);
70     msgCount++;
71     break;
72   case 2:  // simultaneous ring with elapse
73     destWorker = (myPID + 1) % totalNumWorkers;
74     msgTransitTime = (POSE_TimeType)P2_MSG_TRANSIT_TIME;
75     wm = new WorkMsg(myPID, msgCount);
76     msgCount++;
77     break;
78   case 3: {  // simultaneous ring without elapse
79     destWorker = (myPID + 1) % totalNumWorkers;
80     msgTransitTime = (POSE_TimeType)P3_MSG_TRANSIT_TIME;
81     wm = new WorkMsg(myPID, msgCount);
82     msgCount++;
83     break;
84   }
85   default:
86     CkPrintf("Invalid pattern number: %d\n", patternNum);
87     CkAbort("");
88     break;
89   }
90
91   // send message
92   POSE_invoke(recvMessage(wm), Worker, destWorker, msgTransitTime);
93 }
94
95 /// ENTRY: Receive a message from a Worker
96 void Worker::recvMessage(WorkMsg *wm) {
97   dbPrintf("[ID=%d][ovt=%lld] recvMessage msgCount=%d iterNum=%d msgNum=%d wm:[srcWorkerPID=%d msgID=%d]\n", 
98            myPID, ovt, msgCount, iterNum, msgNum, wm->srcWorkerPID, wm->msgID);
99
100   switch (patternNum) {
101   case 0:  // ring
102     elapse(P0_ELAPSE_TIME);
103     if (((wm->msgID * totalNumWorkers) + wm->srcWorkerPID) < (P0_MESSAGES_TO_SEND - 1)) {
104       sendMessage();
105     }
106     break;
107   case 1:  // short communication burst, long message send, repeat
108     // do nothing; everything is done on the sending side
109     break;
110   case 2:  // simultaneous ring with elapse
111     if (((wm->msgID * totalNumWorkers) + wm->srcWorkerPID) < (P2_MESSAGES_TO_SEND - 1)) {
112     elapse(P2_ELAPSE_TIME);
113       sendMessage();
114     }
115     break;
116   case 3: {  // simultaneous ring without elapse
117     if (((wm->msgID * totalNumWorkers) + wm->srcWorkerPID) < (P3_MESSAGES_TO_SEND - 1)) {
118       // manually set evt for DOP analysis
119 #ifndef CMK_OPTIMIZE
120       if ((pose_config.stats) && (pose_config.dop)) {
121         parent->dop_override_evt = ovt + (POSE_TimeType)P3_ELAPSE_TIME;
122       }
123 #endif
124       sendMessage();
125     }
126     break;
127   }
128   default:
129     CkPrintf("Invalid pattern number: %d\n", patternNum);
130     CkAbort("");
131     break;
132   }
133 }
134
135 /// ENTRY: Send a message for pattern 1
136 void Worker::pattern1Iter(WorkMsg *wm) {
137   dbPrintf("[ID=%d][ovt=%lld] pattern1Iter msgCount=%d iterNum=%d msgNum=%d\n", myPID, ovt, msgCount, iterNum, msgNum);
138
139   // For each iter, send P1_MESSAGES_PER_ITER messages and then wait a
140   // while before starting the next iter
141   if (iterNum < P1_ITERS) {
142     if (msgNum < P1_MESSAGES_PER_ITER) {
143       sendMessage();
144       WorkMsg *wm = new WorkMsg(myPID, -((iterNum * P1_MESSAGES_PER_ITER) + msgNum));
145       POSE_local_invoke(pattern1Iter(wm), P1_SHORT_DELAY);
146       msgNum++;
147     } else {
148       WorkMsg *wm = new WorkMsg(myPID, -((iterNum * P1_MESSAGES_PER_ITER) + msgNum));
149       POSE_local_invoke(pattern1Iter(wm), P1_LARGE_DELAY);
150       msgNum = 0;
151       iterNum++;
152     }
153   }
154 }
155
156 /// Termination function called at the end of the simulation
157 void Worker::terminus() {
158   dbPrintf("[ID=%d] Simulation finished\n", myPID);
159 }