PaCO++
0.05
|
00001 #include "BasicBC.h" 00002 #include <iostream> 00003 00004 #define SRC_TOPOLOGY 1 00005 #define DST_TOPOLOGY 2 00006 #define ELEMENT_SIZE 4 00007 #define TOTAL_SIZE 8 00008 #define DISTRIBUTION_TYPE 16 00009 00010 #undef DEBUG_INTERNAL 00011 #undef DEBUG_INTERNAL2 00012 00014 00015 // Compute the owner of a bloc accoring a cyclic distribution 00016 static inline unsigned OwnerBloc(const unsigned bid, const unsigned nbprocs) { 00017 return bid % nbprocs; 00018 } 00019 00021 00022 // Compute the id of a proc owning an element 00023 inline static unsigned getProcRangeInf(unsigned low, unsigned bsz) { 00024 return low / bsz; // first remote node 00025 } 00026 00027 // Compue the id of the proc owning the previous element 00028 inline static unsigned getProcRangeSup(unsigned high, unsigned bsz) { 00029 return (high-1) / bsz; // last remote node 00030 } 00031 00033 00034 // Compute the number of bloc a given processor owns accoring to a cyclic distribution 00035 static inline unsigned NumberOfBlocProc(const unsigned glen, const unsigned nbprocs, 00036 const unsigned bsz, const unsigned rank) { 00037 unsigned nbbloc = (glen + bsz - 1 ) / bsz; 00038 return (nbbloc / nbprocs) + (rank < (nbbloc % nbprocs ) ) ; 00039 } 00040 00042 00043 // Compute the number of element of a given bloc (local bloc pos) 00044 // on a proc of given rank according to a cyclic distribution 00045 static inline unsigned BlocNumberOfElementProc(const unsigned glen, const unsigned rank, 00046 const unsigned nbprocs, const unsigned bsz, 00047 const unsigned pos) { 00048 00049 unsigned long low = ( pos * nbprocs + rank ) * bsz; 00050 unsigned long end = low + bsz; 00051 unsigned long high = (glen < end ? glen : end); 00052 00053 return ( high - low ); 00054 00055 } 00056 00058 00059 // compute the global low bounds of local bloc number pos 00060 static inline unsigned computeBlocBoundInf(const unsigned bsz, const unsigned rank, 00061 const unsigned nbprocs, const unsigned pos) { 00062 return ( pos * nbprocs + rank) * bsz; 00063 } 00064 00066 00067 // Compute the global bounds (low & high) of a given bloc (local bloc pos) 00068 // on a proc of given rank according to a cyclic distribution 00069 static inline void computeBlocBounds(unsigned long *low, unsigned long *high, 00070 const unsigned glen, const unsigned rank, 00071 const unsigned nbprocs, const unsigned bsz, 00072 const unsigned pos) { 00073 unsigned long start = (pos * nbprocs + rank) * bsz; 00074 unsigned long end = start + bsz; 00075 *low = start; 00076 *high = ((glen <= end)?glen:end); // min 00077 } 00078 00080 00081 // Compute the number of element own by the processor of rank rank 00082 static inline unsigned TotalNumberOfElementProc(const unsigned glen, const unsigned rank, 00083 const unsigned nbprocs, const unsigned bsz) { 00084 00085 unsigned nbblocfull = NumberOfBlocProc(glen, nbprocs, bsz, rank) - 1; 00086 // Is the last full ? 00087 unsigned long low = ( nbblocfull * nbprocs + rank ) * bsz; 00088 unsigned long end = low + bsz; 00089 unsigned long high = (glen < end ? glen : end); 00090 00091 return nbblocfull * bsz + ( high - low ); 00092 } 00093 00095 00096 // Compute the size in octet of a bloc according to the given parameter 00097 // 00098 static inline unsigned blocSize(const unsigned glen, const unsigned nbprocs, 00099 const BasicBC_param_t& param) { 00100 switch(param.type) 00101 { 00102 case BASICBC_BLOC: 00103 { 00104 unsigned nbbloc = (glen + param.unitsize - 1) / param.unitsize; 00105 return ((nbbloc + nbprocs - 1 ) / nbprocs) * param.unitsize; 00106 } 00107 case BASICBC_CYCLIC: return param.unitsize; break; 00108 case BASICBC_BLOCCYCLIC: return param.blocsize*param.unitsize; break; 00109 } 00110 return 0; 00111 } 00112 00116 00117 BasicBC::BasicBC() 00118 { 00119 // Common 00120 _config = 0; 00121 00122 // By default 1->1 :) 00123 _sTopo.total=1; 00124 _dTopo.total=1; 00125 _param.type = BASICBC_BLOC; 00126 _nodeRank=0; 00127 00128 // Client side 00129 _clientBuffer=NULL; 00130 _descr_to_be_cleaned=true; 00131 00132 this->internalSetComId(-1); // set anonymous & init iterator, infolists & _cur_id 00133 00134 // Server side 00135 _serverDescr=NULL; 00136 _serverBuffer=NULL; 00137 } 00138 00139 BasicBC::~BasicBC() 00140 { 00141 for(info_list_map_t::iterator it=_info_list_map.begin(); it!=_info_list_map.end(); ++it) 00142 this->internalFreeComId(it); 00143 _info_list_map.clear(); 00144 } 00145 00146 void 00147 BasicBC::setSourceTopology(PaCO::PacoTopology_t topo) 00148 { 00149 #ifdef DEBUG_INTERNAL 00150 std::cerr << "-- setSourceTopology: " << topo.total << std::endl; 00151 #endif 00152 _config |= SRC_TOPOLOGY; 00153 _sTopo = topo; 00154 } 00155 00156 PaCO::PacoTopology_t 00157 BasicBC::getSourceTopology() 00158 { 00159 std::cerr << "****** Why is the method " << __FUNCTION__ << "called?\n"; 00160 abort(); 00161 return _sTopo; 00162 } 00163 00164 void 00165 BasicBC::setDestTopology(PaCO::PacoTopology_t topo) 00166 { 00167 #ifdef DEBUG_INTERNAL 00168 std::cerr << "-- setDestTopology: " << topo.total << std::endl; 00169 #endif 00170 _config |= DST_TOPOLOGY; 00171 00172 if ( _dTopo.total == topo.total ) return ; // Nothing change !!!! 00173 00174 // Delete old entries wrt to old state 00175 info_list_map_t::iterator it = _info_list_map.find(_cur_id); 00176 this->internalFreeComId(it); 00177 _info_list_map.erase(it); 00178 00179 // Change the state of the object 00180 _dTopo = topo; 00181 00182 // Set new entries 00183 this->internalSetComId(_cur_id); 00184 00185 // BUG: MUST ALSO DELETE ALL ENTRIES IN _info_list_map 00186 00187 } 00188 00189 PaCO::PacoTopology_t 00190 BasicBC::getDestTopology() 00191 { 00192 std::cerr << "****** Why is the method " << __FUNCTION__ << "called?\n"; 00193 abort(); 00194 return _dTopo; 00195 } 00196 00197 void 00198 BasicBC::setNodeRank(long Rank) 00199 { 00200 #ifdef DEBUG_INTERNAL 00201 std::cerr << "-- setNodeRank: " << Rank << std::endl; 00202 #endif 00203 _nodeRank = Rank; 00204 } 00205 00206 long 00207 BasicBC::getNodeRank() 00208 { 00209 return _nodeRank; 00210 } 00211 00212 void 00213 BasicBC::setBlocSize(unsigned long size) 00214 { 00215 #ifdef DEBUG_INTERNAL 00216 std::cerr << "-- setBlocSize: " << size << std::endl; 00217 #endif 00218 _config |= DISTRIBUTION_TYPE; 00219 switch(size) { 00220 case 0: 00221 #ifdef DEBUG_INTERNAL 00222 cout << "Selecting a BLOC distribution\n"; 00223 #endif 00224 _param.type = BASICBC_BLOC; 00225 _clientDescr.bsz = 0; 00226 break; 00227 case 1: 00228 #ifdef DEBUG_INTERNAL 00229 cout << "Selecting a CYCLIC distribution\n"; 00230 #endif 00231 _param.type = BASICBC_CYCLIC; 00232 _clientDescr.bsz = 1; 00233 break; 00234 default: 00235 #ifdef DEBUG_INTERNAL 00236 cout << "Selecting a BLOCCYCLIC with bsz= " << size << " \n"; 00237 #endif 00238 _param.type = BASICBC_BLOCCYCLIC; 00239 _clientDescr.bsz = _param.blocsize = size; 00240 } 00241 } 00242 00243 void 00244 BasicBC::setEltSize(unsigned long size) 00245 { 00246 #ifdef DEBUG_INTERNAL 00247 std::cerr << "-- setEltSize: " << size << std::endl; 00248 #endif 00249 _config |= ELEMENT_SIZE; 00250 _param.unitsize = size; 00251 } 00252 00253 void 00254 BasicBC::setTotalNbElt(unsigned long elt_nb) 00255 { 00256 #ifdef DEBUG_INTERNAL 00257 std::cerr << "-- setTotalNbElt: " << elt_nb << std::endl; 00258 #endif 00259 _config |= TOTAL_SIZE; 00260 _clientDescr.glen = _glen = elt_nb; 00261 } 00262 00263 00264 PieceToSend* 00265 BasicBC::computePiecesToSend(unsigned& size_out) 00266 { 00267 /* 00268 * store src/dst/sz/start 00269 * 00270 * where start is a local offset to apply to the vector 00271 * 00272 */ 00273 00274 PieceToSend * sched; 00275 unsigned long golen = _glen*_param.unitsize; 00276 00277 // We need to compute _lstart and _llen 00278 _sbsz = blocSize( golen, _sTopo.total, _param); 00279 _lstart = _nodeRank*_sbsz; 00280 _lstart = (_lstart < golen ? _lstart:golen); 00281 _llen = TotalNumberOfElementProc(golen, _nodeRank, _sTopo.total, _sbsz); 00282 00283 #ifdef DEBUG_INTERNAL 00284 // std::cerr << "In computePiecesToSend-------------------- all in octet !\n"; 00285 00286 fprintf(stderr, "-- stopo: %ld\tdtopo: %ld\n", _sTopo.total, _dTopo.total); 00287 fprintf(stderr, "-- golen: %ld\ttype: %d\tsd.start %d\tllen: %d\n", golen, 00288 _param.type, _lstart, _llen); 00289 #endif 00290 00291 if (_sTopo.total == _dTopo.total) { 00292 #ifdef DEBUG_INTERNAL 00293 fprintf(stderr, "-- easy: n<->n case !\n"); 00294 #endif 00295 size_out = 1; 00296 sched = new PieceToSend[1]; 00297 sched[0].sourceNode = _nodeRank; // my self :) 00298 sched[0].destNode = _nodeRank; // the corresponding node 00299 sched[0].size = _llen; // msg size 00300 00301 info_t* inf = new info_t(); 00302 00303 inf->gstart = _lstart/_param.unitsize; // used start as id -> same at server side 00304 inf->lstart = 0; // do not apply any offset to local ptr 00305 inf->msg_size = _llen; 00306 inf->sent_size = 0; 00307 00308 // add inf to the list 00309 _infolists[_nodeRank]->push_back(inf); 00310 // sched points to the list 00311 sched[0].id = (void*) _infolists[_nodeRank]; 00312 00313 #ifdef DEBUG_INTERNAL 00314 fprintf(stderr, "-- %2d -> %2d : gstart:%2u lstart:%2u len:%2d\n", 00315 sched[0].sourceNode, sched[0].destNode, inf->gstart, inf->lstart, inf->msg_size); 00316 #endif 00317 00318 } else { 00319 if (_param.type == BASICBC_BLOC ) { 00320 // that's a standard bloc redistribution 00321 #ifdef DEBUG_INTERNAL 00322 fprintf(stderr, "-- medium: n<->m bloc redistribution case !\n"); 00323 #endif 00324 00325 unsigned long slow; 00326 unsigned long shigh; 00327 computeBlocBounds(&slow, &shigh, golen, _nodeRank, _sTopo.total, _sbsz, 0); 00328 00329 #ifdef DEBUG_INTERNAL 00330 std::cerr << "-- sbsz: "<<_sbsz<<" sbounds: "<<slow<<" - "<<shigh<<endl; 00331 #endif 00332 00333 unsigned dbsz = blocSize(golen, _dTopo.total, _param); 00334 00335 #ifdef DEBUG_INTERNAL 00336 std::cerr << "-- dbsz: "<<dbsz<<endl; 00337 #endif 00338 00339 unsigned fpid, lpid; 00340 fpid = getProcRangeInf(slow, dbsz); 00341 lpid = getProcRangeSup(shigh, dbsz); 00342 00343 #ifdef DEBUG_INTERNAL 00344 fprintf(stderr, "-- loop from %d to %d width dtotal: %ld\n", fpid, lpid, _dTopo.total); 00345 #endif 00346 00347 // for each dest bloc 00348 size_out = lpid-fpid+1; 00349 sched = new PieceToSend[size_out]; 00350 for(unsigned i=fpid; i <= lpid; i++) { 00351 PieceToSend& s = sched[i-fpid]; 00352 s.sourceNode = _nodeRank; 00353 s.destNode = i; 00354 00355 info_t* inf = new info_t(); 00356 00357 unsigned tmp = i*dbsz; 00358 unsigned tmp2; 00359 tmp2 = ( slow >= tmp)?slow:tmp; // max : global offset in octet as ID 00360 inf->gstart = tmp2 / _param.unitsize; 00361 inf->lstart = tmp2 - _lstart; 00362 00363 tmp += dbsz; 00364 unsigned end = ( shigh <= tmp)?shigh:tmp; // min 00365 00366 inf->msg_size = s.size = end - tmp2; 00367 inf->sent_size = 0; 00368 00369 // add inf to the list 00370 _infolists[i-fpid]->push_back(inf); 00371 // sched points to the list 00372 s.id = (void*) _infolists[i-fpid]; 00373 00374 #ifdef DEBUG_INTERNAL 00375 fprintf(stderr, "-- %2d -> %2d : gstart:%2u lstart:%2u len:%2d\n", 00376 s.sourceNode, s.destNode, inf->gstart, inf->lstart, inf->msg_size); 00377 #endif 00378 } 00379 } else { 00380 // it is a bloccyclic distribution 00381 00382 #ifdef DEBUG_INTERNAL 00383 fprintf(stderr, "-- hard: n<->m bloccyclic redistribution case !\n"); 00384 #endif 00385 00386 unsigned stbsz = _sbsz * _sTopo.total; 00387 unsigned nbbloc = NumberOfBlocProc(golen, _sTopo.total, _sbsz, _nodeRank); 00388 00389 #ifdef DEBUG_INTERNAL 00390 std::cerr << "-- sbsz: "<<_sbsz<<" nbbloc: "<<nbbloc<<endl; 00391 #endif 00392 00393 // for each src bloc, find a dst node 00394 // But only one struct for each dst -> pre-count 00395 00396 // should be equal to the number of real dest ! 00397 size_out = 0; 00398 unsigned *tmp_dnb = (unsigned*) calloc(_dTopo.total, sizeof(unsigned)); // zeroed array 00399 PieceToSend **tmp_dor = (PieceToSend**) calloc(_dTopo.total, sizeof(PieceToSend*)); // zeroed array 00400 for(unsigned b=0; b<nbbloc; b++) { 00401 unsigned gb = b * _sTopo.total + _nodeRank; // global bloc id 00402 unsigned drank = OwnerBloc(gb, _dTopo.total); 00403 if (tmp_dnb[drank]++ == 0) // detect if it is the 1st time 00404 size_out++; 00405 } 00406 // Allocating output 00407 sched = new PieceToSend[size_out]; 00408 unsigned cur=0; 00409 for(unsigned i=0; i<_dTopo.total; i++) { 00410 sched[cur].sourceNode = _nodeRank; 00411 sched[cur].destNode = i; 00412 sched[cur].size = 0; 00413 sched[cur].id = (void*) _infolists[i]; 00414 tmp_dor[i] = &sched[cur]; // an index if valid only if tmp_dnb[index]>0 !!!! 00415 cur+= (tmp_dnb[i]>0?1:0); // increment order only if this dest is not zero 00416 } 00417 00418 #ifdef DEBUG_INTERNAL 00419 cerr << "-- size_out: "<<size_out<<endl; 00420 #endif 00421 00422 for(unsigned b=0; b<nbbloc; b++) { 00423 unsigned gb = b * _sTopo.total + _nodeRank; // global bloc id 00424 unsigned drank = OwnerBloc(gb, _dTopo.total); 00425 00426 PieceToSend* s = tmp_dor[drank]; 00427 00428 // Allocate new element 00429 info_t* inf = new info_t(); 00430 00431 inf->gstart = ((stbsz*b) + (_nodeRank*_sbsz))/ _param.unitsize; 00432 inf->lstart = b * _sbsz; 00433 inf->msg_size = BlocNumberOfElementProc(golen, _nodeRank, _sTopo.total, _sbsz, b); 00434 inf->sent_size = 0; 00435 00436 // Accumulate msg length in PieceToSend 00437 s->size += inf->msg_size; 00438 00439 // insert it in the list 00440 info_list_t* ilsp = (info_list_t*) s->id; // pointer to a list 00441 ilsp->push_back(inf); 00442 00443 00444 #ifdef DEBUG_INTERNAL 00445 fprintf(stderr, "-- %2d -> %2d : gstart:%2u lstart:%2u len:%2d\n", 00446 s->sourceNode, s->destNode, inf->gstart, inf->lstart, inf->msg_size); 00447 #endif 00448 } 00449 } 00450 } 00451 00452 #ifdef DEBUG_INTERNAL 00453 // std::cerr << "computePiecesToSend-------------------- done\n"; 00454 #endif 00455 00456 return sched; 00457 } 00458 00459 void 00460 BasicBC::setDataPtr(void* dataPtr) 00461 { 00462 _clientBuffer = (char *) dataPtr; 00463 #ifdef DEBUG_INTERNAL 00464 cerr << "-- _clientBuffer set to "<<dataPtr<<endl; 00465 #endif 00466 } 00467 00468 void * 00469 BasicBC::getClientData(void *pid, int dnode, long & remaining_size_octet, long & returned_length_element, bool & end) 00470 { 00471 info_list_t* ilsp = (info_list_t*) pid; 00472 00473 #ifdef DEBUG_INTERNAL2 00474 std::cerr << "-- getClientData : _clientBuffer=" << (void*) _clientBuffer << std::endl; 00475 std::cerr << "-- getClientData : " << dnode << " " << remaining_size_octet << std::endl; 00476 #endif 00477 00478 if (_descr_to_be_cleaned) { 00479 _descr_to_be_cleaned = false; 00480 _clientDescr.ids.length(0); 00481 } 00482 00483 // look for 1st one not "empty" 00484 long rst_data=0; 00485 info_list_t::const_iterator ci; 00486 for(ci=ilsp->begin(); ci!=ilsp->end(); ++ci) { 00487 rst_data = (*ci)->msg_size - (*ci)->sent_size; 00488 if (rst_data>0) 00489 break; 00490 } 00491 00492 // No more element: return immediatly 00493 if (ci == ilsp->end()) 00494 { 00495 #ifdef DEBUG_INTERNAL2 00496 std::cerr << "-- getClientData0 : no more block for this argument\n"; 00497 #endif 00498 returned_length_element = 0; 00499 end = true; 00500 return NULL; 00501 } 00502 // No more data of this element but there are more 00503 if (rst_data == 0) 00504 { 00505 #ifdef DEBUG_INTERNAL2 00506 std::cerr << "-- getClientData0 : no more data for this bloc\n"; 00507 #endif 00508 returned_length_element = 0; 00509 end = false; 00510 return NULL; 00511 } 00512 // *ci assumed ok here (else return above !!) 00513 info_t* info = *ci; 00514 00515 // More asked data as I can provide -> give all the data of this bloc 00516 if (remaining_size_octet >= rst_data) 00517 { 00518 unsigned descr_len = _clientDescr.ids.length(); 00519 _clientDescr.ids.length(descr_len+1); 00520 _clientDescr.ids[descr_len] = info->gstart+(info->sent_size/_param.unitsize); 00521 00522 unsigned start = info->lstart+info->sent_size; 00523 info->sent_size += rst_data; 00524 returned_length_element = rst_data / _param.unitsize; // should divide; 00525 remaining_size_octet -= rst_data; 00526 end = (remaining_size_octet == 0); 00527 00528 #ifdef DEBUG_INTERNAL2 00529 std::cerr << "-- getClientData1 : gstart:"<<_clientDescr.ids[descr_len]<<" #element:"<<returned_length_element<<endl; 00530 #endif 00531 00532 return (void *)&_clientBuffer[start]; 00533 } 00534 else 00535 { 00536 // I have more data than requested 00537 unsigned descr_len = _clientDescr.ids.length(); 00538 _clientDescr.ids.length(descr_len+1); 00539 _clientDescr.ids[descr_len] = info->gstart+(info->sent_size/_param.unitsize); 00540 00541 unsigned start = info->lstart+info->sent_size; 00542 returned_length_element = (remaining_size_octet+_param.unitsize-1)/_param.unitsize; // max 00543 unsigned mlen = returned_length_element*_param.unitsize; 00544 info->sent_size += mlen; 00545 remaining_size_octet -= mlen; 00546 end = true; 00547 00548 00549 #ifdef DEBUG_INTERNAL2 00550 std::cerr << "-- getClientData1 : gstart:"<<_clientDescr.ids[descr_len]<<" #element:"<<returned_length_element<<endl; 00551 #endif 00552 00553 return (void *)&_clientBuffer[start]; 00554 } 00555 } 00556 00557 void 00558 BasicBC::clientFree() // always called at the end of an invocation (reset some variables) 00559 { 00560 00561 #ifdef DEBUG_INTERNAL 00562 std::cerr << "-- clientFree\n"; 00563 #endif 00564 if (_cur_id == -1) { 00565 this->clear_info_list(); 00566 } else { 00567 this->reset_info_list(); 00568 } 00569 } 00570 00571 void * 00572 BasicBC::getDescr() 00573 { 00574 #ifdef DEBUG_INTERNAL 00575 std::cerr << "-- descr: glen: "<<_clientDescr.glen<<" #element: "<<_clientDescr.ids.length()<<" bsz: "<<_clientDescr.bsz; 00576 for(unsigned i=0;i<_clientDescr.ids.length();i++) { 00577 std::cerr<<" "<<_clientDescr.ids[i]; 00578 } 00579 std::cerr<<std::endl; 00580 #endif 00581 _descr_to_be_cleaned = true; 00582 return &_clientDescr; 00583 } 00584 00585 bool 00586 BasicBC::insertData(void* rcptBuf, unsigned long element_nb) 00587 { 00588 // We are receiving one bloc 00589 unsigned gstart = _serverDescr->ids[_descr_ids_counter++]; // in octet !!! 00590 unsigned lstart; 00591 unsigned llen = element_nb*_param.unitsize; 00592 00593 // Need to compute lstart :( 00594 if (_param.type == BASICBC_BLOC ) { 00595 lstart = (gstart*_param.unitsize)/ _dbsz; // bloc number 00596 lstart = (gstart*_param.unitsize) - (lstart*_dbsz); 00597 } else { 00598 lstart = (gstart*_param.unitsize)/ _dbsz; // bloc number 00599 lstart /= _dTopo.total; // local number 00600 } 00601 00602 char* rptr = &_serverBuffer[lstart]; 00603 #ifdef DEBUG_INTERNAL 00604 std::cerr << " gstart: "<< gstart<<" lstart: "<<lstart<<" #element " << element_nb<<" llen: "<<llen<<std::endl; 00605 #endif 00606 memcpy(rptr, rcptBuf, llen); 00607 00608 _serverToReceived -= llen; 00609 #ifdef DEBUG_INTERNAL 00610 std::cerr << " #missing data"<<_serverToReceived<<std::endl; 00611 #endif 00612 return (_serverToReceived == 0); 00613 } 00614 00615 void * 00616 BasicBC::getServerData(long & length) // in element ! 00617 { 00618 length= _llen / _param.unitsize; 00619 #ifdef DEBUG_INTERNAL 00620 std::cerr << "-- getServerData: ptr : "<<(void*)_serverBuffer<<" #element:"<<length<<std::endl; 00621 #endif 00622 return (void*) _serverBuffer; 00623 } 00624 00625 void 00626 BasicBC::setDescr(void * descr) 00627 { 00628 _serverDescr = (BasicBCLib::BasicBCDescr*) descr; 00629 _descr_ids_counter=0; 00630 00631 // Descr already received 00632 00633 if ( _serverBuffer == NULL) 00634 { 00635 // 1st time -> allocate memory & init 00636 //this->setEltSize(_descr->usz); BUG: usz can be different in client and server (32bit vs 64bit) 00637 unsigned long golen = _serverDescr->glen*_param.unitsize; 00638 this->setTotalNbElt(_serverDescr->glen); 00639 this->setBlocSize(_serverDescr->bsz); 00640 _dbsz = blocSize( golen, _dTopo.total, _param); 00641 _llen = TotalNumberOfElementProc(golen, _nodeRank, _dTopo.total, _dbsz); 00642 00643 #ifdef DEBUG_INTERNAL 00644 fprintf(stderr, "-- setDescr: stopo: %ld\tdtopo: %ld\n",_sTopo.total, _dTopo.total); 00645 fprintf(stderr, " setDescr: golen: %ld\tllen %d\tbsz:%ld\n", _serverDescr->glen, _llen, _serverDescr->bsz); 00646 #endif 00647 _serverBuffer = (char*) malloc(_llen); 00648 #ifdef DEBUG_INTERNAL 00649 std::cerr << "-- serverMalloc: "<<(void*)_serverBuffer<<" - "<<_llen<<endl; 00650 #endif 00651 _serverToReceived = _llen; 00652 } 00653 } 00654 00655 void 00656 BasicBC::serverFree() 00657 { 00658 #ifdef DEBUG_INTERNAL 00659 std::cerr << "-- serverFree: "<<(void*)_serverBuffer<<endl; 00660 #endif 00661 free(_serverBuffer); 00662 _serverBuffer=NULL; // the orb (or the user) need to free the memory! 00663 } 00664 00665 void 00666 BasicBC::internalSetComId(long id) // called by constructor 00667 { 00668 info_list_map_t::iterator it = _info_list_map.find(id); 00669 00670 if (it == _info_list_map.end() ) { 00671 #ifdef DEBUG_INTERNAL 00672 cerr << "setComiI: set 1st time communication id "<<id<<endl; 00673 #endif 00674 // we must allocate a new one 00675 this->allocate_new_info_list(); 00676 #ifdef DEBUG_INTERNAL 00677 cerr << "setComId: allocating a new _infolists: "<<_infolists<<endl; 00678 #endif 00679 _info_list_map[id] = _infolists; 00680 } else { 00681 #ifdef DEBUG_INTERNAL 00682 cerr << "setComId: set (not 1st time) communication id "<<id<<endl; 00683 #endif 00684 _infolists = it->second; 00685 } 00686 00687 _cur_id = id; 00688 } 00689 00690 bool 00691 BasicBC::setComId(long id) 00692 { 00693 if (_cur_id == id) return true; // already initialized 00694 00695 this->internalSetComId(id); 00696 00697 return true; 00698 } 00699 00700 00701 void 00702 BasicBC::internalFreeComId(info_list_map_t::iterator& it) 00703 { 00704 if (it == _info_list_map.end() ) { 00705 #ifdef DEBUG_INTERNAL 00706 cerr << "freeComid: communication id not found (ignoring)\n"; 00707 #endif 00708 } else { 00709 #ifdef DEBUG_INTERNAL 00710 cerr << "freeComid: freeing communication "<<endl; 00711 #endif 00712 info_list_t** info = it->second; 00713 // for each destNode 00714 for(unsigned i=0; i< _dTopo.total; i++) { 00715 // for each element of the list 00716 info_list_t *ilp = info[i]; 00717 for(info_list_t::const_iterator ci=ilp->begin(); ci!=ilp->end(); ++ci) 00718 delete (*ci); 00719 info[i] -> clear(); 00720 delete info[i]; 00721 } 00722 } 00723 } 00724 00725 bool 00726 BasicBC::freeComId(long id) 00727 { 00728 if (id == -1) { 00729 #ifdef DEBUG_INTERNAL 00730 cerr << "freeComId: not allowed to free com id -1 (ignoring)\n"; 00731 #endif 00732 return true; 00733 } 00734 00735 if (_cur_id == id) { 00736 #ifdef DEBUG_INTERNAL 00737 cerr << "freeComId: not allowed to free current com (ignoring)\n"; 00738 #endif 00739 return true; 00740 } 00741 00742 #ifdef DEBUG_INTERNAL 00743 cerr << "freeComid: communication id: "<<id<<endl; 00744 #endif 00745 00746 info_list_map_t::iterator it = _info_list_map.find(id); 00747 this->internalFreeComId(it); 00748 _info_list_map.erase(it); 00749 00750 return true; 00751 } 00752 00753 void 00754 BasicBC::allocate_new_info_list() 00755 { 00756 _infolists = new info_list_t*[_dTopo.total]; 00757 for(unsigned i=0;i<_dTopo.total;i++) 00758 _infolists[i]=new info_list_t(); 00759 } 00760 00761 void 00762 BasicBC::reset_info_list() 00763 { 00764 #ifdef DEBUG_INTERNAL 00765 std::cerr << "-- reset info list\n"; 00766 #endif 00767 // for each destNode 00768 for(unsigned i=0; i< _dTopo.total; i++) { 00769 // for each element of the list 00770 info_list_t *ilp = _infolists[i]; 00771 for(info_list_t::const_iterator ci=ilp->begin(); ci!=ilp->end(); ++ci) 00772 (*ci)->sent_size = 0; 00773 } 00774 } 00775 00776 void 00777 BasicBC::clear_info_list() 00778 { 00779 #ifdef DEBUG_INTERNAL 00780 std::cerr << "-- clear info list\n"; 00781 #endif 00782 // for each destNode 00783 for(unsigned i=0; i< _dTopo.total; i++) { 00784 // for each element of the list 00785 info_list_t *ilp = _infolists[i]; 00786 for(info_list_t::const_iterator ci=ilp->begin(); ci!=ilp->end(); ++ci) 00787 delete (*ci); 00788 _infolists[i] -> clear(); 00789 } 00790 }