Changeset 1263


Ignore:
Timestamp:
09/12/17 16:35:36 (3 years ago)
Author:
oabramkina
Message:

Modifications allowing to avoid recalculation of the grid distribution if receivers are of the same size.

Location:
XIOS/dev/XIOS_DEV_CMIP6/src/node
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp

    r1250 r1263  
    132132    CContext* context = CContext::getCurrent(); 
    133133    CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient(); 
     134    int receiverSize = client->serverSize; 
    134135 
    135136    CEventClient event(getType(), EVENT_ID_UPDATE_DATA); 
     
    175176 
    176177        list_msg.back() << getId() << data_tmp; 
    177         event.push(rank, grid->nbSenders[client][rank], list_msg.back()); 
     178        event.push(rank, grid->nbSenders[receiverSize][rank], list_msg.back()); 
    178179      } 
    179180      client->sendEvent(event); 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.cpp

    r1250 r1263  
    146146 
    147147   /*! 
    148     * Compute the minimum buffer size required to send the data to the server(s). 
    149     * 
     148    * Compute the minimum buffer size required to send the data. 
     149    * \param client contextClient used to determine the size of connected receivers 
    150150    * \param id the id used to tag the data 
    151     * \return A map associating the server rank with its minimum buffer size. 
     151    * \return A map associating the sender rank with its minimum buffer size. 
    152152    */ 
    153153   std::map<int, StdSize> CGrid::getDataBufferSize(CContextClient* client, const std::string& id /*= ""*/) 
     
    176176 
    177177     std::map<int, StdSize> dataSizes; 
    178      std::map<int, size_t>::const_iterator itEnd = connectedDataSize_[client].end(); 
    179      for (size_t k = 0; k < connectedServerRank_[client].size(); ++k) 
     178     int receiverSize = client->serverSize; 
     179     std::map<int, size_t>::const_iterator itEnd = connectedDataSize_[receiverSize].end(); 
     180     for (size_t k = 0; k < connectedServerRank_[receiverSize].size(); ++k) 
    180181     { 
    181        int rank = connectedServerRank_[client][k]; 
    182        std::map<int, size_t>::const_iterator it = connectedDataSize_[client].find(rank); 
     182       int rank = connectedServerRank_[receiverSize][k]; 
     183       std::map<int, size_t>::const_iterator it = connectedDataSize_[receiverSize].find(rank); 
    183184       size_t count = (it != itEnd) ? it->second : 0; 
    184185 
     
    315316   { 
    316317     CContext* context = CContext::getCurrent(); 
    317      // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    318318     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;    
    319319     nbSrvPools = 1;   
     
    658658     CContext* context = CContext::getCurrent(); 
    659659 
    660      // This needs to change one day 
    661      int nbSrvPools = 1;  
    662      for (int p = 0; p < nbSrvPools; ++p) 
     660     CContextClient* client = context->client;  // Here it's not important which contextClient to recuperate 
     661     int rank = client->clientRank; 
     662 
     663     clientDistribution_ = new CDistributionClient(rank, this); 
     664     // Get local data index on client 
     665     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 
     666     int nbStoreIndex = storeIndex_client.numElements(); 
     667     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
     668 
     669     if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
     670     else 
    663671     { 
    664        CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client) : context->client; 
    665        int rank = client->clientRank; 
    666  
    667        clientDistribution_ = new CDistributionClient(rank, this); 
    668        // Get local data index on client 
    669        storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 
    670        int nbStoreIndex = storeIndex_client.numElements(); 
    671        for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];        
    672       
    673        if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
    674        else           
    675        {           
    676           // Mapping global index received from clients to the storeIndex_client 
    677           CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
    678           CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
    679           map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    680                                                  ite = outGlobalIndexFromClient.end(), it; 
    681                    
    682           for (it = itb; it != ite; ++it) 
     672        // Mapping global index received from clients to the storeIndex_client 
     673        CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
     674        CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
     675        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
     676                                               ite = outGlobalIndexFromClient.end(), it; 
     677 
     678        for (it = itb; it != ite; ++it) 
     679        { 
     680          int rank = it->first; 
     681          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
     682          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
     683          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
     684          size_t nbIndex = 0; 
     685 
     686          // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
     687          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    683688          { 
    684             int rank = it->first; 
    685             CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    686             outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    687             CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
    688             size_t nbIndex = 0; 
    689              
    690             // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
    691             for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     689            if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    692690            { 
    693               if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    694               { 
    695                 ++nbIndex;                            
    696               }               
     691              ++nbIndex; 
    697692            } 
    698  
    699              
    700             if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
    701                  ERROR("void CGrid::computeClientIndex()", 
    702                     << "Number of local index on client is different from number of received global index"  
    703                     << "Rank of sent client " << rank <<"." 
    704                     << "Number of local index " << nbIndex << ". " 
    705                     << "Number of received global index " << localIndex.numElements() << "."); 
    706  
    707             nbIndex = 0; 
    708             for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     693          } 
     694 
     695          if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
     696               ERROR("void CGrid::computeClientIndex()", 
     697                  << "Number of local index on client is different from number of received global index" 
     698                  << "Rank of sent client " << rank <<"." 
     699                  << "Number of local index " << nbIndex << ". " 
     700                  << "Number of received global index " << localIndex.numElements() << "."); 
     701 
     702          nbIndex = 0; 
     703          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     704          { 
     705            if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    709706            { 
    710               if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    711               {             
    712                 localIndex(idx) = globalDataIndex[globalIndex(idx)];                 
    713               }               
     707              localIndex(idx) = globalDataIndex[globalIndex(idx)]; 
    714708            } 
    715           }           
     709          } 
    716710        } 
    717711      } 
     
    719713 
    720714   /*! 
    721      Compute the connected clients and index to send to these clients. 
    722      Each client can connect to a pool of other clients, each of which can have a piece of information of a grid 
     715     Compute connected receivers and indexes to be sent to these receivers. 
    723716   */ 
    724717   void CGrid::computeConnectedClients() 
    725718   { 
    726719     CContext* context = CContext::getCurrent(); 
    727      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     720     int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 
    728721     connectedServerRank_.clear(); 
    729722     connectedDataSize_.clear(); 
     
    733726     for (int p = 0; p < nbSrvPools; ++p) 
    734727     { 
    735        CContextClient* client = (context->hasServer) ? context->clientPrimServer[p] : context->client; 
    736  
    737        connectedServerRank_[client].clear(); 
    738  
    739        if (!doGridHaveDataDistributed(client)) 
     728       CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 
     729       int receiverSize = client->serverSize; 
     730//       connectedServerRank_[client].clear(); 
     731 
     732       if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 
    740733       { 
    741           if (client->isServerLeader()) 
    742           { 
    743             size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
    744             const std::list<int>& ranks = client->getRanksServerLeader(); 
    745             for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     734        if (!doGridHaveDataDistributed(client)) 
     735         { 
     736            if (client->isServerLeader()) 
    746737            { 
    747               connectedServerRank_[client].push_back(*itRank); 
    748               connectedDataSize_[client][*itRank] = ssize; 
     738              size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
     739              const std::list<int>& ranks = client->getRanksServerLeader(); 
     740              for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     741              { 
     742                connectedServerRank_[receiverSize].push_back(*itRank); 
     743                connectedDataSize_[receiverSize][*itRank] = ssize; 
     744              } 
    749745            } 
    750           } 
    751           return; 
     746            return; 
     747         } 
     748 
     749         // Compute mapping between client and server 
     750         std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
     751         CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
     752         std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
     753                                                                                                    client->clientRank, 
     754                                                                                                    client->clientSize, 
     755                                                                                                    axis_domain_order, 
     756                                                                                                    getDistributedDimension()); 
     757 
     758         // Even if servers have no index, they must received something from client 
     759         // We only use several client to send "empty" message to these servers 
     760         std::list<int> serverZeroIndexLeader; 
     761         std::list<int> serverZeroIndexNotLeader; 
     762         CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     763         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     764           *it = serverZeroIndex[*it]; 
     765 
     766         if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 
     767           computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 
     768 
     769         const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
     770         CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
     771         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
     772         itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
     773         iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
     774 
     775         for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
     776         { 
     777           int serverRank = itGlobalMap->first; 
     778           int indexSize = itGlobalMap->second.size(); 
     779           const std::vector<size_t>& indexVec = itGlobalMap->second; 
     780           for (int idx = 0; idx < indexSize; ++idx) 
     781           { 
     782              itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
     783              if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
     784              { 
     785                if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 
     786                  connectedDataSize_[receiverSize][serverRank] = 1; 
     787                else 
     788                  ++connectedDataSize_[receiverSize][serverRank]; 
     789              } 
     790           } 
     791         } 
     792 
     793         // Connected servers which really have index 
     794         for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
     795           connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 
     796         } 
     797 
     798         // Connected servers which have no index at all 
     799         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     800           connectedServerRank_[receiverSize].push_back(*it); 
     801 
     802         // Even if a client has no index, it must connect to at least one server and 
     803         // send an "empty" data to this server 
     804         if (connectedServerRank_[receiverSize].empty()) 
     805          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
     806 
     807         nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
    752808       } 
    753  
    754        // Compute mapping between client and server 
    755        std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    756        CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    757        std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    758                                                                                                   client->clientRank, 
    759                                                                                                   client->clientSize, 
    760                                                                                                   axis_domain_order, 
    761                                                                                                   getDistributedDimension()); 
    762  
    763        // Even if servers have no index, they must received something from client 
    764        // We only use several client to send "empty" message to these servers 
    765        std::list<int> serverZeroIndexLeader; 
    766        std::list<int> serverZeroIndexNotLeader;  
    767        CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    768        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    769          *it = serverZeroIndex[*it]; 
    770  
    771        computeIndexByElement(indexServerOnElement, globalIndexOnServer_[client]); 
    772  
    773        const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    774        CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    775        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    776        itbGlobalMap = globalIndexOnServer_[client].begin(); 
    777        iteGlobalMap = globalIndexOnServer_[client].end(); 
    778  
    779        for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    780        { 
    781          int serverRank = itGlobalMap->first; 
    782          int indexSize = itGlobalMap->second.size(); 
    783          const std::vector<size_t>& indexVec = itGlobalMap->second; 
    784          for (int idx = 0; idx < indexSize; ++idx) 
    785          { 
    786             itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
    787             if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
    788             { 
    789                if (connectedDataSize_[client].end() == connectedDataSize_[client].find(serverRank)) 
    790                  connectedDataSize_[client][serverRank] = 1; 
    791                else 
    792                  ++connectedDataSize_[client][serverRank]; 
    793             } 
    794          } 
    795        } 
    796  
    797        // Connected servers which really have index 
    798        for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
    799          connectedServerRank_[client].push_back(itGlobalMap->first); 
    800        } 
    801  
    802        // Connected servers which have no index at all 
    803        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    804          connectedServerRank_[client].push_back(*it); 
    805  
    806        // Even if a client has no index, it must connect to at least one server and  
    807        // send an "empty" data to this server 
    808        if (connectedServerRank_[client].empty()) 
    809         connectedServerRank_[client].push_back(client->clientRank % client->serverSize); 
    810  
    811        nbSenders[client] = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[client]); 
    812809     } 
    813810   } 
     
    847844      on each element whose size is much smaller than one of whole grid. 
    848845      \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 
     846      \param [in] client contextClient 
    849847      \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 
    850848   */ 
    851849   void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     850                                     const CContextClient* client, 
    852851                                     CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 
    853852   { 
    854      CContext* context = CContext::getCurrent(); 
    855      // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    856      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    857      nbSrvPools = 1; 
    858      for (int p = 0; p < nbSrvPools; ++p) 
     853     int serverSize = client->serverSize; 
     854 
     855     std::vector<CDomain*> domList = getDomains(); 
     856     std::vector<CAxis*> axisList = getAxis(); 
     857 
     858     // Some pre-calculations of global index on each element of current grid. 
     859     int nbElement = axis_domain_order.numElements(); 
     860     std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 
     861     int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 
     862     std::vector<size_t> elementNGlobal(nbElement); 
     863     elementNGlobal[0] = 1; 
     864     size_t globalSize = 1; 
     865     for (int idx = 0; idx < nbElement; ++idx) 
    859866     { 
    860        CContextClient* client = context->hasServer ? context->clientPrimServer[p] : context->client; 
    861        int serverSize = client->serverSize; 
    862        std::vector<CDomain*> domList = getDomains(); 
    863        std::vector<CAxis*> axisList = getAxis(); 
    864  
    865        // Some pre-calculations of global index on each element of current grid. 
    866        int nbElement = axis_domain_order.numElements(); 
    867        std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 
    868        int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 
    869        std::vector<size_t> elementNGlobal(nbElement); 
    870        elementNGlobal[0] = 1; 
    871        size_t globalSize = 1; 
    872        for (int idx = 0; idx < nbElement; ++idx) 
     867       elementNGlobal[idx] = globalSize; 
     868       size_t elementSize; 
     869       size_t elementGlobalSize = 1; 
     870       if (2 == axis_domain_order(idx)) // This is domain 
    873871       { 
    874          elementNGlobal[idx] = globalSize; 
    875          size_t elementSize; 
    876          size_t elementGlobalSize = 1; 
    877          if (2 == axis_domain_order(idx)) // This is domain 
     872         elementSize = domList[domainIdx]->i_index.numElements(); 
     873         globalIndexElement[idx].resize(elementSize); 
     874         for (int jdx = 0; jdx < elementSize; ++jdx) 
    878875         { 
    879            elementSize = domList[domainIdx]->i_index.numElements(); 
    880            globalIndexElement[idx].resize(elementSize); 
    881            for (int jdx = 0; jdx < elementSize; ++jdx) 
     876           globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 
     877         } 
     878         elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 
     879         ++domainIdx; 
     880       } 
     881       else if (1 == axis_domain_order(idx))  // This is axis 
     882       { 
     883         elementSize = axisList[axisIdx]->index.numElements(); 
     884         globalIndexElement[idx].resize(elementSize); 
     885         for (int jdx = 0; jdx < elementSize; ++jdx) 
     886         { 
     887           globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 
     888         } 
     889         elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 
     890         ++axisIdx; 
     891       } 
     892       else  // Of course, this is scalar 
     893       { 
     894         globalIndexElement[idx].resize(1); 
     895         globalIndexElement[idx](0) = 0; 
     896         elementGlobalSize = 1; 
     897       } 
     898       globalSize *= elementGlobalSize; 
     899     } 
     900 
     901     std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 
     902     std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 
     903     CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 
     904     // Number of temporary distributed global index held by each client for each server 
     905     // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 
     906     CArray<int,1> nbIndexOnServerTmp(serverSize); 
     907     for (int idx = 0; idx < nbElement; ++idx) 
     908     { 
     909       nbIndexOnServer = 0; 
     910       const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 
     911       const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 
     912       CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 
     913       clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 
     914       const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 
     915       CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 
     916                                                                    ite = globalIndexElementOnServerMap.end(), it; 
     917       for (it = itb; it != ite; ++it) 
     918       { 
     919         const std::vector<int>& tmp = it->second; 
     920         nbIndexOnServerTmp = 0; 
     921         for (int i = 0; i < tmp.size(); ++i) 
     922         { 
     923           if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 
     924         } 
     925         nbIndexOnServer += nbIndexOnServerTmp; 
     926       } 
     927 
     928       for (int i = 0; i < serverSize; ++i) 
     929       { 
     930         if (0 != nbIndexOnServer(i)) 
     931         { 
     932           globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 
     933           elementOnServer[idx][i] = true; 
     934         } 
     935       } 
     936 
     937     nbIndexOnServer = 0; 
     938     for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
     939     { 
     940       it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
     941       if (it != ite) 
     942       { 
     943         const std::vector<int>& tmp = it->second; 
     944         nbIndexOnServerTmp = 0; 
     945         for (int i = 0; i < tmp.size(); ++i) 
     946         { 
     947           if (0 == nbIndexOnServerTmp(tmp[i])) 
    882948           { 
    883              globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 
    884            } 
    885            elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 
    886            ++domainIdx; 
    887          } 
    888          else if (1 == axis_domain_order(idx))  // This is axis 
    889          { 
    890            elementSize = axisList[axisIdx]->index.numElements(); 
    891            globalIndexElement[idx].resize(elementSize); 
    892            for (int jdx = 0; jdx < elementSize; ++jdx) 
    893            { 
    894              globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 
    895            } 
    896            elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 
    897            ++axisIdx; 
    898          } 
    899          else  // Of course, this is scalar 
    900          { 
    901            globalIndexElement[idx].resize(1); 
    902            globalIndexElement[idx](0) = 0; 
    903            elementGlobalSize = 1; 
    904          } 
    905          globalSize *= elementGlobalSize; 
    906        } 
    907  
    908        std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 
    909        std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 
    910        CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 
    911        // Number of temporary distributed global index held by each client for each server 
    912        // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 
    913        CArray<int,1> nbIndexOnServerTmp(serverSize); 
    914        for (int idx = 0; idx < nbElement; ++idx) 
    915        { 
    916          nbIndexOnServer = 0; 
    917          const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 
    918          const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 
    919          CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 
    920          clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 
    921          const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 
    922          CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 
    923                                                                       ite = globalIndexElementOnServerMap.end(), it; 
    924          for (it = itb; it != ite; ++it) 
    925          { 
    926            const std::vector<int>& tmp = it->second; 
    927            nbIndexOnServerTmp = 0; 
    928            for (int i = 0; i < tmp.size(); ++i) 
    929            { 
    930              if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 
    931            } 
    932            nbIndexOnServer += nbIndexOnServerTmp; 
    933          } 
    934  
    935          for (int i = 0; i < serverSize; ++i) 
    936          { 
    937            if (0 != nbIndexOnServer(i)) 
    938            { 
    939              globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 
    940              elementOnServer[idx][i] = true; 
     949             globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 
     950             ++nbIndexOnServerTmp(tmp[i]); 
    941951           } 
    942952         } 
    943  
    944        nbIndexOnServer = 0; 
    945        for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
    946        { 
    947          it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
    948          if (it != ite) 
    949          { 
    950            const std::vector<int>& tmp = it->second; 
    951            nbIndexOnServerTmp = 0; 
    952            for (int i = 0; i < tmp.size(); ++i) 
    953            { 
    954              if (0 == nbIndexOnServerTmp(tmp[i])) 
    955              { 
    956                globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 
    957                ++nbIndexOnServerTmp(tmp[i]); 
    958              } 
    959            } 
    960            nbIndexOnServer += nbIndexOnServerTmp; 
    961          } 
     953         nbIndexOnServer += nbIndexOnServerTmp; 
    962954       } 
    963955     } 
    964  
    965       // Determine server which contain global source index 
    966       std::vector<bool> intersectedProc(serverSize, true); 
     956   } 
     957 
     958    // Determine server which contain global source index 
     959    std::vector<bool> intersectedProc(serverSize, true); 
     960    for (int idx = 0; idx < nbElement; ++idx) 
     961    { 
     962      std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 
     963                     intersectedProc.begin(), intersectedProc.begin(), 
     964                     std::logical_and<bool>()); 
     965    } 
     966 
     967    std::vector<int> srcRank; 
     968    for (int idx = 0; idx < serverSize; ++idx) 
     969    { 
     970      if (intersectedProc[idx]) srcRank.push_back(idx); 
     971    } 
     972 
     973    // Compute the global index of grid from global index of each element. 
     974    for (int i = 0; i < srcRank.size(); ++i) 
     975    { 
     976      size_t ssize = 1; 
     977      int rankSrc = srcRank[i]; 
     978      std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 
     979      std::vector<size_t> currentIndex(nbElement,0); 
    967980      for (int idx = 0; idx < nbElement; ++idx) 
    968981      { 
    969         std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 
    970                        intersectedProc.begin(), intersectedProc.begin(), 
    971                        std::logical_and<bool>()); 
    972       } 
    973  
    974       std::vector<int> srcRank; 
    975       for (int idx = 0; idx < serverSize; ++idx) 
    976       { 
    977         if (intersectedProc[idx]) srcRank.push_back(idx); 
    978       } 
    979  
    980       // Compute the global index of grid from global index of each element. 
    981       for (int i = 0; i < srcRank.size(); ++i) 
    982       { 
    983         size_t ssize = 1; 
    984         int rankSrc = srcRank[i]; 
    985         std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 
    986         std::vector<size_t> currentIndex(nbElement,0); 
    987         for (int idx = 0; idx < nbElement; ++idx) 
    988         { 
    989           ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 
    990           globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 
    991         } 
    992         globalIndexOnServer[rankSrc].resize(ssize); 
    993  
    994         std::vector<int> idxLoop(nbElement,0); 
    995         int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 
    996         size_t idx = 0; 
    997         while (idx < ssize) 
    998         { 
    999           for (int ind = 0; ind < nbElement; ++ind) 
     982        ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 
     983        globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 
     984      } 
     985      globalIndexOnServer[rankSrc].resize(ssize); 
     986 
     987      std::vector<int> idxLoop(nbElement,0); 
     988      int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 
     989      size_t idx = 0; 
     990      while (idx < ssize) 
     991      { 
     992        for (int ind = 0; ind < nbElement; ++ind) 
     993        { 
     994          if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 
    1000995          { 
    1001             if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 
    1002             { 
    1003               idxLoop[ind] = 0; 
    1004               ++idxLoop[ind+1]; 
    1005             } 
    1006  
    1007             currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 
     996            idxLoop[ind] = 0; 
     997            ++idxLoop[ind+1]; 
    1008998          } 
    1009999 
    1010           for (int ind = 0; ind < innnerLoopSize; ++ind) 
     1000          currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 
     1001        } 
     1002 
     1003        for (int ind = 0; ind < innnerLoopSize; ++ind) 
     1004        { 
     1005          currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 
     1006          size_t globalSrcIndex = 0; 
     1007          for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
    10111008          { 
    1012             currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 
    1013             size_t globalSrcIndex = 0; 
    1014             for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
    1015             { 
    1016               globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 
    1017             } 
    1018             globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 
    1019             ++idx; 
    1020             ++idxLoop[0]; 
     1009            globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 
    10211010          } 
     1011          globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 
     1012          ++idx; 
     1013          ++idxLoop[0]; 
    10221014        } 
    10231015      } 
     
    12701262  { 
    12711263    CContext* context = CContext::getCurrent();     
    1272     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; // This should be changed soon 
    1273     for (int p = 0; p < nbSrvPools; ++p) 
    1274     { 
    1275       CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client)  
    1276                                                     : context->client; 
     1264//    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; // This should be changed soon 
     1265//    for (int p = 0; p < nbSrvPools; ++p) 
     1266    { 
     1267//      CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client) 
     1268//                                                    : context->client; 
     1269      CContextClient* client = context->client; 
    12771270 
    12781271      int rank = client->clientRank; 
     
    13081301  { 
    13091302    CContext* context = CContext::getCurrent();     
    1310     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     1303    int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 
    13111304    connectedServerRank_.clear(); 
    13121305    connectedDataSize_.clear(); 
     
    13151308    for (int p = 0; p < nbSrvPools; ++p) 
    13161309    { 
    1317       CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client)  
    1318                                                     : context->client; 
    1319  
    1320       connectedServerRank_[client].clear(); 
    1321  
    1322       if (client->isServerLeader()) 
    1323       { 
    1324         const std::list<int>& ranks = client->getRanksServerLeader(); 
    1325         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1326         { 
    1327           int rank = *itRank; 
    1328           int nb = 1; 
    1329           connectedServerRank_[client].push_back(rank); 
    1330           connectedDataSize_[client][rank] = nb; 
    1331           nbSenders[client][rank] = nb; 
    1332         } 
    1333       } 
    1334       else 
    1335       { 
    1336         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1337         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1338         { 
    1339           int rank = *itRank; 
    1340           int nb = 1; 
    1341           connectedServerRank_[client].push_back(rank); 
    1342           connectedDataSize_[client][rank] = nb; 
    1343           nbSenders[client][rank] = nb; 
    1344         }         
    1345       } 
    1346  
     1310      CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 
     1311      int receiverSize = client->serverSize; 
     1312 
     1313//      connectedServerRank_[client].clear(); 
     1314 
     1315      if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 
     1316      { 
     1317        if (client->isServerLeader()) 
     1318        { 
     1319          const std::list<int>& ranks = client->getRanksServerLeader(); 
     1320          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1321          { 
     1322            int rank = *itRank; 
     1323            int nb = 1; 
     1324            connectedServerRank_[receiverSize].push_back(rank); 
     1325            connectedDataSize_[receiverSize][rank] = nb; 
     1326            nbSenders[receiverSize][rank] = nb; 
     1327          } 
     1328        } 
     1329        else 
     1330        { 
     1331          const std::list<int>& ranks = client->getRanksServerNotLeader(); 
     1332          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1333          { 
     1334            int rank = *itRank; 
     1335            int nb = 1; 
     1336            connectedServerRank_[receiverSize].push_back(rank); 
     1337            connectedDataSize_[receiverSize][rank] = nb; 
     1338            nbSenders[receiverSize][rank] = nb; 
     1339          } 
     1340        } 
     1341      } 
    13471342      isDataDistributed_ = false; 
    13481343    } 
     
    13581353    { 
    13591354      CContextClient* client = context->hasServer ? context->clientPrimServer[p] : context->client; 
     1355      int receiverSize = client->serverSize; 
    13601356 
    13611357      CEventClient event(getType(), EVENT_ID_INDEX); 
     
    14161412  { 
    14171413    CContext* context = CContext::getCurrent(); 
    1418     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     1414    int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 
    14191415    storeIndex_toSrv.clear(); 
    14201416    for (int p = 0; p < nbSrvPools; ++p) 
    14211417    { 
    1422       CContextClient* client = context->hasServer ? context->clientPrimServer[p] : context->client ; 
     1418      CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 
     1419      int receiverSize = client->serverSize; 
    14231420 
    14241421      CEventClient event(getType(), EVENT_ID_INDEX); 
     
    14801477      { 
    14811478        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    1482         itGlobalMap = globalIndexOnServer_[client].begin(); 
    1483         iteGlobalMap = globalIndexOnServer_[client].end(); 
     1479        itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
     1480        iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    14841481 
    14851482        std::map<int,std::vector<int> >localIndexTmp; 
     
    15011498        } 
    15021499 
    1503         for (int ns = 0; ns < connectedServerRank_[client].size(); ++ns) 
    1504         { 
    1505           rank = connectedServerRank_[client][ns]; 
     1500        for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 
     1501        { 
     1502          rank = connectedServerRank_[receiverSize][ns]; 
    15061503          int nb = 0; 
    15071504          if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
     
    15241521          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    15251522 
    1526           event.push(rank, nbSenders[client][rank], listMsg.back()); 
     1523          event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 
    15271524        } 
    15281525 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.hpp

    r1250 r1263  
    205205         CArray<int, 1> storeIndex_client; 
    206206 
    207 /** Map containing indexes that will be sent in sendIndex(). In future: change the key to pair<distrType, serverSize> (?) */ 
     207/** Map containing indexes that will be sent in sendIndex(). */ 
    208208         std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv; 
    209209 
     210/** Map storing the number of senders. Key = size of receiver's intracomm */ 
     211         std::map<int, std::map<int,int> > nbSenders; 
     212 
     213         std::map<CContextClient*, std::map<int,int> > nbReadSenders; 
     214 
    210215         map<int, CArray<int, 1> > storeIndex_fromSrv; // Support, for now, reading with level-1 server 
    211216 
    212  
    213          std::map<CContextClient*, std::map<int,int> > nbSenders, nbReadSenders; 
    214217 
    215218         map<int, CArray<size_t, 1> > outIndexFromClient, compressedOutIndexFromClient, outGlobalIndexFromClient; 
     
    271274        void setTransformationAlgorithms(); 
    272275        void computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     276                                   const CContextClient* client, 
    273277                                   CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 
    274278        int computeGridGlobalDimension(std::vector<int>& globalDim, 
     
    305309        int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    306310 
    307 /** Map storing ranks of connected servers. In future: change the key to the server size (?) */ 
    308         std::map<CContextClient*, std::vector<int> > connectedServerRank_; 
    309  
    310 /** Map storing data size that will be sent to connected servers. In future: change the key to the server size (?) */ 
    311         std::map<CContextClient*, std::map<int,size_t> > connectedDataSize_; 
     311/** Map storing local ranks of connected receivers. Key = size of receiver's intracomm */ 
     312        std::map<int, std::vector<int> > connectedServerRank_; 
     313 
     314/** Map storing the size of data to be send. Key = size of receiver's intracomm */ 
     315        std::map<int, std::map<int,size_t> > connectedDataSize_; 
    312316 
    313317        bool isDataDistributed_;         
     
    324328        bool hasTransform_; 
    325329 
    326 /** Map storing data size that will be sent to connected servers. In future: change the key to the server size (?) */ 
    327         std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
     330/** Map storing global indexes of server-like (band-wise) distribution for sending to receivers. 
     331  * Key = size of receiver's intracomm. 
     332  */ 
     333//        std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
     334        std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
     335 
    328336 
    329337/** List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false) */ 
Note: See TracChangeset for help on using the changeset viewer.