b253b05c0628cd04afd0d0c5b1e5e7165f3c7e57
[charm.git] / src / ck-core / ckarray.C
1 #include "charm++.h"
2 #include "register.h"
3 #include "CkArray.def.h"
4
5 void *
6 ArrayMigrateMessage::alloc(int msgnum,int size,int *array,int priobits)
7 {
8   int totalsize;
9   totalsize = size + array[0]*sizeof(char) + 8;
10   // CkPrintf("Allocating %d %d %d\n",msgnum,totalsize,priobits);
11   ArrayMigrateMessage *newMsg = (ArrayMigrateMessage *)
12     CkAllocMsg(msgnum,totalsize,priobits);
13   // CkPrintf("Allocated %d\n",newMsg);
14   newMsg->elementData = (char *)newMsg + ALIGN8(size);
15   return (void *) newMsg;
16 }
17   
18 void *
19 ArrayMigrateMessage::pack(ArrayMigrateMessage* in)
20 {
21   /*
22   CkPrintf("%d:Packing %d %d %d\n",CkMyPe(),in->from,in->index,in->elementSize);
23   */
24   in->elementData = (void*)((char*)in->elementData-(char *)&(in->elementData));
25   return (void*) in;
26 }
27
28 ArrayMigrateMessage* 
29 ArrayMigrateMessage::unpack(void *in)
30 {
31   ArrayMigrateMessage *me = new (in) ArrayMigrateMessage;
32   /*
33   CkPrintf("PE %d Unpacking me=%d from=%d index=%d elementSize=%d\n",
34     CkMyPe(),me,me->from,me->index,me->elementSize);
35   */
36   me->elementData = (char *)&(me->elementData) + (size_t)me->elementData;
37   return me;
38 }
39
40 CkGroupID Array1D::CreateArray(int numElements,
41                                ChareIndexType mapChare,
42                                EntryIndexType mapConstructor,
43                                ChareIndexType elementChare,
44                                EntryIndexType elementConstructor,
45                                EntryIndexType elementMigrator)
46 {
47   int group;
48
49   ArrayCreateMessage *msg = new ArrayCreateMessage;
50
51   msg->numElements = numElements;
52   msg->mapChareType = mapChare;
53   msg->mapConstType = mapConstructor;
54   msg->elementChareType = elementChare;
55   msg->elementConstType = elementConstructor;
56   msg->elementMigrateType = elementMigrator;
57   group = CProxy_Array1D::ckNew(msg);
58
59   return group;
60 }
61
62 Array1D::Array1D(ArrayCreateMessage *msg)
63 {
64   numElements = msg->numElements;
65   elementChareType = msg->elementChareType;
66   elementConstType = msg->elementConstType;
67   elementMigrateType = msg->elementMigrateType;
68
69   if (CkMyPe()==0) {
70     ArrayMapCreateMessage *mapMsg = new ArrayMapCreateMessage;
71     mapMsg->numElements = numElements;
72     mapMsg->arrayID = thishandle;
73     mapMsg->groupID = thisgroup;
74     CkCreateGroup(msg->mapChareType,msg->mapConstType,mapMsg,-1,0);
75   }
76   /*
77   CkPrintf("Array1D constructed\n");
78   */
79   delete msg;
80 }
81
82 void Array1D::RecvMapID(ArrayMap *mPtr, CkChareID mHandle,
83                         CkGroupID mGroup)
84 {
85   map = mPtr;
86   mapHandle = mHandle;
87   mapGroup = mGroup;
88
89   elementIDs = new ElementIDs[numElements];
90   elementIDsReported = 0;
91   numLocalElements=0;
92   int i;
93   for(i=0; i < numElements; i++)
94   {
95     elementIDs[i].originalPE = elementIDs[i].pe = map->procNum(i);
96     elementIDs[i].curHop = 0;
97     if (elementIDs[i].pe != CkMyPe())
98     {
99       elementIDs[i].state = at;
100       elementIDs[i].element = NULL;
101     }
102     else
103     {
104       elementIDs[i].state = creating;
105       numLocalElements++;
106
107       CkChareID vid;
108       ArrayElementCreateMessage *msg = new ArrayElementCreateMessage;
109       
110       msg->numElements = numElements;
111       msg->arrayID = thishandle;
112       msg->groupID = thisgroup;
113       msg->arrayPtr = this;
114       msg->index = i;
115       CkCreateChare(elementChareType, elementConstType, msg, &vid, CkMyPe());
116     }
117   }
118 }
119
120 void Array1D::RecvElementID(int index, ArrayElement *elem, CkChareID handle)
121 {
122   elementIDs[index].state = here;
123   elementIDs[index].element = elem;
124   elementIDs[index].elementHandle = handle;
125   elementIDsReported++;
126
127   /*
128   if (elementIDsReported == numLocalElements)
129     CkPrintf("PE %d all elements reported in\n",CkMyPe());
130   */
131 }
132
133 static int serial_num = 0;
134
135 void Array1D::send(ArrayMessage *msg, int index, EntryIndexType ei)
136 {
137   msg->destIndex = index;
138   msg->entryIndex = ei;
139   msg->hopCount = 0;
140   msg->serial_num = 1000*serial_num+CkMyPe();
141   serial_num++;
142
143   if (elementIDs[index].state == here) {
144 #if 0
145     CPrintf("PE %d sending local message to index %d\n",CMyPe(),index);
146 #endif
147     CProxy_Array1D arr(thisgroup);
148     arr.RecvForElement(msg, CkMyPe());
149   } else if (elementIDs[index].state == moving_to) {
150     // CkPrintf("PE %d sending message to migrating index %d on PE %d\n",
151       // CkMyPe(),index,elementIDs[index].pe);
152     CProxy_Array1D arr(thisgroup);
153     arr.RecvForElement(msg, elementIDs[index].pe);
154   } else if (elementIDs[index].state == arriving) {
155     // CkPrintf("PE %d sending message for index %d to myself\n",
156       // CkMyPe(),index);
157     CProxy_Array1D arr(thisgroup);
158     arr.RecvForElement(msg, CkMyPe());
159  } else if (elementIDs[index].state == at) {
160 #if 0
161     CPrintf("PE %d AT message to index %d on original PE %d\n",
162             CMyPe(),elementIDs[index].state,index,
163             elementIDs[index].pe);
164 #endif
165     CProxy_Array1D arr(thisgroup);
166     arr.RecvForElement(msg, elementIDs[index].pe);
167  } else {
168     // CkPrintf("PE %d sending message to index %d on original PE %d\n",
169       // CkMyPe(),index,elementIDs[index].originalPE);
170     CProxy_Array1D arr(thisgroup);
171     arr.RecvForElement(msg, elementIDs[index].originalPE);
172   }
173 }
174
175 void Array1D::broadcast(ArrayMessage *msg, EntryIndexType ei)
176 {
177   CkPrintf("Broadcast not implemented\n");
178 }
179
180 void Array1D::RecvForElement(ArrayMessage *msg)
181 {
182   /*
183   CkPrintf("PE %d RecvForElement sending to index %d\n",CkMyPe(),msg->destIndex);
184   */
185   msg->hopCount++;
186   if (elementIDs[msg->destIndex].state == here) {
187     // CkPrintf("PE %d DELIVERING index %d RecvForElement state %d\n",
188     // CkMyPe(),msg->destIndex,elementIDs[msg->destIndex].state);
189     // CkSendMsg(msg->entryIndex,msg,&elementIDs[msg->destIndex].elementHandle);
190     //    register int epIdx = env->getEpIdx();
191     register int epIdx = msg->entryIndex;
192     //    register void *obj = env->getObjPtr();
193     CkChareID handle = elementIDs[msg->destIndex].elementHandle;
194     register void *obj = handle.objPtr;
195     _entryTable[epIdx]->call(msg, obj);
196
197     //    EP_STRUCT *epinfo = CsvAccess(EpInfoTable)+msg->entryIndex;
198     //    CHARE_BLOCK *chareblock = GetID_chareBlockPtr(handle);
199     //    void *current_usr = msg;
200     //USER_MSG_PTR(env);
201     //    callep(epinfo->function,msg,chareblock->chareptr);
202  } else if (elementIDs[msg->destIndex].state == at) {
203     // CkPrintf("PE %d Sending to SELF index %d RecvForElement state %d\n",
204       // CkMyPe(),msg->destIndex,elementIDs[msg->destIndex].state);
205     CProxy_Array1D arr(thisgroup);
206     arr.RecvForElement(msg, elementIDs[msg->destIndex].pe);
207   } else {
208     // CkPrintf("PE %d Sending to SELF index %d RecvForElement state %d\n",
209       // CkMyPe(),msg->destIndex,elementIDs[msg->destIndex].state);
210     CProxy_Array1D arr(thisgroup);
211     arr.RecvForElement(msg, elementIDs[msg->destIndex].originalPE);
212   }
213 }
214
215 void Array1D::migrateMe(int index, int where)
216 {
217   int bufSize = elementIDs[index].element->packsize();
218
219   ArrayMigrateMessage *msg = new (&bufSize, 0) ArrayMigrateMessage;
220
221   msg->index = index;
222   msg->from = CkMyPe();
223   msg->elementSize = bufSize;
224   msg->hopCount = elementIDs[index].curHop + 1;
225   elementIDs[index].element->pack(msg->elementData);
226   elementIDs[index].state = moving_to;
227   elementIDs[index].pe = where;
228   numLocalElements--;
229   CProxy_Array1D arr(thisgroup);
230   arr.RecvMigratedElement(msg, where);
231 }
232
233 void Array1D::RecvMigratedElement(ArrayMigrateMessage *msg)
234 {
235   CkChareID vid;
236   
237   int index =msg->index;
238
239   elementIDs[index].state = arriving;
240   elementIDs[index].pe = CkMyPe();
241   elementIDs[index].curHop = msg->hopCount;
242   elementIDs[index].cameFrom = msg->from;
243   elementIDs[index].migrateMsg = msg;
244
245   ArrayElementMigrateMessage *new_msg = new ArrayElementMigrateMessage;
246
247   new_msg->index = index;
248   new_msg->numElements = numElements;
249   new_msg->arrayID = thishandle;
250   new_msg->groupID = thisgroup;
251   new_msg->arrayPtr = this;
252   new_msg->packData = msg->elementData;
253   
254   CkCreateChare(elementChareType, elementMigrateType, new_msg, 0, CkMyPe());
255 }
256
257 void Array1D::RecvMigratedElementID(int index, ArrayElement *elem,
258                                     CkChareID handle)
259 {
260   // CkPrintf("PE %d index %d receiving migrated element handle %d\n",
261     // CkMyPe(),index,handle);
262   elementIDs[index].state = here;
263   elementIDs[index].element = elem;
264   elementIDs[index].elementHandle = handle;
265   delete elementIDs[index].migrateMsg;
266   elementIDs[index].migrateMsg = NULL;
267
268   ArrayElementAckMessage *ack_msg = new ArrayElementAckMessage;
269
270   ack_msg->hopCount = elementIDs[index].curHop;
271   ack_msg->index = index;
272   ack_msg->arrivedAt = elementIDs[index].pe;
273   ack_msg->handle = elementIDs[index].elementHandle;
274   ack_msg->deleteElement = 1;
275
276   CProxy_Array1D arr(thisgroup);
277   arr.AckMigratedElement(ack_msg, elementIDs[index].cameFrom);
278   
279   if (elementIDs[index].cameFrom != elementIDs[index].originalPE) {
280     ack_msg = new ArrayElementAckMessage;
281
282     ack_msg->hopCount = elementIDs[index].curHop;
283     ack_msg->index = index;
284     ack_msg->arrivedAt = elementIDs[index].pe;
285     ack_msg->handle = elementIDs[index].elementHandle;
286     ack_msg->deleteElement = 0;
287
288     arr.AckMigratedElement(ack_msg, elementIDs[index].originalPE);
289   }
290   numLocalElements++;
291 }
292
293 void Array1D::AckMigratedElement(ArrayElementAckMessage *msg)
294 {
295   int index = msg->index;
296
297   // CkPrintf("PE %d Message acknowledged hop=%d curHop=%d\n",
298     // CkMyPe(),msg->hopCount,elementIDs[index].curHop);
299
300   if (msg->hopCount > elementIDs[index].curHop) {
301     if (msg->deleteElement) {
302       ArrayElementExitMessage *exitmsg = new ArrayElementExitMessage;
303       // CkPrintf("I want to delete the element %d\n",index);
304       CProxy_ArrayElement elem(elementIDs[index].elementHandle);
305       elem.exit(exitmsg);
306     }
307     elementIDs[index].pe = msg->arrivedAt;
308     elementIDs[index].state = at;
309     elementIDs[index].elementHandle = msg->handle;
310   } else if (msg->hopCount <= elementIDs[index].curHop) {
311     // CkPrintf("PE %d STALE Message acknowledged hop=%d curHop=%d\n",
312       // CkMyPe(),msg->hopCount,elementIDs[index].curHop);
313     
314   }
315   delete msg;
316 }
317
318
319 ArrayElement::ArrayElement(ArrayElementCreateMessage *msg)
320 {
321   numElements = msg->numElements;
322   arrayChareID = msg->arrayID;
323   arrayGroupID = msg->groupID;
324   thisArray = msg->arrayPtr;
325   thisAID.setAid(thisArray->ckGetGroupId());
326   thisAID._elem = (-1);
327   thisIndex = msg->index;
328 }
329
330 ArrayElement::ArrayElement(ArrayElementMigrateMessage *msg)
331 {
332   numElements = msg->numElements;
333   arrayChareID = msg->arrayID;
334   arrayGroupID = msg->groupID;
335   thisArray = msg->arrayPtr;
336   thisAID.setAid(thisArray->ckGetGroupId());
337   thisAID._elem = (-1);
338   thisIndex = msg->index;
339 }
340
341 void ArrayElement::finishConstruction(void)
342 {
343   thisArray->RecvElementID(thisIndex, this, thishandle);
344 }
345
346 void ArrayElement::finishMigration(void)
347 {
348   // CkPrintf("Finish Migration registering %d,%d\n",thisIndex,thishandle);
349   thisArray->RecvMigratedElementID(thisIndex, this, thishandle);
350 }
351
352 void ArrayElement::migrate(int where)
353 {
354   // CkPrintf("Migrating element %d to %d\n",thisIndex,where);
355   if (where != CkMyPe())
356     thisArray->migrateMe(thisIndex,where);
357 /*
358   else 
359     CkPrintf("PE %d I won't migrating element %d to myself\n", where,thisIndex);
360 */
361 }
362
363 void ArrayElement::exit(ArrayElementExitMessage *msg)
364 {
365   delete msg;
366   // CkPrintf("ArrayElement::exit exiting %d\n",thisIndex);
367   delete this;
368 }
369
370 ArrayMap::ArrayMap(ArrayMapCreateMessage *msg)
371 {
372   // CkPrintf("PE %d creating ArrayMap\n",CkMyPe());
373   arrayChareID = msg->arrayID;
374   arrayGroupID = msg->groupID;
375   array = CProxy_Array1D::ckLocalBranch(arrayGroupID);
376   numElements = msg->numElements;
377
378   delete msg;
379 }
380
381 void ArrayMap::finishConstruction(void)
382 {
383   array->RecvMapID(this, thishandle, thisgroup);
384 }
385
386 RRMap::RRMap(ArrayMapCreateMessage *msg) : ArrayMap(msg)
387 {
388   // CkPrintf("PE %d creating RRMap for %d elements\n",CkMyPe(),numElements);
389
390   finishConstruction();
391 }
392
393 RRMap::~RRMap()
394 {
395   // CkPrintf("Bye from RRMap\n");
396 }
397
398 int RRMap::procNum(int element)
399 {
400   return ((element+1) % CkNumPes());
401 }