Changeset 865
- Timestamp:
- 06/09/16 11:33:08 (9 years ago)
- Location:
- XIOS/trunk/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/grid.cpp
r857 r865 32 32 , transformations_(0), isTransformed_(false) 33 33 , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 34 , gridSrc_(), hasTransform_(false), order_() 34 , gridSrc_(), hasTransform_(false), order_(), globalIndexOnServer_() 35 35 { 36 36 setVirtualDomainGroup(); … … 47 47 , transformations_(0), isTransformed_(false) 48 48 , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 49 , gridSrc_(), hasTransform_(false), order_() 49 , gridSrc_(), hasTransform_(false), order_(), globalIndexOnServer_() 50 50 { 51 51 setVirtualDomainGroup(); … … 409 409 //--------------------------------------------------------------- 410 410 411 /*! 412 Compute the global index of grid to send to server as well as the connected server of the current client. 413 First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 414 their global index. We can have a map of global index of grid and local index that each client holds 415 Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 416 of the current client. 417 */ 411 418 void CGrid::computeIndex(void) 412 419 { … … 434 441 435 442 // Compute mapping between client and server 436 size_t globalSizeIndex = 1, indexBegin, indexEnd; 437 int range, clientSize = client->clientSize; 438 for (int i = 0; i < globalDim_.size(); ++i) globalSizeIndex *= globalDim_[i]; 439 indexBegin = 0; 440 for (int i = 0; i < clientSize; ++i) 441 { 442 range = globalSizeIndex / clientSize; 443 if (i < (globalSizeIndex%clientSize)) ++range; 444 if (i == client->clientRank) break; 445 indexBegin += range; 446 } 447 indexEnd = indexBegin + range - 1; 448 449 // Then compute distribution on server side 443 std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 450 444 CServerDistributionDescription serverDistributionDescription(globalDim_, client->serverSize); 451 serverDistributionDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), positionDimensionDistributed_); 452 453 // Finally, compute index mapping between client(s) and server(s) 454 clientServerMap_ = new CClientServerMappingDistributed(serverDistributionDescription.getGlobalIndexRange(), 455 client->intraComm, 456 clientDistribution_->isDataDistributed()); 457 458 clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex()); 459 const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer(); 445 serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 446 client->clientRank, 447 client->clientSize, 448 axis_domain_order, 449 positionDimensionDistributed_); 450 computeIndexByElement(indexServerOnElement, globalIndexOnServer_); 460 451 461 452 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 462 453 CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 463 454 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 464 itGlobalMap = itbGlobalMap = globalIndexOnServer .begin();465 iteGlobalMap = globalIndexOnServer .end();455 itGlobalMap = itbGlobalMap = globalIndexOnServer_.begin(); 456 iteGlobalMap = globalIndexOnServer_.end(); 466 457 467 458 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) … … 491 482 } 492 483 484 /*! 485 Compute the global of (client) grid to send to server with the global index of each element of grid 486 Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 487 server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 488 on each element whose size is much smaller than one of whole grid. 489 \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 490 \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 491 */ 492 void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 493 CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 494 { 495 CContext* context = CContext::getCurrent(); 496 CContextClient* client = context->client; 497 int serverSize = client->serverSize; 498 std::vector<CDomain*> domList = getDomains(); 499 std::vector<CAxis*> axisList = getAxis(); 500 501 // Some pre-calculations of global index on each element of current grid. 502 int nbElement = axis_domain_order.numElements(); 503 std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 504 int domainIdx = 0, axisIdx = 0; 505 std::vector<size_t> elementNGlobal(nbElement); 506 elementNGlobal[0] = 1; 507 size_t globalSize = 1; 508 for (int idx = 0; idx < nbElement; ++idx) 509 { 510 elementNGlobal[idx] = globalSize; 511 size_t elementSize; 512 size_t elementGlobalSize = 1; 513 if (axis_domain_order(idx)) 514 { 515 elementSize = domList[domainIdx]->i_index.numElements(); 516 globalIndexElement[idx].resize(elementSize); 517 for (int jdx = 0; jdx < elementSize; ++jdx) 518 { 519 globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 520 } 521 elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 522 ++domainIdx; 523 } 524 else 525 { 526 elementSize = axisList[axisIdx]->index.numElements(); 527 globalIndexElement[idx].resize(elementSize); 528 for (int jdx = 0; jdx < elementSize; ++jdx) 529 { 530 globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 531 } 532 elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 533 ++axisIdx; 534 } 535 globalSize *= elementGlobalSize; 536 } 537 538 std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 539 std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 540 for (int idx = 0; idx < nbElement; ++idx) 541 { 542 std::vector<int> nbIndexOnServer(serverSize,0); 543 const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 544 const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 545 CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 546 clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 547 const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 548 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 549 ite = globalIndexElementOnServerMap.end(), it; 550 for (it = itb; it != ite; ++it) 551 { 552 const std::vector<int>& tmp = it->second; 553 for (int i = 0; i < tmp.size(); ++i) 554 { 555 ++nbIndexOnServer[tmp[i]]; 556 } 557 } 558 559 for (int i = 0; i < serverSize; ++i) 560 { 561 if (0 != nbIndexOnServer[i]) 562 { 563 globalElementIndexOnServer[idx][i].resize(nbIndexOnServer[i]); 564 nbIndexOnServer[i] = 0; 565 elementOnServer[idx][i] = true; 566 } 567 } 568 569 for (it = itb; it != ite; ++it) 570 { 571 const std::vector<int>& tmp = it->second; 572 for (int i = 0; i < tmp.size(); ++i) 573 { 574 globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer[tmp[i]]] = it->first; 575 ++nbIndexOnServer[tmp[i]]; 576 } 577 } 578 } 579 580 // Determine server which contain global source index 581 std::vector<bool> intersectedProc(serverSize, true); 582 for (int idx = 0; idx < nbElement; ++idx) 583 { 584 std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 585 intersectedProc.begin(), intersectedProc.begin(), 586 std::logical_and<bool>()); 587 } 588 589 std::vector<int> srcRank; 590 for (int idx = 0; idx < serverSize; ++idx) 591 { 592 if (intersectedProc[idx]) srcRank.push_back(idx); 593 } 594 595 // Compute the global index of grid from global index of each element. 596 for (int i = 0; i < srcRank.size(); ++i) 597 { 598 size_t ssize = 1; 599 int rankSrc = srcRank[i]; 600 std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 601 std::vector<size_t> currentIndex(nbElement,0); 602 for (int idx = 0; idx < nbElement; ++idx) 603 { 604 ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 605 globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 606 } 607 globalIndexOnServer[rankSrc].resize(ssize); 608 609 std::vector<int> idxLoop(nbElement,0); 610 int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 611 size_t idx = 0; 612 while (idx < ssize) 613 { 614 for (int ind = 0; ind < nbElement; ++ind) 615 { 616 if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 617 { 618 idxLoop[ind] = 0; 619 ++idxLoop[ind+1]; 620 } 621 622 currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 623 } 624 625 for (int ind = 0; ind < innnerLoopSize; ++ind) 626 { 627 currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 628 size_t globalSrcIndex = 0; 629 for (int idxElement = 0; idxElement < nbElement; ++idxElement) 630 { 631 globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 632 } 633 globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 634 ++idx; 635 ++idxLoop[0]; 636 } 637 } 638 } 639 } 493 640 //---------------------------------------------------------------- 494 641 … … 783 930 list<CMessage> listMsg; 784 931 list<CArray<size_t,1> > listOutIndex; 785 const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer(); 932 // const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer(); 933 // const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer(); 786 934 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 787 935 CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(), … … 820 968 { 821 969 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 822 itGlobalMap = globalIndexOnServer .begin();823 iteGlobalMap = globalIndexOnServer .end();970 itGlobalMap = globalIndexOnServer_.begin(); 971 iteGlobalMap = globalIndexOnServer_.end(); 824 972 825 973 std::map<int,std::vector<int> >localIndexTmp; -
XIOS/trunk/src/node/grid.hpp
r835 r865 242 242 243 243 void checkAttributesAfterTransformation(); 244 245 246 244 void setTransformationAlgorithms(); 247 245 void computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 246 CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 248 247 249 248 … … 274 273 std::map<CGrid*, std::pair<bool,StdString> > gridSrc_; 275 274 bool hasTransform_; 275 CClientServerMapping::GlobalIndexMap globalIndexOnServer_; 276 276 // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false) 277 277 std::vector<bool> order_; -
XIOS/trunk/src/server_distribution_description.cpp
r843 r865 97 97 Compute global index assigned to a server with a range.E.g: if a grid has 100 points and 98 98 there are 2 servers, the first one takes index from 0 to 49, the second has index from 50 to 99 99 100 99 \param [in] indexBeginEnd begining and ending index of range 100 \param [in] positionDimensionDistributed dimension of server on which we make the cut. 101 101 */ 102 102 void CServerDistributionDescription::computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, … … 161 161 } 162 162 } 163 163 } 164 165 /*! 166 Compute the global index of grid elements (domain, axis) and their associated server rank. 167 Each client knows the general distribution of servers and from which they can compute the pieces of information to hold 168 \param [out] indexServerOnElement global index of each element as well as the corresponding server which contains these indices 169 \param [in] clientRank rank of client 170 \param [in] clientSize number of client 171 \param [in] axisDomainOrder the order of element in grid (true for domain, false for axis) 172 \param [in] positionDimensionDistributed dimension of server on which we make the cut. 173 */ 174 void CServerDistributionDescription::computeServerGlobalByElement(std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 175 int clientRank, 176 int clientSize, 177 const CArray<bool,1>& axisDomainOrder, 178 int positionDimensionDistributed) 179 { 180 switch (serverType_) { 181 case BAND_DISTRIBUTION: 182 computeBandDistribution(nServer_, positionDimensionDistributed); 183 break; 184 default: 185 break; 186 } 187 188 int nbElement = axisDomainOrder.numElements(); 189 indexServerOnElement.resize(nbElement); 190 int idx = 0; 191 std::vector<int> idxMap(nbElement); 192 for (int i = 0; i < nbElement; ++i) 193 { 194 idxMap[i] = idx; 195 if (true == axisDomainOrder(i)) idx += 2; 196 else ++idx; 197 } 198 199 for (int idxServer = 0; idxServer < nServer_; ++idxServer) 200 { 201 std::vector<int> elementDimension(4); 202 for (int i = 0; i < nbElement; ++i) 203 { 204 int elementSize = 1; 205 if (axisDomainOrder(i)) 206 { 207 elementSize *= dimensionSizes_[idxServer][idxMap[i]] * dimensionSizes_[idxServer][idxMap[i]+1]; 208 elementDimension[0] = indexBegin_[idxServer][idxMap[i]]; 209 elementDimension[1] = indexBegin_[idxServer][idxMap[i]+1]; 210 elementDimension[2] = dimensionSizes_[idxServer][idxMap[i]]; 211 elementDimension[3] = dimensionSizes_[idxServer][idxMap[i]+1]; 212 } 213 214 else 215 { 216 elementSize *= dimensionSizes_[idxServer][idxMap[i]]; 217 elementDimension[0] = indexBegin_[idxServer][idxMap[i]]; 218 elementDimension[1] = 0; 219 elementDimension[2] = dimensionSizes_[idxServer][idxMap[i]]; 220 elementDimension[3] = 1; 221 } 222 223 int rangeBegin, rangeSize; 224 computeRangeProcIndex(clientRank, clientSize, elementSize, rangeBegin, rangeSize); 225 226 size_t globalIndexElement; 227 idx = 0; int idxRange = 0; 228 for (int k = 0; k < elementDimension[3]; ++k) 229 for (int l = 0; l < elementDimension[2]; ++l) 230 { 231 globalIndexElement = (l+elementDimension[0]) + (k+elementDimension[1])*elementDimension[2]; 232 if ((rangeBegin <= idx) && (idxRange < rangeSize)) 233 { 234 indexServerOnElement[i][globalIndexElement].push_back(idxServer); 235 ++idxRange; 236 } 237 ++idx; 238 } 239 } 240 } 241 } 242 243 /*! 244 Compute a range of index on server which a client holds 245 For a range of index on a specific server, each client can hold a piece of the index range 246 If the range size is smaller than the number of client, there are some clients holding the same index 247 \param [in] clientRank rank of client 248 \param [in] clientSize number of client 249 \param [in] rangeProcSize index range size 250 \param [out] rangeBegin begin of range index a client holds 251 \param [out] rangeSize size of range index a client holds 252 */ 253 void CServerDistributionDescription::computeRangeProcIndex(int clientRank, 254 int clientSize, 255 int rangeProcSize, 256 int& rangeBegin, 257 int& rangeSize) 258 { 259 if (rangeProcSize < clientSize) 260 { 261 int rangeIndex = 0; 262 for (int idx = 0; idx < clientSize; ++idx) 263 { 264 if (idx == clientRank) 265 { 266 rangeBegin = rangeIndex; 267 rangeSize = 1; 268 } 269 ++rangeIndex; 270 if (rangeIndex == rangeProcSize) rangeIndex = 0; 271 } 272 return; 273 } 274 275 int range, indexBegin = 0; 276 for (int i = 0; i < clientSize; ++i) 277 { 278 range = rangeProcSize / clientSize; 279 if (i < (rangeProcSize%clientSize)) ++range; 280 if (i == clientRank) break; 281 indexBegin += range; 282 } 283 rangeBegin = indexBegin; 284 rangeSize = range; 164 285 } 165 286 -
XIOS/trunk/src/server_distribution_description.hpp
r815 r865 39 39 void computeServerDistribution(bool doComputeGlobalIndex = false, int positionDimensionDistributed = 1); 40 40 void computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, int positionDimensionDistributed = 1); 41 void computeServerGlobalByElement(std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 42 int rank, 43 int clientSize, 44 const CArray<bool,1>& axisDomainOrder, 45 int positionDimensionDistributed = 1); 41 46 42 47 std::vector<std::vector<int> > getServerIndexBegin() const; … … 49 54 void computeBandDistribution(int nServer, int positionDimensionDistributed = 1); 50 55 void computePlanDistribution(int nServer); 56 void computeRangeProcIndex(int clientRank, 57 int clientSize, 58 int rangeProcSize, 59 int& rangeBegin, 60 int& rangeSize); 51 61 52 62 private:
Note: See TracChangeset
for help on using the changeset viewer.