Changeset 865 for XIOS/trunk/src/node/grid.cpp
- Timestamp:
- 06/09/16 11:33:08 (8 years ago)
- File:
-
- 1 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;
Note: See TracChangeset
for help on using the changeset viewer.