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