Merge branch 'charm' of charmgit:charm into charm
[charm.git] / examples / pose / ASIM / Worker.C
1 #include <math.h>
2
3 worker::worker(WorkerData *m)
4 {
5   int i;
6   numObjs = m->numObjs;
7   numMsgs = m->numMsgs;
8   msgSize = m->msgSize;
9   distribution = m->distribution;
10   connectivity = m->connectivity;
11   locality = m->locality;
12   grainSize = m->grainSize;
13   elapsePattern = m->elapsePattern;
14   offsetPattern = m->offsetPattern;
15   sendPattern = m->sendPattern;
16   granularity = m->granularity;
17   for (i=0; i<100; i++) data[i] = 0;
18   for (i=0; i<5; i++) {
19     elapseTimes[i] = m->elapseTimes[i];
20     numSends[i] = m->numSends[i];
21     offsets[i] = m->offsets[i];
22   } 
23   numNbrs = m->numNbrs;
24   for (i=0; i<numNbrs; i++) neighbors[i] = m->neighbors[i];
25   delete m;
26   elapseIdx = sendIdx = nbrIdx = offsetIdx = msgIdx = gsIdx = 0;
27   SmallWorkMsg *sm = new SmallWorkMsg;
28   memset(sm->data, 0, SM_MSG_SZ*sizeof(int));
29   //CkPrintf("Worker %d created on PE %d. Sending message to self...\n", parent->thisIndex, CkMyPe());
30   POSE_invoke(workSmall(sm), worker, parent->thisIndex, 0);
31 }
32
33 worker::worker()
34 {
35   elapseIdx = sendIdx = nbrIdx = offsetIdx = msgIdx = gsIdx = 0;
36 }
37
38 worker& worker::operator=(const worker& obj)
39 {
40   int i;
41   rep::operator=(obj);
42   numObjs = obj.numObjs;
43   numMsgs = obj.numMsgs;
44   msgSize = obj.msgSize;
45   distribution = obj.distribution;
46   connectivity = obj.connectivity;
47   locality = obj.locality;
48   grainSize = obj.grainSize;
49   elapsePattern = obj.elapsePattern;
50   offsetPattern = obj.offsetPattern;
51   sendPattern = obj.sendPattern;
52   granularity = obj.granularity;
53   for (i=0; i<100; i++) data[i] = obj.data[i];
54   for (i=0; i<5; i++) {
55     elapseTimes[i] = obj.elapseTimes[i];
56     numSends[i] = obj.numSends[i];
57     offsets[i] = obj.offsets[i];
58   }
59   for (i=0; i<100; i++) neighbors[i] = obj.neighbors[i];
60   numNbrs = obj.numNbrs;
61   elapseIdx = obj.elapseIdx;
62   sendIdx = obj.sendIdx;
63   nbrIdx = obj.nbrIdx;
64   offsetIdx = obj.offsetIdx;
65   msgIdx = obj.msgIdx;
66   gsIdx = obj.gsIdx;
67   return *this;
68 }
69
70
71 void worker::workSmall(SmallWorkMsg *m)
72 {
73   //CkPrintf("%d receiving small work at %d\n", parent->thisIndex, ovt);
74   doWork();
75 }
76
77 void worker::workSmall_anti(SmallWorkMsg *m)
78 {
79   restore(this);
80 }
81
82 void worker::workSmall_commit(SmallWorkMsg *m)
83 {
84 }
85
86 void worker::workMedium(MediumWorkMsg *m)
87 {
88   //CkPrintf("%d receiving medium work at %d\n", parent->thisIndex, ovt);
89   doWork();
90 }
91
92 void worker::workMedium_anti(MediumWorkMsg *m)
93 {
94   restore(this);
95 }
96
97 void worker::workMedium_commit(MediumWorkMsg *m)
98 {
99 }
100
101 void worker::workLarge(LargeWorkMsg *m)
102 {
103   //CkPrintf("%d receiving large work at %d\n", parent->thisIndex, ovt);
104   doWork();
105 }
106
107 void worker::workLarge_anti(LargeWorkMsg *m)
108 {
109   restore(this);
110 }
111
112 void worker::workLarge_commit(LargeWorkMsg *m)
113 {
114 }
115
116 void worker::doWork()
117 {
118   SmallWorkMsg *sm;
119   MediumWorkMsg *mm;
120   LargeWorkMsg *lm;
121
122   if ((POSE_endtime > -1) && (OVT() > POSE_endtime))  return;
123
124   // do some computation based on gsIdx
125   if (granularity > 0.0) POSE_busy_wait(granularity);
126   else if (grainSize == FINE) POSE_busy_wait(FINE_GRAIN);
127   else if (grainSize == MEDIUM_GS) POSE_busy_wait(MEDIUM_GRAIN);
128   else if (grainSize == COARSE) POSE_busy_wait(COARSE_GRAIN);
129   else if (grainSize == MIX_GS) {
130     if (gsIdx == FINE) POSE_busy_wait(FINE_GRAIN);
131     else if (gsIdx == MEDIUM_GS) POSE_busy_wait(MEDIUM_GRAIN);
132     else if (gsIdx == COARSE) POSE_busy_wait(COARSE_GRAIN);
133     gsIdx = (gsIdx + 1) % 3;
134   }
135
136   // elapse some time
137   elapse(elapseTimes[elapseIdx]);
138   elapseIdx = (elapseIdx + 1) % 5;
139
140   // generate some events
141   int actualMsgSize = msgSize;
142   for (int i=0; i<numSends[sendIdx]; i++) {
143     if (msgSize == MIX_MS) {
144       actualMsgSize = msgIdx+1;
145       msgIdx = (msgIdx + 1) % 3;
146     }
147     
148     if (actualMsgSize == SMALL) {
149       sm = new SmallWorkMsg;
150       memset(sm->data, 0, SM_MSG_SZ*sizeof(int));
151       //CkPrintf("%d sending small work to %d at %d + %d\n", parent->thisIndex,
152       //       neighbors[nbrIdx], ovt, offsets[offsetIdx]);
153       POSE_invoke(workSmall(sm), worker, neighbors[nbrIdx], offsets[offsetIdx]);
154     }
155     else if (actualMsgSize == MEDIUM) {
156       mm = new MediumWorkMsg;
157       memset(mm->data, 0, MD_MSG_SZ*sizeof(int));
158       //CkPrintf("%d sending medium work to %d at %d + %d\n", parent->thisIndex, 
159       //       neighbors[nbrIdx], ovt, offsets[offsetIdx]);
160       POSE_invoke(workMedium(mm), worker, neighbors[nbrIdx], offsets[offsetIdx]);
161     }
162     else if (actualMsgSize == LARGE) {
163       lm = new LargeWorkMsg;
164       memset(lm->data, 0, LG_MSG_SZ*sizeof(int));
165       //CkPrintf("%d sending large work to %d at %d + %d\n", parent->thisIndex,
166       //       neighbors[nbrIdx], ovt, offsets[offsetIdx]);
167       POSE_invoke(workLarge(lm), worker, neighbors[nbrIdx], offsets[offsetIdx]);
168     }
169     nbrIdx = (nbrIdx + 1) % numNbrs;
170     offsetIdx = (offsetIdx + 1) % 5;
171   }
172   sendIdx = (sendIdx + 1) % 5;
173 }
174