Changeset 865


Ignore:
Timestamp:
06/09/16 11:33:08 (5 years ago)
Author:
mhnguyen
Message:

Optimizing codes: Change the way to compute distribution of grid

+) Instead of using DHT on grid, we make use of it only for elements of grid
+) Make change to calculation of server distribution.

Test
+) On Curie
+) Two times faster than the precedent commit.

Location:
XIOS/trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/node/grid.cpp

    r857 r865  
    3232      , transformations_(0), isTransformed_(false) 
    3333      , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 
    34       , gridSrc_(), hasTransform_(false), order_() 
     34      , gridSrc_(), hasTransform_(false), order_(), globalIndexOnServer_() 
    3535   { 
    3636     setVirtualDomainGroup(); 
     
    4747      , transformations_(0), isTransformed_(false) 
    4848      , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 
    49       , gridSrc_(), hasTransform_(false), order_() 
     49      , gridSrc_(), hasTransform_(false), order_(), globalIndexOnServer_() 
    5050   { 
    5151     setVirtualDomainGroup(); 
     
    409409   //--------------------------------------------------------------- 
    410410 
     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   */ 
    411418   void CGrid::computeIndex(void) 
    412419   { 
     
    434441 
    435442     // 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; 
    450444     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_); 
    460451 
    461452     const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    462453     CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    463454     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(); 
    466457 
    467458     for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
     
    491482   } 
    492483 
     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   } 
    493640   //---------------------------------------------------------------- 
    494641 
     
    783930    list<CMessage> listMsg; 
    784931    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(); 
    786934    const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    787935    CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(), 
     
    820968    { 
    821969      CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    822       itGlobalMap = globalIndexOnServer.begin(); 
    823       iteGlobalMap = globalIndexOnServer.end(); 
     970      itGlobalMap = globalIndexOnServer_.begin(); 
     971      iteGlobalMap = globalIndexOnServer_.end(); 
    824972 
    825973      std::map<int,std::vector<int> >localIndexTmp; 
  • XIOS/trunk/src/node/grid.hpp

    r835 r865  
    242242 
    243243        void checkAttributesAfterTransformation(); 
    244  
    245  
    246244        void setTransformationAlgorithms(); 
    247  
     245        void computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     246                                   CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 
    248247 
    249248 
     
    274273        std::map<CGrid*, std::pair<bool,StdString> > gridSrc_; 
    275274        bool hasTransform_; 
     275        CClientServerMapping::GlobalIndexMap globalIndexOnServer_; 
    276276            // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false) 
    277277        std::vector<bool> order_; 
  • XIOS/trunk/src/server_distribution_description.cpp

    r843 r865  
    9797  Compute global index assigned to a server with a range.E.g: if a grid has 100 points and 
    9898  there are 2 servers, the first one takes index from 0 to 49, the second has index from 50 to 99 
    99  
    10099  \param [in] indexBeginEnd begining and ending index of range 
     100  \param [in] positionDimensionDistributed dimension of server on which we make the cut. 
    101101*/ 
    102102void CServerDistributionDescription::computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, 
     
    161161    } 
    162162  } 
    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*/ 
     174void 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*/ 
     253void 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; 
    164285} 
    165286 
  • XIOS/trunk/src/server_distribution_description.hpp

    r815 r865  
    3939    void computeServerDistribution(bool doComputeGlobalIndex = false, int positionDimensionDistributed = 1); 
    4040    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); 
    4146 
    4247    std::vector<std::vector<int> > getServerIndexBegin() const; 
     
    4954    void computeBandDistribution(int nServer, int positionDimensionDistributed = 1); 
    5055    void computePlanDistribution(int nServer); 
     56    void computeRangeProcIndex(int clientRank, 
     57                               int clientSize, 
     58                               int rangeProcSize, 
     59                               int& rangeBegin, 
     60                               int& rangeSize); 
    5161 
    5262  private: 
Note: See TracChangeset for help on using the changeset viewer.