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