added CMK_HAS_ALLOCA_H flag before including alloca.h
[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::unpack(envelope *cb_env,
97                                int &nLocalElems,
98                                CkArrayIndexMax *&dest_indices, 
99                                envelope *&env) {
100         
101     ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
102     int i;
103
104     dest_indices = ccmsg->indices;
105     for (i=0; i<ccmsg->nPes; ++i) {
106       if (ccmsg->indicesCount[i].pe == CkMyPe()) break;
107       dest_indices += ccmsg->indicesCount[i].count;
108     }
109
110     CkAssert(i < ccmsg->nPes);
111     nLocalElems = ccmsg->indicesCount[i].count;
112
113     /*
114     CkPrintf("Unpacking: %d local elements:",nLocalElems);
115     for (int j=0; j<nLocalElems; ++j) CkPrintf(" %d",((int*)&dest_indices[j])[1]);
116     CkPrintf("\n");
117     */
118     /*
119     for(int count = 0; count < ccmsg->nIndices; count++){
120         CkArrayIndexMax idx = ccmsg->indices[count];
121         
122         //This will work because. lastknown always knows if I have the
123         //element of not
124         int dest_proc = ComlibGetLastKnown(destArrayID, idx);
125         //CkArrayID::CkLocalBranch(destArrayID)->lastKnown(idx);
126         
127         //        if(dest_proc == CkMyPe())
128         dest_indices.insertAtEnd(idx);                        
129     }
130     */
131
132     envelope *usrenv = (envelope *) ccmsg->usrMsg;
133     env = (envelope *)CmiAlloc(usrenv->getTotalsize());
134     memcpy(env, ccmsg->usrMsg, usrenv->getTotalsize());
135 }
136
137
138 void ComlibSectionInfo::processOldSectionMessage(CharmMessageHolder *cmsg) {
139
140     ComlibPrintf("Process Old Section Message \n");
141
142     int cur_sec_id = ComlibSectionInfo::getSectionID(*cmsg->sec_id);
143
144     //Old section id, send the id with the message
145     CkMcastBaseMsg *cbmsg = (CkMcastBaseMsg *)cmsg->getCharmMessage();
146     cbmsg->_cookie.sInfo.cInfo.id = cur_sec_id;
147     cbmsg->_cookie.sInfo.cInfo.status = COMLIB_MULTICAST_OLD_SECTION;
148 }
149
150 void ComlibSectionInfo::getPeList(int _nElems, 
151                                   CkArrayIndexMax *_elems, 
152                                   int &npes, int *&pelist){
153     
154     int length = CkNumPes();
155     if(length > _nElems)    //There will not be more processors than
156                             //number of elements. This is wastage of
157                             //memory as there may be fewer
158                             //processors. Fix later.
159         length = _nElems;
160     
161     pelist = new int[length];
162     npes = 0;
163     
164     int count = 0, acount = 0;
165     
166     for(acount = 0; acount < _nElems; acount++){
167         
168         int p = ComlibGetLastKnown(destArrayID, _elems[acount]);
169         
170         if(p == -1) CkAbort("Invalid Section\n");        
171         for(count = 0; count < npes; count ++)
172             if(pelist[count] == p)
173                 break;
174         
175         if(count == npes) {
176             pelist[npes ++] = p;
177         }
178     }   
179
180     if(npes == 0) {
181         delete [] pelist;
182         pelist = NULL;
183     }
184 }
185
186
187 void ComlibSectionInfo::getPeCount(int nindices, CkArrayIndexMax *idxlist, 
188                       int &npes, int &nidx,
189                       ComlibMulticastIndexCount *&counts, int *&belongs) {
190   int count = 0;
191   int i;
192     
193   int length = CkNumPes();
194
195   if(length > nindices) length = nindices;
196     
197   counts = new ComlibMulticastIndexCount[length];
198   belongs = new int[nindices];
199   npes = 0;
200   nidx = 0;
201
202   for(i=0; i<nindices; ++i){
203     int p = ComlibGetLastKnown(destArrayID, idxlist[i]);
204     
205     if(p == -1) CkAbort("Invalid Section\n");        
206
207     //Collect processors
208     for(count = 0; count < npes; count ++)
209       if(counts[count].pe == p)
210         break;
211     
212     if(count == npes) {
213       counts[npes].pe = p;
214       counts[npes].count = 0;
215       ++npes;
216     }
217
218     if(p == CkMyPe()) {
219       belongs[i] = -1;
220       continue;
221     }
222
223     ++nidx;
224     counts[count].count++;
225     belongs[i] = count;
226   }
227   //CkPrintf("section has %d procs\n",npes);
228
229   if(npes == 0) {
230     delete [] counts;
231     delete [] belongs;
232     counts = NULL;
233     belongs = NULL;
234   }
235 }
236
237
238 void ComlibSectionInfo::getRemotePelist(int nindices, 
239                                         CkArrayIndexMax *idxlist, 
240                                         int &npes, int *&pelist) {
241
242     int count = 0, acount = 0;
243     
244     int length = CkNumPes();
245
246     // HACK FOR DEBUGGING
247     /*pelist = new int[length-1];
248     npes = length-1;
249     for (acount=0; acount<length; acount++) {
250       if (acount == CkMyPe()) continue;
251       pelist[count]=acount;
252       count++;
253     }
254     return;*/
255     // END HACK
256
257     if(length > nindices)
258         length = nindices;
259     
260     pelist = new int[length+1];
261     npes = 0;
262
263     for(acount = 0; acount < nindices; acount++){
264         
265         int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
266         if(p == CkMyPe())
267             continue;
268         
269         if(p == -1) CkAbort("Invalid Section\n");        
270         
271         //Collect remote processors
272         for(count = 0; count < npes; count ++)
273             if(pelist[count] == p)
274                 break;
275         
276         if(count == npes) {
277             pelist[npes ++] = p;
278         }
279     }
280     
281     if(npes == 0) {
282         delete [] pelist;
283         pelist = NULL;
284     }
285 }
286
287
288 void ComlibSectionInfo::getLocalIndices(int nindices, 
289                                         CkArrayIndexMax *idxlist, 
290                                         CkVec<CkArrayIndexMax> &idx_vec){    
291     int count = 0, acount = 0;
292     idx_vec.resize(0);
293     
294     for(acount = 0; acount < nindices; acount++){
295         int p = ComlibGetLastKnown(destArrayID, idxlist[acount]);
296         if(p == CkMyPe()) 
297             idx_vec.insertAtEnd(idxlist[acount]);
298     }
299 }
300
301
302 void ComlibSectionInfo::localMulticast(envelope *env){
303     ComlibArrayInfo::localMulticast(&localDestIndexVec, env);
304 }