fixed so that it can report error when convert to int.
[charm.git] / examples / pose / HiSim / Main / TCsim.C
1 #include "BgSim_sim.h"
2 extern BgTimeLineRec* currTline;
3 extern int currTlineIdx;
4
5 #define ALLTHREAD -1
6
7 // the application name to simulate
8 extern roarray<char, 1024>  appname;
9
10 POSE_TimeType Task::convertToInt(double inp) 
11 {
12   POSE_TimeType out = (long long)(inp*factor);
13   if (out <0 && inp != -1.0) {
14     CmiPrintf("Invalid value in convertToInt() - %ld %f\n", out, inp);
15     CmiPrintf("Considering changing factor %e to a smaller value. \n", factor);
16     CmiAssert(out >= 0 || inp == -1);
17   }
18   return (out<0?0:out);
19 }
20
21
22 void Task::convertFrom(BgTimeLog* bglog, int procNum, int numWth) 
23 {
24   int i;
25
26   taskID.srcNode = bglog->msgId.node();
27   taskID.msgID = bglog->msgId.msgID();
28   taskID.index = bglog->seqno;
29
30   strncpy(name,bglog->name,19);  name[19]=0;
31   startTime = convertToInt(bglog->startTime);
32   receiveTime = convertToInt(bglog->recvTime);
33   execTime = convertToInt(bglog->execTime);
34   done = 0;
35
36   //CkPrintf("LOG rcv=%d start=%d\n", receiveTime, startTime);
37   bDepsLen = bglog->backwardDeps.length();
38   backwardDeps = NULL;
39   if (bDepsLen) {
40     backwardDeps = new TaskID[bDepsLen];
41     for(i=0;i<bDepsLen;i++){
42       backwardDeps[i].srcNode = -1;//bglog->backwardDeps[i]->srcnode;
43       backwardDeps[i].msgID = -1;//bglog->backwardDeps[i]->msgID;
44       backwardDeps[i].index = bglog->backwardDeps[i]->seqno;
45     }
46   }
47
48   fDepsLen = bglog->forwardDeps.length();
49   forwardDeps = NULL;
50   if (fDepsLen) {
51     forwardDeps = new TaskID[fDepsLen];
52     for(i=0;i<fDepsLen;i++){
53       forwardDeps[i].srcNode = -1;//bglog->forwardDeps[i]->srcnode;
54       forwardDeps[i].msgID = -1;//bglog->forwardDeps[i]->msgID;
55       forwardDeps[i].index = bglog->forwardDeps[i]->seqno;
56     }
57   }
58   
59   // these are the generated tasks?
60   taskMsgsLen = bglog->msgs.length();
61   taskmsgs = new TaskMsg[taskMsgsLen];
62   for(i=0; i< taskMsgsLen;i++){
63     taskmsgs[i].taskID.srcNode = procNum/numWth;
64     taskmsgs[i].taskID.msgID = bglog->msgs[i]->msgID;
65     taskmsgs[i].taskID.index = -1; 
66     taskmsgs[i].destNode = bglog->msgs[i]->dstPe;
67     taskmsgs[i].desttID = bglog->msgs[i]->tID;
68     taskmsgs[i].receiveTime = convertToInt(bglog->msgs[i]->recvTime);
69     taskmsgs[i].msgsize = bglog->msgs[i]->msgsize;
70     if (taskmsgs[i].desttID >= 0) CmiAssert(taskmsgs[i].desttID < numWth);
71     CmiAssert(taskmsgs[i].msgsize > 0);
72   }
73   
74   // trace projections events and bgPrint Events
75   printevtLen = projevtLen = 0;
76   projevts = NULL;
77   printevts = NULL;
78   for(i=0; i< bglog->evts.length();i++){
79     if (bglog->evts[i]->eType == BG_EVENT_PROJ)  projevtLen++;
80     if (bglog->evts[i]->eType == BG_EVENT_PRINT)  printevtLen++;
81   }
82   if (projevtLen)  projevts = new ProjEvent[projevtLen];
83   if (printevtLen)  printevts = new bgPrintEvent[printevtLen];
84
85   printevtLen = projevtLen = 0;
86   for(i=0; i< bglog->evts.length();i++){
87     // CmiPrintf("[%d] %d %d \n", procNum, bglog->evts[i]->eType, bglog->evts[i]->index);
88       if (bglog->evts[i]->eType == BG_EVENT_PROJ) {
89         projevts[projevtLen].index = bglog->evts[i]->index;
90         projevts[projevtLen].startTime = convertToInt(bglog->evts[i]->rTime);
91         projevtLen++;
92       }
93       if (bglog->evts[i]->eType == BG_EVENT_PRINT) {
94         printevts[printevtLen].data = (char *)bglog->evts[i]->data;
95         printevts[printevtLen].sTime = convertToInt(bglog->evts[i]->rTime);
96         printevtLen++;
97       }
98   }
99
100 }
101
102
103 void Task::pup(PUP::er &p) 
104 {
105   taskID.pup(p);
106   p|receiveTime; p|execTime; p|startTime;
107   p(name,20);
108   p|bDepsLen; p|fDepsLen;p|taskMsgsLen; p|printevtLen;p|projevtLen;
109   p|done;
110
111   if(p.isUnpacking()){
112     backwardDeps = new TaskID[bDepsLen];
113     forwardDeps = new TaskID[fDepsLen];
114     taskmsgs = new TaskMsg[taskMsgsLen];
115     projevts = new ProjEvent[projevtLen];
116     printevts = new bgPrintEvent[printevtLen];
117   }
118   for(int i=0;i<bDepsLen;i++)
119     backwardDeps[i].pup(p);
120   for(int i=0;i<fDepsLen;i++)
121     forwardDeps[i].pup(p);
122   for(int i=0;i<taskMsgsLen;i++)
123     taskmsgs[i].pup(p);
124   for(int i=0;i<printevtLen;i++)
125     p|printevts[i];
126   for(int i=0;i<projevtLen;i++)
127     p|projevts[i];
128 }
129
130 BGproc::BGproc() 
131 {
132   // implement as you wish
133   proj = NULL;
134   done = NULL;
135   taskList = NULL;
136 }
137
138 // read trace projections logs if there is any
139 void BGproc::loadProjections() 
140 {
141   int i;
142
143   proj = NULL;
144   binary = 0;
145   char str[1024];
146   char app[128];
147   for (i=0; i<128; i++) app[i] = appname[i];
148   sprintf(str, "%s.%d.log", app, procNum);
149   FILE *f = fopen(str, "r");
150   if (f) {
151     CmiPrintf("Loading projections file: %s\n", str);
152     // figure out the log size
153     if (!binary) {
154       fgets(str, 1024, f);              // skip header
155       sscanf(str, "PROJECTIONS-RECORD %d", &numLogs);
156     }
157     else {
158       fread(&numLogs, sizeof(int), 1, f);
159     }
160     CmiAssert(numLogs);
161     logs = new LogEntry[numLogs]; 
162     fromProjectionsFile p(f);
163 //    PUP::fromDisk p(f);
164     for (i=0; i<numLogs; i++) {
165       logs[i].pup(p);
166       // CmiPrintf("%d %d\n", i, logs[i].type);
167     }
168     fclose(f);
169     // new log
170     sprintf(str, "%s-bg.%d.log", app, procNum);
171     proj = fopen(str, "w");
172     if (!binary) {
173       fprintf(proj, "PROJECTIONS-RECORD %d\n", numLogs);
174     }
175     CmiAssert(proj);
176   }
177 }
178
179 BGproc::BGproc(BGprocMsg *m)
180 {
181   int i;
182
183   nodePID = m->nodePID;         // node pose index
184   useAntimethods();
185   if (-1==BgLoadTraceSummary("bgTrace", totalProcs, numX, numY, numZ, numCth, numWth, numPes)) CmiAbort("Failed");
186   
187   int* allNodeOffsets = BgLoadOffsets(totalProcs,numPes);
188   BgTimeLineRec tline;
189   procNum = myHandle;
190   currTline = &tline;
191   currTlineIdx = procNum;
192   BgReadProc(procNum,numWth,numPes,totalProcs,allNodeOffsets,tline);
193
194   delete [] allNodeOffsets;
195
196 #if 0    // detail
197   // dump bg timeline log to disk
198   BgWriteThreadTimeLine("detail", 0, 0, 0, procNum, tline.timeline);
199 #endif
200
201   //CkPrintf("bgProc %d has %d tasks\n", myHandle, tline.length());
202   numTasks = tline.length();
203   CmiAssert(numTasks>0);
204   taskList = new Task[tline.length()];
205   int startEvt = 0;             // start event, to skip startup
206   for(i=0;i<tline.length();i++) {
207     taskList[i].convertFrom(tline[i],myHandle,numWth);
208     if (config.skip_on && tline[i]->isStartEvent() && startEvt== 0) { 
209         CmiAssert(procNum==0); 
210         startEvt = i; 
211     }
212   }
213
214   buildHash();
215
216   // store the status of done tasks
217   done = new int[numTasks];
218   for (i = 0; i<numTasks; i++) done[i] = 0;
219
220   //  if (myHandle == 0) { 
221   // this is processor 0 therefore the one to start main
222   // get the taskID for the main task to start and invoke it
223
224   // read trace projections logs if there is any
225   loadProjections();
226
227   if (config.tproj_on) {
228     char str[1024];
229     char app[128];
230 //    for (int j=0; j<128; j++) app[j] = appname[j];
231     sprintf(str, "%s.%d.log", "foo", procNum);
232     lf = fopen(str, "w");
233     toProjectionsFile p(lf);
234     LogEntry *foo = new LogEntry(0.0, 6);
235     foo->pup(p);
236   }
237
238
239   // only pe 0 should start the sim
240   if (procNum == 0) {
241     TaskMsg *tm = new TaskMsg(-1,-1,startEvt);
242     POSE_invoke(executeTask(tm), BGproc, myHandle, taskList[startEvt].startTime);
243     CkPrintf("Info> timing factor %e ...\n", (double)factor);
244     CkPrintf("Info> invoking startup task from proc 0 ...\n");
245     if (config.skip_on)
246       CkPrintf("Info> Skipping startup to %d/%d\n", startEvt, tline.length());
247   }
248 #if 1
249     for (int i=startEvt; i<numTasks; i++) {
250       if (!strcmp(taskList[i].name, "addMsg") ||
251           !strcmp(taskList[i].name, "AMPI_START") ||
252           !strcmp(taskList[i].name, "AMPI_MIGRATE"))  
253       {
254         // skip if it has any backward dependency
255         if (taskList[i].bDepsLen != 0) continue;
256         TaskMsg *tm = new TaskMsg(taskList[i].taskID.srcNode,
257                        taskList[i].taskID.msgID,
258                        taskList[i].taskID.index,
259                        taskList[i].receiveTime,
260                        0,
261                        procNum/numWth,  procNum/numWth,
262                        procNum%numWth
263                        );
264         CmiAssert(taskList[i].receiveTime >= 0);
265         POSE_invoke(executeTask(tm), BGproc, myHandle, taskList[i].receiveTime);
266       }
267     }
268 #endif
269   //}
270   // FIXME:  free tline memory
271 }
272
273 BGproc::~BGproc()
274 {
275   // implement as you wish
276   if (done) delete [] done;
277 }
278
279 void BGproc::pup(PUP::er &p)
280
281   chpt<state_BGproc>::pup(p); 
282   // pup rest of data fields here
283   p|numX;p|numY;p|numZ;p|numCth;p|numWth;p|numPes;p|totalProcs;p|procNum;
284   p|nodePID;
285   p|numTasks;
286   if(p.isUnpacking())
287     taskList = new Task[numTasks];
288   for(int i=0;i<numTasks;i++)
289     taskList[i].pup(p);
290 }
291
292 // Event methods
293 void BGproc::executeTask(TaskMsg *m)
294 {
295 /*
296   CkPrintf("[%d Received TaskID: %d %d %d]\n", procNum, m->taskID.srcNode,
297            m->taskID.msgID, m->taskID.index, locateTask(m->taskID));
298   parent->CommitPrintf("Received %d from %d on %d at %d\n", m->taskID.msgID, 
299                        m->taskID.srcNode, parent->thisIndex, ovt);
300 */
301 //  CmiAssert(done[locateTask(m->taskID)] == 0);
302   int taskLoc = locateTask(m->taskID);
303   if (taskLoc == -1) {
304     // This may be ok if the message is at the end of execution
305     // user is warned here though
306     parent->CommitPrintf("WARNING: executeTask TASK NOT FOUND src:%d msg:%d on:%d\n", m->taskID.srcNode, m->taskID.msgID, parent->thisIndex);
307     return;
308   }
309   if (done[taskLoc] == 1) {
310     char str[1024];
311     sprintf(str, "[%d] Event #%d '%s' already done!\n", procNum, taskLoc, taskList[taskLoc].name);
312     parent->CommitError(str);
313     CkPrintf("POTENTIAL ERROR: [%d] Event %d '%s' already done! %d %d %d at %ld evID=", procNum, taskLoc, taskList[taskLoc].name, m->taskID.srcNode, m->taskID.msgID, m->taskID.index, m->timestamp); m->evID.dump(); CkPrintf("\n");
314     return;
315   }
316
317   POSE_TimeType oldRT = getReceiveTime(m->taskID);
318   POSE_TimeType newRT = m->timestamp;
319   //if(!(m->isNull()))
320   //updateReceiveTime(m);
321   if (dependenciesMet(&(m->taskID))) { // dependencies met; we can execute this
322     Task &task = taskList[taskLoc];
323     POSE_TimeType oldStartTime = task.startTime;
324     POSE_TimeType newStartTime = ovt;
325     task.newStartTime = newStartTime;   // store new start time and used later
326     //updateStartTime(&m->taskID, newStartTime);
327     markTask(&m->taskID);  // what is this doing?
328     //CmiPrintf("[%d] executeTask %d for %d %d %d at %d evID=", procNum, taskLoc, m->taskID.srcNode, m->taskID.msgID, m->taskID.index, m->timestamp); m->evID.dump(); CkPrintf("\n");
329     enableGenTasks(&m->taskID,oldStartTime,newStartTime);
330     elapse(getDuration((m->taskID)));
331     enableDependents(&m->taskID); // invoke dependent tasks
332     /*
333       parent->CommitPrintf("[%d:%s] IDX=%d, RT1=%d RT2=%d ST1=%d ST2=%d e=%d t=%d.\n",
334       procNum, taskList[taskLoc].name, taskLoc, oldRT, newRT, oldStartTime, 
335       newStartTime, getDuration(m->taskID), 
336       newStartTime+getDuration(m->taskID));
337     */
338     for(int i=0;i<task.printevtLen;i++){
339             char str[1000];
340             strcpy(str, "[%d:%s] ");
341             strcat(str, task.printevts[i].data);
342 /*
343             CkPrintf("uncommited ");
344             CkPrintf(str,procNum, taskList[taskLoc].name, (double)(task.printevts[i].sTime+newStartTime)/factor); 
345 */
346             parent->CommitPrintf(str,procNum, taskList[taskLoc].name, (double)(task.printevts[i].sTime+newStartTime)/factor); 
347     }
348 return;
349     // HACK:
350     // look forward and see if there is any standalone or addMsg events
351     for (int i=taskLoc+1; i<numTasks; i++) {
352       if (!strcmp(taskList[i].name, "standalone")) continue; 
353       if (!strcmp(taskList[i].name, "addMsg"))  {
354         TaskMsg *tm = new TaskMsg(taskList[i].taskID.srcNode,
355                        taskList[i].taskID.msgID,
356                        taskList[i].taskID.index,
357                        ovt + taskList[i].execTime,
358                        0,
359                        procNum/numWth,  procNum/numWth,
360                        procNum%numWth
361                        );
362         POSE_invoke(executeTask(tm), BGproc, myHandle, taskList[i].execTime);
363         continue;
364       }
365       break;
366     }
367   }
368 }
369
370 void BGproc::enableGenTasks(TaskID* taskID, POSE_TimeType oldStartTime, POSE_TimeType newStartTime)
371 {
372   TaskMsg* generatedTasks = getGeneratedTasks(taskID);
373   int numGenTasks = getNumGeneratedTasks(taskID);
374   TaskMsg *tm;
375
376   // Given the following inputs for destNode and destTID, we need to 
377   // send out messages either directly to the local node, or through
378   // the network.  To do this we have to specify correct information
379   // about the destination BGproc and the source and destination
380   // switch in the network
381
382   // destNode   destTID   Behavior
383   // ========== ========= ==============================================
384   // -1         -1        Broadcast to ALL worker threads of ALL nodes
385   // -1         K         SHOULD NOT HAPPEN???
386   // N          -1        Send to ALL worker threads of node N
387   // N          K         Send to worker thread K of node N
388   // -100-N     -1        Broadcast to all worker threads of all nodes
389   //                      except for N (no worker threads of N receive)
390   // -100-N     K         Broadcast to all worker threads of all nodes
391   //                      except worker K of node N
392
393   for (int i=0; i<numGenTasks; i++) {
394     // time units offset in future at which task i is generated
395     int taskOffset = generatedTasks[i].receiveTime - oldStartTime;
396     int myNode = parent->thisIndex/numWth;
397     int srcSwitch = myNode;
398     
399     CmiAssert(taskOffset >= 0);
400           
401     //generatedTasks[i].receiveTime = newStartTime + taskOffset;
402     //if(generatedTasks[i].receiveTime < 0) abort();  // Sanity check
403     CmiAssert(newStartTime + taskOffset >= 0);  // Sanity check
404
405     int destNodeCode = generatedTasks[i].getDestNode();
406     int destTID = generatedTasks[i].desttID; 
407
408     if (destNodeCode >= 0) { // send a msg to a specific node
409       if (destTID < -1) {
410         CkPrintf("ERROR: enableGenTasks: bad destTID %d destNodeCode %d\n",
411                  destTID, destNodeCode);
412         CmiAbort("");
413       }
414     }
415     else if (destNodeCode == -1) { // broadcast to all nodes
416       if (destTID != -1) {
417         CkPrintf("ERROR: enableGenTasks: bad destTID %d destNodeCode %d\n",
418                  destTID, destNodeCode);
419         CmiAbort("");
420       }
421     }
422     else if (destNodeCode <= -100) { // broadcast to all nodes with exceptions
423       if (destTID < -1) {
424         CkPrintf("ERROR: enableGenTasks: bad destTID %d destNodeCode %d\n",
425                  destTID, destNodeCode);
426         CmiAbort("");
427       }
428     }
429     else CkPrintf("ERROR: enableGenTasks: bad destNodeCode %d\n",destNodeCode);
430 /*
431     tm = &generatedTasks[i];
432     POSE_TimeType recvTime = tm->receiveTime;   // store old value
433 */
434     tm = new TaskMsg();
435     *tm = generatedTasks[i];
436     tm->receiveTime = newStartTime + taskOffset;
437     SendMessage(tm, myNode, srcSwitch, destNodeCode, destTID, taskOffset);
438 /*
439     tm->receiveTime = recvTime;    // we can not change it
440 */
441     delete tm;
442   }
443 }
444
445 void BGproc::SendMessage(TaskMsg *inMsg, int myNode, int srcSwitch,
446                          int destNodeCode, int destTID, int taskOffset)
447 {
448   int destSwitch, destNode, j;
449
450   if (destNodeCode >= 0) { // send msg to one node
451     destNode = destNodeCode;
452     destSwitch = destNode;
453     GeneralSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
454                destTID, destNode, taskOffset);
455   }
456   else if (destNodeCode == -1) { // send msg to all nodes
457     CmiAssert(destTID == -1);
458     for (j=0; j<totalProcs/numWth; j++) {
459       destNode = j;
460       destSwitch = destNode;
461       GeneralSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
462                  destTID, destNode, taskOffset);
463     }
464   }
465   else { // send msg to all nodes except destNodeExcept when destTID=-1
466     int destNodeExcept = -100 - destNodeCode;
467     for (j=0; j<totalProcs/numWth; j++) {
468       destNode = j;
469       destSwitch = destNode;
470       if ((destNode == destNodeExcept) && (destTID == -1))
471         continue; // exclude the whole node
472       // no fiddling with destTID necessary; receiver will handle
473       GeneralSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
474                  destTID, destNode, taskOffset);
475     }
476   }
477 }
478
479 void BGproc::GeneralSend(TaskMsg *inMsg, int myNode, int srcSwitch,
480                         int destSwitch, int destNodeCode, int destTID, 
481                         int destNode, int taskOffset)
482 {
483   if (config.netsim_on) {
484     if (srcSwitch == destSwitch) 
485       DirectSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
486                destTID, destNode, taskOffset);
487     else 
488       NetSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
489                destTID, destNode, taskOffset);
490   }
491   else 
492     DirectSend(inMsg, myNode, srcSwitch, destSwitch, destNodeCode,
493                destTID, destNode, taskOffset);
494 }
495
496 void BGproc::DirectSend(TaskMsg *inMsg, int myNode, int srcSwitch,
497                      int destSwitch, int destNodeCode, int destTID, 
498                      int destNode, int taskOffset)
499 {
500     TaskMsg *tm = new TaskMsg(inMsg->taskID.srcNode, inMsg->taskID.msgID,
501                      inMsg->taskID.index, inMsg->receiveTime,
502                      inMsg->msgsize, destNode, destNodeCode, destTID);
503     CmiAssert(destNode >= 0);
504     int destNodePID = destNode + totalProcs;    // to node PID
505     POSE_invoke(recvIncomingMsg(tm), BGnode, destNodePID, taskOffset);
506 }
507
508
509 void BGproc::NetSend(TaskMsg *inMsg, int myNode, int srcSwitch,
510                      int destSwitch, int destNodeCode, int destTID, 
511                      int destNode, int taskOffset)
512 {
513   NicMsg *m = new NicMsg;
514   m->src = inMsg->taskID.srcNode;
515   m->routeInfo.dst = destSwitch;
516   m->msgId = inMsg->taskID.msgID;
517   m->index = inMsg->taskID.index;
518   m->destNodeCode = destNodeCode;
519   m->destTID = destTID;
520   m->recvTime = inMsg->receiveTime;
521   m->totalLen = inMsg->msgsize;
522   m->origovt = ovt+taskOffset;
523   //CkPrintf("%d BgSim : Sent %d -> %d msgid %d len %d \n",ovt,m->src,m->dst,m->msgId,m->totalLen);
524
525   elapse(CPU_OVERHEAD);
526   POSE_invoke(recvMsg(m), NetInterface, config.nicStart+m->src, taskOffset+START_LATENCY);
527 //  elapse((int)(m->totalLen/config.switchC_BW)); 
528   elapse(CPU_OVERHEAD);
529  
530   //CkPrintf("[NETWORK: BGproc:%d BGnode:%d srcSwitch:%d destSwitch:%d destNodeCode:%d destTID:%d]\n", parent->thisIndex, myNode, srcSwitch, destSwitch, destNodeCode, destTID);
531   //parent->CommitPrintf("[NETWORK: BGproc:%d BGnode:%d srcSwitch:%d destSwitch:%d destNodeCode:%d destTID:%d]\n", parent->thisIndex, myNode, srcSwitch, destSwitch, destNodeCode, destTID);
532 }
533
534 void BGproc::executeTask_anti(TaskMsg *m)
535 {
536   restore(this);
537   if (usesAntimethods()) {
538     int taskLoc = locateTask(m->taskID);
539     if (taskLoc == -1) {
540       parent->CommitPrintf("WARNING: executeTask_anti TASK NOT FOUND src:%d msg:%d on:%d\n", m->taskID.srcNode, m->taskID.msgID, parent->thisIndex);
541       return;
542     }
543     CmiAssert(taskLoc >= 0);
544     //CmiPrintf("[%d] executeTask_anti %d for %d %d %d\n", procNum, taskLoc, m->taskID.srcNode, m->taskID.msgID, m->taskID.index);
545     done[taskLoc] = 0;
546   }
547 }
548
549 void BGproc::executeTask_commit(TaskMsg *m)
550 {
551   int taskLoc = locateTask(m->taskID);
552   if (taskLoc == -1) {
553     parent->CommitPrintf("WARNING: executeTask_commit TASK NOT FOUND src:%d msg:%d on:%d\n", m->taskID.srcNode, m->taskID.msgID, parent->thisIndex);
554     return;
555   }
556   Task &task = taskList[taskLoc];
557   //CkPrintf("[%d] commit %d for %d %d %d evID=", procNum, taskLoc, m->taskID.srcNode, m->taskID.msgID, m->taskID.index); m->evID.dump(); CkPrintf("\n");
558   //CmiAssert(done[taskLoc] == 1);
559   // trying to commit an unexecuted event (may happen in sequential mode)
560   if (done[taskLoc] == 0) return;
561
562   if (proj) {
563     // pup projections to logs
564     if (!binary)  {
565       toProjectionsFile p(proj);
566       for (int i=0; i<task.projevtLen; i++) {
567         int idx = task.projevts[i].index;
568         POSE_TimeType newStart = task.newStartTime +  task.projevts[i].startTime;
569         CmiAssert(idx < numLogs);
570         logs[idx].time = newStart/1e9;
571         logs[idx].pup(p);
572       }
573     }
574   }
575   else if (config.tproj_on) {
576     toProjectionsFile p(lf);
577     LogEntry *beginLog = new LogEntry((double)task.newStartTime/factor, 2);
578     LogEntry *endLog = new LogEntry(((double)(task.newStartTime+task.execTime))/factor, 3);
579     beginLog->pup(p);
580     endLog->pup(p);
581   }
582 }
583
584 void BGproc::terminus()
585 {
586   if (proj && !binary)  {
587     toProjectionsFile p(proj);
588     logs[numLogs-1].time = ovt/1e9;
589     logs[numLogs-1].pup(p);
590   }
591   else if (config.tproj_on) {
592     toProjectionsFile p(lf);
593     LogEntry *foo = new LogEntry(((double)ovt)/factor, 7);
594     foo->pup(p);
595     fclose(lf);
596   }
597   if (config.check_on) 
598   {
599   // error checking
600   int i, count=0;
601   for (i=0; i<numTasks; i++) if (done[i] == 0) count++;
602   if (count) {
603     CkPrintf("[%d] %d/%d uncommitted events: ", procNum, count, numTasks);
604     i=0;
605     while (i<numTasks) {
606       if (done[i] == 0) {
607         CkPrintf(" %d", i);
608         i++; count = 0;
609         while (i<numTasks && done[i] == 0) { i++; count++; }
610         if (count) CkPrintf("-%d", i-1);
611       }
612       i++;
613     }
614     CkPrintf("\n");
615   }
616   }
617 }
618
619
620 // local methods
621 void BGproc::buildHash(){
622   // make index starting from 1 so that we can use 0 to represent absence
623   for(int i=0;i<numTasks;i++){
624     msgTable.put(taskList[i].taskID) = i+1;
625   }
626 }
627
628 int BGproc::locateTask(TaskID* t){
629
630 //  if the index has been already set, use it directly
631   if (t->index >= 0) return t->index;
632 #if 1
633   int index = msgTable.get(*t);
634   if (index>0) {
635     t->index = index-1;
636     return t->index;
637   }
638 #else
639   for(int i=0;i<numTasks;i++){
640
641     if(*t == taskList[i].taskID) {
642       t->index = i;
643       return i;
644     }
645   }
646 #endif
647  
648   //parent->CommitPrintf("WARNING: TASK NOT FOUND src:%d msg:%d on:%d\n",
649   //           t->srcNode, t->msgID, parent->thisIndex);
650   //abort();
651   return -1;
652 }
653
654 void BGproc::markTask(TaskID* t) {
655   done[locateTask(t)] = 1;
656 }
657
658 // not used
659 void BGproc::updateReceiveTime(TaskMsg* m)
660 {
661   // update the task's receive time to timestamp, and set a flag to
662   // indicate the update was made. ignore subsequent receive time
663   // updates to this taskID
664
665   taskList[locateTask(&(m->taskID))].receiveTime = m->timestamp;
666 }
667
668 int BGproc::dependenciesMet(yourUniqueTaskIDtype taskID)
669 {
670   // tests to see if this taskID is dependent on other tasks that have
671   // not yet been executed.  If succeed, mark this task executed.
672
673   int idx = locateTask(taskID);
674   CmiAssert(idx != -1);
675
676   int bidx;
677   for(int i=0;i<taskList[idx].bDepsLen;i++){
678     bidx = locateTask(&taskList[idx].backwardDeps[i]);
679 //    if(!taskList[bidx].done)
680     if(!done[bidx])
681       return 0;
682   }
683   return 1;
684 }
685
686 // not used
687 void BGproc::updateStartTime(TaskID* taskID, POSE_TimeType newTime)
688 {
689   // update the task's start time to newTime
690   taskList[locateTask(taskID)].startTime = newTime;
691 }
692
693 void BGproc::enableDependents(TaskID* taskID)
694 {
695   TaskMsg *tm;
696   TaskID* ftid;
697   int taskIdx = locateTask(taskID);
698   CmiAssert(taskIdx != -1);
699   POSE_TimeType execT = taskList[taskIdx].execTime;
700   
701   int fDepsLen = taskList[taskIdx].fDepsLen;
702   for(int i=0;i<fDepsLen;i++){
703
704     ftid = &taskList[taskIdx].forwardDeps[i];
705     // CkPrintf("[Checking dependent task %d %d on %d\n", ftid->index, ftid->msgID, ftid->srcNode); 
706     if(dependenciesMet(ftid)){
707       // should not have done here
708       CmiAssert(done[locateTask(ftid)]==0);
709
710       tm = new TaskMsg(ftid->srcNode,
711                        ftid->msgID,
712                        ftid->index,
713                        ovt + execT,
714                        0,
715                        procNum/numWth,  procNum/numWth,
716                        procNum%numWth
717                        );
718       
719       //CkPrintf("[%d] dependent: executeTask call %d, for %d %d %d\n", procNum, locateTask(ftid), ftid->srcNode, ftid->msgID, ftid->index); 
720       POSE_invoke(executeTask(tm), BGproc, myHandle, 0);
721     }
722   }
723 }
724
725
726 TaskMsg* BGproc::getGeneratedTasks(yourUniqueTaskIDtype taskID)
727 {
728   return taskList[locateTask(taskID)].taskmsgs;
729 }
730
731
732 int BGproc::getNumGeneratedTasks(yourUniqueTaskIDtype taskID)
733 {
734   // get the number of generated tasks in the list of tasks generated
735   // by this one
736   return taskList[locateTask(taskID)].taskMsgsLen;
737 }
738
739 POSE_TimeType BGproc::getDuration(TaskID taskID)
740 {
741   // get the duration of this task
742   return taskList[locateTask(taskID)].execTime;
743 }
744
745  
746 POSE_TimeType BGproc::getReceiveTime(TaskID taskID)
747 {
748   // get the receive time of this task
749   return taskList[locateTask(taskID)].receiveTime;
750 }
751
752 BGnode::BGnode(BGnodeMsg *m)
753 {
754   useAntimethods();
755   procsPerNode = m->procsPerNode;
756   switchPID = m->switchID;
757   nodePID = parent->thisIndex;          // pose index
758   myNodeIndex = m->nodeIdx;             // index in node array
759   firstProcPID = myNodeIndex*procsPerNode;  // first BGproc PID
760   // CmiPrintf("BGnode (%d %d) with switchPID: %d firstPE: %d\n", nodePID, myNodeIndex, switchPID, firstProcPID);
761 }
762
763 void BGnode::pup(PUP::er &p)
764 {
765   p|procsPerNode;
766   p|switchPID;
767   p|nodePID;
768   p|myNodeIndex;
769   p|firstProcPID;
770 }
771
772 void BGnode::recvOutgoingMsg(TaskMsg *m)
773 {
774 #if 0
775   int destNodeCode = m->destNodeCode;
776   int destTID
777   int destNode;
778   int destSwitch, destProc = -1, j;
779
780   if (destNodeCode >= 0) { // send msg to one node
781     destNode = destNodeCode;
782     destSwitch = nodeToSwitchPID(destNode);
783     if (destTID >= 0)
784       destProc = destNode*numWth + destTID;
785     SimpleSend(inMsg, myProc, myNode, srcSwitch, destSwitch, destNodeCode,
786                destTID, destNode, destProc, taskOffset);
787   }
788   else if (destNodeCode == -1) { // send msg to all nodes
789     CmiAssert(destTID == -1);
790     for (j=0; j<totalProcs/numWth; j++) {
791       destNode = j;
792       destSwitch = totalProcs + destNode;
793       SimpleSend(inMsg, myProc, myNode, srcSwitch, destSwitch, destNodeCode,
794                  destTID, destNode, destProc, taskOffset);
795     }
796   }
797   else { // send msg to all nodes except destNodeExcept when destTID=-1
798     int destNodeExcept = -100 - destNodeCode;
799     for (j=0; j<totalProcs/numWth; j++) {
800       destNode = j;
801       destSwitch = totalProcs + destNode;
802       if ((destNode == destNodeExcept) && (destTID == -1))
803         continue; // exclude the whole node
804       // no fiddling with destTID necessary; receiver will handle
805       SimpleSend(inMsg, myProc, myNode, srcSwitch, destSwitch, destNodeCode,
806                  destTID, destNode, destProc, taskOffset);
807     }
808   }
809
810
811 //???
812   if (destNode>=0 && destNode == myNodeIndex) {
813     // slef
814   }
815   else {
816     // network
817   }
818 #endif
819 }
820                                                                                 
821 // message send to this node
822 // called by Switch or local node
823 void BGnode::recvIncomingMsg(TaskMsg *m)
824 { // this function should do ONE of the following:
825   // 1) send message to one worker thread on this node
826   // 2) send message to all worker threads on this node
827   // 3) send messages to all but one worker threads on this node
828   if (config.netsim_on) elapse(2*CPU_OVERHEAD);
829   CmiAssert(m->destNode == myNodeIndex);
830
831   int destNodeCode = m->destNodeCode;
832   int destTID = m->desttID;
833
834   TaskMsg *tm;
835   if ((destNodeCode >= 0) && (destTID >= 0)) { // case 1
836     int destNode = destNodeCode;
837     tm = new TaskMsg(m->taskID.srcNode, m->taskID.msgID,
838                      m->taskID.index, m->receiveTime,
839                      m->msgsize, destNode, destNodeCode, destTID);
840     int destProc = firstProcPID + destTID;
841     //    CkPrintf("[%d] incoming: executeTask call %d %d %d\n", destProc, m->taskID.srcNode, m->taskID.msgID, m->taskID.index); 
842     POSE_invoke(executeTask(tm), BGproc, destProc, 0);
843     //CkPrintf("[Incoming NODE: %d %d destProc:%d]\n", nodePID, myNodeIndex, destProc);
844     //parent->CommitPrintf("[Incoming NODE: %d %d destProc:%d]\n", nodePID, myNodeIndex, destProc);
845   }
846   else {        // case 2 and 3
847     int destProc = firstProcPID;
848     int destNodeExcept = -1;
849     if (destNodeCode < -1) destNodeExcept = -100 - destNodeCode;
850     CmiAssert(!(destNodeExcept == myNodeIndex && destTID == -1));
851     for (int j=0; j<procsPerNode; j++, destProc++) {
852       if (destTID != -1) 
853         if (myNodeIndex == destNodeExcept && j == destTID) continue;
854       tm = new TaskMsg(m->taskID.srcNode, m->taskID.msgID,
855                        m->taskID.index, m->receiveTime,
856                        m->msgsize, destNodeCode, destNodeCode, j);
857       //    CkPrintf("[%d] incoming: executeTask call %d %d %d\n", destProc, m->taskID.srcNode, m->taskID.msgID, m->taskID.index); 
858       POSE_invoke(executeTask(tm), BGproc, destProc, 0);
859       //CkPrintf("[Incoming NODE: %d %d bcast destNodeCode:%d destTID:%d destProc:%d]\n", nodePID, myNodeIndex, destNodeCode, destTID, destProc);
860       //parent->CommitPrintf("[Incoming NODE: %d %d bcast destNodeCode:%d destTID:%d destProc:%d]\n", nodePID, myNodeIndex, destNodeCode, destTID, destProc);
861       //myProc, myNode, destProc);
862     }
863   }
864 }
865
866 #define NUM_MSG 64
867 #define MSG_SIZE 16384
868 #define GAP 5
869
870 Transceiver::Transceiver(TransMsg *copyM)
871 {
872 id = copyM->id;
873 TransMsg *m;
874 m = new TransMsg;
875 POSE_local_invoke(sendMessage(m),0);
876 }
877
878 void Transceiver::sendMessage(TransMsg *copyM)
879 {
880 //  NodeMsg *m;
881   int i;
882
883   for(i=0;i<NUM_MSG;i++) {
884 /*  m  = new NodeMsg;
885   m->dstNode = (id+i+1)%num_nodes;
886   if(m->dstNode == id) continue;
887   m->msgId = i;
888   m->msgsize = MSG_SIZE;
889   m->orig_msglen = MSG_SIZE;
890   m->msgtype = ENVELOPE;
891   CkPrintf("%d %d I sent Message %d -> %d  msgid %d !!! \n",ovt,id,id,m->dstNode,m->msgId);
892   POSE_invoke(genMessages(m), Node, nodeStart+id, i*GAP);
893 */
894   }
895 }
896
897 void Transceiver::recvMessage(TransMsg *m)
898 {
899   CkPrintf("%d %d I received Message %d -> %d msgid %d !!! \n",ovt,id,m->origSrc,m->dstNode,m->msgId);
900 }