Changeset 1235 for XIOS


Ignore:
Timestamp:
08/03/17 15:50:40 (7 years ago)
Author:
mhnguyen
Message:

Fixing a bug on writting axis label

+) Axis label is correctly processed before being written
+) Do some code cleaning and add some comments

Test
+) On Curie
+) OK

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

Legend:

Unmodified
Added
Removed
  • XIOS/dev/XIOS_DEV_CMIP6/src/io/nc4_data_output.cpp

    r1222 r1235  
    11361136        int zoom_size  = (MULTI_FILE == SuperClass::type) ? axis->zoom_n 
    11371137                                                          : axis->global_zoom_n; 
    1138         int zoom_begin = (MULTI_FILE == SuperClass::type) ? axis->zoom_begin 
    1139                                                           : axis->global_zoom_begin; 
     1138 
     1139        int zoom_count = axis->zoom_n;                                                  
     1140        int zoom_begin = axis->zoom_begin; 
     1141        // int zoom_begin = (MULTI_FILE == SuperClass::type) ? axis->global_zoom_begin  
     1142        //                                                   : axis->zoom_begin; 
    11401143 
    11411144        if ((0 == axis->zoom_n) && (MULTI_FILE == SuperClass::type)) return; 
     
    11481151        nc_type typePrec ; 
    11491152        if (axis->prec.isEmpty()) typePrec =  NC_FLOAT ; 
    1150         else if (axis->prec==4)  typePrec =  NC_FLOAT ; 
     1153        else if (axis->prec==4)   typePrec =  NC_FLOAT ; 
    11511154        else if (axis->prec==8)   typePrec =  NC_DOUBLE ; 
    11521155          
     
    11981201            for (int i = 0; i < nbWritten; i++) axis_value(i) = axis->value(indexToWrite(i)); 
    11991202            CArray<double,2> axis_bounds; 
     1203            CArray<string,1> axis_label; 
     1204            if (!axis->label.isEmpty()) 
     1205            { 
     1206              axis_label.resize(indexToWrite.numElements()); 
     1207              for (int i = 0; i < nbWritten; i++) axis_label(i) = axis->label(indexToWrite(i)); 
     1208            } 
    12001209 
    12011210            switch (SuperClass::type) 
     
    12031212              case MULTI_FILE: 
    12041213              { 
    1205                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0); 
     1214                if (axis->label.isEmpty()) 
     1215                  SuperClassWriter::writeData(axis_value, axisid, isCollective, 0); 
    12061216 
    12071217                if (!axis->bounds.isEmpty() && axis->label.isEmpty()) 
     
    12091219 
    12101220                // Need to check after 
    1211                 if (! axis->label.isEmpty())  SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0); 
     1221                if (!axis->label.isEmpty())  
     1222                  SuperClassWriter::writeData(axis_label, axisid, isCollective, 0); 
    12121223  
    12131224                SuperClassWriter::definition_start(); 
     
    12191230                std::vector<StdSize> count(1), countBounds(2) ; 
    12201231                start[0] = startBounds[0] = zoom_begin - axis->global_zoom_begin; 
    1221                 count[0] = countBounds[0] = zoom_size; 
     1232                count[0] = countBounds[0] = zoom_count; // zoom_size 
    12221233                startBounds[1] = 0; 
    12231234                countBounds[1] = 2; 
    1224                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count); 
    1225  
    1226                 if (!axis->bounds.isEmpty()&& axis->label.isEmpty()) 
     1235 
     1236                if (axis->label.isEmpty()) 
     1237                  SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count); 
     1238 
     1239                if (!axis->bounds.isEmpty() && axis->label.isEmpty()) 
    12271240                { 
    12281241                  axis_bounds.resize(2, indexToWrite.numElements()); 
     
    12361249 
    12371250                // Need to check after 
    1238                 if (! axis->label.isEmpty())  SuperClassWriter::writeData(axis->label_srv, axisid, isCollective, 0); 
     1251                if (!axis->label.isEmpty()) 
     1252                { 
     1253                  std::vector<StdSize> startLabel(2), countLabel(2); 
     1254                  startLabel[0] = start[0]; startLabel[1] = 0; 
     1255                  countLabel[0] = count[0]; countLabel[1] = stringArrayLen; 
     1256                  SuperClassWriter::writeData(axis_label, axisid, isCollective, 0, &startLabel, &countLabel); 
     1257                } 
    12391258 
    12401259                SuperClassWriter::definition_start(); 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/axis.cpp

    r1215 r1235  
    1010#include "context_server.hpp" 
    1111#include "xios_spl.hpp" 
    12 #include "inverse_axis.hpp" 
    13 #include "zoom_axis.hpp" 
    14 #include "interpolate_axis.hpp" 
    1512#include "server_distribution_description.hpp" 
    1613#include "client_server_mapping_distributed.hpp" 
     
    2522      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
    2623      , isClientAfterTransformationChecked(false) 
    27       , hasBounds_(false), isCompressible_(false) 
     24      , hasBounds(false), isCompressible_(false) 
    2825      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    2926      , transformationMap_(), hasValue(false), hasLabel(false) 
     
    3633      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
    3734      , isClientAfterTransformationChecked(false) 
    38       , hasBounds_(false), isCompressible_(false) 
     35      , hasBounds(false), isCompressible_(false) 
    3936      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    4037      , transformationMap_(), hasValue(false), hasLabel(false) 
     
    179176 
    180177         size_t sizeValEvent = CArray<double,1>::size(it->second.size()); 
    181          if (hasBounds_) 
     178         if (hasBounds) 
    182179           sizeValEvent += CArray<double,2>::size(2 * it->second.size()); 
    183180  
     
    353350               << "Axis size is " << n.getValue() << "." << std::endl 
    354351               << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << "."); 
    355        hasBounds_ = true; 
     352       hasBounds = true; 
    356353     } 
    357      else hasBounds_ = false; 
     354     else hasBounds = false; 
    358355   } 
    359356 
     
    372369  } 
    373370 
     371  /*! 
     372    Check whether we can do compressed output 
     373  */ 
    374374  void CAxis::checkEligibilityForCompressedOutput() 
    375375  { 
     
    378378  } 
    379379 
     380  /* 
     381    Check whether we do zooming by indexing 
     382    return true if do zooming by index 
     383  */ 
    380384  bool CAxis::zoomByIndex() 
    381385  { 
     
    383387  } 
    384388 
    385    bool CAxis::dispatchEvent(CEventServer& event) 
    386    { 
    387       if (SuperClass::dispatchEvent(event)) return true; 
    388       else 
    389       { 
    390         switch(event.type) 
    391         { 
    392            case EVENT_ID_DISTRIBUTION_ATTRIBUTE : 
    393              recvDistributionAttribute(event); 
    394              return true; 
    395              break; 
    396           case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES: 
    397             recvNonDistributedAttributes(event); 
     389  /*! 
     390    Dispatch event from the lower communication layer then process event according to its type 
     391  */ 
     392  bool CAxis::dispatchEvent(CEventServer& event) 
     393  { 
     394     if (SuperClass::dispatchEvent(event)) return true; 
     395     else 
     396     { 
     397       switch(event.type) 
     398       { 
     399          case EVENT_ID_DISTRIBUTION_ATTRIBUTE : 
     400            recvDistributionAttribute(event); 
    398401            return true; 
    399402            break; 
    400           case EVENT_ID_DISTRIBUTED_ATTRIBUTES: 
    401             recvDistributedAttributes(event); 
    402             return true; 
    403             break; 
    404            default : 
    405              ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 
    406                     << "Unknown Event"); 
    407            return false; 
    408          } 
    409       } 
    410    } 
     403         case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES: 
     404           recvNonDistributedAttributes(event); 
     405           return true; 
     406           break; 
     407         case EVENT_ID_DISTRIBUTED_ATTRIBUTES: 
     408           recvDistributedAttributes(event); 
     409           return true; 
     410           break; 
     411          default : 
     412            ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 
     413                   << "Unknown Event"); 
     414          return false; 
     415        } 
     416     } 
     417  } 
    411418 
    412419   /*! 
     
    423430 
    424431   /* 
    425      The (spatial) transformation sometimes can change attributes of an axis. Therefore, we should recheck them. 
     432     The (spatial) transformation sometimes can change attributes of an axis (e.g zoom can change mask or generate can change whole attributes) 
     433     Therefore, we should recheck them. 
    426434   */ 
    427435   void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 
     
    432440     if (this->isClientAfterTransformationChecked) return; 
    433441     if (context->hasClient) 
    434      { 
    435        if (index.numElements() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType); 
     442     {         
     443       if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
     444         || (index.numElements() != n_glo)) 
     445          computeConnectedClients(globalDim, orderPositionInGrid, distType); 
    436446     } 
    437447 
     
    439449   } 
    440450 
    441    // Send all checked attributes to server 
     451   /* 
     452     Send all checked attributes to server? (We dont have notion of server any more so client==server) 
     453     \param [in] globalDim global dimension of grid containing this axis 
     454     \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     455     \param [in] distType distribution type of the server. For now, we only have band distribution. 
     456 
     457   */ 
    442458   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    443459                                     CServerDistributionDescription::ServerDistributionType distType) 
     
    461477                             CServerDistributionDescription::ServerDistributionType distType) 
    462478  { 
    463      if (index.numElements() == n_glo.getValue()) 
    464        sendNonDistributedAttributes(); 
    465      else 
     479     sendDistributionAttribute(globalDim, orderPositionInGrid, distType); 
     480 
     481     // if (index.numElements() == n_glo.getValue()) 
     482     if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
     483         || (index.numElements() != n_glo)) 
    466484     { 
    467485       sendDistributedAttributes();        
    468486     } 
    469      sendDistributionAttribute(globalDim, orderPositionInGrid, distType); 
    470   } 
    471  
    472   void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid, 
     487     else 
     488     { 
     489       sendNonDistributedAttributes();     
     490     }      
     491  } 
     492 
     493  /* 
     494    Compute the connection between group of clients (or clients/servers). 
     495    (E.g: Suppose we have 2 group of clients in two model: A (client role) connect to B (server role), 
     496    this function calculate number of clients B connect to one client of A) 
     497     \param [in] globalDim global dimension of grid containing this axis 
     498     \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     499     \param [in] distType distribution type of the server. For now, we only have band distribution. 
     500  */ 
     501  void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 
    473502                                     CServerDistributionDescription::ServerDistributionType distType) 
    474503  { 
     
    489518      size_t nbIndex = index.numElements(); 
    490519 
    491       for (size_t idx = 0; idx < nbIndex; ++idx) 
    492       { 
    493         globalLocalIndexMap_[index(idx)] = idx; 
    494       } 
     520      // First of all, we should compute the mapping of the global index and local index of the current client 
     521      if (globalLocalIndexMap_.empty()) 
     522      { 
     523        for (size_t idx = 0; idx < nbIndex; ++idx) 
     524        { 
     525          globalLocalIndexMap_[index(idx)] = idx; 
     526        } 
     527      } 
     528 
     529      // Calculate the compressed index if any 
    495530      std::set<int> writtenInd; 
    496531      if (isCompressible_) 
     
    509544      } 
    510545 
    511       CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer, distType); 
    512       int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed(); 
    513       CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer; 
    514       if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side* 
    515       { 
    516         std::vector<int> nGlobAxis(1); 
    517         nGlobAxis[0] = n_glo.getValue(); 
    518  
    519         size_t globalSizeIndex = 1, indexBegin, indexEnd; 
    520         for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 
    521         indexBegin = 0; 
    522         if (globalSizeIndex <= clientSize) 
    523         { 
    524           indexBegin = rank%globalSizeIndex; 
    525           indexEnd = indexBegin; 
    526         } 
    527         else 
    528         { 
    529           for (int i = 0; i < clientSize; ++i) 
    530           { 
    531             range = globalSizeIndex / clientSize; 
    532             if (i < (globalSizeIndex%clientSize)) ++range; 
    533             if (i == client->clientRank) break; 
    534             indexBegin += range; 
    535           } 
    536           indexEnd = indexBegin + range - 1; 
    537         } 
    538  
    539         CArray<size_t,1> globalIndex(index.numElements()); 
    540         for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    541           globalIndex(idx) = index(idx); 
    542  
    543         CServerDistributionDescription serverDescription(nGlobAxis, nbServer); 
    544         serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd)); 
    545         CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
    546         clientServerMap->computeServerIndexMapping(globalIndex); 
    547         globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer(); 
    548         delete clientServerMap; 
     546      // Compute the global index of the current client (process) hold 
     547      std::vector<int> nGlobAxis(1); 
     548      nGlobAxis[0] = n_glo.getValue(); 
     549 
     550      size_t globalSizeIndex = 1, indexBegin, indexEnd; 
     551      for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 
     552      indexBegin = 0; 
     553      if (globalSizeIndex <= clientSize) 
     554      { 
     555        indexBegin = rank%globalSizeIndex; 
     556        indexEnd = indexBegin; 
    549557      } 
    550558      else 
    551559      { 
    552         std::vector<size_t> globalIndexServer(n_glo.getValue()); 
    553         for (size_t idx = 0; idx < n_glo.getValue(); ++idx) 
    554         { 
    555           globalIndexServer[idx] = idx; 
    556         } 
    557  
    558         for (int idx = 0; idx < nbServer; ++idx) 
    559         { 
    560           globalIndexAxisOnServer[idx] = globalIndexServer; 
    561         } 
    562       } 
     560        for (int i = 0; i < clientSize; ++i) 
     561        { 
     562          range = globalSizeIndex / clientSize; 
     563          if (i < (globalSizeIndex%clientSize)) ++range; 
     564          if (i == client->clientRank) break; 
     565          indexBegin += range; 
     566        } 
     567        indexEnd = indexBegin + range - 1; 
     568      } 
     569 
     570      CArray<size_t,1> globalIndex(index.numElements()); 
     571      for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     572        globalIndex(idx) = index(idx); 
     573 
     574      // Describe the distribution of server side 
     575      CServerDistributionDescription serverDescription(nGlobAxis, nbServer); 
     576      std::vector<int> serverZeroIndex; 
     577      serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0);       
     578 
     579      std::list<int> serverZeroIndexLeader; 
     580      std::list<int> serverZeroIndexNotLeader;  
     581      CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     582      for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     583        *it = serverZeroIndex[*it]; 
     584 
     585      // Find out the connection between client and server side 
     586      CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
     587      clientServerMap->computeServerIndexMapping(globalIndex); 
     588      CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();       
     589 
    563590 
    564591      indSrv_.swap(globalIndexAxisOnServer); 
    565  
    566592      CClientServerMapping::GlobalIndexMap::const_iterator it  = indSrv_.begin(), 
    567593                                                           ite = indSrv_.end(); 
    568  
    569594      connectedServerRank_.clear(); 
    570595      for (it = indSrv_.begin(); it != ite; ++it) { 
     
    572597      } 
    573598 
     599      for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     600        connectedServerRank_.push_back(*it); 
     601 
     602       // Even if a client has no index, it must connect to at least one server and  
     603       // send an "empty" data to this server 
     604       if (connectedServerRank_.empty()) 
     605        connectedServerRank_.push_back(client->clientRank % client->serverSize); 
     606 
    574607      nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 
    575     } 
    576   } 
    577  
    578    void CAxis::computeWrittenIndex() 
    579    {   
    580       if (computedWrittenIndex_) return; 
    581       computedWrittenIndex_ = true; 
    582  
    583       CContext* context=CContext::getCurrent();       
    584       CContextServer* server = context->server;  
    585  
    586       std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
    587       nBegin[0]       = zoom_begin; 
    588       nSize[0]        = zoom_n;    
    589       nBeginGlobal[0] = 0;  
    590       nGlob[0]        = n_glo; 
    591       CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
    592       const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
    593  
    594       size_t nbWritten = 0, indGlo;       
     608 
     609      delete clientServerMap; 
     610    } 
     611  } 
     612 
     613  /* 
     614    Compute the index of data to write into file 
     615    (Different from the previous version, this version of XIOS allows data be written into file (classical role), 
     616    or transfered to another clients) 
     617  */ 
     618  void CAxis::computeWrittenIndex() 
     619  {   
     620    if (computedWrittenIndex_) return; 
     621    computedWrittenIndex_ = true; 
     622 
     623    CContext* context=CContext::getCurrent();       
     624    CContextServer* server = context->server;  
     625 
     626    // We describe the distribution of client (server) on which data are written 
     627    std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
     628    nBegin[0]       = zoom_begin; 
     629    nSize[0]        = zoom_n;    
     630    nBeginGlobal[0] = 0;  
     631    nGlob[0]        = n_glo; 
     632    CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
     633    const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
     634 
     635    // Because all written data are local on a client,  
     636    // we need to compute the local index on the server from its corresponding global index 
     637    size_t nbWritten = 0, indGlo;       
     638    boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
     639                                                        ite = globalLocalIndexMap_.end(), it;           
     640    CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
     641                                     itSrve = writtenGlobalIndex.end(), itSrv;   
     642    if (!zoomByIndex()) 
     643    {    
     644      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     645      { 
     646        indGlo = *itSrv; 
     647        if (ite != globalLocalIndexMap_.find(indGlo)) 
     648        {           
     649          ++nbWritten; 
     650        }                  
     651      } 
     652 
     653      localIndexToWriteOnServer.resize(nbWritten); 
     654 
     655      nbWritten = 0; 
     656      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     657      { 
     658        indGlo = *itSrv; 
     659        if (ite != globalLocalIndexMap_.find(indGlo)) 
     660        { 
     661          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
     662          ++nbWritten; 
     663        }                  
     664      } 
     665    } 
     666    else 
     667    { 
     668      nbWritten = 0; 
    595669      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    596                                                           ite = globalLocalIndexMap_.end(), it;           
    597       CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    598                                        itSrve = writtenGlobalIndex.end(), itSrv;   
    599       if (!zoomByIndex()) 
    600       {    
    601         for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    602         { 
    603           indGlo = *itSrv; 
    604           if (ite != globalLocalIndexMap_.find(indGlo)) 
    605           {           
    606             ++nbWritten; 
    607           }                  
    608         } 
    609  
    610         localIndexToWriteOnServer.resize(nbWritten); 
    611  
    612         nbWritten = 0; 
    613         for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    614         { 
    615           indGlo = *itSrv; 
    616           if (ite != globalLocalIndexMap_.find(indGlo)) 
    617           { 
    618             localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
    619             ++nbWritten; 
    620           }                  
    621         } 
     670                                                          ite = globalLocalIndexMap_.end(), it; 
     671      for (int i = 0; i < zoom_index.numElements(); ++i) 
     672      { 
     673         if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
     674          ++nbWritten; 
     675      } 
     676 
     677      localIndexToWriteOnServer.resize(nbWritten); 
     678 
     679      nbWritten = 0; 
     680      for (int i = 0; i < zoom_index.numElements(); ++i) 
     681      { 
     682         if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
     683         { 
     684           localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[zoom_index(i)]; 
     685           ++nbWritten; 
     686         } 
     687      } 
     688    } 
     689 
     690    if (isCompressible()) 
     691    { 
     692      nbWritten = 0; 
     693      boost::unordered_map<size_t,size_t> localGlobalIndexMap; 
     694      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     695      { 
     696        indGlo = *itSrv; 
     697        if (ite != globalLocalIndexMap_.find(indGlo)) 
     698        { 
     699          localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
     700          ++nbWritten; 
     701        }                  
     702      } 
     703 
     704      nbWritten = 0; 
     705      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     706      { 
     707        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     708        { 
     709          ++nbWritten; 
     710        } 
     711      } 
     712 
     713      compressedIndexToWriteOnServer.resize(nbWritten); 
     714      nbWritten = 0; 
     715      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     716      { 
     717        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     718        { 
     719          compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_index(idx)]; 
     720          ++nbWritten; 
     721        } 
     722      } 
     723 
     724      numberWrittenIndexes_ = nbWritten; 
     725      if (isDistributed()) 
     726      { 
     727              
     728        MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     729        MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     730        offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    622731      } 
    623732      else 
    624       { 
    625         nbWritten = 0; 
    626         boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    627                                                             ite = globalLocalIndexMap_.end(), it; 
    628         for (int i = 0; i < zoom_index.numElements(); ++i) 
    629         { 
    630            if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
    631             ++nbWritten; 
    632         } 
    633  
    634         localIndexToWriteOnServer.resize(nbWritten); 
    635  
    636         nbWritten = 0; 
    637         for (int i = 0; i < zoom_index.numElements(); ++i) 
    638         { 
    639            if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
    640            { 
    641              localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[zoom_index(i)]; 
    642              ++nbWritten; 
    643            } 
    644         } 
    645       } 
    646  
    647       if (isCompressible()) 
    648       { 
    649         nbWritten = 0; 
    650         boost::unordered_map<size_t,size_t> localGlobalIndexMap; 
    651         for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    652         { 
    653           indGlo = *itSrv; 
    654           if (ite != globalLocalIndexMap_.find(indGlo)) 
    655           { 
    656             localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
    657             ++nbWritten; 
    658           }                  
    659         } 
    660  
    661         nbWritten = 0; 
    662         for (int idx = 0; idx < data_index.numElements(); ++idx) 
    663         { 
    664           if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    665           { 
    666             ++nbWritten; 
    667           } 
    668         } 
    669  
    670         compressedIndexToWriteOnServer.resize(nbWritten); 
    671         nbWritten = 0; 
    672         for (int idx = 0; idx < data_index.numElements(); ++idx) 
    673         { 
    674           if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    675           { 
    676             compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_index(idx)]; 
    677             ++nbWritten; 
    678           } 
    679         } 
    680  
    681         numberWrittenIndexes_ = nbWritten; 
    682         if (isDistributed()) 
    683         { 
    684                 
    685           MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    686           MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    687           offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    688         } 
    689         else 
    690           totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    691       } 
    692  
    693    } 
    694  
    695  
    696  
     733        totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
     734    } 
     735  } 
     736 
     737 
     738  /*! 
     739    Send distribution information from a group of client (client role) to another group of client (server role) 
     740    The distribution of a group of client (server role) is imposed by the group of client (client role) 
     741    \param [in] globalDim global dimension of grid containing this axis 
     742    \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     743    \param [in] distType distribution type of the server. For now, we only have band distribution. 
     744  */ 
    697745  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 
    698746                                        CServerDistributionDescription::ServerDistributionType distType) 
     
    712760      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 
    713761      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 
    714  
    715       globalDimGrid.resize(globalDim.size()); 
    716       for (int idx = 0; idx < globalDim.size(); ++idx) globalDimGrid(idx) = globalDim[idx]; 
    717762 
    718763      CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE); 
     
    732777          CMessage& msg = msgs.back(); 
    733778          msg << this->getId(); 
    734           msg << ni << begin << end; 
    735           // msg << global_zoom_begin.getValue() << global_zoom_n.getValue(); 
    736           msg << isCompressible_; 
    737           msg << orderPositionInGrid; 
    738           msg << globalDimGrid; 
     779          msg << ni << begin << end;           
     780          msg << isCompressible_;                     
    739781 
    740782          event.push(*itRank,1,msg); 
     
    746788  } 
    747789 
    748   void CAxis::sendNonDistributedAttributes() 
    749   { 
    750     CContext* context = CContext::getCurrent(); 
    751  
    752     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    753     for (int p = 0; p < nbSrvPools; ++p) 
    754     { 
    755       CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
    756  
    757       CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES); 
    758       size_t nbIndex = index.numElements(); 
    759       size_t nbDataIndex = 0; 
    760  
    761       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    762       { 
    763         int ind = data_index(idx); 
    764         if (ind >= 0 && ind < nbIndex) ++nbDataIndex; 
    765       } 
    766  
    767       CArray<int,1> dataIndex(nbDataIndex); 
    768       nbDataIndex = 0; 
    769       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    770       { 
    771         int ind = data_index(idx); 
    772         if (ind >= 0 && ind < nbIndex) 
    773         { 
    774           dataIndex(nbDataIndex) = ind; 
    775           ++nbDataIndex; 
    776         } 
    777       } 
    778  
    779       if (client->isServerLeader()) 
    780       { 
    781         std::list<CMessage> msgs; 
    782  
    783         const std::list<int>& ranks = client->getRanksServerLeader(); 
    784         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    785         { 
    786           msgs.push_back(CMessage()); 
    787           CMessage& msg = msgs.back(); 
    788           msg << this->getId(); 
    789           msg << index.getValue() << dataIndex << mask.getValue(); 
    790           msg << hasValue; 
    791           if (hasValue) msg << value.getValue(); 
    792           msg << hasBounds_; 
    793           if (hasBounds_) msg << bounds.getValue(); 
    794  
    795           event.push(*itRank, 1, msg); 
    796         } 
    797         client->sendEvent(event); 
    798       } 
    799       else client->sendEvent(event); 
    800     } 
    801   } 
    802  
    803   void CAxis::recvNonDistributedAttributes(CEventServer& event) 
    804   { 
    805     list<CEventServer::SSubEvent>::iterator it; 
    806     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    807     { 
    808       CBufferIn* buffer = it->buffer; 
    809       string axisId; 
    810       *buffer >> axisId; 
    811       get(axisId)->recvNonDistributedAttributes(it->rank, *buffer); 
    812     } 
    813   } 
    814  
    815   void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer) 
    816   {  
    817     CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index; 
    818     CArray<bool,1> tmp_mask; 
    819     CArray<double,1> tmp_val; 
    820     CArray<double,2> tmp_bnds; 
    821  
    822     buffer >> tmp_index; 
    823     index.reference(tmp_index); 
    824     buffer >> tmp_data_index; 
    825     data_index.reference(tmp_data_index); 
    826     buffer >> tmp_mask; 
    827     mask.reference(tmp_mask); 
    828  
    829     buffer >> hasValue; 
    830     if (hasValue) 
    831     { 
    832       buffer >> tmp_val; 
    833       value.reference(tmp_val); 
    834     } 
    835  
    836     buffer >> hasBounds_; 
    837     if (hasBounds_) 
    838     { 
    839       buffer >> tmp_bnds; 
    840       bounds.reference(tmp_bnds); 
    841     } 
    842  
    843     data_begin.setValue(0); 
    844     globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
    845     for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx); 
    846   } 
    847  
    848   void CAxis::sendDistributedAttributes(void) 
    849   { 
    850     int ns, n, i, j, ind, nv, idx; 
    851     CContext* context = CContext::getCurrent(); 
    852      
    853     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    854     for (int p = 0; p < nbSrvPools; ++p) 
    855     { 
    856       CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
    857  
    858       CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES); 
    859  
    860       list<CMessage> listData; 
    861       list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd; 
    862       list<CArray<bool,1> > list_mask; 
    863       list<CArray<double,1> > list_val; 
    864       list<CArray<double,2> > list_bounds; 
    865  
    866       int nbIndex = index.numElements(); 
    867       CArray<int,1> dataIndex(nbIndex); 
    868       dataIndex = -1; 
    869       for (int inx = 0; inx < data_index.numElements(); ++inx) 
    870       { 
    871         if (0 <= data_index(inx) && data_index(inx) < nbIndex) 
    872           dataIndex(inx) = data_index(inx); 
    873       } 
    874  
    875       boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap; 
    876       iteMap = indSrv_.end(); 
    877       for (int k = 0; k < connectedServerRank_.size(); ++k) 
    878       { 
    879         int nbData = 0; 
    880         int rank = connectedServerRank_[k]; 
    881         int nbSendingClient = nbConnectedClients_[rank]; 
    882         it = indSrv_.find(rank); 
    883         if (iteMap != it) 
    884           nbData = it->second.size(); 
    885  
    886         list_indi.push_back(CArray<int,1>(nbData)); 
    887         list_dataInd.push_back(CArray<int,1>(nbData));         
    888         list_mask.push_back(CArray<bool,1>(nbData)); 
    889  
    890         if (hasValue) 
    891           list_val.push_back(CArray<double,1>(nbData)); 
    892  
    893         if (hasBounds_) 
    894         { 
    895           list_bounds.push_back(CArray<double,2>(2,nbData)); 
    896         } 
    897  
    898         CArray<int,1>& indi = list_indi.back(); 
    899         CArray<int,1>& dataIndi = list_dataInd.back();         
    900         CArray<bool,1>& maskIndi = list_mask.back(); 
    901  
    902         for (n = 0; n < nbData; ++n) 
    903         { 
    904           idx = static_cast<int>(it->second[n]); 
    905           indi(n) = idx; 
    906  
    907           ind = globalLocalIndexMap_[idx]; 
    908           dataIndi(n) = dataIndex(ind); 
    909           maskIndi(n) = mask(ind); 
    910  
    911           if (hasValue) 
    912           { 
    913             CArray<double,1>& val = list_val.back(); 
    914             val(n) = value(ind); 
    915           } 
    916  
    917           if (hasBounds_) 
    918           { 
    919             CArray<double,2>& boundsVal = list_bounds.back(); 
    920             boundsVal(0, n) = bounds(0,n); 
    921             boundsVal(1, n) = bounds(1,n); 
    922           } 
    923         } 
    924  
    925         listData.push_back(CMessage()); 
    926         listData.back() << this->getId() 
    927                         << list_indi.back() << list_dataInd.back() << list_mask.back(); 
    928  
    929         listData.back() << hasValue; 
    930         if (hasValue) 
    931           listData.back() << list_val.back(); 
    932  
    933         listData.back() << hasBounds_; 
    934         if (hasBounds_) 
    935           listData.back() << list_bounds.back(); 
    936  
    937         eventData.push(rank, nbConnectedClients_[rank], listData.back()); 
    938       } 
    939  
    940       client->sendEvent(eventData); 
    941     } 
    942   } 
    943  
    944   void CAxis::recvDistributedAttributes(CEventServer& event) 
    945   { 
    946     string axisId; 
    947     vector<int> ranks; 
    948     vector<CBufferIn*> buffers; 
    949  
    950     list<CEventServer::SSubEvent>::iterator it; 
    951     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    952     { 
    953       ranks.push_back(it->rank); 
    954       CBufferIn* buffer = it->buffer; 
    955       *buffer >> axisId; 
    956       buffers.push_back(buffer); 
    957     } 
    958     get(axisId)->recvDistributedAttributes(ranks, buffers); 
    959   } 
    960  
    961  
    962   void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers) 
    963   { 
    964     int nbReceived = ranks.size(); 
    965     vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);     
    966     vector<CArray<bool,1> > vec_mask(nbReceived); 
    967     vector<CArray<double,1> > vec_val(nbReceived); 
    968     vector<CArray<double,2> > vec_bounds(nbReceived); 
    969      
    970     for (int idx = 0; idx < nbReceived; ++idx) 
    971     {       
    972       CBufferIn& buffer = *buffers[idx]; 
    973       buffer >> vec_indi[idx]; 
    974       buffer >> vec_dataInd[idx];       
    975       buffer >> vec_mask[idx]; 
    976  
    977       buffer >> hasValue; 
    978       if (hasValue) 
    979         buffer >> vec_val[idx]; 
    980  
    981       buffer >> hasBounds_; 
    982       if (hasBounds_) 
    983         buffer >> vec_bounds[idx]; 
    984     } 
    985  
    986     int nbData = 0; 
    987     for (int idx = 0; idx < nbReceived; ++idx) 
    988     { 
    989       nbData += vec_indi[idx].numElements(); 
    990     } 
    991  
    992     index.resize(nbData); 
    993     globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
    994     CArray<int,1> nonCompressedData(nbData);     
    995     mask.resize(nbData); 
    996     if (hasValue) 
    997       value.resize(nbData); 
    998     if (hasBounds_) 
    999       bounds.resize(2,nbData); 
    1000  
    1001     nbData = 0; 
    1002     for (int idx = 0; idx < nbReceived; ++idx) 
    1003     { 
    1004       CArray<int,1>& indi = vec_indi[idx]; 
    1005       CArray<int,1>& dataIndi = vec_dataInd[idx]; 
    1006       CArray<bool,1>& maskIndi = vec_mask[idx]; 
    1007       int nb = indi.numElements(); 
    1008       for (int n = 0; n < nb; ++n) 
    1009       { 
    1010         index(nbData) = indi(n); 
    1011         globalLocalIndexMap_[indi(n)] = nbData; 
    1012         nonCompressedData(nbData) = (0 <= dataIndi(n)) ? nbData : -1; 
    1013         mask(nbData) = maskIndi(n); 
    1014         if (hasValue) 
    1015           value(nbData) = vec_val[idx](n); 
    1016         if (hasBounds_) 
    1017         { 
    1018           bounds(0,nbData) = vec_bounds[idx](0,n); 
    1019           bounds(1,nbData) = vec_bounds[idx](1,n); 
    1020         } 
    1021         ++nbData; 
    1022       } 
    1023     } 
    1024  
    1025     int nbIndex = index.numElements(); 
    1026     int nbCompressedData = 0;  
    1027     for (int idx = 0; idx < nonCompressedData.numElements(); ++idx) 
    1028     { 
    1029       if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex) 
    1030         ++nbCompressedData;         
    1031     } 
    1032  
    1033     data_index.resize(nbCompressedData); 
    1034     nbCompressedData = 0; 
    1035     for (int idx = 0; idx < nonCompressedData.numElements(); ++idx) 
    1036     { 
    1037       if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex) 
    1038       { 
    1039         data_index(nbCompressedData) = nonCompressedData(idx); 
    1040         ++nbCompressedData;         
    1041       } 
    1042     } 
    1043     data_begin.setValue(0); 
    1044  
    1045     if (hasLabel) 
    1046     { 
    1047       //label_srv(ind_srv) = labelVal( ind); 
    1048     } 
    1049   } 
    1050  
     790  /* 
     791    Receive distribution attribute from another client 
     792    \param [in] event event containing data of these attributes 
     793  */ 
    1051794  void CAxis::recvDistributionAttribute(CEventServer& event) 
    1052795  { 
     
    1057800  } 
    1058801 
     802  /* 
     803    Receive distribution attribute from another client 
     804    \param [in] buffer buffer containing data of these attributes 
     805  */ 
    1059806  void CAxis::recvDistributionAttribute(CBufferIn& buffer) 
    1060807  { 
     
    1066813    std::vector<int>::iterator itZoomBegin, itZoomEnd, itZoom; 
    1067814 
    1068     buffer >> ni_srv >> begin_srv >> end_srv; 
    1069     // buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;    
    1070     buffer >> isCompressible_; 
    1071     buffer >> orderPosInGrid; 
    1072     buffer >> globalDimGrid;     
     815    buffer >> ni_srv >> begin_srv >> end_srv;     
     816    buffer >> isCompressible_;             
    1073817 
    1074818    // Set up new local size of axis on the receiving clients 
     
    1116860  } 
    1117861 
     862  /* 
     863    Send attributes of axis from a group of client to other group of clients/servers  
     864    on supposing that these attributes are not distributed among the sending group 
     865    In the future, if new attributes are added, they should also be processed in this function 
     866  */ 
     867  void CAxis::sendNonDistributedAttributes() 
     868  { 
     869    CContext* context = CContext::getCurrent(); 
     870 
     871    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     872    for (int p = 0; p < nbSrvPools; ++p) 
     873    { 
     874      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
     875 
     876      CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES); 
     877      size_t nbIndex = index.numElements(); 
     878      size_t nbDataIndex = 0; 
     879 
     880      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     881      { 
     882        int ind = data_index(idx); 
     883        if (ind >= 0 && ind < nbIndex) ++nbDataIndex; 
     884      } 
     885 
     886      CArray<int,1> dataIndex(nbDataIndex); 
     887      nbDataIndex = 0; 
     888      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     889      { 
     890        int ind = data_index(idx); 
     891        if (ind >= 0 && ind < nbIndex) 
     892        { 
     893          dataIndex(nbDataIndex) = ind; 
     894          ++nbDataIndex; 
     895        } 
     896      } 
     897 
     898      if (client->isServerLeader()) 
     899      { 
     900        std::list<CMessage> msgs; 
     901 
     902        const std::list<int>& ranks = client->getRanksServerLeader(); 
     903        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     904        { 
     905          msgs.push_back(CMessage()); 
     906          CMessage& msg = msgs.back(); 
     907          msg << this->getId(); 
     908          msg << index.getValue() << dataIndex << mask.getValue(); 
     909          msg << hasValue; 
     910          if (hasValue) msg << value.getValue(); 
     911          msg << hasBounds; 
     912          if (hasBounds) msg << bounds.getValue(); 
     913          msg << hasLabel; 
     914          if (hasLabel) msg << label.getValue(); 
     915 
     916          event.push(*itRank, 1, msg); 
     917        } 
     918        client->sendEvent(event); 
     919      } 
     920      else client->sendEvent(event); 
     921    } 
     922  } 
     923 
     924  /* 
     925    Receive the non-distributed attributes from another group of clients 
     926    \param [in] event event containing data of these attributes 
     927  */ 
     928  void CAxis::recvNonDistributedAttributes(CEventServer& event) 
     929  { 
     930    list<CEventServer::SSubEvent>::iterator it; 
     931    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
     932    { 
     933      CBufferIn* buffer = it->buffer; 
     934      string axisId; 
     935      *buffer >> axisId; 
     936      get(axisId)->recvNonDistributedAttributes(it->rank, *buffer); 
     937    } 
     938  } 
     939 
     940  /* 
     941    Receive the non-distributed attributes from another group of clients 
     942    \param [in] rank rank of the sender 
     943    \param [in] buffer buffer containing data sent from the sender 
     944  */ 
     945  void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer) 
     946  {  
     947    CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index; 
     948    CArray<bool,1> tmp_mask; 
     949    CArray<double,1> tmp_val; 
     950    CArray<double,2> tmp_bnds; 
     951    CArray<string,1> tmp_label; 
     952 
     953    buffer >> tmp_index; 
     954    index.reference(tmp_index); 
     955    buffer >> tmp_data_index; 
     956    data_index.reference(tmp_data_index); 
     957    buffer >> tmp_mask; 
     958    mask.reference(tmp_mask); 
     959 
     960    buffer >> hasValue; 
     961    if (hasValue) 
     962    { 
     963      buffer >> tmp_val; 
     964      value.reference(tmp_val); 
     965    } 
     966 
     967    buffer >> hasBounds; 
     968    if (hasBounds) 
     969    { 
     970      buffer >> tmp_bnds; 
     971      bounds.reference(tmp_bnds); 
     972    } 
     973 
     974    buffer >> hasLabel; 
     975    if (hasLabel) 
     976    { 
     977      buffer >> tmp_label; 
     978      label.reference(tmp_label); 
     979    } 
     980 
     981    // Some value should be reset here 
     982    data_begin.setValue(0); 
     983    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
     984    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx); 
     985  } 
     986 
     987  /* 
     988    Send attributes of axis from a group of client to other group of clients/servers  
     989    on supposing that these attributes are distributed among the clients of the sending group 
     990    In the future, if new attributes are added, they should also be processed in this function 
     991  */ 
     992  void CAxis::sendDistributedAttributes(void) 
     993  { 
     994    int ns, n, i, j, ind, nv, idx; 
     995    CContext* context = CContext::getCurrent(); 
     996     
     997    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     998    for (int p = 0; p < nbSrvPools; ++p) 
     999    { 
     1000      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
     1001 
     1002      CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES); 
     1003 
     1004      list<CMessage> listData; 
     1005      list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd; 
     1006      list<CArray<bool,1> > list_mask; 
     1007      list<CArray<double,1> > list_val; 
     1008      list<CArray<double,2> > list_bounds; 
     1009      list<CArray<string,1> > list_label; 
     1010 
     1011      int nbIndex = index.numElements(); 
     1012      CArray<int,1> dataIndex(nbIndex); 
     1013      dataIndex = -1; 
     1014      for (idx = 0; idx < data_index.numElements(); ++idx) 
     1015      { 
     1016        if (0 <= data_index(idx) && data_index(idx) < nbIndex) 
     1017          dataIndex(idx) = 1; 
     1018      } 
     1019 
     1020      boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap; 
     1021      iteMap = indSrv_.end(); 
     1022      for (int k = 0; k < connectedServerRank_.size(); ++k) 
     1023      { 
     1024        int nbData = 0; 
     1025        int rank = connectedServerRank_[k];         
     1026        it = indSrv_.find(rank); 
     1027        if (iteMap != it) 
     1028          nbData = it->second.size(); 
     1029 
     1030        list_indi.push_back(CArray<int,1>(nbData)); 
     1031        list_dataInd.push_back(CArray<int,1>(nbData));         
     1032        list_mask.push_back(CArray<bool,1>(nbData)); 
     1033 
     1034        if (hasValue) 
     1035          list_val.push_back(CArray<double,1>(nbData)); 
     1036 
     1037        if (hasBounds)         
     1038          list_bounds.push_back(CArray<double,2>(2,nbData)); 
     1039 
     1040        if (hasLabel) 
     1041          list_label.push_back(CArray<string,1>(nbData)); 
     1042 
     1043        CArray<int,1>& indi = list_indi.back(); 
     1044        CArray<int,1>& dataIndi = list_dataInd.back();         
     1045        CArray<bool,1>& maskIndi = list_mask.back(); 
     1046 
     1047        for (n = 0; n < nbData; ++n) 
     1048        { 
     1049          idx = static_cast<int>(it->second[n]); 
     1050          indi(n) = idx; 
     1051 
     1052          ind = globalLocalIndexMap_[idx]; 
     1053          dataIndi(n) = dataIndex(ind); 
     1054          maskIndi(n) = mask(ind); 
     1055 
     1056          if (hasValue) 
     1057          { 
     1058            CArray<double,1>& val = list_val.back(); 
     1059            val(n) = value(ind); 
     1060          } 
     1061 
     1062          if (hasBounds) 
     1063          { 
     1064            CArray<double,2>& boundsVal = list_bounds.back(); 
     1065            boundsVal(0, n) = bounds(0,n); 
     1066            boundsVal(1, n) = bounds(1,n); 
     1067          } 
     1068 
     1069          if (hasLabel) 
     1070          { 
     1071            CArray<string,1>& labelVal = list_label.back(); 
     1072            labelVal(n) = label(ind);  
     1073          } 
     1074        } 
     1075 
     1076        listData.push_back(CMessage()); 
     1077        listData.back() << this->getId() 
     1078                        << list_indi.back() << list_dataInd.back() << list_mask.back(); 
     1079 
     1080        listData.back() << hasValue; 
     1081        if (hasValue) 
     1082          listData.back() << list_val.back(); 
     1083 
     1084        listData.back() << hasBounds; 
     1085        if (hasBounds) 
     1086          listData.back() << list_bounds.back(); 
     1087 
     1088        listData.back() << hasLabel; 
     1089        if (hasLabel) 
     1090          listData.back() << list_label.back(); 
     1091 
     1092        eventData.push(rank, nbConnectedClients_[rank], listData.back()); 
     1093      } 
     1094 
     1095      client->sendEvent(eventData); 
     1096    } 
     1097  } 
     1098 
     1099  /* 
     1100    Receive the distributed attributes from another group of clients 
     1101    \param [in] event event containing data of these attributes 
     1102  */ 
     1103  void CAxis::recvDistributedAttributes(CEventServer& event) 
     1104  { 
     1105    string axisId; 
     1106    vector<int> ranks; 
     1107    vector<CBufferIn*> buffers; 
     1108 
     1109    list<CEventServer::SSubEvent>::iterator it; 
     1110    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
     1111    { 
     1112      ranks.push_back(it->rank); 
     1113      CBufferIn* buffer = it->buffer; 
     1114      *buffer >> axisId; 
     1115      buffers.push_back(buffer); 
     1116    } 
     1117    get(axisId)->recvDistributedAttributes(ranks, buffers); 
     1118  } 
     1119 
     1120  /* 
     1121    Receive the non-distributed attributes from another group of clients 
     1122    \param [in] ranks rank of the sender 
     1123    \param [in] buffers buffer containing data sent from the sender 
     1124  */ 
     1125  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers) 
     1126  { 
     1127    int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 
     1128    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);     
     1129    vector<CArray<bool,1> > vec_mask(nbReceived); 
     1130    vector<CArray<double,1> > vec_val(nbReceived); 
     1131    vector<CArray<double,2> > vec_bounds(nbReceived); 
     1132    vector<CArray<string,1> > vec_label(nbReceived); 
     1133     
     1134    for (idx = 0; idx < nbReceived; ++idx) 
     1135    {       
     1136      CBufferIn& buffer = *buffers[idx]; 
     1137      buffer >> vec_indi[idx]; 
     1138      buffer >> vec_dataInd[idx];       
     1139      buffer >> vec_mask[idx]; 
     1140 
     1141      buffer >> hasValue; 
     1142      if (hasValue) 
     1143        buffer >> vec_val[idx]; 
     1144 
     1145      buffer >> hasBounds; 
     1146      if (hasBounds) 
     1147        buffer >> vec_bounds[idx]; 
     1148 
     1149      buffer >> hasLabel; 
     1150      if (hasLabel) 
     1151        buffer >> vec_label[idx];  
     1152    } 
     1153 
     1154    // Estimate size of index array 
     1155    int nbIndexGlob = 0; 
     1156    for (idx = 0; idx < nbReceived; ++idx) 
     1157    { 
     1158      nbIndexGlob += vec_indi[idx].numElements(); 
     1159    } 
     1160 
     1161    // Recompute global index 
     1162    // Take account of the overlapped index  
     1163    index.resize(nbIndexGlob); 
     1164    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
     1165    nbIndexGlob = 0; 
     1166    for (idx = 0; idx < nbReceived; ++idx) 
     1167    { 
     1168      CArray<int,1>& tmp = vec_indi[idx]; 
     1169      for (ind = 0; ind < tmp.numElements(); ++ind) 
     1170      { 
     1171         gloInd = tmp(ind); 
     1172         if (0 == globalLocalIndexMap_.count(gloInd)) 
     1173         { 
     1174           index(nbIndexGlob) = gloInd % n_glo;            
     1175           globalLocalIndexMap_[gloInd] = nbIndexGlob;   
     1176           ++nbIndexGlob; 
     1177         }  
     1178      }  
     1179    } 
     1180 
     1181    // Resize index to its real size 
     1182    index.resizeAndPreserve(nbIndexGlob); 
     1183 
     1184    int nbData = nbIndexGlob; 
     1185    CArray<int,1> nonCompressedData(nbData); 
     1186    nonCompressedData = -1;    
     1187    mask.resize(nbData); 
     1188    if (hasValue) 
     1189      value.resize(nbData); 
     1190    if (hasBounds) 
     1191      bounds.resize(2,nbData); 
     1192    if (hasLabel) 
     1193      label.resize(nbData); 
     1194 
     1195    nbData = 0; 
     1196    for (idx = 0; idx < nbReceived; ++idx) 
     1197    { 
     1198      CArray<int,1>& indi = vec_indi[idx]; 
     1199      CArray<int,1>& dataIndi = vec_dataInd[idx]; 
     1200      CArray<bool,1>& maskIndi = vec_mask[idx]; 
     1201      int nb = indi.numElements(); 
     1202      for (int n = 0; n < nb; ++n) 
     1203      {  
     1204        locInd = globalLocalIndexMap_[size_t(indi(n))]; 
     1205 
     1206        nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 
     1207 
     1208        if (!mask(locInd)) // Only rewrite mask if it's not true 
     1209          mask(locInd) = maskIndi(n); 
     1210         
     1211        if (hasValue) 
     1212          value(locInd) = vec_val[idx](n); 
     1213 
     1214        if (hasBounds) 
     1215        { 
     1216          bounds(0,locInd) = vec_bounds[idx](0,n); 
     1217          bounds(1,locInd) = vec_bounds[idx](1,n); 
     1218        } 
     1219 
     1220        if (hasLabel) 
     1221          label(locInd) = vec_label[idx](n); 
     1222      } 
     1223    } 
     1224     
     1225    int nbCompressedData = 0;  
     1226    for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
     1227    { 
     1228      if (0 <= nonCompressedData(idx)) 
     1229        ++nbCompressedData;         
     1230    } 
     1231 
     1232    data_index.resize(nbCompressedData); 
     1233    nbCompressedData = 0; 
     1234    for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
     1235    { 
     1236      if (0 <= nonCompressedData(idx)) 
     1237      { 
     1238        data_index(nbCompressedData) = idx % n; 
     1239        ++nbCompressedData;         
     1240      } 
     1241    } 
     1242 
     1243    data_begin.setValue(0); 
     1244  } 
     1245 
     1246 
    11181247  /*! 
    11191248    Compare two axis objects.  
     
    11481277  } 
    11491278 
     1279  /* 
     1280    Add transformation into axis. This function only servers for Fortran interface 
     1281    \param [in] transType transformation type 
     1282    \param [in] id identifier of the transformation object 
     1283  */ 
    11501284  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id) 
    11511285  { 
     
    11541288  } 
    11551289 
     1290  /* 
     1291    Check whether an axis has (spatial) transformation 
     1292  */ 
    11561293  bool CAxis::hasTransformation() 
    11571294  { 
     
    11591296  } 
    11601297 
     1298  /* 
     1299    Set transformation 
     1300    \param [in] axisTrans transformation to set 
     1301  */ 
    11611302  void CAxis::setTransformations(const TransMapTypes& axisTrans) 
    11621303  { 
     
    11641305  } 
    11651306 
     1307  /* 
     1308    Return all transformation held by the axis 
     1309    \return transformation the axis has 
     1310  */ 
    11661311  CAxis::TransMapTypes CAxis::getAllTransformations(void) 
    11671312  { 
     
    11691314  } 
    11701315 
     1316  /* 
     1317    Duplicate transformation of another axis 
     1318    \param [in] src axis whose transformations are copied 
     1319  */ 
    11711320  void CAxis::duplicateTransformation(CAxis* src) 
    11721321  { 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/axis.hpp

    r1215 r1235  
    4242         typedef CAxisAttributes SuperClassAttribute; 
    4343          
    44       public : 
     44      public: 
    4545         enum EEventId 
    4646         { 
     
    5252         } ; 
    5353 
    54  
    55  
    56       public : 
    57  
     54      public: 
    5855         typedef CAxisAttributes RelAttributes; 
    5956         typedef CAxisGroup      RelGroup; 
     
    10198         static ENodeType GetType(void); 
    10299 
    103          static bool dispatchEvent(CEventServer& event); 
    104          static void recvDistributionAttribute(CEventServer& event); 
    105          void recvDistributionAttribute(CBufferIn& buffer) ; 
     100         static bool dispatchEvent(CEventServer& event);          
     101          
    106102         void checkAttributesOnClient(); 
    107103         void checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 
     
    122118         bool zoomByIndex(); 
    123119 
    124       public:                 
    125         CArray<StdString,1> label_srv; 
    126         bool hasValue; 
    127         CArray<int,1> globalDimGrid; 
    128         int orderPosInGrid; 
     120      public:  
     121        bool hasValue;         
    129122        CArray<size_t,1> localIndexToWriteOnServer; 
    130123        CArray<int, 1> compressedIndexToWriteOnServer; 
     
    140133         void sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 
    141134                                        CServerDistributionDescription::ServerDistributionType distType); 
    142          void computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid, 
     135         void computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 
    143136                                     CServerDistributionDescription::ServerDistributionType distType); 
    144137 
     
    148141         static void recvNonDistributedAttributes(CEventServer& event); 
    149142         static void recvDistributedAttributes(CEventServer& event); 
     143         static void recvDistributionAttribute(CEventServer& event); 
    150144         void recvNonDistributedAttributes(int rank, CBufferIn& buffer); 
    151145         void recvDistributedAttributes(vector<int>& rank, vector<CBufferIn*> buffers); 
     146         void recvDistributionAttribute(CBufferIn& buffer); 
    152147 
    153148         void setTransformations(const TransMapTypes&); 
     
    167162         std::vector<int> indexesToWrite; 
    168163         int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    169          std::vector<int> connectedServerRank_; 
    170          std::map<int, CArray<int,1> > indiSrv_; 
    171          bool hasBounds_; 
     164         std::vector<int> connectedServerRank_;          
     165         bool hasBounds; 
    172166         bool hasLabel;          
    173          bool computedWrittenIndex_; 
     167         bool computedWrittenIndex_;                   
    174168 
    175169       private: 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp

    r1232 r1235  
    139139    list<CArray<double,1> > list_data; 
    140140 
    141     if (!grid->doGridHaveDataDistributed()) 
     141    if (!grid->doGridHaveDataDistributed(client)) 
    142142    { 
    143143       if (client->isServerLeader()) 
     
    358358 
    359359    map<int, CArray<double,1> >::iterator it; 
    360     if (!grid->doGridHaveDataDistributed()) 
     360    if (!grid->doGridHaveDataDistributed(client)) 
    361361    { 
    362362       if (client->isServerLeader()) 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.cpp

    r1232 r1235  
    659659 
    660660             
    661             if (nbIndex != localIndex.numElements()) 
     661            if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
    662662                 ERROR("void CGrid::computeClientIndex()", 
    663663                    << "Number of local index on client is different from number of received global index"  
     
    698698       connectedServerRank_[p].clear(); 
    699699 
    700        if (!doGridHaveDataDistributed()) 
     700       if (!doGridHaveDataDistributed(client)) 
    701701       { 
    702702          if (client->isServerLeader()) 
     
    769769       if (connectedServerRank_[p].empty()) 
    770770        connectedServerRank_[p].push_back(client->clientRank % client->serverSize); 
    771        
     771 
    772772       nbSenders[p] = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[p]); 
    773773     } 
     
    13731373      itIndex = itbIndex;                                                               
    13741374 
    1375       if (!doGridHaveDataDistributed()) 
     1375      if (!doGridHaveDataDistributed(client)) 
    13761376      { 
    13771377        if (client->isServerLeader()) 
     
    15931593          for (int i = 0; i < nZoomSize.size(); ++i) 
    15941594            dataSize *= nZoomSize[i]; 
    1595           // serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize, 
    1596           //                                               nZoomBeginGlobal, nGlob); 
    15971595          serverDistribution_ = new CDistributionServer(server->intraCommRank,  
    15981596                                                        globalZoomIndex, axis_domain_order, 
     
    16041602        outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex));         
    16051603 
    1606         if (isDataDistributed_) 
     1604        if (doGridHaveDataDistributed(client)) 
    16071605        {} 
    16081606        else 
     
    18271825  } 
    18281826 
    1829   bool CGrid::doGridHaveDataDistributed() 
     1827  bool CGrid::doGridHaveDataDistributed(CContextClient* client) 
    18301828  { 
    18311829    if (isScalarGrid()) return false; 
     1830    else if (0 != client) 
     1831    { 
     1832      return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize)); 
     1833    } 
    18321834    else 
    1833       return isDataDistributed_; 
     1835      return isDataDistributed_;     
    18341836  } 
    18351837 
  • XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.hpp

    r1215 r1235  
    179179 
    180180         bool doGridHaveDataToWrite(); 
    181          bool doGridHaveDataDistributed(); 
     181         bool doGridHaveDataDistributed(CContextClient* client = 0); 
    182182         size_t getWrittenDataSize() const; 
    183183         int getNumberWrittenIndexes() const; 
  • XIOS/dev/XIOS_DEV_CMIP6/src/server_distribution_description.cpp

    r1232 r1235  
    2929{ /* Nothing to do */ } 
    3030 
     31int CServerDistributionDescription::defaultDistributedDimension(int gridDimension,                                    
     32                                                                ServerDistributionType serType) 
     33 
     34  switch (serType)  
     35  { 
     36    case BAND_DISTRIBUTION:        
     37       return ((1 == gridDimension) ? 0 : 1); 
     38      break; 
     39    default: 
     40      break; 
     41  }  
     42} 
     43 
    3144/*! 
    3245  Compute pre-defined global index distribution of server(s). 
  • XIOS/dev/XIOS_DEV_CMIP6/src/server_distribution_description.hpp

    r1232 r1235  
    5151    int getDimensionDistributed(); 
    5252 
     53    static int defaultDistributedDimension(int gridDimension,                                    
     54                                           ServerDistributionType serType=BAND_DISTRIBUTION); 
     55 
    5356  protected: 
    5457    int computeBandDistribution(int nServer, int positionDimensionDistributed = 1); 
Note: See TracChangeset for help on using the changeset viewer.