Ignore:
Timestamp:
03/22/18 10:43:20 (6 years ago)
Author:
yushan
Message:

branch_openmp merged with XIOS_DEV_CMIP6@1459

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/branch_openmp/src/node/axis.cpp

    r1334 r1460  
    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" 
    1714#include "distribution_client.hpp" 
    1815 
     16using namespace ep_lib; 
     17 
    1918namespace xios { 
    2019 
    21    /// ////////////////////// Définitions ////////////////////// /// 
     20   /// ////////////////////// Definitions ////////////////////// /// 
    2221 
    2322   CAxis::CAxis(void) 
    2423      : CObjectTemplate<CAxis>() 
    25       , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
     24      , CAxisAttributes(), isChecked(false), relFiles() 
     25      , areClientAttributesChecked_(false) 
    2626      , isClientAfterTransformationChecked(false) 
    27       , isDistributed_(false), hasBounds_(false), isCompressible_(false) 
    28       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    29       , transformationMap_(), hasValue(false), hasLabel(false) 
     27      , hasBounds(false), isCompressible_(false) 
     28      , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 
     29      , transformationMap_() 
     30      , hasValue(false), hasLabel(false) 
     31      , computedWrittenIndex_(false) 
     32      , clients() 
    3033   { 
    3134   } 
     
    3336   CAxis::CAxis(const StdString & id) 
    3437      : CObjectTemplate<CAxis>(id) 
    35       , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
     38      , CAxisAttributes(), isChecked(false), relFiles() 
     39      , areClientAttributesChecked_(false) 
    3640      , isClientAfterTransformationChecked(false) 
    37       , isDistributed_(false), hasBounds_(false), isCompressible_(false) 
    38       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    39       , transformationMap_(), hasValue(false), hasLabel(false) 
     41      , hasBounds(false), isCompressible_(false) 
     42      , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 
     43      , transformationMap_() 
     44      , hasValue(false), hasLabel(false) 
     45      , computedWrittenIndex_(false) 
     46      , clients() 
    4047   { 
    4148   } 
     
    5259     m["inverse_axis"] = TRANS_INVERSE_AXIS; 
    5360     m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS; 
     61     m["reduce_axis"] = TRANS_REDUCE_AXIS_TO_AXIS; 
    5462     m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS; 
     63     m["temporal_splitting"] = TRANS_TEMPORAL_SPLITTING; 
     64     m["duplicate_scalar"] = TRANS_DUPLICATE_SCALAR_TO_AXIS; 
    5565   } 
    5666 
     
    6373     (*CAxis::transformationMapList_ptr)["reduce_domain"]    = TRANS_REDUCE_DOMAIN_TO_AXIS; 
    6474     (*CAxis::transformationMapList_ptr)["extract_domain"]   = TRANS_EXTRACT_DOMAIN_TO_AXIS; 
     75     (*CAxis::transformationMapList_ptr)["reduce_axis"]      = TRANS_REDUCE_AXIS_TO_AXIS; 
     76     (*CAxis::transformationMapList_ptr)["temporal_splitting"] = TRANS_TEMPORAL_SPLITTING; 
     77     (*CAxis::transformationMapList_ptr)["duplicate_scalar"] = TRANS_DUPLICATE_SCALAR_TO_AXIS; 
    6578   } 
    6679 
     
    8497   bool CAxis::isDistributed(void) const 
    8598   { 
    86       return isDistributed_; 
     99      bool distributed = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 
     100             (!this->n.isEmpty() && (this->n != this->n_glo)); 
     101      // A same stupid condition to make sure that if there is only one client, axis 
     102      // should be considered to be distributed. This should be a temporary solution      
     103      distributed |= (1 == CContext::getCurrent()->client->clientSize); 
     104      return distributed; 
    87105   } 
    88106 
     
    109127   //---------------------------------------------------------------- 
    110128 
    111    const std::vector<int>& CAxis::getIndexesToWrite(void) const 
    112    { 
    113      return indexesToWrite; 
    114    } 
    115  
    116129   /*! 
    117130     Returns the number of indexes written by each server. 
    118131     \return the number of indexes written by each server 
    119132   */ 
    120    int CAxis::getNumberWrittenIndexes() const 
    121    { 
    122      return numberWrittenIndexes_; 
     133   int CAxis::getNumberWrittenIndexes(ep_lib::MPI_Comm writtenCom) 
     134   { 
     135     int writtenSize; 
     136     ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 
     137     return numberWrittenIndexes_[writtenSize]; 
    123138   } 
    124139 
     
    127142     \return the total number of indexes written by the servers 
    128143   */ 
    129    int CAxis::getTotalNumberWrittenIndexes() const 
    130    { 
    131      return totalNumberWrittenIndexes_; 
     144   int CAxis::getTotalNumberWrittenIndexes(ep_lib::MPI_Comm writtenCom) 
     145   { 
     146     int writtenSize; 
     147     ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 
     148     return totalNumberWrittenIndexes_[writtenSize]; 
    132149   } 
    133150 
     
    136153     \return the offset of indexes written by each server 
    137154   */ 
    138    int CAxis::getOffsetWrittenIndexes() const 
    139    { 
    140      return offsetWrittenIndexes_; 
     155   int CAxis::getOffsetWrittenIndexes(ep_lib::MPI_Comm writtenCom) 
     156   { 
     157     int writtenSize; 
     158     ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 
     159     return offsetWrittenIndexes_[writtenSize]; 
     160   } 
     161 
     162   CArray<int, 1>& CAxis::getCompressedIndexToWriteOnServer(ep_lib::MPI_Comm writtenCom) 
     163   { 
     164     int writtenSize; 
     165     ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 
     166     return compressedIndexToWriteOnServer[writtenSize]; 
    141167   } 
    142168 
    143169   //---------------------------------------------------------------- 
    144170 
    145    /*! 
     171      /*! 
    146172    * Compute the minimum buffer size required to send the attributes to the server(s). 
    147173    * 
    148174    * \return A map associating the server rank with its minimum buffer size. 
    149175    */ 
    150    std::map<int, StdSize> CAxis::getAttributesBufferSize() 
    151    { 
    152      CContextClient* client = CContext::getCurrent()->client; 
    153  
    154      std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(); 
    155  
    156      bool isNonDistributed = (n == n_glo); 
     176   std::map<int, StdSize> CAxis::getAttributesBufferSize(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid, 
     177                                                         CServerDistributionDescription::ServerDistributionType distType) 
     178   { 
     179 
     180     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client); 
     181 
     182//     bool isNonDistributed = (n_glo == n); 
     183     bool isDistributed = (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
     184                         || (index.numElements() != n_glo); 
    157185 
    158186     if (client->isServerLeader()) 
     
    161189       size_t size = 6 * sizeof(size_t); 
    162190       // size estimation for sendNonDistributedValue 
    163        if (isNonDistributed) 
    164          size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0)); 
     191       if (!isDistributed) 
     192       { 
     193//         size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0)); 
     194         size += CArray<int,1>::size(n_glo); 
     195         size += CArray<int,1>::size(n_glo); 
     196         size += CArray<bool,1>::size(n_glo); 
     197         size += CArray<double,1>::size(n_glo); 
     198         if (hasBounds) 
     199           size += CArray<double,2>::size(2*n_glo); 
     200         if (hasLabel) 
     201          size += CArray<StdString,1>::size(n_glo); 
     202       } 
    165203       size += CEventClient::headerSize + getId().size() + sizeof(size_t); 
    166204 
     
    171209           attributesSizes[*itRank] = size; 
    172210       } 
     211       const std::list<int>& ranksNonLeaders = client->getRanksServerNotLeader(); 
     212       for (std::list<int>::const_iterator itRank = ranksNonLeaders.begin(), itRankEnd = ranksNonLeaders.end(); itRank != itRankEnd; ++itRank) 
     213       { 
     214         if (size > attributesSizes[*itRank]) 
     215           attributesSizes[*itRank] = size; 
     216       } 
     217 
    173218     } 
    174219 
    175      if (!isNonDistributed) 
     220     if (isDistributed) 
    176221     { 
    177222       // size estimation for sendDistributedValue 
    178        std::map<int, std::vector<size_t> >::const_iterator it, ite = indSrv_.end(); 
    179        for (it = indSrv_.begin(); it != ite; ++it) 
     223       boost::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_[client->serverSize].end(); 
     224       for (it = indSrv_[client->serverSize].begin(); it != ite; ++it) 
    180225       { 
    181          size_t sizeIndexEvent = CArray<int,1>::size(it->second.size()); 
    182          if (isCompressible_) 
    183            sizeIndexEvent += CArray<int,1>::size(indWrittenSrv_[it->first].size()); 
    184  
    185          size_t sizeValEvent = CArray<double,1>::size(it->second.size()); 
    186          if (hasBounds_) 
    187            sizeValEvent += CArray<double,2>::size(2 * it->second.size()); 
    188   
     226         size_t size = 6 * sizeof(size_t); 
     227         size += CArray<int,1>::size(it->second.size()); 
     228         size += CArray<int,1>::size(it->second.size()); 
     229         size += CArray<bool,1>::size(it->second.size()); 
     230         size += CArray<double,1>::size(it->second.size()); 
     231         if (hasBounds) 
     232           size += CArray<double,2>::size(2 * it->second.size()); 
    189233         if (hasLabel) 
    190            sizeValEvent += CArray<StdString,1>::size(it->second.size()); 
    191  
    192          size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent); 
     234           size += CArray<StdString,1>::size(it->second.size()); 
     235 
     236         size += CEventClient::headerSize + getId().size() + sizeof(size_t); 
    193237         if (size > attributesSizes[it->first]) 
    194238           attributesSizes[it->first] = size; 
     
    213257   } 
    214258 
    215    void CAxis::fillInValues(const CArray<double,1>& values) 
    216    { 
    217      this->value = values; 
    218    } 
    219  
     259   /*! 
     260     Check common attributes of an axis. 
     261     This check should be done in the very beginning of work flow 
     262   */ 
    220263   void CAxis::checkAttributes(void) 
    221264   { 
     
    260303      } 
    261304 
     305      // Remove this check because it doen't make sense in case of a hole or overlapping axes 
    262306      if (!this->value.isEmpty()) 
    263307      { 
    264         StdSize true_size = value.numElements(); 
    265         if (this->n.getValue() != true_size) 
    266           ERROR("CAxis::checkAttributes(void)", 
    267                 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
    268                 << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
     308//        StdSize true_size = value.numElements(); 
     309//        if (this->n.getValue() != true_size) 
     310//          ERROR("CAxis::checkAttributes(void)", 
     311//                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
     312//                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
    269313        this->hasValue = true; 
    270314      } 
    271315 
    272       this->checkData(); 
    273       this->checkZoom(); 
    274       this->checkMask(); 
    275316      this->checkBounds(); 
    276       this->checkLabel(); 
    277  
    278       isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 
    279                        (!this->n.isEmpty() && (this->n != this->n_glo)); 
    280  
    281       // A same stupid condition to make sure that if there is only one client, axis 
    282       // should be considered to be distributed. This should be a temporary solution      
    283       isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize); 
    284    } 
    285  
     317 
     318      CContext* context=CContext::getCurrent(); 
     319      if (context->hasClient) 
     320      { 
     321        this->checkData(); 
     322        this->checkZoom(); 
     323        this->checkMask(); 
     324        this->checkLabel(); 
     325      } 
     326   } 
     327 
     328   /*! 
     329      Check the validity of data and fill in values if any. 
     330   */ 
    286331   void CAxis::checkData() 
    287332   { 
     
    306351   } 
    307352 
     353   /*! 
     354     Check validity of zoom info and fill in values if any. 
     355   */ 
    308356   void CAxis::checkZoom(void) 
    309357   { 
    310358     if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0); 
    311359     if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue()); 
    312    } 
    313  
     360     if (zoom_index.isEmpty()) 
     361     { 
     362       zoom_index.setValue(index.getValue()); 
     363     } 
     364     if (zoom_n.isEmpty()) zoom_n.setValue(n); 
     365     if (zoom_begin.isEmpty()) zoom_begin.setValue(begin); 
     366   } 
     367 
     368    size_t CAxis::getGlobalWrittenSize(void) 
     369    { 
     370      if (zoomByIndex()) return  global_zoom_index.numElements(); 
     371      else return global_zoom_n ; 
     372    } 
     373 
     374   /*! 
     375     Check validity of mask info and fill in values if any. 
     376   */ 
    314377   void CAxis::checkMask() 
    315378   { 
     
    333396   } 
    334397 
    335   void CAxis::checkBounds() 
    336   { 
    337     if (!bounds.isEmpty()) 
    338     { 
    339       if (bounds.extent(0) != 2 || bounds.extent(1) != n) 
    340         ERROR("CAxis::checkAttributes(void)", 
    341               << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl 
    342               << "Axis size is " << n.getValue() << "." << std::endl 
    343               << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << "."); 
    344       hasBounds_ = true; 
    345     } 
    346     else hasBounds_ = false; 
    347   } 
     398   /*! 
     399     Check validity of bounds info and fill in values if any. 
     400   */ 
     401   void CAxis::checkBounds() 
     402   { 
     403     if (!bounds.isEmpty()) 
     404     { 
     405       if (bounds.extent(0) != 2 || bounds.extent(1) != n) 
     406         ERROR("CAxis::checkAttributes(void)", 
     407               << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl 
     408               << "Axis size is " << n.getValue() << "." << std::endl 
     409               << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << "."); 
     410       hasBounds = true; 
     411     } 
     412     else hasBounds = false; 
     413   } 
    348414 
    349415  void CAxis::checkLabel() 
     
    360426    else hasLabel = false; 
    361427  } 
     428 
     429  /*! 
     430    Check whether we can do compressed output 
     431  */ 
    362432  void CAxis::checkEligibilityForCompressedOutput() 
    363433  { 
     
    366436  } 
    367437 
     438  /* 
     439    Check whether we do zooming by indexing 
     440    return true if do zooming by index 
     441  */ 
    368442  bool CAxis::zoomByIndex() 
    369443  { 
     
    371445  } 
    372446 
     447  /*! 
     448    Dispatch event from the lower communication layer then process event according to its type 
     449  */ 
    373450  bool CAxis::dispatchEvent(CEventServer& event) 
    374    { 
    375       if (SuperClass::dispatchEvent(event)) return true; 
    376       else 
    377       { 
    378         switch(event.type) 
    379         { 
    380            case EVENT_ID_SERVER_ATTRIBUT : 
    381              recvServerAttribut(event); 
    382              return true; 
    383              break; 
    384            case EVENT_ID_INDEX: 
    385             recvIndex(event); 
     451  { 
     452     if (SuperClass::dispatchEvent(event)) return true; 
     453     else 
     454     { 
     455       switch(event.type) 
     456       { 
     457          case EVENT_ID_DISTRIBUTION_ATTRIBUTE : 
     458            recvDistributionAttribute(event); 
    386459            return true; 
    387460            break; 
    388           case EVENT_ID_DISTRIBUTED_VALUE: 
    389             recvDistributedValue(event); 
    390             return true; 
    391             break; 
    392           case EVENT_ID_NON_DISTRIBUTED_VALUE: 
    393             recvNonDistributedValue(event); 
    394             return true; 
    395             break; 
    396            default : 
    397              ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 
    398                     << "Unknown Event"); 
    399            return false; 
    400          } 
    401       } 
    402    } 
    403  
     461         case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES: 
     462           recvNonDistributedAttributes(event); 
     463           return true; 
     464           break; 
     465         case EVENT_ID_DISTRIBUTED_ATTRIBUTES: 
     466           recvDistributedAttributes(event); 
     467           return true; 
     468           break; 
     469          default : 
     470            ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 
     471                   << "Unknown Event"); 
     472          return false; 
     473        } 
     474     } 
     475  } 
     476   
     477  /*! 
     478     Check attributes on client side (This name is still adequate???) 
     479   */ 
    404480   void CAxis::checkAttributesOnClient() 
    405481   { 
    406482     if (this->areClientAttributesChecked_) return; 
    407483 
    408      this->checkAttributes(); 
     484     CContext* context=CContext::getCurrent(); 
     485     if (context->hasClient && !context->hasServer) this->checkAttributes(); 
    409486 
    410487     this->areClientAttributesChecked_ = true; 
    411488   } 
    412489 
     490   /* 
     491     The (spatial) transformation sometimes can change attributes of an axis (e.g zoom can change mask or generate can change whole attributes) 
     492     Therefore, we should recheck them. 
     493   */ 
    413494   void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 
    414495                                                          CServerDistributionDescription::ServerDistributionType distType) 
     
    418499     if (this->isClientAfterTransformationChecked) return; 
    419500     if (context->hasClient) 
    420      { 
    421        if (n.getValue() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType); 
     501     {         
     502       if (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
     503         computeConnectedClients(globalDim, orderPositionInGrid, distType); 
     504       else if (index.numElements() != n_glo) computeConnectedClients(globalDim, orderPositionInGrid,  CServerDistributionDescription::ROOT_DISTRIBUTION); 
    422505     } 
    423506 
     
    425508   } 
    426509 
    427    // Send all checked attributes to server 
     510   /* 
     511     Send all checked attributes to server? (We dont have notion of server any more so client==server) 
     512     \param [in] globalDim global dimension of grid containing this axis 
     513     \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     514     \param [in] distType distribution type of the server. For now, we only have band distribution. 
     515 
     516   */ 
    428517   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    429518                                     CServerDistributionDescription::ServerDistributionType distType) 
     
    434523 
    435524     if (this->isChecked) return; 
    436      if (context->hasClient) 
     525     if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType);     
     526 
     527     this->isChecked = true; 
     528   } 
     529 
     530   /*! 
     531    Send attributes from one client to other clients 
     532    \param[in] globalDim global dimension of grid which contains this axis 
     533    \param[in] order 
     534  */ 
     535  void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
     536                             CServerDistributionDescription::ServerDistributionType distType) 
     537  { 
     538     sendDistributionAttribute(globalDim, orderPositionInGrid, distType); 
     539 
     540     // if (index.numElements() == n_glo.getValue()) 
     541     if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
     542         || (index.numElements() != n_glo)) 
    437543     { 
    438        sendServerAttribut(globalDim, orderPositionInGrid, distType); 
    439        if (hasValue) sendValue(); 
     544       sendDistributedAttributes();        
    440545     } 
    441  
    442      this->isChecked = true; 
    443    } 
    444  
    445   void CAxis::sendValue() 
    446   { 
    447      if (n.getValue() == n_glo.getValue()) 
    448        sendNonDistributedValue(); 
    449546     else 
    450        sendDistributedValue(); 
    451   } 
    452  
    453   void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid, 
     547     { 
     548       sendNonDistributedAttributes();     
     549     }      
     550  } 
     551 
     552  /* 
     553    Compute the connection between group of clients (or clients/servers). 
     554    (E.g: Suppose we have 2 group of clients in two model: A (client role) connect to B (server role), 
     555    this function calculate number of clients B connect to one client of A) 
     556     \param [in] globalDim global dimension of grid containing this axis 
     557     \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     558     \param [in] distType distribution type of the server. For now, we only have band distribution. 
     559  */ 
     560  void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 
    454561                                     CServerDistributionDescription::ServerDistributionType distType) 
    455562  { 
    456563    CContext* context = CContext::getCurrent(); 
    457     CContextClient* client = context->client; 
    458     int nbServer = client->serverSize; 
    459     int range, clientSize = client->clientSize; 
    460     int rank = client->clientRank; 
    461  
    462     size_t ni = this->n.getValue(); 
    463     size_t ibegin = this->begin.getValue(); 
    464     size_t zoom_end = global_zoom_begin+global_zoom_n-1; 
    465     size_t nZoomCount = 0; 
    466     size_t nbIndex = index.numElements(); 
    467  
    468     int end = (0 == n) ? begin : begin + n - 1; 
    469     int zoom_size = zoomByIndex() ? global_zoom_index.numElements() : global_zoom_n; 
    470     int minInd = min(index); 
    471     int maxInd = max(index); 
    472     for (size_t idx = 0; idx < zoom_size; ++idx) 
    473     { 
    474       size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 
    475       if (globalZoomIndex >= minInd && globalZoomIndex <= maxInd) ++nZoomCount; 
    476     } 
    477  
    478 /*    for (size_t idx = 0; idx < nbIndex; ++idx) 
    479     { 
    480       size_t globalIndex = index(idx); 
    481       if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount; 
    482     }*/ 
     564 
     565    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     566 
     567    connectedServerRank_.clear(); 
     568    nbSenders.clear(); 
     569 
     570    for (int p = 0; p < nbSrvPools; ++p) 
     571    { 
     572      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
     573      int nbServer = client->serverSize; 
     574      int range, clientSize = client->clientSize; 
     575      int rank = client->clientRank; 
     576 
     577      if (connectedServerRank_.find(nbServer) == connectedServerRank_.end()) 
     578      { 
     579        size_t ni = this->n.getValue(); 
     580        size_t ibegin = this->begin.getValue(); 
     581        size_t global_zoom_end = global_zoom_begin+global_zoom_n-1; 
     582        size_t nZoomCount = 0; 
     583        size_t nbIndex = index.numElements(); 
     584 
     585        // First of all, we should compute the mapping of the global index and local index of the current client 
     586        if (globalLocalIndexMap_.empty()) 
     587        { 
     588          for (size_t idx = 0; idx < nbIndex; ++idx) 
     589          { 
     590            globalLocalIndexMap_[index(idx)] = idx; 
     591          } 
     592        } 
     593 
     594        // Calculate the compressed index if any 
     595        std::set<int> writtenInd; 
     596        if (isCompressible_) 
     597        { 
     598          for (int idx = 0; idx < data_index.numElements(); ++idx) 
     599          { 
     600            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
     601 
     602            if (ind >= 0 && ind < ni && mask(ind)) 
     603            { 
     604              ind += ibegin; 
     605              if (ind >= global_zoom_begin && ind <= global_zoom_end) 
     606                writtenInd.insert(ind); 
     607            } 
     608          } 
     609        } 
     610 
     611        // Compute the global index of the current client (process) hold 
     612        std::vector<int> nGlobAxis(1); 
     613        nGlobAxis[0] = n_glo.getValue(); 
     614 
     615        size_t globalSizeIndex = 1, indexBegin, indexEnd; 
     616        for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 
     617        indexBegin = 0; 
     618        if (globalSizeIndex <= clientSize) 
     619        { 
     620          indexBegin = rank%globalSizeIndex; 
     621          indexEnd = indexBegin; 
     622        } 
     623        else 
     624        { 
     625          for (int i = 0; i < clientSize; ++i) 
     626          { 
     627            range = globalSizeIndex / clientSize; 
     628            if (i < (globalSizeIndex%clientSize)) ++range; 
     629            if (i == client->clientRank) break; 
     630            indexBegin += range; 
     631          } 
     632          indexEnd = indexBegin + range - 1; 
     633        } 
     634 
     635        CArray<size_t,1> globalIndex(index.numElements()); 
     636        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     637          globalIndex(idx) = index(idx); 
     638 
     639        // Describe the distribution of server side 
     640 
     641        CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType); 
     642 
     643        std::vector<int> serverZeroIndex; 
     644        serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0);       
     645 
     646        std::list<int> serverZeroIndexLeader; 
     647        std::list<int> serverZeroIndexNotLeader;  
     648        CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     649 
     650        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     651          *it = serverZeroIndex[*it]; 
     652 
     653        // Find out the connection between client and server side 
     654        CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
     655        clientServerMap->computeServerIndexMapping(globalIndex, nbServer); 
     656        CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();       
     657 
     658        indSrv_[nbServer].swap(globalIndexAxisOnServer); 
     659 
     660        if (distType==CServerDistributionDescription::ROOT_DISTRIBUTION) 
     661        { 
     662          for(int i=1; i<nbServer; ++i)  
     663          { 
     664            indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ; 
     665          } 
     666 
     667          serverZeroIndexLeader.clear() ; 
     668        } 
     669 
     670        CClientServerMapping::GlobalIndexMap::const_iterator it  = indSrv_[nbServer].begin(), 
     671                                                             ite = indSrv_[nbServer].end(); 
     672 
     673        for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first); 
     674 
     675        for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     676          connectedServerRank_[nbServer].push_back(*it); 
     677 
     678         // Even if a client has no index, it must connect to at least one server and  
     679         // send an "empty" data to this server 
     680         if (connectedServerRank_[nbServer].empty()) 
     681          connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 
     682 
     683         nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
     684 
     685        delete clientServerMap; 
     686      } 
     687    } 
     688  } 
     689 
     690  /* 
     691    Compute the index of data to write into file 
     692    (Different from the previous version, this version of XIOS allows data be written into file (classical role), 
     693    or transfered to another clients) 
     694  */ 
     695  void CAxis::computeWrittenIndex() 
     696  {   
     697    if (computedWrittenIndex_) return; 
     698    computedWrittenIndex_ = true; 
     699 
     700    CContext* context=CContext::getCurrent();       
     701    CContextServer* server = context->server;  
     702 
     703    // We describe the distribution of client (server) on which data are written 
     704    std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
     705    nBegin[0]       = zoom_begin; 
     706    nSize[0]        = zoom_n;    
     707    nBeginGlobal[0] = 0;  
     708    nGlob[0]        = n_glo; 
     709    CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
     710    const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
     711 
     712    // Because all written data are local on a client,  
     713    // we need to compute the local index on the server from its corresponding global index 
     714    size_t nbWritten = 0, indGlo;       
     715    boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
     716                                                        ite = globalLocalIndexMap_.end(), it;           
     717    CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
     718                                     itSrve = writtenGlobalIndex.end(), itSrv;   
     719    if (!zoomByIndex()) 
     720    {    
     721      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     722      { 
     723        indGlo = *itSrv; 
     724        if (ite != globalLocalIndexMap_.find(indGlo)) 
     725        {           
     726          ++nbWritten; 
     727        }                  
     728      } 
     729 
     730      localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
     731//      localIndexToWriteOnServer.resize(nbWritten); 
     732 
     733      nbWritten = 0; 
     734      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     735      { 
     736        indGlo = *itSrv; 
     737        if (ite != globalLocalIndexMap_.find(indGlo)) 
     738        { 
     739          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
     740          ++nbWritten; 
     741        }                  
     742      } 
     743    } 
     744    else 
     745    { 
     746      nbWritten = 0; 
     747      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
     748                                                          ite = globalLocalIndexMap_.end(), it; 
     749      for (int i = 0; i < zoom_index.numElements(); ++i) 
     750      { 
     751         if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
     752          ++nbWritten; 
     753      } 
     754 
     755      localIndexToWriteOnServer.resize(nbWritten); 
     756 
     757      nbWritten = 0; 
     758      for (int i = 0; i < zoom_index.numElements(); ++i) 
     759      { 
     760         if (ite != globalLocalIndexMap_.find(zoom_index(i))) 
     761         { 
     762           localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[zoom_index(i)]; 
     763           ++nbWritten; 
     764         } 
     765      } 
     766    } 
     767 
     768  } 
     769 
     770  void CAxis::computeWrittenCompressedIndex(ep_lib::MPI_Comm writtenComm) 
     771  { 
     772    int writtenCommSize; 
     773    ep_lib::MPI_Comm_size(writtenComm, &writtenCommSize); 
     774    if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end()) 
     775      return; 
     776 
     777    if (isCompressible()) 
     778    { 
     779      size_t nbWritten = 0, indGlo; 
     780      CContext* context=CContext::getCurrent();       
     781      CContextServer* server = context->server;  
     782 
     783      // We describe the distribution of client (server) on which data are written 
     784      std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
     785      nBegin[0]       = zoom_begin; 
     786      nSize[0]        = zoom_n;    
     787      nBeginGlobal[0] = 0;  
     788      nGlob[0]        = n_glo; 
     789      CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
     790      const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
     791      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
     792                                                          ite = globalLocalIndexMap_.end(), it;    
     793 
     794      CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
     795                                       itSrve = writtenGlobalIndex.end(), itSrv; 
     796      boost::unordered_map<size_t,size_t> localGlobalIndexMap; 
     797      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
     798      { 
     799        indGlo = *itSrv; 
     800        if (ite != globalLocalIndexMap_.find(indGlo)) 
     801        { 
     802          localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
     803          ++nbWritten; 
     804        }                  
     805      } 
     806 
     807      nbWritten = 0; 
     808      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     809      { 
     810        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     811        { 
     812          ++nbWritten; 
     813        } 
     814      } 
     815 
     816      compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 
     817      nbWritten = 0; 
     818      for (int idx = 0; idx < data_index.numElements(); ++idx) 
     819      { 
     820        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
     821        { 
     822          compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 
     823          ++nbWritten; 
     824        } 
     825      } 
     826 
     827      numberWrittenIndexes_[writtenCommSize] = nbWritten; 
     828      if (isDistributed()) 
     829      { 
     830              
     831        ep_lib::MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
     832        ep_lib::MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
     833        offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize]; 
     834      } 
     835      else 
     836        totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize]; 
     837    } 
     838  } 
     839 
     840  /*! 
     841    Send distribution information from a group of client (client role) to another group of client (server role) 
     842    The distribution of a group of client (server role) is imposed by the group of client (client role) 
     843    \param [in] globalDim global dimension of grid containing this axis 
     844    \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
     845    \param [in] distType distribution type of the server. For now, we only have band distribution. 
     846  */ 
     847  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 
     848                                        CServerDistributionDescription::ServerDistributionType distType) 
     849  { 
     850    std::list<CContextClient*>::iterator it; 
     851    for (it=clients.begin(); it!=clients.end(); ++it) 
     852    { 
     853      CContextClient* client = *it; 
     854      int nbServer = client->serverSize; 
     855 
     856      CServerDistributionDescription serverDescription(globalDim, nbServer); 
     857      serverDescription.computeServerDistribution(); 
     858 
     859      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 
     860      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 
     861 
     862      CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE); 
     863      if (client->isServerLeader()) 
     864      { 
     865        std::list<CMessage> msgs; 
     866 
     867        const std::list<int>& ranks = client->getRanksServerLeader(); 
     868        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     869        { 
     870          // Use const int to ensure CMessage holds a copy of the value instead of just a reference 
     871          const int begin = serverIndexBegin[*itRank][orderPositionInGrid]; 
     872          const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid]; 
     873          const int end   = begin + ni - 1;           
     874 
     875          msgs.push_back(CMessage()); 
     876          CMessage& msg = msgs.back(); 
     877          msg << this->getId(); 
     878          msg << ni << begin << end;           
     879          msg << isCompressible_;                     
     880 
     881          event.push(*itRank,1,msg); 
     882        } 
     883        client->sendEvent(event); 
     884      } 
     885      else client->sendEvent(event); 
     886    } 
     887  } 
     888 
     889  /* 
     890    Receive distribution attribute from another client 
     891    \param [in] event event containing data of these attributes 
     892  */ 
     893  void CAxis::recvDistributionAttribute(CEventServer& event) 
     894  { 
     895    CBufferIn* buffer = event.subEvents.begin()->buffer; 
     896    string axisId; 
     897    *buffer >> axisId; 
     898    get(axisId)->recvDistributionAttribute(*buffer); 
     899  } 
     900 
     901  /* 
     902    Receive distribution attribute from another client 
     903    \param [in] buffer buffer containing data of these attributes 
     904  */ 
     905  void CAxis::recvDistributionAttribute(CBufferIn& buffer) 
     906  { 
     907    int ni_srv, begin_srv, end_srv; 
     908    int global_zoom_end, zoom_end; 
     909    bool zoomIndex = zoomByIndex(); 
    483910     
    484     CArray<size_t,1> globalIndexAxis(nbIndex); 
    485     for (size_t idx = 0; idx < nbIndex; ++idx) 
    486     {       
    487       globalIndexAxis(idx) = (size_t)index(idx); 
    488     } 
    489  
    490     std::vector<size_t> globalAxisZoom(nZoomCount); 
    491     nZoomCount = 0; 
    492     for (size_t idx = 0; idx < zoom_size; ++idx) 
    493     { 
    494       size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 
    495       if (globalZoomIndex >= minInd && globalZoomIndex <= maxInd) 
    496       { 
    497         globalAxisZoom[nZoomCount] = globalZoomIndex; 
    498         ++nZoomCount; 
    499       } 
    500     } 
    501  
    502     std::set<int> writtenInd; 
    503     if (isCompressible_) 
    504     { 
     911    std::vector<int> zoom_index_tmp; 
     912    std::vector<int>::iterator itZoomBegin, itZoomEnd, itZoom; 
     913 
     914    buffer >> ni_srv >> begin_srv >> end_srv;     
     915    buffer >> isCompressible_;             
     916 
     917    // Set up new local size of axis on the receiving clients 
     918    n.setValue(ni_srv); 
     919    begin.setValue(begin_srv); 
     920 
     921    // If we have zoom by index then process it 
     922    if (zoomIndex) 
     923    { 
     924      zoom_index_tmp.resize(global_zoom_index.numElements()); 
     925      std::copy(global_zoom_index.begin(), global_zoom_index.end(), zoom_index_tmp.begin()); 
     926      std::sort(zoom_index_tmp.begin(), zoom_index_tmp.end()); 
     927      itZoomBegin = std::lower_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), begin_srv); 
     928      itZoomEnd   = std::upper_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), end_srv);       
     929      int sz = std::distance(itZoomBegin, itZoomEnd); 
     930      zoom_index.resize(sz); 
     931      itZoom = itZoomBegin; 
     932      for (int i = 0; i < sz; ++i, ++itZoom) 
     933      { 
     934        zoom_index(i) = *(itZoom); 
     935      } 
     936    } 
     937 
     938    global_zoom_begin = zoomIndex ? 0 : global_zoom_begin ; 
     939    global_zoom_n     = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 
     940    global_zoom_end   = global_zoom_begin + global_zoom_n - 1; 
     941 
     942    zoom_begin = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomBegin) 
     943                           : global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ; 
     944    zoom_end   = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomEnd) - 1  
     945                           : global_zoom_end < end_srv ? global_zoom_end : end_srv ; 
     946    zoom_n     = zoom_end - zoom_begin + 1; 
     947 
     948    if (zoom_n<=0) 
     949    { 
     950      zoom_n = 0; zoom_begin=global_zoom_begin; //0; zoom_begin = 0;  
     951    } 
     952 
     953    if (n_glo == n) 
     954    { 
     955      zoom_begin = zoomIndex ? std::distance(itZoomBegin, zoom_index_tmp.begin()) 
     956                             : global_zoom_begin;       
     957      zoom_n     = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 
     958    } 
     959  } 
     960 
     961  /* 
     962    Send attributes of axis from a group of client to other group of clients/servers  
     963    on supposing that these attributes are not distributed among the sending group 
     964    In the future, if new attributes are added, they should also be processed in this function 
     965  */ 
     966  void CAxis::sendNonDistributedAttributes() 
     967  { 
     968    std::list<CContextClient*>::iterator it; 
     969    for (it=clients.begin(); it!=clients.end(); ++it) 
     970  { 
     971    CContextClient* client = *it; 
     972 
     973      CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES); 
     974      size_t nbIndex = index.numElements(); 
     975      size_t nbDataIndex = 0; 
     976 
    505977      for (int idx = 0; idx < data_index.numElements(); ++idx) 
    506978      { 
    507         int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
    508  
    509         if (ind >= 0 && ind < ni && mask(ind)) 
    510         { 
    511           ind += ibegin; 
    512           if (ind >= global_zoom_begin && ind <= zoom_end) 
    513             writtenInd.insert(ind); 
    514         } 
    515       } 
    516     } 
    517  
    518     CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer); 
    519     int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed(); 
    520     CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer; 
    521     if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side* 
    522     { 
    523       std::vector<int> nGlobAxis(1); 
    524       nGlobAxis[0] = n_glo.getValue(); 
    525  
    526       size_t globalSizeIndex = 1, indexBegin, indexEnd; 
    527       for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 
    528       indexBegin = 0; 
    529       if (globalSizeIndex <= clientSize) 
    530       { 
    531         indexBegin = rank%globalSizeIndex; 
    532         indexEnd = indexBegin; 
    533       } 
    534       else 
    535       { 
    536         for (int i = 0; i < clientSize; ++i) 
    537         { 
    538           range = globalSizeIndex / clientSize; 
    539           if (i < (globalSizeIndex%clientSize)) ++range; 
    540           if (i == client->clientRank) break; 
    541           indexBegin += range; 
    542         } 
    543         indexEnd = indexBegin + range - 1; 
    544       } 
    545  
    546       CServerDistributionDescription serverDescription(nGlobAxis, nbServer); 
    547       serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd)); 
    548       CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
    549       clientServerMap->computeServerIndexMapping(globalIndexAxis); 
    550       globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer(); 
    551       delete clientServerMap; 
    552     } 
    553     else 
    554     { 
    555       std::vector<size_t> globalIndexServer(n_glo.getValue()); 
    556       for (size_t idx = 0; idx < n_glo.getValue(); ++idx) 
    557       { 
    558         globalIndexServer[idx] = idx; 
    559       } 
    560  
    561       for (int idx = 0; idx < nbServer; ++idx) 
    562       { 
    563         globalIndexAxisOnServer[idx] = globalIndexServer; 
    564       } 
    565     } 
    566  
    567     CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(), 
    568                                                          ite = globalIndexAxisOnServer.end(); 
    569     std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(), 
    570                                         iteVec = (globalAxisZoom).end(); 
    571     indSrv_.clear(); 
    572     indWrittenSrv_.clear(); 
    573     for (; it != ite; ++it) 
    574     { 
    575       int rank = it->first; 
    576       const std::vector<size_t>& globalIndexTmp = it->second; 
    577       int nb = globalIndexTmp.size(); 
    578  
    579       for (int i = 0; i < nb; ++i) 
    580       { 
    581         if (std::binary_search(itbVec, iteVec, globalIndexTmp[i])) 
    582         { 
    583           indSrv_[rank].push_back(globalIndexTmp[i]); 
    584         } 
    585  
    586         if (writtenInd.count(globalIndexTmp[i])) 
    587         { 
    588           indWrittenSrv_[rank].push_back(globalIndexTmp[i]); 
    589         } 
    590       } 
    591     } 
    592  
    593     connectedServerRank_.clear(); 
    594     for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) { 
    595       connectedServerRank_.push_back(it->first); 
    596     } 
    597  
    598     if (!indSrv_.empty()) 
    599     { 
    600       std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(), 
    601                                                      iteIndSrv = indSrv_.end(); 
    602       connectedServerRank_.clear(); 
    603       for (; itIndSrv != iteIndSrv; ++itIndSrv) 
    604         connectedServerRank_.push_back(itIndSrv->first); 
    605     } 
    606     nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 
    607   } 
    608  
    609   void CAxis::sendNonDistributedValue() 
    610   { 
    611     CContext* context = CContext::getCurrent(); 
    612     CContextClient* client = context->client; 
    613     CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_VALUE); 
    614  
    615     int zoom_end = global_zoom_begin + global_zoom_n - 1; 
    616     int nb = 0; 
    617 /*    for (size_t idx = 0; idx < n; ++idx) 
    618     { 
    619       size_t globalIndex = begin + idx; 
    620       if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nb; 
    621     }*/ 
    622  
    623     int end = (0 == n) ? begin : begin + n - 1; 
    624     int zoom_size = zoomByIndex() ? global_zoom_index.numElements() : global_zoom_n; 
    625     for (size_t idx = 0; idx < zoom_size; ++idx) 
    626     { 
    627       size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 
    628       if (globalZoomIndex >= begin && globalZoomIndex <= end) ++nb; 
    629     } 
    630  
    631     int nbWritten = 0; 
    632     if (isCompressible_) 
    633     { 
     979        int ind = data_index(idx); 
     980        if (ind >= 0 && ind < nbIndex) ++nbDataIndex; 
     981      } 
     982 
     983      CArray<int,1> dataIndex(nbDataIndex); 
     984      nbDataIndex = 0; 
    634985      for (int idx = 0; idx < data_index.numElements(); ++idx) 
    635986      { 
    636         int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n); 
    637  
    638         if (ind >= 0 && ind < n && mask(ind)) 
    639         { 
    640           ind += begin; 
    641           if (ind >= global_zoom_begin && ind <= zoom_end) 
    642             ++nbWritten; 
    643         } 
    644       } 
    645     } 
    646  
    647     CArray<double,1> val(nb); 
    648     nb = 0; 
    649 /*    for (size_t idx = 0; idx < n; ++idx) 
    650     { 
    651       size_t globalIndex = begin + idx; 
    652       if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) 
    653       { 
    654         val(nb) = value(idx); 
    655         ++nb; 
    656       } 
    657     }*/ 
    658  
    659     for (size_t idx = 0; idx < zoom_size; ++idx) 
    660     { 
    661       size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 
    662       if (globalZoomIndex >= begin && globalZoomIndex <= end) 
    663       { 
    664         val(nb) = value(globalZoomIndex-begin); 
    665         ++nb; 
    666       } 
    667     } 
    668  
    669     CArray<int, 1> writtenInd(nbWritten); 
    670     nbWritten = 0; 
    671     if (isCompressible_) 
    672     { 
    673       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    674       { 
    675         int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n); 
    676  
    677         if (ind >= 0 && ind < n && mask(ind)) 
    678         { 
    679           ind += begin; 
    680           if (ind >= global_zoom_begin && ind <= zoom_end) 
    681           { 
    682             writtenInd(nbWritten) = ind; 
    683             ++nbWritten; 
    684           } 
    685         } 
    686       } 
    687     } 
    688  
    689     if (client->isServerLeader()) 
    690     { 
    691       std::list<CMessage> msgs; 
    692  
    693       const std::list<int>& ranks = client->getRanksServerLeader(); 
    694       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    695       { 
    696         msgs.push_back(CMessage()); 
    697         CMessage& msg = msgs.back(); 
    698         msg << this->getId(); 
    699         msg << val; 
    700         if (isCompressible_) 
    701           msg << writtenInd; 
    702         event.push(*itRank, 1, msg); 
    703       } 
    704       client->sendEvent(event); 
    705     } 
    706     else client->sendEvent(event); 
    707   } 
    708  
    709   void CAxis::sendDistributedValue(void) 
    710   { 
    711     int ns, n, i, j, ind, nv, idx; 
    712     CContext* context = CContext::getCurrent(); 
    713     CContextClient* client=context->client; 
    714  
    715     // send value for each connected server 
    716     CEventClient eventIndex(getType(), EVENT_ID_INDEX); 
    717     CEventClient eventVal(getType(), EVENT_ID_DISTRIBUTED_VALUE); 
    718  
    719     list<CMessage> list_msgsIndex, list_msgsVal; 
    720     list<CArray<int,1> > list_indi; 
    721     list<CArray<int,1> > list_writtenInd; 
    722     list<CArray<double,1> > list_val; 
    723     list<CArray<double,2> > list_bounds; 
    724     list<CArray<StdString,1> > list_label; 
    725  
    726     std::map<int, std::vector<size_t> >::const_iterator it, iteMap; 
    727     iteMap = indSrv_.end(); 
    728     for (int k = 0; k < connectedServerRank_.size(); ++k) 
    729     { 
    730       int nbData = 0; 
    731       int rank = connectedServerRank_[k]; 
    732       it = indSrv_.find(rank); 
    733       if (iteMap != it) 
    734         nbData = it->second.size(); 
    735  
    736       list_indi.push_back(CArray<int,1>(nbData)); 
    737       list_val.push_back(CArray<double,1>(nbData)); 
    738  
    739       if (hasBounds_) 
    740       { 
    741         list_bounds.push_back(CArray<double,2>(2,nbData)); 
    742       } 
    743        
    744       if (hasLabel) 
    745       { 
    746         list_label.push_back(CArray<StdString,1>(nbData)); 
    747       } 
    748  
    749       CArray<int,1>& indi = list_indi.back(); 
    750       CArray<double,1>& val = list_val.back(); 
    751  
    752       for (n = 0; n < nbData; ++n) 
    753       { 
    754         idx = static_cast<int>(it->second[n]); 
    755         ind = idx - begin; 
    756  
    757         val(n) = value(ind); 
    758         indi(n) = idx; 
    759  
    760         if (hasBounds_) 
    761         { 
    762           CArray<double,2>& boundsVal = list_bounds.back(); 
    763           boundsVal(0, n) = bounds(0,n); 
    764           boundsVal(1, n) = bounds(1,n); 
    765         } 
    766          
    767         if (hasLabel) 
    768         { 
    769           CArray<StdString,1>& labelVal = list_label.back(); 
    770           labelVal(n) = label(n); 
    771         } 
    772       } 
    773  
    774       list_msgsIndex.push_back(CMessage()); 
    775       list_msgsIndex.back() << this->getId() << list_indi.back(); 
    776  
    777       if (isCompressible_) 
    778       { 
    779         std::vector<int>& writtenIndSrc = indWrittenSrv_[rank]; 
    780         list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size())); 
    781         CArray<int,1>& writtenInd = list_writtenInd.back(); 
    782  
    783         for (n = 0; n < writtenInd.numElements(); ++n) 
    784           writtenInd(n) = writtenIndSrc[n]; 
    785  
    786         list_msgsIndex.back() << writtenInd; 
    787       } 
    788  
    789       list_msgsVal.push_back(CMessage()); 
    790       list_msgsVal.back() << this->getId() << list_val.back(); 
    791  
    792       if (hasBounds_) 
    793       { 
    794         list_msgsVal.back() << list_bounds.back(); 
    795       } 
    796   
    797       if (hasLabel) 
    798       { 
    799         list_msgsVal.back() << list_label.back(); 
    800       } 
    801  
    802       eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back()); 
    803       eventVal.push(rank, nbConnectedClients_[rank], list_msgsVal.back()); 
    804     } 
    805  
    806     client->sendEvent(eventIndex); 
    807     client->sendEvent(eventVal); 
    808   } 
    809  
    810   void CAxis::recvIndex(CEventServer& event) 
    811   { 
    812     CAxis* axis; 
    813  
     987        int ind = data_index(idx); 
     988        if (ind >= 0 && ind < nbIndex) 
     989        { 
     990          dataIndex(nbDataIndex) = ind; 
     991          ++nbDataIndex; 
     992        } 
     993      } 
     994 
     995      if (client->isServerLeader()) 
     996      { 
     997        std::list<CMessage> msgs; 
     998 
     999        const std::list<int>& ranks = client->getRanksServerLeader(); 
     1000        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1001        { 
     1002          msgs.push_back(CMessage()); 
     1003          CMessage& msg = msgs.back(); 
     1004          msg << this->getId(); 
     1005          msg << index.getValue() << dataIndex << mask.getValue(); 
     1006          msg << hasValue; 
     1007          if (hasValue) msg << value.getValue(); 
     1008          msg << hasBounds; 
     1009          if (hasBounds) msg << bounds.getValue(); 
     1010          msg << hasLabel; 
     1011          if (hasLabel) msg << label.getValue(); 
     1012 
     1013          event.push(*itRank, 1, msg); 
     1014        } 
     1015        client->sendEvent(event); 
     1016      } 
     1017      else client->sendEvent(event); 
     1018    } 
     1019  } 
     1020 
     1021  /* 
     1022    Receive the non-distributed attributes from another group of clients 
     1023    \param [in] event event containing data of these attributes 
     1024  */ 
     1025  void CAxis::recvNonDistributedAttributes(CEventServer& event) 
     1026  { 
    8141027    list<CEventServer::SSubEvent>::iterator it; 
    8151028    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
     
    8181031      string axisId; 
    8191032      *buffer >> axisId; 
    820       axis = get(axisId); 
    821       axis->recvIndex(it->rank, *buffer); 
    822     } 
    823  
    824     if (axis->isCompressible_) 
    825     { 
    826       std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end()); 
    827  
    828       CContextServer* server = CContext::getCurrent()->server; 
    829       axis->numberWrittenIndexes_ = axis->indexesToWrite.size(); 
    830       MPI_Allreduce(&axis->numberWrittenIndexes_, &axis->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    831       MPI_Scan(&axis->numberWrittenIndexes_, &axis->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    832       axis->offsetWrittenIndexes_ -= axis->numberWrittenIndexes_; 
    833     } 
    834   } 
    835  
    836   void CAxis::recvIndex(int rank, CBufferIn& buffer) 
    837   { 
    838     buffer >> indiSrv_[rank]; 
    839  
    840     if (isCompressible_) 
    841     { 
    842       CArray<int, 1> writtenIndexes; 
    843       buffer >> writtenIndexes; 
    844       indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements()); 
    845       for (int i = 0; i < writtenIndexes.numElements(); ++i) 
    846         indexesToWrite.push_back(writtenIndexes(i)); 
    847     } 
    848   } 
    849  
    850   void CAxis::recvDistributedValue(CEventServer& event) 
    851   { 
     1033      get(axisId)->recvNonDistributedAttributes(it->rank, *buffer); 
     1034    } 
     1035  } 
     1036 
     1037  /* 
     1038    Receive the non-distributed attributes from another group of clients 
     1039    \param [in] rank rank of the sender 
     1040    \param [in] buffer buffer containing data sent from the sender 
     1041  */ 
     1042  void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer) 
     1043  {  
     1044    CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index; 
     1045    CArray<bool,1> tmp_mask; 
     1046    CArray<double,1> tmp_val; 
     1047    CArray<double,2> tmp_bnds; 
     1048    CArray<string,1> tmp_label; 
     1049 
     1050    buffer >> tmp_index; 
     1051    index.reference(tmp_index); 
     1052    buffer >> tmp_data_index; 
     1053    data_index.reference(tmp_data_index); 
     1054    buffer >> tmp_mask; 
     1055    mask.reference(tmp_mask); 
     1056 
     1057    buffer >> hasValue; 
     1058    if (hasValue) 
     1059    { 
     1060      buffer >> tmp_val; 
     1061      value.reference(tmp_val); 
     1062    } 
     1063 
     1064    buffer >> hasBounds; 
     1065    if (hasBounds) 
     1066    { 
     1067      buffer >> tmp_bnds; 
     1068      bounds.reference(tmp_bnds); 
     1069    } 
     1070 
     1071    buffer >> hasLabel; 
     1072    if (hasLabel) 
     1073    { 
     1074      buffer >> tmp_label; 
     1075      label.reference(tmp_label); 
     1076    } 
     1077 
     1078    // Some value should be reset here 
     1079    data_begin.setValue(0); 
     1080    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
     1081//    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx); 
     1082    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[index(idx)] = idx; 
     1083  } 
     1084 
     1085/* 
     1086    Send attributes of axis from a group of client to other group of clients/servers  
     1087    on supposing that these attributes are distributed among the clients of the sending group 
     1088    In the future, if new attributes are added, they should also be processed in this function 
     1089  */ 
     1090  void CAxis::sendDistributedAttributes(void) 
     1091  { 
     1092    int ns, n, i, j, ind, nv, idx; 
     1093    std::list<CContextClient*>::iterator it; 
     1094 
     1095    for (it=clients.begin(); it!=clients.end(); ++it) 
     1096    { 
     1097      CContextClient* client = *it; 
     1098      int nbServer = client->serverSize; 
     1099 
     1100      CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES); 
     1101 
     1102      list<CMessage> listData; 
     1103      list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd; 
     1104      list<CArray<bool,1> > list_mask; 
     1105      list<CArray<double,1> > list_val; 
     1106      list<CArray<double,2> > list_bounds; 
     1107      list<CArray<string,1> > list_label; 
     1108 
     1109      int nbIndex = index.numElements(); 
     1110      CArray<int,1> dataIndex(nbIndex); 
     1111      dataIndex = -1; 
     1112      for (idx = 0; idx < data_index.numElements(); ++idx) 
     1113      { 
     1114        if (0 <= data_index(idx) && data_index(idx) < nbIndex) 
     1115          dataIndex(idx) = 1; 
     1116      } 
     1117 
     1118      boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap; 
     1119      iteMap = indSrv_[nbServer].end(); 
     1120      for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 
     1121      { 
     1122        int nbData = 0; 
     1123        int rank = connectedServerRank_[nbServer][k]; 
     1124        it = indSrv_[nbServer].find(rank); 
     1125        if (iteMap != it) 
     1126          nbData = it->second.size(); 
     1127 
     1128        list_indi.push_back(CArray<int,1>(nbData)); 
     1129        list_dataInd.push_back(CArray<int,1>(nbData));         
     1130        list_mask.push_back(CArray<bool,1>(nbData)); 
     1131 
     1132        if (hasValue) 
     1133          list_val.push_back(CArray<double,1>(nbData)); 
     1134 
     1135        if (hasBounds)         
     1136          list_bounds.push_back(CArray<double,2>(2,nbData)); 
     1137 
     1138        if (hasLabel) 
     1139          list_label.push_back(CArray<string,1>(nbData)); 
     1140 
     1141        CArray<int,1>& indi = list_indi.back(); 
     1142        CArray<int,1>& dataIndi = list_dataInd.back();         
     1143        CArray<bool,1>& maskIndi = list_mask.back(); 
     1144 
     1145        for (n = 0; n < nbData; ++n) 
     1146        { 
     1147          idx = static_cast<int>(it->second[n]); 
     1148          indi(n) = idx; 
     1149 
     1150          ind = globalLocalIndexMap_[idx]; 
     1151          dataIndi(n) = dataIndex(ind); 
     1152          maskIndi(n) = mask(ind); 
     1153 
     1154          if (hasValue) 
     1155          { 
     1156            CArray<double,1>& val = list_val.back(); 
     1157            val(n) = value(ind); 
     1158          } 
     1159 
     1160          if (hasBounds) 
     1161          { 
     1162            CArray<double,2>& boundsVal = list_bounds.back(); 
     1163            boundsVal(0, n) = bounds(0,ind); 
     1164            boundsVal(1, n) = bounds(1,ind); 
     1165          } 
     1166 
     1167          if (hasLabel) 
     1168          { 
     1169            CArray<string,1>& labelVal = list_label.back(); 
     1170            labelVal(n) = label(ind);  
     1171          } 
     1172        } 
     1173 
     1174        listData.push_back(CMessage()); 
     1175        listData.back() << this->getId() 
     1176                        << list_indi.back() << list_dataInd.back() << list_mask.back(); 
     1177 
     1178        listData.back() << hasValue; 
     1179        if (hasValue) 
     1180          listData.back() << list_val.back(); 
     1181 
     1182        listData.back() << hasBounds; 
     1183        if (hasBounds) 
     1184          listData.back() << list_bounds.back(); 
     1185 
     1186        listData.back() << hasLabel; 
     1187        if (hasLabel) 
     1188          listData.back() << list_label.back(); 
     1189 
     1190        eventData.push(rank, nbSenders[nbServer][rank], listData.back()); 
     1191      } 
     1192 
     1193      client->sendEvent(eventData); 
     1194    } 
     1195  } 
     1196 
     1197  /* 
     1198    Receive the distributed attributes from another group of clients 
     1199    \param [in] event event containing data of these attributes 
     1200  */ 
     1201  void CAxis::recvDistributedAttributes(CEventServer& event) 
     1202  { 
     1203    string axisId; 
     1204    vector<int> ranks; 
     1205    vector<CBufferIn*> buffers; 
     1206 
    8521207    list<CEventServer::SSubEvent>::iterator it; 
    8531208    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    8541209    { 
     1210      ranks.push_back(it->rank); 
    8551211      CBufferIn* buffer = it->buffer; 
    856       string axisId; 
    8571212      *buffer >> axisId; 
    858       get(axisId)->recvDistributedValue(it->rank, *buffer); 
    859     } 
    860   } 
    861  
    862   void CAxis::recvDistributedValue(int rank, CBufferIn& buffer) 
    863   { 
    864     CArray<int,1> &indi = indiSrv_[rank]; 
    865     CArray<double,1> val; 
    866     CArray<double,2> boundsVal; 
    867     CArray<StdString,1> labelVal; 
    868  
    869     buffer >> val; 
    870     if (hasBounds_) buffer >> boundsVal; 
    871     if (hasLabel) buffer >> labelVal; 
    872  
    873     int i, j, ind_srv; 
    874     for (int ind = 0; ind < indi.numElements(); ++ind) 
    875     { 
    876       i = indi(ind); 
    877       ind_srv = i - zoom_begin_srv; 
    878       value_srv(ind_srv) = val(ind); 
    879       if (hasBounds_) 
    880       { 
    881         bound_srv(0,ind_srv) = boundsVal(0, ind); 
    882         bound_srv(1,ind_srv) = boundsVal(1, ind); 
    883       } 
    884  
     1213      buffers.push_back(buffer); 
     1214    } 
     1215    get(axisId)->recvDistributedAttributes(ranks, buffers); 
     1216  } 
     1217 
     1218  /* 
     1219    Receive the non-distributed attributes from another group of clients 
     1220    \param [in] ranks rank of the sender 
     1221    \param [in] buffers buffer containing data sent from the sender 
     1222  */ 
     1223  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers) 
     1224  { 
     1225    int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 
     1226    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);     
     1227    vector<CArray<bool,1> > vec_mask(nbReceived); 
     1228    vector<CArray<double,1> > vec_val(nbReceived); 
     1229    vector<CArray<double,2> > vec_bounds(nbReceived); 
     1230    vector<CArray<string,1> > vec_label(nbReceived); 
     1231     
     1232    for (idx = 0; idx < nbReceived; ++idx) 
     1233    {       
     1234      CBufferIn& buffer = *buffers[idx]; 
     1235      buffer >> vec_indi[idx]; 
     1236      buffer >> vec_dataInd[idx];       
     1237      buffer >> vec_mask[idx]; 
     1238 
     1239      buffer >> hasValue; 
     1240      if (hasValue) 
     1241        buffer >> vec_val[idx]; 
     1242 
     1243      buffer >> hasBounds; 
     1244      if (hasBounds) 
     1245        buffer >> vec_bounds[idx]; 
     1246 
     1247      buffer >> hasLabel; 
    8851248      if (hasLabel) 
    886       { 
    887         label_srv(ind_srv) = labelVal( ind); 
    888       } 
    889  
    890     } 
    891   } 
    892  
    893    void CAxis::recvNonDistributedValue(CEventServer& event) 
    894   { 
    895     CAxis* axis; 
    896  
    897     list<CEventServer::SSubEvent>::iterator it; 
    898     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    899     { 
    900       CBufferIn* buffer = it->buffer; 
    901       string axisId; 
    902       *buffer >> axisId; 
    903       axis = get(axisId); 
    904       axis->recvNonDistributedValue(it->rank, *buffer); 
    905     } 
    906  
    907     if (axis->isCompressible_) 
    908     { 
    909       std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end()); 
    910  
    911       axis->numberWrittenIndexes_ = axis->totalNumberWrittenIndexes_ = axis->indexesToWrite.size(); 
    912       axis->offsetWrittenIndexes_ = 0; 
    913     } 
    914   } 
    915  
    916   void CAxis::recvNonDistributedValue(int rank, CBufferIn& buffer) 
    917   { 
    918     CArray<double,1> val; 
    919     buffer >> val; 
    920  
    921     for (int ind = 0; ind < val.numElements(); ++ind) 
    922     { 
    923       value_srv(ind) = val(ind); 
    924       if (hasBounds_) 
    925       { 
    926         bound_srv(0,ind) = bounds(0,ind); 
    927         bound_srv(1,ind) = bounds(1,ind); 
    928       } 
    929       if (hasLabel) 
    930       { 
    931         label_srv(ind) = label(ind); 
    932       } 
    933     } 
    934  
    935     if (isCompressible_) 
    936     { 
    937       CArray<int, 1> writtenIndexes; 
    938       buffer >> writtenIndexes; 
    939       indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements()); 
    940       for (int i = 0; i < writtenIndexes.numElements(); ++i) 
    941         indexesToWrite.push_back(writtenIndexes(i)); 
    942     } 
    943   } 
    944  
    945   void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid, 
    946                                  CServerDistributionDescription::ServerDistributionType distType) 
    947   { 
    948     CContext* context = CContext::getCurrent(); 
    949     CContextClient* client = context->client; 
    950     int nbServer = client->serverSize; 
    951  
    952     CServerDistributionDescription serverDescription(globalDim, nbServer); 
    953     serverDescription.computeServerDistribution(); 
    954  
    955     std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 
    956     std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 
    957  
    958     CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT); 
    959     if (client->isServerLeader()) 
    960     { 
    961       std::list<CMessage> msgs; 
    962  
    963       const std::list<int>& ranks = client->getRanksServerLeader(); 
    964       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    965       { 
    966         // Use const int to ensure CMessage holds a copy of the value instead of just a reference 
    967         const int begin = serverIndexBegin[*itRank][orderPositionInGrid]; 
    968         const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid]; 
    969         const int end   = begin + ni - 1; 
    970         const bool zoomIndex = zoomByIndex(); 
    971  
    972         msgs.push_back(CMessage()); 
    973         CMessage& msg = msgs.back(); 
    974         msg << this->getId(); 
    975         msg << ni << begin << end; 
    976         msg << global_zoom_begin.getValue() << global_zoom_n.getValue(); 
    977         msg << isCompressible_; 
    978         msg << zoomIndex; 
    979         if (zoomIndex) 
    980           msg << global_zoom_index.getValue(); 
    981  
    982         event.push(*itRank,1,msg); 
    983       } 
    984       client->sendEvent(event); 
    985     } 
    986     else client->sendEvent(event); 
    987   } 
    988  
    989   void CAxis::recvServerAttribut(CEventServer& event) 
    990   { 
    991     CBufferIn* buffer = event.subEvents.begin()->buffer; 
    992     string axisId; 
    993     *buffer >> axisId; 
    994     get(axisId)->recvServerAttribut(*buffer); 
    995   } 
    996  
    997   void CAxis::recvServerAttribut(CBufferIn& buffer) 
    998   { 
    999     int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp; 
    1000     bool zoomIndex;     
    1001     CArray<int,1> zoom_index_recv; 
    1002     std::vector<int> zoom_index_tmp; 
    1003     std::vector<int>::iterator itZoomBeginSrv, itZoomEndSrv, itZoomSrv; 
    1004  
    1005     buffer >> ni_srv >> begin_srv >> end_srv; 
    1006     buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp; 
    1007     buffer >> isCompressible_; 
    1008     buffer >> zoomIndex; 
    1009     if (zoomIndex) 
    1010     { 
    1011       buffer >> zoom_index_recv; 
    1012       global_zoom_index.reference(zoom_index_recv); 
    1013       zoom_index_tmp.resize(global_zoom_index.numElements()); 
    1014       std::copy(global_zoom_index.begin(), global_zoom_index.end(), zoom_index_tmp.begin()); 
    1015       std::sort(zoom_index_tmp.begin(), zoom_index_tmp.end()); 
    1016       itZoomBeginSrv = std::lower_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), begin_srv); 
    1017       itZoomEndSrv   = std::upper_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), end_srv);       
    1018       int sz = std::distance(itZoomBeginSrv, itZoomEndSrv); 
    1019       zoom_index_srv.resize(sz); 
    1020       itZoomSrv = itZoomBeginSrv; 
    1021       for (int i = 0; i < sz; ++i, ++itZoomSrv) 
    1022       { 
    1023         zoom_index_srv(i) = *(itZoomSrv); 
    1024       } 
    1025     } 
    1026  
    1027     global_zoom_begin = global_zoom_begin_tmp; 
    1028     global_zoom_n  = global_zoom_n_tmp; 
    1029     int global_zoom_end = global_zoom_begin + global_zoom_n - 1; 
    1030  
    1031     zoom_begin_srv = zoomIndex ? std::distance(itZoomBeginSrv, zoom_index_tmp.begin()) 
    1032                                  : global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ; 
    1033     zoom_end_srv   = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomEndSrv) - 1  
    1034                                  : global_zoom_end < end_srv ? global_zoom_end : end_srv ; 
    1035     zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1; 
    1036       
    1037     global_zoom_begin_srv = zoomIndex ? 0 : global_zoom_begin ; 
    1038     global_zoom_size_srv  = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 
    1039  
    1040     if (zoom_size_srv<=0) 
    1041     { 
    1042       zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0; 
    1043     } 
    1044  
    1045     if (n_glo == n) 
    1046     { 
    1047       zoom_begin_srv = zoomIndex ? std::distance(itZoomBeginSrv, zoom_index_tmp.begin()) 
    1048                                    : global_zoom_begin;       
    1049       zoom_size_srv  = zoomIndex ? zoom_index_tmp.size() 
    1050                                    : global_zoom_n; 
    1051     } 
     1249        buffer >> vec_label[idx];  
     1250    } 
     1251 
     1252    // Estimate size of index array 
     1253    int nbIndexGlob = 0; 
     1254    for (idx = 0; idx < nbReceived; ++idx) 
     1255    { 
     1256      nbIndexGlob += vec_indi[idx].numElements(); 
     1257    } 
     1258 
     1259    // Recompute global index 
     1260    // Take account of the overlapped index  
     1261    index.resize(nbIndexGlob); 
     1262    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
     1263    nbIndexGlob = 0; 
     1264    for (idx = 0; idx < nbReceived; ++idx) 
     1265    { 
     1266      CArray<int,1>& tmp = vec_indi[idx]; 
     1267      for (ind = 0; ind < tmp.numElements(); ++ind) 
     1268      { 
     1269         gloInd = tmp(ind); 
     1270         if (0 == globalLocalIndexMap_.count(gloInd)) 
     1271         { 
     1272           index(nbIndexGlob) = gloInd % n_glo;            
     1273           globalLocalIndexMap_[gloInd] = nbIndexGlob;   
     1274           ++nbIndexGlob; 
     1275         }  
     1276      }  
     1277    } 
     1278 
     1279    // Resize index to its real size 
     1280    if (nbIndexGlob==0) index.resize(nbIndexGlob) ; 
     1281    else index.resizeAndPreserve(nbIndexGlob); 
     1282 
     1283    int nbData = nbIndexGlob; 
     1284    CArray<int,1> nonCompressedData(nbData); 
     1285    nonCompressedData = -1;    
     1286    mask.resize(nbData); 
    10521287    if (hasValue) 
    1053     { 
    1054       value_srv.resize(zoom_size_srv); 
    1055       if (hasBounds_)  bound_srv.resize(2,zoom_size_srv); 
    1056       if (hasLabel)  label_srv.resize(zoom_size_srv); 
    1057     } 
     1288      value.resize(nbData); 
     1289    if (hasBounds) 
     1290      bounds.resize(2,nbData); 
     1291    if (hasLabel) 
     1292      label.resize(nbData); 
     1293 
     1294    nbData = 0; 
     1295    for (idx = 0; idx < nbReceived; ++idx) 
     1296    { 
     1297      CArray<int,1>& indi = vec_indi[idx]; 
     1298      CArray<int,1>& dataIndi = vec_dataInd[idx]; 
     1299      CArray<bool,1>& maskIndi = vec_mask[idx]; 
     1300      int nb = indi.numElements(); 
     1301      for (int n = 0; n < nb; ++n) 
     1302      {  
     1303        locInd = globalLocalIndexMap_[size_t(indi(n))]; 
     1304 
     1305        nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 
     1306 
     1307        if (!mask(locInd)) // Only rewrite mask if it's not true 
     1308          mask(locInd) = maskIndi(n); 
     1309         
     1310        if (hasValue) 
     1311          value(locInd) = vec_val[idx](n); 
     1312 
     1313        if (hasBounds) 
     1314        { 
     1315          bounds(0,locInd) = vec_bounds[idx](0,n); 
     1316          bounds(1,locInd) = vec_bounds[idx](1,n); 
     1317        } 
     1318 
     1319        if (hasLabel) 
     1320          label(locInd) = vec_label[idx](n); 
     1321      } 
     1322    } 
     1323     
     1324    int nbCompressedData = 0;  
     1325    for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
     1326    { 
     1327      if (0 <= nonCompressedData(idx)) 
     1328        ++nbCompressedData;         
     1329    } 
     1330 
     1331    data_index.resize(nbCompressedData); 
     1332    nbCompressedData = 0; 
     1333    for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
     1334    { 
     1335      if (0 <= nonCompressedData(idx)) 
     1336      { 
     1337        data_index(nbCompressedData) = idx % n; 
     1338        ++nbCompressedData;         
     1339      } 
     1340    } 
     1341 
     1342    data_begin.setValue(0); 
    10581343  } 
    10591344 
     
    10901375  } 
    10911376 
     1377  /* 
     1378    Add transformation into axis. This function only servers for Fortran interface 
     1379    \param [in] transType transformation type 
     1380    \param [in] id identifier of the transformation object 
     1381  */ 
    10921382  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id) 
    10931383  { 
     
    10961386  } 
    10971387 
     1388  /* 
     1389    Check whether an axis has (spatial) transformation 
     1390  */ 
    10981391  bool CAxis::hasTransformation() 
    10991392  { 
     
    11011394  } 
    11021395 
     1396  /* 
     1397    Set transformation 
     1398    \param [in] axisTrans transformation to set 
     1399  */ 
    11031400  void CAxis::setTransformations(const TransMapTypes& axisTrans) 
    11041401  { 
     
    11061403  } 
    11071404 
     1405  /* 
     1406    Return all transformation held by the axis 
     1407    \return transformation the axis has 
     1408  */ 
    11081409  CAxis::TransMapTypes CAxis::getAllTransformations(void) 
    11091410  { 
     
    11111412  } 
    11121413 
     1414  /* 
     1415    Duplicate transformation of another axis 
     1416    \param [in] src axis whose transformations are copied 
     1417  */ 
    11131418  void CAxis::duplicateTransformation(CAxis* src) 
    11141419  { 
     
    11401445  } 
    11411446 
     1447  void CAxis::setContextClient(CContextClient* contextClient) 
     1448  { 
     1449    if (clientsSet.find(contextClient)==clientsSet.end()) 
     1450    { 
     1451      clients.push_back(contextClient) ; 
     1452      clientsSet.insert(contextClient); 
     1453    } 
     1454} 
     1455 
    11421456  void CAxis::parse(xml::CXMLNode & node) 
    11431457  { 
Note: See TracChangeset for help on using the changeset viewer.