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/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 
Note: See TracChangeset for help on using the changeset viewer.