adds RectMulticastStrategy. Depends on BGML native layer on BG/L.
[charm.git] / src / ck-com / ComlibSectionInfo.C
1 #include "charm++.h" // for CMK_HAS_ALLOCA_H
2
3 #if CMK_HAS_ALLOCA_H
4 #include <alloca.h>
5 #endif
6
7 #include "ComlibManager.h"
8 #include "ComlibSectionInfo.h"
9
10 ComlibMulticastMsg * ComlibSectionInfo::getNewMulticastMessage(CharmMessageHolder *cmsg, int needSort){
11     
12     if(cmsg->sec_id == NULL || cmsg->sec_id->_nElems == 0)
13         return NULL;
14
15     void *m = cmsg->getCharmMessage();
16     envelope *env = UsrToEnv(m);
17         
18     if(cmsg->sec_id->_cookie.sInfo.cInfo.id != 0) 
19         CmiAbort("In correct section\n");
20
21     initSectionID(cmsg->sec_id);   
22
23     CkPackMessage(&env);
24     int nRemotePes, nRemoteIndices;
25     ComlibMulticastIndexCount *indicesCount;
26     int *belongingList;
27     getPeCount(cmsg->sec_id->_nElems, cmsg->sec_id->_elems, nRemotePes, nRemoteIndices, indicesCount, belongingList);
28     if (nRemotePes == 0) return NULL;
29
30     int sizes[3];
31     sizes[0] = nRemotePes;
32     sizes[1] = nRemoteIndices; // only those remote ///cmsg->sec_id->_nElems;
33     sizes[2] = env->getTotalsize();
34     
35     ComlibPrintf("Creating new comlib multicast message %d, %d %d\n", sizes[0], sizes[1], sizes[2]);
36     
37     ComlibMulticastMsg *msg = new(sizes, 0) ComlibMulticastMsg;
38     msg->nPes = nRemotePes;
39     msg->_cookie.sInfo.cInfo.instId = instanceID;
40     msg->_cookie.sInfo.cInfo.id = MaxSectionID - 1;
41     msg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_NEW_SECTION;
42     msg->_cookie.type = COMLIB_MULTICAST_MESSAGE;
43     msg->_cookie.pe = CkMyPe();
44
45     // fill in the three pointers of the ComlibMulticastMsg
46     memcpy(msg->indicesCount, indicesCount, sizes[0] * sizeof(ComlibMulticastIndexCount));
47     //memcpy(msg->indices, cmsg->sec_id->_elems, sizes[1] * sizeof(CkArrayIndexMax));
48
49     CkArrayIndexMax **indicesPe = (CkArrayIndexMax**)alloca(nRemotePes * sizeof(CkArrayIndexMax*));
50
51     if (needSort) {
52       // if we are sorting the array, then we need to fix the problem that belongingList
53       // refers to the original ordering! This is done by mapping indicesPe in a way coherent
54       // with the original ordering.
55       int previous, i, j;
56       qsort(msg->indicesCount, sizes[0], sizeof(ComlibMulticastIndexCount), indexCountCompare);
57
58       for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[0].pe) break;
59       indicesPe[j] = msg->indices;
60       previous = j;
61       for (i=1; i<nRemotePes; ++i) {
62         for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[i].pe) break;
63         indicesPe[j] = indicesPe[previous] + indicesCount[previous].count;
64         previous = j;
65       }
66     } else {
67       indicesPe[0] = msg->indices;
68       for (int i=1; i<nRemotePes; ++i) indicesPe[i] = indicesPe[i-1] + indicesCount[i-1].count;
69     }
70
71     for (int i=0; i<cmsg->sec_id->_nElems; ++i) {
72       if (belongingList[i] >= 0) {
73         *indicesPe[belongingList[i]] = cmsg->sec_id->_elems[i];
74         indicesPe[belongingList[i]]++;
75       }
76     }
77     memcpy(msg->usrMsg, env, sizes[2] * sizeof(char));
78     envelope *newenv = UsrToEnv(msg);
79     delete [] indicesCount;
80     delete [] belongingList;
81
82     newenv->getsetArrayMgr() = env->getsetArrayMgr();
83     newenv->getsetArraySrcPe() = env->getsetArraySrcPe();
84     newenv->getsetArrayEp() = env->getsetArrayEp();
85     newenv->getsetArrayHops() = env->getsetArrayHops();
86     newenv->getsetArrayIndex() = env->getsetArrayIndex();
87
88     // for trace projections
89     newenv->setEvent(env->getEvent());
90     newenv->setSrcPe(env->getSrcPe());
91     
92     CkPackMessage(&newenv);        
93     return (ComlibMulticastMsg *)EnvToUsr(newenv);
94 }
95
96 void ComlibSectionInfo::getPeList(envelope *cb_env, int npes, int *&pelist)
97 {
98     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
99     int i;
100     
101     CkAssert(npes==ccmsg->nPes);
102     for (i=0; i<ccmsg->nPes; ++i) {
103       pelist[i]=ccmsg->indicesCount[i].pe;
104     }
105
106 }
107
108
109 void ComlibSectionInfo::unpack(envelope *cb_env,
110                                int &nLocalElems,
111                                CkArrayIndexMax *&dest_indices, 
112                                envelope *&env) {
113         
114     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
115     int i;
116
117     dest_indices = ccmsg->indices;
118     for (i=0; i<ccmsg->nPes; ++i) {
119       if (ccmsg->indicesCount[i].pe == CkMyPe()) break;
120       dest_indices += ccmsg->indicesCount[i].count;
121     }
122
123     if(i >= ccmsg->nPes)
124       {  //cheap hack for rect bcast
125         nLocalElems=0;
126         dest_indices=NULL;
127       }
128     else
129       {
130         nLocalElems = ccmsg->indicesCount[i].count;
131
132         /*
133           CkPrintf("Unpacking: %d local elements:",nLocalElems);
134           for (int j=0; j<nLocalElems; ++j) CkPrintf(" %d",((int*)&dest_indices[j])[1]);
135           CkPrintf("\n");
136         */
137         /*
138           for(int count = 0; count < ccmsg->nIndices; count++){
139           CkArrayIndexMax idx = ccmsg->indices[count];
140         
141           //This will work because. lastknown always knows if I have the
142           //element of not
143           int dest_proc = ComlibGetLastKnown(destArrayID, idx);
144           //CkArrayID::CkLocalBranch(destArrayID)->lastKnown(idx);
145         
146           //        if(dest_proc == CkMyPe())
147           dest_indices.insertAtEnd(idx);                        
148           }
149         */
150       }
151     envelope *usrenv = (envelope *) ccmsg->usrMsg;
152     env = (envelope *)CmiAlloc(usrenv->getTotalsize());
153     memcpy(env, ccmsg->usrMsg, usrenv->getTotalsize());
154 }
155
156
157 void ComlibSectionInfo::processOldSectionMessage(CharmMessageHolder *cmsg) {
158
159     ComlibPrintf("Process Old Section Message \n");
160
161     int cur_sec_id = ComlibSectionInfo::getSectionID(*cmsg->sec_id);
162
163     //Old section id, send the id with the message
164     CkMcastBaseMsg *cbmsg = (CkMcastBaseMsg *)cmsg->getCharmMessage();
165     cbmsg->_cookie.sInfo.cInfo.id = cur_sec_id;
166     cbmsg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_OLD_SECTION;
167 }
168
169 void ComlibSectionInfo::getPeList(int _nElems, 
170                                   CkArrayIndexMax *_elems, 
171                                   int &npes, int *&pelist){
172     
173     int length = CkNumPes();
174     if(length > _nElems)    //There will not be more processors than
175                             //number of elements. This is wastage of
176                             //memory as there may be fewer
177                             //processors. Fix later.
178         length = _nElems;
179     
180     pelist = new int[length];
181     npes = 0;
182     
183     int count = 0, acount = 0;
184     
185     for(acount = 0; acount < _nElems; acount++){
186         
187         int p = ComlibGetLastKnown(destArrayID, _elems[acount]);
188         
189         if(p == -1) CkAbort("Invalid Section\n");        
190         for(count = 0; count < npes; count ++)
191             if(pelist[count] == p)
192                 break;
193         
194         if(count == npes) {
195             pelist[npes ++] = p;
196         }
197     }   
198
199     if(npes == 0) {
200         delete [] pelist;
201         pelist = NULL;
202     }
203 }
204
205
206 void ComlibSectionInfo::getPeCount(int nindices, CkArrayIndexMax *idxlist, 
207                       int &npes, int &nidx,
208                       ComlibMulticastIndexCount *&counts, int *&belongs) {
209   int count = 0;
210   int i;
211     
212   int length = CkNumPes();
213
214   if(length > nindices) length = nindices;
215     
216   counts = new ComlibMulticastIndexCount[length];
217   belongs = new int[nindices];
218   npes = 0;
219   nidx = 0;
220
221   for(i=0; i<nindices; ++i){
222     int p = ComlibGetLastKnown(destArrayID, idxlist[i]);
223     
224     if(p == -1) CkAbort("Invalid Section\n");        
225
226     //Collect processors
227     for(count = 0; count < npes; count ++)
228       if(counts[count].pe == p)
229         break;
230     
231     if(count == npes) {
232       counts[npes].pe = p;
233       counts[npes].count = 0;
234       ++npes;
235     }
236
237     if(p == CkMyPe()) {
238       belongs[i] = -1;
239       continue;
240     }
241
242     ++nidx;
243     counts[count].count++;
244     belongs[i] = count;
245   }
246   //CkPrintf("section has %d procs\n",npes);
247
248   if(npes == 0) {
249     delete [] counts;
250     delete [] belongs;
251     counts = NULL;
252     belongs = NULL;
253   }
254 }
255
256
257 void ComlibSectionInfo::getRemotePelist(int nindices, 
258                                         CkArrayIndexMax *idxlist, 
259                                         int &npes, int *&pelist) {
260
261     int count = 0, acount = 0;
262     
263     int length = CkNumPes();
264
265     // HACK FOR DEBUGGING
266     /*pelist = new int[length-1];
267     npes = length-1;
268     for (acount=0; acount<length; acount++) {
269       if (acount == CkMyPe()) continue;
270       pelist[count]=acount;
271       count++;
272     }
273     return;*/
274     // END HACK
275
276     if(length > nindices)
277         length = nindices;
278     
279     pelist = new int[length+1];
280     npes = 0;
281
282     for(acount = 0; acount < nindices; acount++){
283         
284         int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
285         if(p == CkMyPe())
286             continue;
287         
288         if(p == -1) CkAbort("Invalid Section\n");        
289         
290         //Collect remote processors
291         for(count = 0; count < npes; count ++)
292             if(pelist[count] == p)
293                 break;
294         
295         if(count == npes) {
296             pelist[npes ++] = p;
297         }
298     }
299     
300     if(npes == 0) {
301         delete [] pelist;
302         pelist = NULL;
303     }
304 }
305
306
307 void ComlibSectionInfo::getLocalIndices(int nindices, 
308                                         CkArrayIndexMax *idxlist, 
309                                         CkVec<CkArrayIndexMax> &idx_vec){    
310     int count = 0, acount = 0;
311     idx_vec.resize(0);
312     
313     for(acount = 0; acount < nindices; acount++){
314         int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
315         if(p == CkMyPe()) 
316             idx_vec.insertAtEnd(idxlist[acount]);
317     }
318 }
319
320
321 void ComlibSectionInfo::localMulticast(envelope *env){
322     ComlibArrayInfo::localMulticast(&localDestIndexVec, env);
323 }