00001
00009 #include "ComlibManager.h"
00010 #include "ComlibSectionInfo.h"
00011 #ifdef __MINGW_H
00012 #include <malloc.h>
00013 #endif
00014
00015
00016 #define USE_CONTROL_POINTS 0
00017
00018 #if USE_CONTROL_POINTS
00019 #include "controlPoints.h"
00020 #endif
00021
00022 #if CMK_HAS_ALLOCA_H
00023 #include <alloca.h>
00024 #endif
00025
00026
00027
00031 ComlibMulticastMsg * ComlibSectionInfo::getNewMulticastMessage(CharmMessageHolder *cmsg, int needSort, int instanceID){
00032
00033
00034
00035 if(cmsg->sec_id == NULL || cmsg->sec_id->_nElems == 0)
00036 return NULL;
00037
00038 void *m = cmsg->getCharmMessage();
00039 envelope *env = UsrToEnv(m);
00040
00041
00042 initSectionID(cmsg->sec_id);
00043
00044 CkPackMessage(&env);
00045
00046 const CkArrayID destArrayID(env->getsetArrayMgr());
00047 int nRemotePes=-1, nRemoteIndices=-1;
00048 ComlibMulticastIndexCount *indicesCount;
00049 int *belongingList;
00050
00051
00052
00053 getPeCount(cmsg->sec_id->_nElems, cmsg->sec_id->_elems, destArrayID, nRemotePes, nRemoteIndices, indicesCount, belongingList);
00054
00055
00056
00057 #if 0
00058 CkPrintf("nRemotePes=%d\n", nRemotePes);
00059 CkPrintf("nRemoteIndices=%d\n",nRemoteIndices);
00060 CkPrintf("env->getTotalsize()=%d\n", env->getTotalsize());
00061 CkPrintf("cmsg->sec_id->_nElems=%d\n", cmsg->sec_id->_nElems);
00062 #endif
00063
00064 int sizes[3];
00065 sizes[0] = nRemotePes;
00066 sizes[1] = nRemoteIndices;
00067 sizes[2] = env->getTotalsize();
00068
00069 ComlibPrintf("Creating new comlib multicast message %d, %d %d\n", sizes[0], sizes[1], sizes[2]);
00070
00071 ComlibMulticastMsg *msg = new(sizes, 0) ComlibMulticastMsg;
00072 msg->nPes = nRemotePes;
00073 msg->_cookie.info.sInfo.cInfo.instId = instanceID;
00074 msg->_cookie.info.sInfo.cInfo.id = MaxSectionID - 1;
00075 msg->_cookie.info.sInfo.cInfo.status = COMLIB_MULTICAST_NEW_SECTION;
00076 msg->_cookie.get_type() = COMLIB_MULTICAST_MESSAGE;
00077 msg->_cookie.get_pe() = CkMyPe();
00078
00079
00080 memcpy(msg->indicesCount, indicesCount, sizes[0] * sizeof(ComlibMulticastIndexCount));
00081
00082
00083 CkArrayIndex **indicesPe = (CkArrayIndex**)alloca(nRemotePes * sizeof(CkArrayIndex*));
00084
00085 if (needSort) {
00086
00087
00088
00089 int previous, i, j;
00090 qsort(msg->indicesCount, sizes[0], sizeof(ComlibMulticastIndexCount), indexCountCompare);
00091
00092 for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[0].pe) break;
00093 indicesPe[j] = msg->indices;
00094 previous = j;
00095 for (i=1; i<nRemotePes; ++i) {
00096 for (j=0; j<nRemotePes; ++j) if (indicesCount[j].pe == msg->indicesCount[i].pe) break;
00097 indicesPe[j] = indicesPe[previous] + indicesCount[previous].count;
00098 previous = j;
00099 }
00100 } else {
00101 indicesPe[0] = msg->indices;
00102 for (int i=1; i<nRemotePes; ++i) indicesPe[i] = indicesPe[i-1] + indicesCount[i-1].count;
00103 }
00104
00105 for (int i=0; i<cmsg->sec_id->_nElems; ++i) {
00106 if (belongingList[i] >= 0) {
00107
00108 *indicesPe[belongingList[i]] = cmsg->sec_id->_elems[i];
00109 indicesPe[belongingList[i]]++;
00110 }
00111 }
00112 memcpy(msg->usrMsg, env, sizes[2] * sizeof(char));
00113 envelope *newenv = UsrToEnv(msg);
00114 delete [] indicesCount;
00115 delete [] belongingList;
00116
00117 newenv->getsetArrayMgr() = env->getsetArrayMgr();
00118 newenv->getsetArraySrcPe() = env->getsetArraySrcPe();
00119 newenv->getsetArrayEp() = env->getsetArrayEp();
00120 newenv->getsetArrayHops() = env->getsetArrayHops();
00121 newenv->getsetArrayIndex() = env->getsetArrayIndex();
00122
00123
00124 newenv->setEvent(env->getEvent());
00125 newenv->setSrcPe(env->getSrcPe());
00126
00127 return (ComlibMulticastMsg *)EnvToUsr(newenv);
00128 }
00129
00130 void ComlibSectionInfo::getPeList(envelope *cb_env, int npes, int *&pelist)
00131 {
00132 ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
00133 int i;
00134
00135 CkAssert(npes==ccmsg->nPes);
00136 for (i=0; i<ccmsg->nPes; ++i) {
00137 pelist[i]=ccmsg->indicesCount[i].pe;
00138 }
00139
00140 }
00141
00142
00143 void ComlibSectionInfo::unpack(envelope *cb_env,
00144 int &nLocalElems,
00145 CkArrayIndex *&dest_indices,
00146 envelope *&env) {
00147
00148 ComlibMulticastMsg *ccmsg = (ComlibMulticastMsg *)EnvToUsr(cb_env);
00149 int i;
00150
00151 dest_indices = ccmsg->indices;
00152 for (i=0; i<ccmsg->nPes; ++i) {
00153 if (ccmsg->indicesCount[i].pe == CkMyPe()) break;
00154 dest_indices += ccmsg->indicesCount[i].count;
00155 }
00156
00157 if(i >= ccmsg->nPes)
00158 {
00159 nLocalElems=0;
00160 dest_indices=NULL;
00161 }
00162 else
00163 {
00164 nLocalElems = ccmsg->indicesCount[i].count;
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 }
00185 envelope *usrenv = (envelope *) ccmsg->usrMsg;
00186 env = (envelope *)CmiAlloc(usrenv->getTotalsize());
00187 memcpy(env, usrenv, usrenv->getTotalsize());
00188 env->setEvent(cb_env->getEvent());
00189 }
00190
00191
00192 void ComlibSectionInfo::processOldSectionMessage(CharmMessageHolder *cmsg) {
00193
00194
00195 ComlibPrintf("Process Old Section Message \n");
00196
00197 int cur_sec_id = cmsg->sec_id->getSectionID();
00198
00199
00200 CkMcastBaseMsg *cbmsg = (CkMcastBaseMsg *)cmsg->getCharmMessage();
00201 cbmsg->_cookie.get_pe() = CkMyPe();
00202 cbmsg->_cookie.info.sInfo.cInfo.id = cur_sec_id;
00203 cbmsg->_cookie.info.sInfo.cInfo.status = COMLIB_MULTICAST_OLD_SECTION;
00204 }
00205
00206 CkMcastBaseMsg *ComlibSectionInfo::getNewDeliveryErrorMsg(CkMcastBaseMsg *base) {
00207 CkMcastBaseMsg *dest= (CkMcastBaseMsg*)CkAllocMsg(0, sizeof(CkMcastBaseMsg), 0);
00208 memcpy(dest, base, sizeof(CkMcastBaseMsg));
00209 dest->_cookie.info.sInfo.cInfo.status = COMLIB_MULTICAST_SECTION_ERROR;
00210 return dest;
00211 }
00212
00213 void ComlibSectionInfo::getPeList(int _nElems,
00214 CkArrayIndex *_elems,
00215 CkArrayID &destArrayID,
00216 int &npes, int *&pelist){
00217
00218 int length = CkNumPes();
00219 if(length > _nElems)
00220
00221
00222
00223 length = _nElems;
00224
00225 pelist = new int[length];
00226 npes = 0;
00227
00228 int count = 0, acount = 0;
00229
00230 CkArray *a = (CkArray *)_localBranch(destArrayID);
00231 for(acount = 0; acount < _nElems; acount++){
00232
00233
00234 int p = a->lastKnown(_elems[acount]);
00235
00236 if(p == -1) CkAbort("Invalid Section\n");
00237 for(count = 0; count < npes; count ++)
00238 if(pelist[count] == p)
00239 break;
00240
00241 if(count == npes) {
00242 pelist[npes ++] = p;
00243 }
00244 }
00245
00246 if(npes == 0) {
00247 delete [] pelist;
00248 pelist = NULL;
00249 }
00250 }
00251
00252
00253
00254 inline int getPErepresentingNodeContainingPE(int pe){
00255
00256 #if 1
00257 return pe;
00258
00259 #else
00260
00261 #if USE_CONTROL_POINTS
00262 std::vector<int> v;
00263 v.push_back(1);
00264 if(CkNumPes() >= 2)
00265 v.push_back(2);
00266 if(CkNumPes() >= 4)
00267 v.push_back(4);
00268 if(CkNumPes() >= 8)
00269 v.push_back(8);
00270 int pes_per_node = controlPoint("Number of PEs per Node", v);
00271 #else
00272 int pes_per_node = 1;
00273 #endif
00274
00275
00276 if(getenv("PE_PER_NODES") != NULL)
00277 pes_per_node = CkNumPes()/atoi(getenv("PE_PER_NODES"));
00278
00279 if( pes_per_node > 1 && pes_per_node <= CkNumPes() ){
00280 ComlibPrintf("NODE AWARE Sending a message to a representative of the node instead of its real owner\n");
00281 int newpe = pe - (pe % pes_per_node);
00282 return newpe;
00283 } else {
00284 return pe;
00285 }
00286 #endif
00287 }
00288
00297 void ComlibSectionInfo::getPeCount(int nindices, CkArrayIndex *idxlist,
00298 const CkArrayID &destArrayID, int &npes, int &nidx,
00299 ComlibMulticastIndexCount *&counts, int *&belongs) {
00300
00301 int i;
00302
00303 int length = CkNumPes();
00304
00305 if(length > nindices) length = nindices;
00306
00307 counts = new ComlibMulticastIndexCount[length];
00308 belongs = new int[nindices];
00309 npes = 0;
00310 nidx = 0;
00311
00312 CkArray *a = (CkArray *)_localBranch(destArrayID);
00313 for(i=0; i<nindices; ++i){
00314 int p = a->lastKnown(idxlist[i]);
00315
00316 #define USE_NODE_AWARE 0
00317 #if USE_NODE_AWARE
00318
00319 ComlibPrintf("NODE AWARE old p=%d\n", p);
00320
00321
00322
00323 ComlibPrintf("NODE AWARE new p=%d\n", p);
00324 #endif
00325
00326 if(p == -1) CkAbort("Invalid Section\n");
00327
00328 if(p == CkMyPe()) {
00329 belongs[i] = -1;
00330 continue;
00331 }
00332
00333
00334 int count = 0;
00335 for(count = 0; count < npes; count ++)
00336 if(counts[count].pe == p)
00337 break;
00338
00339 if(count == npes) {
00340 counts[npes].pe = p;
00341 counts[npes].count = 0;
00342 ++npes;
00343 }
00344
00345 ++nidx;
00346 counts[count].count++;
00347 belongs[i] = count;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357 }
00358
00359
00360 void ComlibSectionInfo::getRemotePelist(int nindices,
00361 CkArrayIndex *idxlist,
00362 CkArrayID &destArrayID,
00363 int &npes, int *&pelist) {
00364
00365 ComlibPrintf("ComlibSectionInfo::getRemotePelist()\n");
00366
00367 int count = 0, acount = 0;
00368
00369 int length = CkNumPes();
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 if(length > nindices)
00383 length = nindices;
00384
00385 pelist = new int[length+1];
00386 npes = 0;
00387
00388 CkArray *a = (CkArray *)_localBranch(destArrayID);
00389 for(acount = 0; acount < nindices; acount++){
00390
00391
00392 int p = a->lastKnown(idxlist[acount]);
00393 if(p == CkMyPe())
00394 continue;
00395
00396 if(p == -1) CkAbort("Invalid Section\n");
00397
00398
00399 for(count = 0; count < npes; count ++)
00400 if(pelist[count] == p)
00401 break;
00402
00403 if(count == npes) {
00404 pelist[npes ++] = p;
00405 }
00406 }
00407
00408 if(npes == 0) {
00409 delete [] pelist;
00410 pelist = NULL;
00411 }
00412 }
00413
00414
00415 void ComlibSectionInfo::getLocalIndices(int nindices,
00416 CkArrayIndex *idxlist,
00417 CkArrayID &destArrayID,
00418 CkVec<CkArrayIndex> &idx_vec){
00419 ComlibPrintf("ComlibSectionInfo::getLocalIndices()\n");
00420
00421 int acount = 0;
00422 idx_vec.resize(0);
00423
00424 CkArray *a = (CkArray *)_localBranch(destArrayID);
00425 for(acount = 0; acount < nindices; acount++){
00426
00427 int p = a->lastKnown(idxlist[acount]);
00428 if(p == CkMyPe())
00429 idx_vec.insertAtEnd(idxlist[acount]);
00430 }
00431 }
00432
00433
00434
00435 void ComlibSectionInfo::getNodeLocalIndices(int nindices,
00436 CkArrayIndex *idxlist,
00437 CkArrayID &destArrayID,
00438 CkVec<CkArrayIndex> &idx_vec){
00439 int acount = 0;
00440 idx_vec.resize(0);
00441
00442 CkArray *a = (CkArray *)_localBranch(destArrayID);
00443 for(acount = 0; acount < nindices; acount++){
00444
00445 int p = a->lastKnown(idxlist[acount]);
00446 if(p == CkMyPe())
00447 idx_vec.insertAtEnd(idxlist[acount]);
00448 }
00449 }
00450
00451