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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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   } 
Note: See TracChangeset for help on using the changeset viewer.