Changeset 1232


Ignore:
Timestamp:
07/31/17 17:59:25 (7 years ago)
Author:
mhnguyen
Message:

Fixing the blocking problem where there are more servers than the number of grid band distribution

+) Correct this problem not only for writing but also for reading
+) Allow "zero-size" domain, axis (i.e: domain, axis with ni = 0, and/or nj=0)

Test
+) On Curie
+) Work in both cases: Read and Write data

Location:
XIOS/dev/XIOS_DEV_CMIP6/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/XIOS_DEV_CMIP6/src/context_client.cpp

    r1201 r1232  
    3535      else  MPI_Comm_size(interComm, &serverSize); 
    3636 
     37      computeLeader(clientRank, clientSize, serverSize, ranksServerLeader, ranksServerNotLeader); 
     38 
     39      timeLine = 0; 
     40    } 
     41 
     42    void CContextClient::computeLeader(int clientRank, int clientSize, int serverSize, 
     43                                       std::list<int>& rankRecvLeader, 
     44                                       std::list<int>& rankRecvNotLeader) 
     45    { 
     46      if ((0 == clientSize) || (0 == serverSize)) return; 
     47 
    3748      if (clientSize < serverSize) 
    3849      { 
     
    5061 
    5162        for (int i = 0; i < serverByClient; i++) 
    52           ranksServerLeader.push_back(rankStart + i); 
    53  
    54         ranksServerNotLeader.resize(0); 
     63          rankRecvLeader.push_back(rankStart + i); 
     64 
     65        rankRecvNotLeader.resize(0); 
    5566      } 
    5667      else 
     
    6273        { 
    6374          if (clientRank % (clientByServer + 1) == 0) 
    64             ranksServerLeader.push_back(clientRank / (clientByServer + 1)); 
     75            rankRecvLeader.push_back(clientRank / (clientByServer + 1)); 
    6576          else 
    66             ranksServerNotLeader.push_back(clientRank / (clientByServer + 1)); 
     77            rankRecvNotLeader.push_back(clientRank / (clientByServer + 1)); 
    6778        } 
    6879        else 
     
    7081          int rank = clientRank - (clientByServer + 1) * remain; 
    7182          if (rank % clientByServer == 0) 
    72             ranksServerLeader.push_back(remain + rank / clientByServer); 
     83            rankRecvLeader.push_back(remain + rank / clientByServer); 
    7384          else 
    74             ranksServerNotLeader.push_back(remain + rank / clientByServer); 
    75         } 
    76       } 
    77  
    78       timeLine = 0; 
     85            rankRecvNotLeader.push_back(remain + rank / clientByServer); 
     86        } 
     87      } 
    7988    } 
    8089 
  • XIOS/dev/XIOS_DEV_CMIP6/src/context_client.hpp

    r1201 r1232  
    4949      bool isAttachedModeEnabled() const; 
    5050      bool hasTemporarilyBufferedEvent() const { return !tmpBufferedEvent.isEmpty(); }; 
     51 
     52      static void computeLeader(int clientRank, int clientSize, int serverSize, 
     53                                std::list<int>& rankRecvLeader, 
     54                                std::list<int>& rankRecvNotLeader); 
    5155 
    5256      // Close and finalize context client 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/context.cpp

    r1227 r1232  
    477477         finalized = true; 
    478478 
     479         closeAllFile(); // Just move to here to make sure that server-level 1 can close files 
    479480         if (hasServer && !hasClient) 
    480          { 
    481            closeAllFile(); 
     481         {            
    482482           registryOut->hierarchicalGatherRegistry() ; 
    483483           if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ; 
     
    525525 
    526526     // Check grid and calculate its distribution 
    527      checkGridEnabledFields();     
    528  
     527     checkGridEnabledFields(); 
     528  
    529529     // Distribute files between secondary servers according to the data size 
    530530     distributeFiles(); 
     
    548548      // We have enough information to send to server 
    549549      // First of all, send all enabled files 
    550       sendEnabledFiles(); 
    551  
    552       // Then, send all enabled fields 
    553       sendEnabledFields(); 
     550      sendEnabledFiles(this->enabledWriteModeFiles); 
     551      // We only use server-level 1 (for now) to read data 
     552      if (!hasServer) 
     553        sendEnabledFiles(this->enabledReadModeFiles); 
     554 
     555      // Then, send all enabled fields       
     556      sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 
     557      if (!hasServer) 
     558        sendEnabledFieldsInFiles(this->enabledReadModeFiles); 
    554559 
    555560      // At last, we have all info of domain and axis, then send them 
    556        sendRefDomainsAxis(); 
     561       sendRefDomainsAxisScalars(this->enabledWriteModeFiles); 
     562      if (!hasServer) 
     563        sendRefDomainsAxisScalars(this->enabledReadModeFiles);         
    557564 
    558565       // After that, send all grid (if any) 
    559        sendRefGrid(); 
     566      sendRefGrid(this->enabledWriteModeFiles); 
     567      if (!hasServer) 
     568        sendRefGrid(this->enabledReadModeFiles); 
    560569 
    561570       // We have a xml tree on the server side and now, it should be also processed 
    562571       sendPostProcessing(); 
    563  
    564        sendGridEnabledFields();        
     572        
     573       sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles);        
     574       if (!hasServer) 
     575        sendGridEnabledFieldsInFiles(this->enabledReadModeFiles);        
    565576     } 
    566577     allProcessed = true; 
     
    630641    } 
    631642     
    632     checkGridEnabledFields();     
     643    checkGridEnabledFields();    
    633644 
    634645    if (hasClient) this->sendProcessingGridOfEnabledFields(); 
     
    646657   } 
    647658 
    648    void CContext::findAllEnabledFields(void) 
    649    { 
    650      for (unsigned int i = 0; i < this->enabledFiles.size(); i++) 
    651      (void)this->enabledFiles[i]->getEnabledFields(); 
    652    } 
    653  
    654    void CContext::findAllEnabledFieldsInReadModeFiles(void) 
    655    { 
    656      for (unsigned int i = 0; i < this->enabledReadModeFiles.size(); ++i) 
    657      (void)this->enabledReadModeFiles[i]->getEnabledFields(); 
     659   void CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
     660   { 
     661     for (unsigned int i = 0; i < activeFiles.size(); i++) 
     662     (void)activeFiles[i]->getEnabledFields(); 
    658663   } 
    659664 
     
    664669   } 
    665670 
    666    void CContext::sendGridEnabledFields() 
     671   /*! 
     672      Send active (enabled) fields in file from a client to others 
     673      \param [in] activeFiles files contains enabled fields to send 
     674   */ 
     675   void CContext::sendGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
     676   { 
     677     int size = activeFiles.size(); 
     678     for (int i = 0; i < size; ++i) 
     679     {        
     680       activeFiles[i]->sendGridOfEnabledFields(); 
     681     } 
     682   } 
     683 
     684   void CContext::checkGridEnabledFields() 
     685   { 
     686     int size = enabledFiles.size(); 
     687     for (int i = 0; i < size; ++i) 
     688     { 
     689       enabledFiles[i]->checkGridOfEnabledFields();        
     690     } 
     691   } 
     692 
     693   /*! 
     694      Check grid of active (enabled) fields in file  
     695      \param [in] activeFiles files contains enabled fields whose grid needs checking 
     696   */ 
     697   void CContext::checkGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
     698   { 
     699     int size = activeFiles.size(); 
     700     for (int i = 0; i < size; ++i) 
     701     { 
     702       activeFiles[i]->checkGridOfEnabledFields();        
     703     } 
     704   } 
     705 
     706    /*! 
     707      Go up the hierachical tree via field_ref and do check of attributes of fields 
     708      This can be done in a client then all computed information will be sent from this client to others 
     709      \param [in] sendToServer Flag to indicate whether calculated information will be sent 
     710   */ 
     711   void CContext::solveOnlyRefOfEnabledFields(bool sendToServer) 
    667712   { 
    668713     int size = this->enabledFiles.size(); 
    669714     for (int i = 0; i < size; ++i) 
    670      {        
    671        this->enabledFiles[i]->sendGridOfEnabledFields(); 
    672      } 
    673    } 
    674  
    675    void CContext::checkGridEnabledFields() 
    676    { 
    677      int size = this->enabledFiles.size(); 
     715     { 
     716       this->enabledFiles[i]->solveOnlyRefOfEnabledFields(sendToServer); 
     717     } 
     718 
    678719     for (int i = 0; i < size; ++i) 
    679720     { 
    680        this->enabledFiles[i]->checkGridOfEnabledFields();        
    681      } 
    682    } 
    683  
    684    void CContext::solveOnlyRefOfEnabledFields(bool sendToServer) 
    685    { 
    686      int size = this->enabledFiles.size(); 
    687      for (int i = 0; i < size; ++i) 
    688      { 
    689        this->enabledFiles[i]->solveOnlyRefOfEnabledFields(sendToServer); 
    690      } 
    691  
    692      for (int i = 0; i < size; ++i) 
    693      { 
    694721       this->enabledFiles[i]->generateNewTransformationGridDest(); 
    695722     } 
    696723   } 
    697724 
     725    /*! 
     726      Go up the hierachical tree via field_ref and do check of attributes of fields. 
     727      The transformation can be done in this step. 
     728      All computed information will be sent from this client to others. 
     729      \param [in] sendToServer Flag to indicate whether calculated information will be sent 
     730   */ 
    698731   void CContext::solveAllRefOfEnabledFieldsAndTransform(bool sendToServer) 
    699732   { 
     
    831864 
    832865       // (1) Find all enabled files in write mode 
    833        for (int i = 0; i < this->enabledFiles.size(); ++i) 
    834        { 
    835          if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write )) 
    836           enabledWriteModeFiles.push_back(enabledFiles[i]); 
    837        } 
     866       // for (int i = 0; i < this->enabledFiles.size(); ++i) 
     867       // { 
     868       //   if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write )) 
     869       //    enabledWriteModeFiles.push_back(enabledFiles[i]); 
     870       // } 
    838871 
    839872       // (2) Estimate the data volume for each file 
     
    882915  
    883916       for (int i = 0; i < this->enabledReadModeFiles.size(); ++i) 
    884          enabledReadModeFiles[i]->setContextClient(client); 
     917       { 
     918         enabledReadModeFiles[i]->setContextClient(client);           
     919       } 
    885920     } 
    886921     else 
     
    891926   } 
    892927 
     928   /*! 
     929      Find all files in write mode 
     930   */ 
     931   void CContext::findEnabledWriteModeFiles(void) 
     932   { 
     933     int size = this->enabledFiles.size(); 
     934     for (int i = 0; i < size; ++i) 
     935     { 
     936       if (enabledFiles[i]->mode.isEmpty() ||  
     937          (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write )) 
     938        enabledWriteModeFiles.push_back(enabledFiles[i]); 
     939     } 
     940   } 
     941 
     942   /*! 
     943      Find all files in read mode 
     944   */ 
    893945   void CContext::findEnabledReadModeFiles(void) 
    894946   { 
     
    12171269 
    12181270      //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 
    1219       this->findEnabledFiles(); 
    1220        
     1271      findEnabledFiles(); 
     1272      findEnabledWriteModeFiles(); 
     1273      findEnabledReadModeFiles(); 
     1274 
    12211275      // For now, only read files with client and only one level server 
    1222       if (hasClient && !hasServer) this->findEnabledReadModeFiles(); 
    1223  
    1224       // Find all enabled fields of each file 
    1225       this->findAllEnabledFields(); 
     1276      // if (hasClient && !hasServer) findEnabledReadModeFiles();       
     1277 
     1278      // Find all enabled fields of each file       
     1279      findAllEnabledFieldsInFiles(this->enabledWriteModeFiles); 
     1280      findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 
     1281 
    12261282      // For now, only read files with client and only one level server 
    1227       if (hasClient && !hasServer) this->findAllEnabledFieldsInReadModeFiles(); 
    1228  
     1283      // if (hasClient && !hasServer)  
     1284      //   findAllEnabledFieldsInFiles(this->enabledReadModeFiles);       
    12291285 
    12301286      if (hasClient && !hasServer) 
    12311287      { 
    1232        // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
    1233        this->readAttributesOfEnabledFieldsInReadModeFiles(); 
     1288        initReadFiles(); 
     1289        // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
     1290        this->readAttributesOfEnabledFieldsInReadModeFiles(); 
    12341291      } 
    12351292 
     
    12591316     if (hasClient) 
    12601317     { 
    1261        size_t numEnabledFiles = this->enabledFiles.size(); 
     1318       size_t numEnabledFiles = this->enabledWriteModeFiles.size(); 
    12621319       for (size_t i = 0; i < numEnabledFiles; ++i) 
    12631320       { 
    1264          CFile* file = this->enabledFiles[i]; 
     1321         CFile* file = this->enabledWriteModeFiles[i]; 
    12651322//         if (file->getContextClient() == contextClient) 
    12661323         { 
     
    12801337               if (maxEventSize[it->first] < it->second) 
    12811338                 maxEventSize[it->first] = it->second; 
     1339             } 
     1340           } 
     1341         } 
     1342       } 
     1343 
     1344      // Not a good approach here, duplicate code 
     1345       if (!hasServer) 
     1346       { 
     1347         size_t numEnabledFiles = this->enabledReadModeFiles.size(); 
     1348         for (size_t i = 0; i < numEnabledFiles; ++i) 
     1349         { 
     1350           CFile* file = this->enabledReadModeFiles[i];   
     1351           { 
     1352             std::vector<CField*> enabledFields = file->getEnabledFields(); 
     1353             size_t numEnabledFields = enabledFields.size(); 
     1354             for (size_t j = 0; j < numEnabledFields; ++j) 
     1355             { 
     1356               const std::map<int, StdSize> mapSize = enabledFields[j]->getGridAttributesBufferSize(); 
     1357               std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end(); 
     1358               for (; it != itE; ++it) 
     1359               { 
     1360                 // If attributesSize[it->first] does not exist, it will be zero-initialized 
     1361                 // so we can use it safely without checking for its existance 
     1362                 if (attributesSize[it->first] < it->second) 
     1363                   attributesSize[it->first] = it->second; 
     1364 
     1365                 if (maxEventSize[it->first] < it->second) 
     1366                   maxEventSize[it->first] = it->second; 
     1367               } 
    12821368             } 
    12831369           } 
     
    13411427 
    13421428   //! Client side: Send infomation of active files (files are enabled to write out) 
    1343    void CContext::sendEnabledFiles() 
    1344    { 
    1345      int size = this->enabledFiles.size(); 
     1429   void CContext::sendEnabledFiles(const std::vector<CFile*>& activeFiles) 
     1430   { 
     1431     int size = activeFiles.size(); 
    13461432 
    13471433     // In a context, each type has a root definition, e.g: axis, domain, field. 
     
    13531439     for (int i = 0; i < size; ++i) 
    13541440     { 
    1355        cfgrpPtr->sendCreateChild(this->enabledFiles[i]->getId(),enabledFiles[i]->getContextClient()); 
    1356        this->enabledFiles[i]->sendAllAttributesToServer(enabledFiles[i]->getContextClient()); 
    1357        this->enabledFiles[i]->sendAddAllVariables(enabledFiles[i]->getContextClient()); 
     1441       CFile* f = activeFiles[i]; 
     1442       cfgrpPtr->sendCreateChild(f->getId(),f->getContextClient()); 
     1443       f->sendAllAttributesToServer(f->getContextClient()); 
     1444       f->sendAddAllVariables(f->getContextClient()); 
    13581445     } 
    13591446   } 
    13601447 
    13611448   //! Client side: Send information of active fields (ones are written onto files) 
    1362    void CContext::sendEnabledFields() 
    1363    { 
    1364      int size = this->enabledFiles.size(); 
     1449   void CContext::sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
     1450   { 
     1451     int size = activeFiles.size(); 
    13651452     for (int i = 0; i < size; ++i) 
    13661453     { 
    1367        this->enabledFiles[i]->sendEnabledFields(enabledFiles[i]->getContextClient()); 
     1454       activeFiles[i]->sendEnabledFields(activeFiles[i]->getContextClient()); 
    13681455     } 
    13691456   } 
     
    14881575 
    14891576   //! Client side: Send information of reference grid of active fields 
    1490    void CContext::sendRefGrid() 
     1577   void CContext::sendRefGrid(const std::vector<CFile*>& activeFiles) 
    14911578   { 
    14921579     std::set<StdString> gridIds; 
    1493      int sizeFile = this->enabledFiles.size(); 
     1580     int sizeFile = activeFiles.size(); 
    14941581     CFile* filePtr(NULL); 
    14951582 
     
    14971584     for (int i = 0; i < sizeFile; ++i) 
    14981585     { 
    1499        filePtr = this->enabledFiles[i]; 
     1586       filePtr = activeFiles[i]; 
    15001587       std::vector<CField*> enabledFields = filePtr->getEnabledFields(); 
    15011588       int sizeField = enabledFields.size(); 
     
    15211608   } 
    15221609 
    1523  
    1524    //! Client side: Send information of reference domain and axis of active fields 
    1525    void CContext::sendRefDomainsAxis() 
     1610   //! Client side: Send information of reference domain, axis and scalar of active fields 
     1611   void CContext::sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles) 
    15261612   { 
    15271613     std::set<StdString> domainIds, axisIds, scalarIds; 
    15281614 
    15291615     // Find all reference domain and axis of all active fields 
    1530      int numEnabledFiles = this->enabledFiles.size(); 
     1616     int numEnabledFiles = activeFiles.size(); 
    15311617     for (int i = 0; i < numEnabledFiles; ++i) 
    15321618     { 
    1533        std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields(); 
     1619       std::vector<CField*> enabledFields = activeFiles[i]->getEnabledFields(); 
    15341620       int numEnabledFields = enabledFields.size(); 
    15351621       for (int j = 0; j < numEnabledFields; ++j) 
     
    15921678      info(50) << " Current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte, at timestep "<<step<<" of context "<<this->getId()<<endl ; 
    15931679#endif 
    1594       if (hasClient) 
     1680      //if (hasClient)  
     1681      if (hasClient && !hasServer) // For now we only use server level 1 to read data 
    15951682      { 
    15961683        checkPrefetchingOfEnabledReadModeFiles(); 
     
    15991686   } 
    16001687 
     1688   void CContext::initReadFiles(void) 
     1689   { 
     1690      vector<CFile*>::const_iterator it; 
     1691 
     1692      for (it=enabledReadModeFiles.begin(); it != enabledReadModeFiles.end(); it++) 
     1693      { 
     1694         (*it)->initRead(); 
     1695      } 
     1696   } 
     1697 
    16011698   //! Server side: Create header of netcdf file 
    1602    void CContext::createFileHeader(void ) 
     1699   void CContext::createFileHeader(void) 
    16031700   { 
    16041701      vector<CFile*>::const_iterator it; 
    16051702 
    16061703      for (it=enabledFiles.begin(); it != enabledFiles.end(); it++) 
     1704      // for (it=enabledWriteModeFiles.begin(); it != enabledWriteModeFiles.end(); it++) 
    16071705      { 
    1608          (*it)->initFile(); 
     1706         (*it)->initWrite(); 
    16091707      } 
    16101708   } 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/context.hpp

    r1212 r1232  
    104104 
    105105         // Some functions to process context 
    106          void findAllEnabledFields(void); 
    107          void findAllEnabledFieldsInReadModeFiles(void); 
     106         void findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
     107         // void findAllEnabledFields(void); 
     108         // void findAllEnabledFieldsInReadModeFiles(void); 
    108109         void readAttributesOfEnabledFieldsInReadModeFiles(); 
    109110         void solveAllInheritance(bool apply=true); 
    110111         void findEnabledFiles(void); 
     112         void findEnabledWriteModeFiles(void); 
    111113         void findEnabledReadModeFiles(void); 
    112114         void closeAllFile(void); 
    113115         void updateCalendar(int step); 
    114          void createFileHeader(void ); 
     116         void createFileHeader(void); 
     117         void initReadFiles(void); 
    115118         void checkAxisDomainsGridsEligibilityForCompressedOutput(); 
    116119         void prepareTimeseries(void); 
     
    127130         void solveAllRefOfEnabledFieldsAndTransform(bool sendToServer); 
    128131         void checkGridEnabledFields(); 
    129          void sendGridEnabledFields(); 
     132         void checkGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
     133         void sendGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);          
    130134 
    131135//         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize); 
     
    144148         void sendUpdateCalendar(int step); 
    145149         void sendCreateFileHeader(void); 
    146          void sendEnabledFiles(); 
    147          void sendEnabledFields(); 
    148          void sendRefDomainsAxis(); 
    149          void sendRefGrid(); 
     150         void sendEnabledFiles(const std::vector<CFile*>& activeFiles); 
     151         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
     152         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles); 
     153         void sendRefGrid(const std::vector<CFile*>& activeFiles); 
    150154         void sendPostProcessing(); 
    151155         void sendPostProcessingGlobalAttributes(); 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/domain.cpp

    r1223 r1232  
    18101810      } 
    18111811 
     1812       // Even if servers have no index, they must received something from client 
     1813       // We only use several client to send "empty" message to these servers 
    18121814      CServerDistributionDescription serverDescription(nGlobDomain, nbServer); 
    1813       if (isUnstructed_) serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0); 
    1814       else serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 1); 
     1815      std::vector<int> serverZeroIndex; 
     1816      if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0); 
     1817      else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 1); 
     1818 
     1819       std::list<int> serverZeroIndexLeader; 
     1820       std::list<int> serverZeroIndexNotLeader;  
     1821       CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     1822       for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     1823         *it = serverZeroIndex[*it]; 
    18151824 
    18161825      CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), 
     
    18211830      CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(), 
    18221831                                                           ite = globalIndexDomainOnServer.end(); 
     1832      indSrv_.swap(globalIndexDomainOnServer); 
    18231833      connectedServerRank_.clear(); 
    1824       for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) { 
     1834      for (it = indSrv_.begin(); it != ite; ++it)  
    18251835        connectedServerRank_.push_back(it->first); 
    1826       } 
    1827  
    1828       indSrv_.swap(globalIndexDomainOnServer); 
     1836 
     1837      for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     1838        connectedServerRank_.push_back(*it); 
     1839 
     1840       // Even if a client has no index, it must connect to at least one server and  
     1841       // send an "empty" data to this server 
     1842       if (connectedServerRank_.empty()) 
     1843        connectedServerRank_.push_back(client->clientRank % client->serverSize); 
     1844 
    18291845      nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 
    18301846 
    1831       clientServerMap->computeServerIndexMapping(globalIndexDomainZoom); 
    1832       CClientServerMapping::GlobalIndexMap& globalIndexDomainZoomOnServer = clientServerMap->getGlobalIndexOnServer(); 
    1833       indZoomSrv_.swap(globalIndexDomainZoomOnServer); 
     1847     // clientServerMap->computeServerIndexMapping(globalIndexDomainZoom); 
     1848     // CClientServerMapping::GlobalIndexMap& globalIndexDomainZoomOnServer = clientServerMap->getGlobalIndexOnServer(); 
     1849     // indZoomSrv_.swap(globalIndexDomainZoomOnServer); 
    18341850       
    1835      for (it = indZoomSrv_.begin(); it != indZoomSrv_.end(); ++it) 
    1836        connectedServerZoomRank_.push_back(it->first); 
    1837  
    1838       nbConnectedClientsZoom_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerZoomRank_); 
     1851     // for (it = indZoomSrv_.begin(); it != indZoomSrv_.end(); ++it) 
     1852     //   connectedServerZoomRank_.push_back(it->first); 
     1853 
     1854     // nbConnectedClientsZoom_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerZoomRank_); 
    18391855 
    18401856      delete clientServerMap; 
     
    20072023    This function can be used in the future??? 
    20082024  */ 
    2009   void CDomain::sendIndexZoom() 
    2010   { 
    2011     int ns, n, i, j, ind, nv, idx; 
    2012     CContext* context = CContext::getCurrent(); 
    2013  
    2014     // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    2015     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
    2016     for (int p = 0; p < nbSrvPools; ++p) 
    2017     { 
    2018       CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
    2019       CEventClient eventIndexZoom(getType(), EVENT_ID_INDEX_ZOOM); 
    2020  
    2021       list<CMessage> list_msgsIndex; 
    2022       list<CArray<int,1> > list_indZoom; 
    2023  
    2024       boost::unordered_map<int, vector<size_t> >::const_iterator itZoom, iteZoom; 
    2025       iteZoom = indZoomSrv_.end(); 
    2026       for (int k = 0; k < connectedServerZoomRank_.size(); ++k) 
    2027       { 
    2028         int nbIndGlob = 0; 
    2029         int rank = connectedServerZoomRank_[k]; 
    2030         int nbIndZoom = 0; 
    2031         itZoom = indZoomSrv_.find(rank); 
    2032         if (iteZoom != itZoom) 
    2033           nbIndZoom = itZoom->second.size(); 
     2025  // void CDomain::sendIndexZoom() 
     2026  // { 
     2027  //   int ns, n, i, j, ind, nv, idx; 
     2028  //   CContext* context = CContext::getCurrent(); 
     2029 
     2030  //   // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
     2031  //   int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
     2032  //   for (int p = 0; p < nbSrvPools; ++p) 
     2033  //   { 
     2034  //     CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
     2035  //     CEventClient eventIndexZoom(getType(), EVENT_ID_INDEX_ZOOM); 
     2036 
     2037  //     list<CMessage> list_msgsIndex; 
     2038  //     list<CArray<int,1> > list_indZoom; 
     2039 
     2040  //     boost::unordered_map<int, vector<size_t> >::const_iterator itZoom, iteZoom; 
     2041  //     iteZoom = indZoomSrv_.end(); 
     2042  //     for (int k = 0; k < connectedServerZoomRank_.size(); ++k) 
     2043  //     { 
     2044  //       int nbIndGlob = 0; 
     2045  //       int rank = connectedServerZoomRank_[k]; 
     2046  //       int nbIndZoom = 0; 
     2047  //       itZoom = indZoomSrv_.find(rank); 
     2048  //       if (iteZoom != itZoom) 
     2049  //         nbIndZoom = itZoom->second.size(); 
    20342050         
    2035         list_indZoom.push_back(CArray<int,1>(nbIndZoom)); 
    2036         CArray<int,1>& indZoom = list_indZoom.back(); 
    2037         for (n = 0; n < nbIndZoom; ++n) 
    2038         { 
    2039           indZoom(n) = static_cast<int>(itZoom->second[n]); 
    2040         } 
    2041  
    2042         list_msgsIndex.push_back(CMessage()); 
    2043         list_msgsIndex.back() << this->getId(); // enum ne fonctionne pour les message => ToFix         
    2044         list_msgsIndex.back() << list_indZoom.back() << doZoomByIndex_; //list_indi.back() << list_indj.back       
    2045  
    2046         eventIndexZoom.push(rank, nbConnectedClientsZoom_[rank], list_msgsIndex.back()); 
    2047       } 
    2048  
    2049       client->sendEvent(eventIndexZoom); 
    2050     } 
    2051   } 
     2051  //       list_indZoom.push_back(CArray<int,1>(nbIndZoom)); 
     2052  //       CArray<int,1>& indZoom = list_indZoom.back(); 
     2053  //       for (n = 0; n < nbIndZoom; ++n) 
     2054  //       { 
     2055  //         indZoom(n) = static_cast<int>(itZoom->second[n]); 
     2056  //       } 
     2057 
     2058  //       list_msgsIndex.push_back(CMessage()); 
     2059  //       list_msgsIndex.back() << this->getId(); // enum ne fonctionne pour les message => ToFix         
     2060  //       list_msgsIndex.back() << list_indZoom.back() << doZoomByIndex_; //list_indi.back() << list_indj.back       
     2061 
     2062  //       eventIndexZoom.push(rank, nbConnectedClientsZoom_[rank], list_msgsIndex.back()); 
     2063  //     } 
     2064 
     2065  //     client->sendEvent(eventIndexZoom); 
     2066  //   } 
     2067  // } 
    20522068 
    20532069  /*! 
     
    26732689      { 
    26742690        lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2675         if (!mask_1d(lInd)) 
    2676          mask_1d(lInd) = tmp(ind); 
     2691        if (!mask_1d(lInd)) // Only rewrite mask_1d if it's not true 
     2692          mask_1d(lInd) = tmp(ind); 
    26772693      } 
    26782694    }     
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp

    r1215 r1232  
    4141      , hasTimeCentered(false) 
    4242      , wasDataAlreadyReceivedFromServer(false) 
    43       , isEOF(false) 
     43      , isEOF(false), nstepMaxRead(false) 
    4444   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    4545 
     
    5656      , hasTimeCentered(false) 
    5757      , wasDataAlreadyReceivedFromServer(false) 
    58       , isEOF(false) 
     58      , isEOF(false), nstepMaxRead(false) 
    5959   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    6060 
     
    262262  void CField::writeField(void) 
    263263  { 
    264     if (!getRelFile()->allDomainEmpty) 
     264    if (!getRelFile()->isEmptyZone()) 
    265265    { 
    266266      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) 
     
    273273  } 
    274274 
     275  /* 
     276    Send a request for reading data. 
     277    Client sends a request to server for demanding server to read data and send back to it. 
     278    For now, this function is called only by client 
     279    In the future, it can be called by level-1 servers 
     280    \param [in] tsDataRequested timestamp when the call is made 
     281  */ 
    275282  bool CField::sendReadDataRequest(const CDate& tsDataRequested) 
    276283  { 
    277284    CContext* context = CContext::getCurrent(); 
    278 //    CContextClient* client = context->client; 
     285    // CContextClient* client = context->client; 
     286 
     287    // This code is for future: If we want to read file with level-2 servers 
    279288    CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient(); 
    280289 
     
    332341  } 
    333342 
     343  /*! 
     344    Receive data request sent from client and process it 
     345    Every time server receives this request, it will try to read data and sent read data back to client 
     346    At the moment, this function is called by server level 1 
     347    In the future, this should (only) be done by the last level servers. 
     348  */ 
    334349  void CField::recvReadDataRequest(void) 
    335350  { 
    336351    CContext* context = CContext::getCurrent(); 
    337352    CContextClient* client = context->client; 
    338 //    CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient(); 
    339353 
    340354    CEventClient event(getType(), EVENT_ID_READ_DATA_READY); 
    341355    std::list<CMessage> msgs; 
    342356 
    343     bool hasData = readField(); 
     357    EReadField hasData = readField(); 
    344358 
    345359    map<int, CArray<double,1> >::iterator it; 
     
    356370              CMessage& msg = msgs.back(); 
    357371              msg << getId(); 
    358               if (hasData) 
    359                 msg << getNStep() - 1 << recvDataSrv; 
    360               else 
    361                 msg << int(-1); 
     372              switch (hasData) 
     373              { 
     374                case RF_DATA: 
     375                  msg << getNStep() - 1 << recvDataSrv; 
     376                  break; 
     377                case RF_NODATA: 
     378                  msg << int(-2); 
     379                  break; 
     380                case RF_EOF:                   
     381                default: 
     382                  msg << int(-1); 
     383                  break; 
     384              } 
     385 
    362386              event.push(*itRank, 1, msg); 
    363387            } 
     
    385409        CMessage& msg = msgs.back(); 
    386410        msg << getId(); 
    387         if (hasData) 
    388           msg << getNStep() - 1 << tmp; 
    389         else 
    390           msg << int(-1); 
     411        switch (hasData) 
     412        { 
     413          case RF_DATA: 
     414            msg << getNStep() - 1 << tmp; 
     415            break; 
     416          case RF_NODATA: 
     417            msg << int(-2) << tmp; 
     418            break; 
     419          case RF_EOF:                   
     420          default: 
     421            msg << int(-1); 
     422            break; 
     423        } 
     424 
    391425        event.push(it->first, grid->nbReadSenders[0][it->first], msg); 
    392426      } 
     
    395429  } 
    396430 
    397   bool CField::readField(void) 
     431  /*! 
     432    Read field from a file. 
     433    A field is read with the distribution of data on the server side 
     434    \return State of field can be read from a file 
     435  */ 
     436  CField::EReadField CField::readField(void) 
    398437  { 
     438    CContext* context = CContext::getCurrent(); 
    399439    grid->computeWrittenIndex(); 
    400     if (!getRelFile()->allDomainEmpty) 
    401     { 
    402       if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) 
     440    getRelFile()->initRead(); 
     441    EReadField readState = RF_DATA; 
     442 
     443    if (!getRelFile()->isEmptyZone()) 
     444    {       
     445      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)       
    403446      { 
    404447        if (0 == recvDataSrv.numElements()) 
     
    407450          recvDataSrv.resize(storeClient.numElements());           
    408451        } 
    409  
     452         
    410453        getRelFile()->checkReadFile(); 
     454 
    411455        if (!nstepMax) 
    412456        { 
     
    417461 
    418462        if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 
    419           return false; 
    420  
    421         getRelFile()->getDataInput()->readFieldData(CField::get(this)); 
    422       } 
    423     } 
    424  
    425     return true; 
     463          readState = RF_EOF; 
     464 
     465        if (RF_EOF != readState) 
     466          getRelFile()->getDataInput()->readFieldData(CField::get(this)); 
     467      } 
     468    } 
     469    else 
     470    { 
     471      this->incrementNStep(); 
     472      if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 
     473        readState = RF_EOF; 
     474      else 
     475        readState = RF_NODATA; 
     476 
     477      if (!nstepMaxRead) // This can be a bug if we try to read field from zero time record 
     478        readState = RF_NODATA; 
     479    } 
     480 
     481    if (!nstepMaxRead) 
     482    { 
     483       MPI_Allreduce(&nstepMax, &nstepMax, 1, MPI_INT, MPI_MAX, context->server->intraComm); 
     484       nstepMaxRead = true; 
     485    } 
     486 
     487    return readState; 
    426488  } 
    427489 
     490  /* 
     491    Receive read data from server. 
     492    At the moment, this function is called in the client side. 
     493    In the future, this function can be called hiearachically (server n-1, server n -2, ..., client) 
     494    \param event event containing read data 
     495  */ 
    428496  void CField::recvReadDataReady(CEventServer& event) 
    429497  { 
     
    443511  } 
    444512 
     513  /*! 
     514    Receive read data from server 
     515    \param [in] ranks Ranks of sending processes 
     516    \param [in] buffers buffers containing read data 
     517  */ 
    445518  void CField::recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers) 
    446519  { 
     
    528601   { 
    529602      this->nstepMax = 0; 
     603      nstepMaxRead = false; 
    530604   } 
    531605 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/field.hpp

    r1215 r1232  
    5858         typedef CFieldAttributes SuperClassAttribute; 
    5959 
     60         enum EReadField 
     61         { 
     62           RF_NODATA, RF_EOF, RF_DATA 
     63         }; 
     64          
    6065      public: 
    6166 
     
    157162        static void recvReadDataRequest(CEventServer& event); 
    158163        void recvReadDataRequest(void); 
    159         bool readField(void); 
     164        EReadField readField(void); 
    160165        static void recvReadDataReady(CEventServer& event); 
    161166        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); 
     
    230235         bool isReferenceSolved; 
    231236         bool isReferenceSolvedAndTransformed; 
     237         bool nstepMaxRead; 
    232238 
    233239      private: 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/file.cpp

    r1201 r1232  
    2525      : CObjectTemplate<CFile>(), CFileAttributes() 
    2626      , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) 
    27       , allDomainEmpty(false), isOpen(false) 
     27      , isOpen(false), read_client(0), checkRead(false), allZoneEmpty(false) 
    2828   { 
    2929     setVirtualFieldGroup(CFieldGroup::create(getId() + "_virtual_field_group")); 
     
    3434      : CObjectTemplate<CFile>(id), CFileAttributes() 
    3535      , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) 
    36       , allDomainEmpty(false), isOpen(false) 
     36      , isOpen(false), read_client(0), checkRead(false), allZoneEmpty(false) 
    3737    { 
    3838      setVirtualFieldGroup(CFieldGroup::create(getId() + "_virtual_field_group")); 
     
    207207 
    208208   //! Initialize a file in order to write into it 
    209    void CFile::initFile(void) 
     209   void CFile::initWrite(void) 
    210210   { 
    211211      CContext* context = CContext::getCurrent(); 
     
    228228        } 
    229229      } 
    230       isOpen = false; 
    231  
    232       allDomainEmpty = true; 
     230      isOpen = false;       
    233231 
    234232//      if (!record_offset.isEmpty() && record_offset < 0) 
     
    243241      for (it = this->enabledFields.begin(); it != end; it++) 
    244242      { 
    245          CField* field = *it; 
    246          allDomainEmpty &= !field->grid->doGridHaveDataToWrite(); 
     243         CField* field = *it;          
    247244         std::vector<CAxis*> vecAxis = field->grid->getAxis(); 
    248245         for (size_t i = 0; i < vecAxis.size(); ++i) 
    249246           setAxis.insert(vecAxis[i]->getAxisOutputName()); 
    250 //            setAxis.insert(vecAxis[i]); 
    251247         std::vector<CDomain*> vecDomains = field->grid->getDomains(); 
    252248         for (size_t i = 0; i < vecDomains.size(); ++i) 
    253249           setDomains.insert(vecDomains[i]->getDomainOutputName()); 
    254 //            setDomains.insert(vecDomains[i]); 
    255250 
    256251         field->resetNStep(recordOffset); 
     
    260255 
    261256      // create sub communicator for file 
    262       int color = allDomainEmpty ? 0 : 1; 
    263       MPI_Comm_split(server->intraComm, color, server->intraCommRank, &fileComm); 
    264       if (allDomainEmpty) MPI_Comm_free(&fileComm); 
     257      createSubComFile(); 
    265258 
    266259      // if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
    267260      if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; 
     261    } 
     262 
     263    //! Initialize a file in order to write into it 
     264    void CFile::initRead(void) 
     265    { 
     266      if (checkRead) return; 
     267      createSubComFile(); 
     268      checkRead = true; 
     269    } 
     270 
     271    /*! 
     272      Create a sub communicator in which processes participate in reading/opening file 
     273    */ 
     274    void CFile::createSubComFile() 
     275    { 
     276      CContext* context = CContext::getCurrent(); 
     277      CContextServer* server = context->server; 
     278 
     279      // create sub communicator for file 
     280      allZoneEmpty = true;       
     281      std::vector<CField*>::iterator it, end = this->enabledFields.end(); 
     282      for (it = this->enabledFields.begin(); it != end; it++) 
     283      { 
     284         CField* field = *it; 
     285         bool nullGrid = (0 == field->grid); 
     286         allZoneEmpty &= nullGrid ? false : !field->grid->doGridHaveDataToWrite(); 
     287      } 
     288 
     289      int color = allZoneEmpty ? 0 : 1; 
     290      MPI_Comm_split(server->intraComm, color, server->intraCommRank, &fileComm); 
     291      if (allZoneEmpty) MPI_Comm_free(&fileComm); 
    268292    } 
    269293 
     
    307331        { 
    308332          CTimer::get("Files : open headers").resume(); 
    309           if (!isOpen) openInReadMode(&(context->server->intraComm)); 
     333           
     334          if (!isOpen) openInReadMode(); 
     335 
    310336          CTimer::get("Files : open headers").suspend(); 
    311337        } 
    312338        //checkSplit(); // Really need for reading? 
    313339      } 
     340    } 
     341 
     342    /*! 
     343      Verify if a process participates in an opening-file communicator  
     344      \return true if the process doesn't participate in opening file 
     345    */ 
     346    bool CFile::isEmptyZone() 
     347    { 
     348      return allZoneEmpty; 
    314349    } 
    315350 
     
    376411      CContextServer* server = context->server; 
    377412 
    378       if (!allDomainEmpty) 
     413      if (!allZoneEmpty) 
    379414      { 
    380415         StdString filename = getFileOutputName(); 
     
    558593  \brief Open an existing NetCDF file in read-only mode 
    559594  */ 
    560   void CFile::openInReadMode(MPI_Comm* comm) 
     595  void CFile::openInReadMode() 
    561596  { 
    562597    CContext* context = CContext::getCurrent(); 
    563598    CContextServer* server = context->server; 
    564     MPI_Comm readComm = *comm; 
    565  
    566     if (!allDomainEmpty) 
     599    MPI_Comm readComm = this->fileComm; 
     600 
     601    if (!allZoneEmpty) 
    567602    { 
    568603      StdString filename = getFileOutputName(); 
     
    632667   void CFile::close(void) 
    633668   { 
    634      if (!allDomainEmpty) 
     669     if (!allZoneEmpty) 
    635670       if (isOpen) 
    636671       { 
     
    639674         else 
    640675          this->data_in->closeFile(); 
     676        isOpen = false; 
    641677       } 
    642678      if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm); 
     
    905941   } 
    906942 
     943   void CFile::setReadContextClient(CContextClient* readContextclient) 
     944   { 
     945     read_client = readContextclient; 
     946   } 
     947 
     948   CContextClient* CFile::getReadContextClient() 
     949   { 
     950     return read_client; 
     951   } 
     952 
    907953   /*! 
    908954   \brief Send a message to create a field on server side 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/file.hpp

    r1158 r1232  
    8989         void checkWriteFile(void); 
    9090         void checkReadFile(void); 
    91          void initFile(void); 
     91         void initWrite(void); 
     92         void initRead(void); 
     93         bool isEmptyZone(); 
    9294 
    9395         /// Mutateurs /// 
     
    9799 
    98100         void createHeader(void); 
    99          void openInReadMode(MPI_Comm* readComm = NULL); 
     101         void openInReadMode(void); 
    100102         void close(void); 
    101103         void readAttributesOfEnabledFieldsInReadMode(); 
     
    122124         void setContextClient(CContextClient* newContextClient); 
    123125         CContextClient* getContextClient(); 
     126 
     127         void setReadContextClient(CContextClient* newContextClient); 
     128         CContextClient* getReadContextClient(); 
    124129 
    125130         // Send info to server          
     
    162167         CDate lastSplit; 
    163168         int nbAxis, nbDomains; 
    164          bool isOpen; 
    165          bool allDomainEmpty; 
     169         bool isOpen;          
    166170         MPI_Comm fileComm; 
    167171 
     172      private: 
     173         void createSubComFile(); 
     174         bool checkRead; 
     175         bool allZoneEmpty; 
     176          
    168177      private : 
    169178         /// Propriétés privées /// 
    170179         CContextClient* client; 
     180         CContextClient* read_client; // Context client for reading (channel between server 1 and client) 
    171181         CFieldGroup* vFieldGroup; 
    172182         CVariableGroup* vVariableGroup; 
     
    175185         std::vector<CField*> enabledFields; 
    176186 
     187 
    177188      public: 
    178189        //         virtual void toBinary  (StdOStream& os) const; 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.cpp

    r1215 r1232  
    155155     // The record index is sometimes sent along with the data but we always 
    156156     // include it in the size calculation for the sake of simplicity 
    157      const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() + 2 * sizeof(size_t); 
     157     const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size()  
     158                                                       + 2 * sizeof(size_t)  
     159                                                       + sizeof(size_t); 
    158160     CContext* context = CContext::getCurrent(); 
    159161     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
     
    162164     { 
    163165       std::map<int, size_t>::const_iterator itEnd = connectedDataSize_[p].end(); 
    164        for (size_t k = 0; k < connectedServerRank_[p].size(); ++k) // TODO: Should change connectedServerRank_[0] to something more general 
     166       for (size_t k = 0; k < connectedServerRank_[p].size(); ++k) 
    165167       { 
    166168         int rank = connectedServerRank_[p][k]; 
    167          std::map<int, size_t>::const_iterator it = connectedDataSize_[0].find(rank); 
     169         std::map<int, size_t>::const_iterator it = connectedDataSize_[p].find(rank); 
    168170         size_t count = (it != itEnd) ? it->second : 0; 
    169171 
     
    714716       std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    715717       CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    716        serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    717                                                                   client->clientRank, 
    718                                                                   client->clientSize, 
    719                                                                   axis_domain_order, 
    720                                                                   getDistributedDimension()); 
     718       std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
     719                                                                                                  client->clientRank, 
     720                                                                                                  client->clientSize, 
     721                                                                                                  axis_domain_order, 
     722                                                                                                  getDistributedDimension()); 
     723 
     724       // Even if servers have no index, they must received something from client 
     725       // We only use several client to send "empty" message to these servers 
     726       std::list<int> serverZeroIndexLeader; 
     727       std::list<int> serverZeroIndexNotLeader;  
     728       CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     729       for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     730         *it = serverZeroIndex[*it]; 
     731 
    721732       computeIndexByElement(indexServerOnElement, globalIndexOnServer_); 
    722733 
     
    724735       CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    725736       CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    726        itGlobalMap  = itbGlobalMap = globalIndexOnServer_.begin(); 
     737       itbGlobalMap = globalIndexOnServer_.begin(); 
    727738       iteGlobalMap = globalIndexOnServer_.end(); 
    728739 
    729        for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
     740       for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    730741       { 
    731742         int serverRank = itGlobalMap->first; 
     
    745756       } 
    746757 
     758       // Connected servers which really have index 
    747759       for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
    748760         connectedServerRank_[p].push_back(itGlobalMap->first); 
    749761       } 
    750762 
     763       // Connected servers which have no index at all 
     764       for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     765         connectedServerRank_[p].push_back(*it); 
     766 
     767       // Even if a client has no index, it must connect to at least one server and  
     768       // send an "empty" data to this server 
     769       if (connectedServerRank_[p].empty()) 
     770        connectedServerRank_[p].push_back(client->clientRank % client->serverSize); 
     771       
    751772       nbSenders[p] = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[p]); 
    752773     } 
  • XIOS/dev/XIOS_DEV_CMIP6/src/server_distribution_description.cpp

    r887 r1232  
    100100  \param [in] positionDimensionDistributed dimension of server on which we make the cut. 
    101101*/ 
    102 void CServerDistributionDescription::computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, 
     102std::vector<int> CServerDistributionDescription::computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, 
    103103                                                                     int positionDimensionDistributed) 
    104104{ 
     105  int nBand  = 0; 
    105106  switch (serverType_) { 
    106107    case BAND_DISTRIBUTION: 
    107       computeBandDistribution(nServer_, positionDimensionDistributed); 
     108      nBand = computeBandDistribution(nServer_, positionDimensionDistributed); 
    108109      break; 
    109110    default: 
     
    122123  std::vector<int> currentIndex(dim); 
    123124 
    124   for (int idxServer = 0; idxServer < nServer_; ++idxServer) 
     125  for (int idxServer = 0; idxServer < nBand; ++idxServer) 
    125126  { 
    126127    size_t ssize = 1, idx = 0; 
     
    161162    } 
    162163  } 
     164 
     165    // List of servers without distribution (cause total number of server is greater than number of bands, for example) 
     166  std::vector<int> zeroIndexServer(nServer_-nBand);  
     167  for (int idxServer = nBand; idxServer < nServer_; ++idxServer) 
     168    zeroIndexServer[idxServer-nBand] = idxServer; 
     169 
     170  return zeroIndexServer; 
    163171} 
    164172 
     
    172180  \param [in] positionDimensionDistributed dimension of server on which we make the cut. 
    173181*/ 
    174 void CServerDistributionDescription::computeServerGlobalByElement(std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    175                                                                   int clientRank, 
    176                                                                   int clientSize, 
    177                                                                   const CArray<int,1>& axisDomainOrder, 
    178                                                                   int positionDimensionDistributed) 
    179 { 
     182std::vector<int> CServerDistributionDescription::computeServerGlobalByElement(std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     183                                                                              int clientRank, 
     184                                                                              int clientSize, 
     185                                                                              const CArray<int,1>& axisDomainOrder, 
     186                                                                              int positionDimensionDistributed) 
     187{ 
     188  int nBand  = 0; 
    180189  switch (serverType_) { 
    181190    case BAND_DISTRIBUTION: 
    182       computeBandDistribution(nServer_, positionDimensionDistributed); 
     191      nBand = computeBandDistribution(nServer_, positionDimensionDistributed); 
    183192      break; 
    184193    default: 
     
    197206  } 
    198207 
    199   for (int idxServer = 0; idxServer < nServer_; ++idxServer) 
     208  for (int idxServer = 0; idxServer < nBand; ++idxServer) 
    200209  { 
    201210    std::vector<int> elementDimension(4); 
     
    247256    } 
    248257  } 
     258 
     259  // List of servers without distribution (cause total number of server is greater than number of bands, for example) 
     260  std::vector<int> zeroIndexServer(nServer_-nBand);  
     261  for (int idxServer = nBand; idxServer < nServer_; ++idxServer) 
     262    zeroIndexServer[idxServer-nBand] = idxServer; 
     263 
     264  return zeroIndexServer; 
    249265} 
    250266 
     
    297313  \param [in] nServer number of server 
    298314*/ 
    299 void CServerDistributionDescription::computeBandDistribution(int nServer, int positionDimensionDistributed) 
     315int CServerDistributionDescription::computeBandDistribution(int nServer, int positionDimensionDistributed) 
    300316{ 
    301317  int dim = nGlobal_.size(); 
     
    324340  int positionDistributed = (1<dim) ? positionDimensionDistributed_ : 0; 
    325341  nGlobTemp = nGlobal_[positionDistributed]; 
    326  
    327   for (int i = 0; i < nServer; ++i) 
     342  int nbBand = std::min(nGlobTemp, nServer); 
     343 
     344  for (int i = 0; i < nbBand; ++i) 
    328345  { 
    329346    if (0 < i) njRangeBegin[i] = njRangeEnd[i-1]; 
    330     njRangeSize = nGlobTemp / nServer; 
    331     if (i < nGlobTemp%nServer) ++njRangeSize; 
     347    njRangeSize = nGlobTemp / nbBand; 
     348    if (i < nGlobTemp%nbBand) ++njRangeSize; 
    332349    njRangeEnd[i] = njRangeSize + njRangeBegin[i]; 
    333350  } 
    334   njRangeEnd[nServer-1] = nGlobTemp; 
     351  njRangeEnd[nbBand-1] = nGlobTemp; 
     352 
     353  for (int i = nbBand; i < nServer; ++i) 
     354  { 
     355    njRangeBegin[i] = njRangeEnd[i] = 0; 
     356  } 
    335357 
    336358  for (int i = 0; i < nServer; ++i) 
     
    358380    } 
    359381  } 
     382 
     383  return nbBand; 
    360384} 
    361385 
  • XIOS/dev/XIOS_DEV_CMIP6/src/server_distribution_description.hpp

    r887 r1232  
    3838 
    3939    void computeServerDistribution(bool doComputeGlobalIndex = false, int positionDimensionDistributed = 1); 
    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<int,1>& axisDomainOrder, 
    45                                       int positionDimensionDistributed = 1); 
     40    std::vector<int> computeServerGlobalIndexInRange(const std::pair<size_t, size_t>& indexBeginEnd, int positionDimensionDistributed = 1); 
     41    std::vector<int> computeServerGlobalByElement(std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     42                                                  int rank, 
     43                                                  int clientSize, 
     44                                                  const CArray<int,1>& axisDomainOrder, 
     45                                                  int positionDimensionDistributed = 1); 
    4646 
    4747    std::vector<std::vector<int> > getServerIndexBegin() const; 
     
    5252 
    5353  protected: 
    54     void computeBandDistribution(int nServer, int positionDimensionDistributed = 1); 
     54    int computeBandDistribution(int nServer, int positionDimensionDistributed = 1); 
    5555    void computePlanDistribution(int nServer); 
    5656    void computeRangeProcIndex(int clientRank, 
Note: See TracChangeset for help on using the changeset viewer.