The new version of comlib! This version passed "make test" in charm/tests on order...
[charm.git] / src / ck-com / ComlibSectionInfo.C
1 /**
2    @addtogroup CharmComlib
3    @{ 
4    @file
5   
6    Implementations of classes defined in ComlibSectionInfo.h
7 */
8
9 #include "ComlibManager.h"
10 #include "ComlibSectionInfo.h"
11 #ifdef __MINGW_H 
12 #include <malloc.h> 
13 #endif
14
15
16 #define USE_CONTROL_POINTS 0
17
18 #if USE_CONTROL_POINTS
19 #include "controlPoints.h"
20 #endif
21
22 #if CMK_HAS_ALLOCA_H
23 #include <alloca.h>
24 #endif
25
26
27
28 /// Create a new multicast message
29 ComlibMulticastMsg * ComlibSectionInfo::getNewMulticastMessage(CharmMessageHolder *cmsg, int needSort, int instanceID){
30     
31   cmsg->checkme();
32
33     if(cmsg->sec_id == NULL || cmsg->sec_id->_nElems == 0)
34         return NULL;
35
36     void *m = cmsg->getCharmMessage();
37     envelope *env = UsrToEnv(m);
38         
39     // Crate a unique identifier for section id in cmsg->sec_id
40     initSectionID(cmsg->sec_id);   
41
42     CkPackMessage(&env);
43
44     const CkArrayID destArrayID(env->getsetArrayMgr());
45     int nRemotePes, nRemoteIndices;
46     ComlibMulticastIndexCount *indicesCount;
47     int *belongingList;
48     getPeCount(cmsg->sec_id->_nElems, cmsg->sec_id->_elems, destArrayID, nRemotePes, nRemoteIndices, indicesCount, belongingList);
49
50     //     if (nRemotePes == 0) return NULL;
51
52 #if 0
53     CkPrintf("nRemotePes=%d\n", nRemotePes);
54     CkPrintf("nRemoteIndices=%d\n",nRemoteIndices);
55     CkPrintf("env->getTotalsize()=%d\n", env->getTotalsize());
56     CkPrintf("cmsg->sec_id->_nElems=%d\n", cmsg->sec_id->_nElems);
57  #endif
58
59     int sizes[3];
60     sizes[0] = nRemotePes;
61     sizes[1] = nRemoteIndices; // only those remote ///cmsg->sec_id->_nElems;
62     sizes[2] = env->getTotalsize();
63     
64     ComlibPrintf("Creating new comlib multicast message %d, %d %d\n", sizes[0], sizes[1], sizes[2]);
65     
66     ComlibMulticastMsg *msg = new(sizes, 0) ComlibMulticastMsg;
67     msg->nPes = nRemotePes;
68     msg->_cookie.sInfo.cInfo.instId = instanceID;
69     msg->_cookie.sInfo.cInfo.id = MaxSectionID - 1;
70     msg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_NEW_SECTION;
71     msg->_cookie.type = COMLIB_MULTICAST_MESSAGE;
72     msg->_cookie.pe = CkMyPe();
73
74     // fill in the three pointers of the ComlibMulticastMsg
75     memcpy(msg->indicesCount, indicesCount, sizes[0] * sizeof(ComlibMulticastIndexCount));
76     //memcpy(msg->indices, cmsg->sec_id->_elems, sizes[1] * sizeof(CkArrayIndexMax));
77
78     CkArrayIndexMax **indicesPe = (CkArrayIndexMax**)alloca(nRemotePes * sizeof(CkArrayIndexMax*));
79
80     if (needSort) {
81         // if we are sorting the array, then we need to fix the problem that belongingList
82         // refers to the original ordering! This is done by mapping indicesPe in a way coherent
83         // with the original ordering.
84         int previous, i, j;
85         qsort(msg->indicesCount, sizes[0], sizeof(ComlibMulticastIndexCount), indexCountCompare);
86
87         for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[0].pe) break;
88         indicesPe[j] = msg->indices;
89         previous = j;
90         for (i=1; i<nRemotePes; ++i) {
91                 for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[i].pe) break;
92                 indicesPe[j] = indicesPe[previous] + indicesCount[previous].count;
93                 previous = j;
94         }
95     } else {
96         indicesPe[0] = msg->indices;
97         for (int i=1; i<nRemotePes; ++i) indicesPe[i] = indicesPe[i-1] + indicesCount[i-1].count;
98     }
99
100     for (int i=0; i<cmsg->sec_id->_nElems; ++i) {
101         if (belongingList[i] >= 0) {
102                 *indicesPe[belongingList[i]] = cmsg->sec_id->_elems[i];
103                 indicesPe[belongingList[i]]++;
104         }
105     }
106     memcpy(msg->usrMsg, env, sizes[2] * sizeof(char));
107     envelope *newenv = UsrToEnv(msg);
108     delete [] indicesCount;
109     delete [] belongingList;
110
111     newenv->getsetArrayMgr() = env->getsetArrayMgr();
112     newenv->getsetArraySrcPe() = env->getsetArraySrcPe();
113     newenv->getsetArrayEp() = env->getsetArrayEp();
114     newenv->getsetArrayHops() = env->getsetArrayHops();
115     newenv->getsetArrayIndex() = env->getsetArrayIndex();
116
117     // for trace projections
118     newenv->setEvent(env->getEvent());
119     newenv->setSrcPe(env->getSrcPe());
120     
121     return (ComlibMulticastMsg *)EnvToUsr(newenv);
122 }
123
124 void ComlibSectionInfo::getPeList(envelope *cb_env, int npes, int *&pelist)
125 {
126     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
127     int i;
128     
129     CkAssert(npes==ccmsg->nPes);
130     for (i=0; i<ccmsg->nPes; ++i) {
131       pelist[i]=ccmsg->indicesCount[i].pe;
132     }
133
134 }
135
136
137 void ComlibSectionInfo::unpack(envelope *cb_env,
138                                int &nLocalElems,
139                                CkArrayIndexMax *&dest_indices, 
140                                envelope *&env) {
141         
142     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
143     int i;
144
145     dest_indices = ccmsg->indices;
146     for (i=0; i<ccmsg->nPes; ++i) {
147       if (ccmsg->indicesCount[i].pe == CkMyPe()) break;
148       dest_indices += ccmsg->indicesCount[i].count;
149     }
150
151     if(i >= ccmsg->nPes)
152       {  //cheap hack for rect bcast
153         nLocalElems=0;
154         dest_indices=NULL;
155       }
156     else
157       {
158     nLocalElems = ccmsg->indicesCount[i].count;
159
160     /*
161     ComlibPrintf("Unpacking: %d local elements:",nLocalElems);
162     for (int j=0; j<nLocalElems; ++j) ComlibPrintf(" %d",((int*)&dest_indices[j])[1]);
163     ComlibPrintf("\n");
164     */
165     /*
166     for(int count = 0; count < ccmsg->nIndices; count++){
167         CkArrayIndexMax idx = ccmsg->indices[count];
168         
169         //This will work because. lastknown always knows if I have the
170         //element of not
171         int dest_proc = ComlibGetLastKnown(destArrayID, idx);
172         //CkArrayID::CkLocalBranch(destArrayID)->lastKnown(idx);
173         
174         //        if(dest_proc == CkMyPe())
175         dest_indices.insertAtEnd(idx);                        
176     }
177     */
178       }
179     envelope *usrenv = (envelope *) ccmsg->usrMsg;
180     env = (envelope *)CmiAlloc(usrenv->getTotalsize());
181     memcpy(env, ccmsg->usrMsg, usrenv->getTotalsize());
182 }
183
184
185 void ComlibSectionInfo::processOldSectionMessage(CharmMessageHolder *cmsg) {
186   cmsg->checkme();
187
188     ComlibPrintf("Process Old Section Message \n");
189
190     int cur_sec_id = cmsg->sec_id->getSectionID();
191
192     //Old section id, send the id with the message
193     CkMcastBaseMsg *cbmsg = (CkMcastBaseMsg *)cmsg->getCharmMessage();
194     cbmsg->_cookie.sInfo.cInfo.id = cur_sec_id;
195     cbmsg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_OLD_SECTION;
196 }
197
198 CkMcastBaseMsg *ComlibSectionInfo::getNewDeliveryErrorMsg(CkMcastBaseMsg *base) {
199   CkMcastBaseMsg *dest= (CkMcastBaseMsg*)CkAllocMsg(0, sizeof(CkMcastBaseMsg), 0);
200   memcpy(dest, base, sizeof(CkMcastBaseMsg));
201   dest->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_SECTION_ERROR;
202   return dest;
203 }
204
205 void ComlibSectionInfo::getPeList(int _nElems, 
206                                   CkArrayIndexMax *_elems,
207                                   CkArrayID &destArrayID,
208                                   int &npes, int *&pelist){
209
210     int length = CkNumPes();
211     if(length > _nElems)    //There will not be more processors than
212                             //number of elements. This is wastage of
213                             //memory as there may be fewer
214                             //processors. Fix later.
215         length = _nElems;
216     
217     pelist = new int[length];
218     npes = 0;
219     
220     int count = 0, acount = 0;
221     
222     CkArray *a = (CkArray *)_localBranch(destArrayID);
223     for(acount = 0; acount < _nElems; acount++){
224         
225       //int p = ComlibGetLastKnown(destArrayID, _elems[acount]);
226         int p = a->lastKnown(_elems[acount]);
227         
228         if(p == -1) CkAbort("Invalid Section\n");        
229         for(count = 0; count < npes; count ++)
230             if(pelist[count] == p)
231                 break;
232         
233         if(count == npes) {
234           pelist[npes ++] = p;
235         }
236     }   
237     
238     if(npes == 0) {
239       delete [] pelist;
240       pelist = NULL;
241     }
242 }
243
244
245
246 inline int getPErepresentingNodeContainingPE(int pe){
247
248 #if 1
249     return pe;
250
251 #else
252
253 #if USE_CONTROL_POINTS
254   std::vector<int> v;
255   v.push_back(1);
256   if(CkNumPes() >= 2)
257     v.push_back(2);
258   if(CkNumPes() >= 4)
259     v.push_back(4);
260   if(CkNumPes() >= 8)
261     v.push_back(8);
262   int pes_per_node = controlPoint("Number of PEs per Node", v);
263 #else
264   int pes_per_node = 1;
265 #endif
266
267
268     if(getenv("PE_PER_NODES") != NULL)
269         pes_per_node = CkNumPes()/atoi(getenv("PE_PER_NODES"));
270             
271     if( pes_per_node > 1 && pes_per_node <= CkNumPes() ){
272         ComlibPrintf("NODE AWARE Sending a message to a representative of the node instead of its real owner\n");
273         int newpe = pe - (pe % pes_per_node);
274         return newpe;
275     } else {
276         return pe;
277     }
278 #endif    
279 }
280
281
282 void ComlibSectionInfo::getPeCount(int nindices, CkArrayIndexMax *idxlist, 
283                       const CkArrayID &destArrayID, int &npes, int &nidx,
284                       ComlibMulticastIndexCount *&counts, int *&belongs) {
285
286   int count = 0;
287   int i;
288     
289   int length = CkNumPes();
290
291   if(length > nindices) length = nindices;
292     
293   counts = new ComlibMulticastIndexCount[length];
294   belongs = new int[nindices];
295   npes = 0;
296   nidx = 0;
297
298   CkArray *a = (CkArray *)_localBranch(destArrayID);
299   for(i=0; i<nindices; ++i){
300     //int p = ComlibGetLastKnown(destArrayID, idxlist[i]);
301     int p = a->lastKnown(idxlist[i]);
302
303
304 #define USE_NODE_AWARE 1
305 #if USE_NODE_AWARE
306 #warning "USING NODE AWARE SECTION INFOs"
307     ComlibPrintf("NODE AWARE old p=%d\n", p);
308   
309     // p = getPErepresentingNodeContainingPE(p);
310     
311     ComlibPrintf("NODE AWARE new p=%d\n", p);
312 #endif
313     
314     if(p == -1) CkAbort("Invalid Section\n");        
315
316     if(p == CkMyPe()) {
317       belongs[i] = -1;
318       continue;
319     }
320
321     //Collect processors
322     for(count = 0; count < npes; count ++)
323       if(counts[count].pe == p)
324         break;
325     
326     if(count == npes) {
327       counts[npes].pe = p;
328       counts[npes].count = 0;
329       ++npes;
330     }
331
332     ++nidx;
333     counts[count].count++;
334     belongs[i] = count;
335   }
336   //ComlibPrintf("section has %d procs\n",npes);
337
338 //   if(npes == 0) {
339 //     delete [] counts;
340 //     delete [] belongs;
341 //     counts = NULL;
342 //     belongs = NULL;
343 //   }
344 }
345
346
347 void ComlibSectionInfo::getRemotePelist(int nindices, 
348                                         CkArrayIndexMax *idxlist,
349                                         CkArrayID &destArrayID,
350                                         int &npes, int *&pelist) {
351
352         ComlibPrintf("ComlibSectionInfo::getRemotePelist()\n");
353         
354     int count = 0, acount = 0;
355     
356     int length = CkNumPes();
357
358     // HACK FOR DEBUGGING
359     /*pelist = new int[length-1];
360     npes = length-1;
361     for (acount=0; acount<length; acount++) {
362       if (acount == CkMyPe()) continue;
363       pelist[count]=acount;
364       count++;
365     }
366     return;*/
367     // END HACK
368
369     if(length > nindices)
370         length = nindices;
371     
372     pelist = new int[length+1];
373     npes = 0;
374
375     CkArray *a = (CkArray *)_localBranch(destArrayID);
376     for(acount = 0; acount < nindices; acount++){
377         
378       //int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
379       int p = a->lastKnown(idxlist[acount]);
380       if(p == CkMyPe())
381             continue;
382         
383         if(p == -1) CkAbort("Invalid Section\n");        
384         
385         //Collect remote processors
386         for(count = 0; count < npes; count ++)
387             if(pelist[count] == p)
388                 break;
389         
390         if(count == npes) {
391             pelist[npes ++] = p;
392         }
393     }
394     
395     if(npes == 0) {
396         delete [] pelist;
397         pelist = NULL;
398     }
399 }
400
401
402 void ComlibSectionInfo::getLocalIndices(int nindices,
403                                         CkArrayIndexMax *idxlist,
404                                         CkArrayID &destArrayID,
405                                         CkVec<CkArrayIndexMax> &idx_vec){    
406         ComlibPrintf("ComlibSectionInfo::getLocalIndices()\n");
407         
408         int count = 0, acount = 0;
409     idx_vec.resize(0);
410     
411     CkArray *a = (CkArray *)_localBranch(destArrayID);
412     for(acount = 0; acount < nindices; acount++){
413         //int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
414         int p = a->lastKnown(idxlist[acount]);
415         if(p == CkMyPe()) 
416             idx_vec.insertAtEnd(idxlist[acount]);
417     }
418 }
419
420
421
422 void ComlibSectionInfo::getNodeLocalIndices(int nindices,
423                                         CkArrayIndexMax *idxlist,
424                                         CkArrayID &destArrayID,
425                                         CkVec<CkArrayIndexMax> &idx_vec){    
426     int count = 0, acount = 0;
427     idx_vec.resize(0);
428     
429     CkArray *a = (CkArray *)_localBranch(destArrayID);
430     for(acount = 0; acount < nindices; acount++){
431         //int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
432         int p = a->lastKnown(idxlist[acount]);
433         if(p == CkMyPe()) 
434             idx_vec.insertAtEnd(idxlist[acount]);
435     }
436 }
437
438