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/grid.cpp

    r1334 r1460  
    1818#include "grid_transformation.hpp" 
    1919#include "grid_generate.hpp" 
     20#include "server.hpp" 
    2021 
    2122namespace xios { 
     
    3132      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    3233      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    33       , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
     34      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
     35          , isDataDistributed_(true), isCompressible_(false) 
    3436      , transformations_(0), isTransformed_(false) 
    3537      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    3638      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
     39      , computedWrittenIndex_(false) 
     40      , clients() 
    3741   { 
    3842     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); 
     
    4953      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    5054      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    51       , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
     55      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
     56          , isDataDistributed_(true), isCompressible_(false) 
    5257      , transformations_(0), isTransformed_(false) 
    5358      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    5459      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
     60      , computedWrittenIndex_(false) 
     61      , clients() 
    5562   { 
    5663     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); 
     
    8794     { 
    8895       std::vector<int> dataNindex = clientDistribution_->getDataNIndex(); 
    89        for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i]; 
     96       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];        
    9097     } 
    9198     return retvalue; 
     
    96103    * 
    97104    * \return A map associating the server rank with its minimum buffer size. 
     105    * TODO: Refactor code 
    98106    */ 
    99    std::map<int, StdSize> CGrid::getAttributesBufferSize() 
    100    { 
    101      std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(); 
     107   std::map<int, StdSize> CGrid::getAttributesBufferSize(CContextClient* client, bool bufferForWriting) 
     108   { 
     109     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client); 
    102110 
    103111     // The grid indexes require a similar size as the actual data 
    104      std::map<int, StdSize> dataSizes = getDataBufferSize(); 
     112     std::map<int, StdSize> dataSizes = getDataBufferSize(client, "", bufferForWriting); 
    105113     std::map<int, StdSize>::iterator it, itE = dataSizes.end(); 
    106114     for (it = dataSizes.begin(); it != itE; ++it) 
     
    110118         attributesSizes[it->first] = it->second; 
    111119     } 
    112  
     120      
    113121     // Account for the axis attributes 
    114122     std::vector<CAxis*> axisList = getAxis(); 
    115123     for (size_t i = 0; i < axisList.size(); ++i) 
    116124     { 
    117        std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(); 
     125       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]); 
    118126       for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it) 
    119127       { 
     128         it->second += 2 * sizeof(bool); 
    120129         if (it->second > attributesSizes[it->first]) 
    121130           attributesSizes[it->first] = it->second; 
     
    127136     for (size_t i = 0; i < domList.size(); ++i) 
    128137     { 
    129        std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize(); 
     138       std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize(client); 
    130139       for (it = domAttBuffSize.begin(), itE = domAttBuffSize.end(); it != itE; ++it) 
    131140       { 
     141         it->second += 2 * sizeof(bool); 
    132142         if (it->second > attributesSizes[it->first]) 
    133143           attributesSizes[it->first] = it->second; 
     
    136146 
    137147     return attributesSizes; 
    138    } 
     148  } 
    139149 
    140150   /*! 
    141     * Compute the minimum buffer size required to send the data to the server(s). 
    142     * 
     151    * Compute the minimum buffer size required to send the data. 
     152    * \param client contextClient used to determine the size of connected receivers 
    143153    * \param id the id used to tag the data 
    144     * \return A map associating the server rank with its minimum buffer size. 
     154    * \param bufferForWriting flag indicating if a buffer is used to send data for writing 
     155    * \return A map associating the sender rank with its minimum buffer size. 
    145156    */ 
    146    std::map<int, StdSize> CGrid::getDataBufferSize(const std::string& id /*= ""*/) 
    147    { 
    148      std::map<int, StdSize> dataSizes; 
     157   std::map<int, StdSize> CGrid::getDataBufferSize(CContextClient* client, const std::string& id /*= ""*/, bool bufferForWriting /*= "false"*/) 
     158   {      
    149159     // The record index is sometimes sent along with the data but we always 
    150160     // include it in the size calculation for the sake of simplicity 
    151      const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() + 2 * sizeof(size_t); 
    152  
    153      std::map<int, size_t>::const_iterator itEnd = connectedDataSize_.end(); 
    154      for (size_t k = 0; k < connectedServerRank_.size(); ++k) 
     161     const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size()  
     162                                                       + 2 * sizeof(size_t)  
     163                                                       + sizeof(size_t); 
     164 
     165     std::map<int, StdSize> dataSizes; 
     166     int receiverSize = client->serverSize; 
     167     std::map<int,size_t>& dataSizeMap = bufferForWriting ? connectedDataSize_[receiverSize]: connectedDataSizeRead_; 
     168     std::vector<int>& connectedServerRanks = bufferForWriting ? connectedServerRank_[receiverSize] : connectedServerRankRead_; 
     169 
     170     std::map<int, size_t>::const_iterator itEnd = dataSizeMap.end(); 
     171     for (size_t k = 0; k < connectedServerRanks.size(); ++k) 
    155172     { 
    156        int rank = connectedServerRank_[k]; 
    157        std::map<int, size_t>::const_iterator it = connectedDataSize_.find(rank); 
     173       int rank = connectedServerRanks[k]; 
     174       std::map<int, size_t>::const_iterator it = dataSizeMap.find(rank); 
    158175       size_t count = (it != itEnd) ? it->second : 0; 
    159176 
     
    164181   } 
    165182 
     183   size_t CGrid::getGlobalWrittenSize(void) 
     184   { 
     185         std::vector<CDomain*> domainP = this->getDomains(); 
     186     std::vector<CAxis*> axisP = this->getAxis(); 
     187      
     188     size_t globalGridSize=1 ; 
     189     for (std::vector<CDomain*>::iterator it=domainP.begin(); it!=domainP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ; 
     190     for (std::vector<CAxis*>::iterator it=axisP.begin(); it!=axisP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ; 
     191     return globalGridSize ; 
     192   } 
     193    
     194    
    166195   void CGrid::checkAttributesAfterTransformation() 
    167196   { 
     
    225254 
    226255   //--------------------------------------------------------------- 
    227  
     256   /* 
     257     Find all reference of grid's components and inherite attributes if necessary 
     258   */ 
    228259   void CGrid::solveDomainAxisRef(bool areAttributesChecked) 
    229260   { 
     
    236267   } 
    237268 
     269   /* 
     270     Go up hierachy reference and fill in the base reference with attributes of the children 
     271     This function should be only used after reading component's attributes from file 
     272   */ 
    238273   void CGrid::solveDomainAxisBaseRef() 
    239274   { 
     
    272307   { 
    273308     CContext* context = CContext::getCurrent(); 
    274      CContextClient* client=context->client; 
    275  
    276      if (isScalarGrid()) 
    277      { 
    278        if (context->hasClient) 
    279           if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; } 
    280  
    281        if (this->isChecked) return; 
    282  
    283        if (context->hasClient) 
    284        { 
    285           this->computeIndexScalarGrid(); 
     309     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;    
     310     nbSrvPools = 1;   
     311     for (int p = 0; p < nbSrvPools; ++p) 
     312     {     
     313       if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent)  
     314       {  
     315         if (isScalarGrid()) 
     316           sendIndexScalarGrid(); 
     317         else 
     318           sendIndex(); 
     319         this->isIndexSent = true;  
    286320       } 
    287321 
    288        if (!(this->hasTransform() && !this->isTransformed())) 
    289         this->isChecked = true; 
    290        return; 
     322       // Not sure about this 
     323       //if (!(this->hasTransform() && !this->isTransformed())) 
     324       // this->isChecked = true; 
     325       //return; 
    291326     } 
    292  
    293      if (context->hasClient) 
    294       if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; } 
    295  
     327     
    296328     if (this->isChecked) return; 
    297  
    298      if (context->hasClient) 
    299      { 
    300         this->checkAttributesAfterTransformation(); 
    301         this->checkMask(); 
    302         this->computeIndex(); 
    303      } 
    304  
    305      if (!(this->hasTransform() && !this->isTransformed()))  
     329     this->checkAttributesAfterTransformation(); 
     330 
     331     // TODO: Transfer grid attributes 
     332     //if (!context->hasClient && context->hasServer) this->createMask(); 
     333     this->computeIndex(); 
     334 
     335     if (!(this->hasTransform() && !this->isTransformed())) 
    306336      this->isChecked = true; 
    307337 
    308338     if (!(this->hasTransform() && (!this->isGenerated()))) 
    309       this->isChecked = true;  
    310    } 
    311  
     339      this->isChecked = true; 
     340   } 
     341 
     342   /* 
     343     Create mask of grid from mask of its components 
     344   */ 
    312345   void CGrid::createMask(void) 
    313346   { 
     
    318351 
    319352      std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    320       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask_1d); 
     353      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    321354      std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    322355      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
     
    349382   } 
    350383 
     384   /* 
     385     Check validity of grid's mask by using the masks of its components 
     386   */ 
    351387   void CGrid::checkMask(void) 
    352388   { 
     
    357393 
    358394      std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    359       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask_1d); 
     395      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    360396      std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    361397      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
     
    388424   } 
    389425 
    390    void CGrid::modifyMask(const CArray<int,1>& indexToModify) 
     426 
     427/*! 
     428  A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 
     429It's not a good idea to store all multi-dimension arrays corresponding to each mask. 
     430One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 
     431  \param [in] multi-dimension array grid mask 
     432*/ 
     433 
     434  void CGrid::getLocalMask(CArray<bool,1>& localMask) 
     435  { 
     436      std::vector<CDomain*> domainP = this->getDomains(); 
     437      std::vector<CAxis*> axisP = this->getAxis(); 
     438      int dim = domainP.size() * 2 + axisP.size(); 
     439 
     440      switch (dim) 
     441      { 
     442        case 0: 
     443          getLocalMask(mask_0d, localMask); 
     444          break; 
     445        case 1: 
     446          getLocalMask(mask_1d, localMask); 
     447          break; 
     448        case 2: 
     449          getLocalMask(mask_2d, localMask); 
     450          break; 
     451        case 3: 
     452          getLocalMask(mask_3d, localMask); 
     453          break; 
     454        case 4: 
     455          getLocalMask(mask_4d, localMask); 
     456          break; 
     457        case 5: 
     458          getLocalMask(mask_5d, localMask); 
     459          break; 
     460        case 6: 
     461          getLocalMask(mask_6d, localMask); 
     462          break; 
     463        case 7: 
     464          getLocalMask(mask_7d, localMask); 
     465          break; 
     466        default: 
     467          break; 
     468      } 
     469  } 
     470       
     471   /* 
     472     Modify value of mask in a certain index 
     473     This function can be used to correct the mask of grid after being constructed with createMask 
     474     \param [in] indexToModify 
     475     \param [in] modifyValue 
     476   */ 
     477   void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 
    391478   { 
    392479      using namespace std; 
     
    396483 
    397484      switch (dim) { 
     485        case 0: 
     486          modifyGridMask(mask_0d, indexToModify, modifyValue); 
     487          break; 
    398488        case 1: 
    399           modifyGridMask(mask_1d, indexToModify); 
     489          modifyGridMask(mask_1d, indexToModify, modifyValue); 
    400490          break; 
    401491        case 2: 
    402           modifyGridMask(mask_2d, indexToModify); 
     492          modifyGridMask(mask_2d, indexToModify, modifyValue); 
    403493          break; 
    404494        case 3: 
    405           modifyGridMask(mask_3d, indexToModify); 
     495          modifyGridMask(mask_3d, indexToModify, modifyValue); 
    406496          break; 
    407497        case 4: 
    408           modifyGridMask(mask_1d, indexToModify); 
     498          modifyGridMask(mask_4d, indexToModify, modifyValue); 
    409499          break; 
    410500        case 5: 
    411           modifyGridMask(mask_2d, indexToModify); 
     501          modifyGridMask(mask_5d, indexToModify, modifyValue); 
    412502          break; 
    413503        case 6: 
    414           modifyGridMask(mask_3d, indexToModify); 
     504          modifyGridMask(mask_6d, indexToModify, modifyValue); 
    415505          break; 
    416506        case 7: 
    417           modifyGridMask(mask_3d, indexToModify); 
     507          modifyGridMask(mask_7d, indexToModify, modifyValue); 
     508          break; 
     509        default: 
     510          break; 
     511      } 
     512   } 
     513 
     514   /* 
     515     Change the mask size. This function is used on reconstructing mask in server side 
     516     \param [in] newDimensionSize 
     517     \param [in] newValue  
     518   */ 
     519   void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 
     520   {       
     521      std::vector<CDomain*> domainP = this->getDomains(); 
     522      std::vector<CAxis*> axisP = this->getAxis();             
     523      int dim = domainP.size() * 2 + axisP.size(); 
     524 
     525      switch (dim) { 
     526        case 0: 
     527          modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 
     528          break; 
     529        case 1: 
     530          modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 
     531          break; 
     532        case 2: 
     533          modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 
     534          break; 
     535        case 3: 
     536          modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 
     537          break; 
     538        case 4: 
     539          modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 
     540          break; 
     541        case 5: 
     542          modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 
     543          break; 
     544        case 6: 
     545          modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 
     546          break; 
     547        case 7: 
     548          modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 
    418549          break; 
    419550        default: 
     
    486617   } 
    487618 
    488    std::vector<int> CGrid::getAxisPositionInGrid() const 
    489    { 
    490      return axisPositionInGrid_; 
     619   /*! 
     620      Compute the index to for write data into a file 
     621   */ 
     622   void CGrid::computeWrittenIndex() 
     623   {       
     624      if (computedWrittenIndex_) return; 
     625      computedWrittenIndex_ = true; 
     626 
     627      if (isScalarGrid()) 
     628      { 
     629        size_t nbWritten = 1; 
     630        int writtenIndex = 0; 
     631 
     632        localIndexToWriteOnClient.resize(nbWritten);   
     633        localIndexToWriteOnServer.resize(nbWritten); 
     634        localIndexToWriteOnServer(0) = writtenIndex; 
     635        localIndexToWriteOnClient(0) = writtenIndex; 
     636         
     637        return; 
     638      } 
     639 
     640      size_t nbWritten = 0, indGlo; 
     641      CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
     642      CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 
     643                                                              ite = globalDataIndex.end(), it;     
     644      const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex();                                                               
     645      CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 
     646                                                          itSrve = globalLocalIndex.end(), itSrv; 
     647      for (it = itb; it != ite; ++it) 
     648      { 
     649        indGlo = it->first; 
     650        if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;                 
     651      } 
     652 
     653      localIndexToWriteOnClient.resize(nbWritten);   
     654      localIndexToWriteOnServer.resize(nbWritten); 
     655       
     656      { 
     657        numberWrittenIndexes_ = nbWritten; 
     658        if (isDataDistributed_) 
     659        { 
     660          CContextServer* server = CContext::getCurrent()->server;       
     661          MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     662          MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
     663          offsetWrittenIndexes_ -= numberWrittenIndexes_; 
     664        } 
     665        else 
     666          totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
     667      } 
     668 
     669      nbWritten = 0;  
     670      for (it = itb; it != ite; ++it) 
     671      { 
     672        indGlo = it->first; 
     673        itSrv = globalLocalIndex.find(indGlo); 
     674        if (itSrve != itSrv) 
     675        { 
     676          localIndexToWriteOnServer(nbWritten) = itSrv->second; 
     677          localIndexToWriteOnClient(nbWritten) = it->second; 
     678          ++nbWritten;                 
     679        }  
     680      } 
    491681   } 
    492682 
    493683   //--------------------------------------------------------------- 
     684 
     685   /* 
     686     Compute the global index and its local index taking account mask and data index. 
     687     These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 
     688     (via function computeConnectedClient) 
     689     These global indexes also correspond to data sent to servers (if any) 
     690   */ 
     691   void CGrid::computeClientIndex() 
     692   { 
     693     CContext* context = CContext::getCurrent(); 
     694 
     695     CContextClient* client = context->client;  // Here it's not important which contextClient to recuperate 
     696     int rank = client->clientRank; 
     697 
     698     clientDistribution_ = new CDistributionClient(rank, this); 
     699     // Get local data index on client 
     700     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 
     701     int nbStoreIndex = storeIndex_client.numElements(); 
     702     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
     703 
     704     if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
     705     else 
     706     { 
     707        // Mapping global index received from clients to the storeIndex_client 
     708        CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
     709        CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
     710        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
     711                                               ite = outGlobalIndexFromClient.end(), it; 
     712 
     713        for (it = itb; it != ite; ++it) 
     714        { 
     715          int rank = it->first; 
     716          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
     717          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
     718          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
     719          size_t nbIndex = 0; 
     720 
     721          // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
     722          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     723          { 
     724            if (itGloe != globalDataIndex.find(globalIndex(idx))) 
     725            { 
     726              ++nbIndex; 
     727            } 
     728          } 
     729 
     730          if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
     731               ERROR("void CGrid::computeClientIndex()", 
     732                  << "Number of local index on client is different from number of received global index" 
     733                  << "Rank of sent client " << rank <<"." 
     734                  << "Number of local index " << nbIndex << ". " 
     735                  << "Number of received global index " << localIndex.numElements() << "."); 
     736 
     737          nbIndex = 0; 
     738          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
     739          { 
     740            if (itGloe != globalDataIndex.find(globalIndex(idx))) 
     741            { 
     742              localIndex(idx) = globalDataIndex[globalIndex(idx)]; 
     743            } 
     744          } 
     745        } 
     746      } 
     747   } 
     748 
     749   /*! 
     750     Compute connected receivers and indexes to be sent to these receivers. 
     751   */ 
     752   void CGrid::computeConnectedClients() 
     753   { 
     754     CContext* context = CContext::getCurrent(); 
     755     int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 
     756     connectedServerRank_.clear(); 
     757     connectedDataSize_.clear(); 
     758     globalIndexOnServer_.clear(); 
     759     nbSenders.clear(); 
     760 
     761     for (int p = 0; p < nbSrvPools; ++p) 
     762     { 
     763       CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 
     764       int receiverSize = client->serverSize; 
     765//       connectedServerRank_[client].clear(); 
     766 
     767       if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 
     768       { 
     769        if (!doGridHaveDataDistributed(client)) 
     770         { 
     771            if (client->isServerLeader()) 
     772            { 
     773              size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
     774              const std::list<int>& ranks = client->getRanksServerLeader(); 
     775              for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     776              { 
     777                connectedServerRank_[receiverSize].push_back(*itRank); 
     778                connectedDataSize_[receiverSize][*itRank] = ssize; 
     779              } 
     780            } 
     781            return; 
     782         } 
     783 
     784         // Compute mapping between client and server 
     785         std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
     786         CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
     787         std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
     788                                                                                                    client->clientRank, 
     789                                                                                                    client->clientSize, 
     790                                                                                                    axis_domain_order, 
     791                                                                                                    getDistributedDimension()); 
     792 
     793         // Even if servers have no index, they must received something from client 
     794         // We only use several client to send "empty" message to these servers 
     795         std::list<int> serverZeroIndexLeader; 
     796         std::list<int> serverZeroIndexNotLeader; 
     797         CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
     798         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     799           *it = serverZeroIndex[*it]; 
     800 
     801         if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 
     802           computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 
     803 
     804         const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
     805         CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
     806         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
     807         itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
     808         iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
     809 
     810         for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
     811         { 
     812           int serverRank = itGlobalMap->first; 
     813           int indexSize = itGlobalMap->second.size(); 
     814           const std::vector<size_t>& indexVec = itGlobalMap->second; 
     815           for (int idx = 0; idx < indexSize; ++idx) 
     816           { 
     817              itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
     818              if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
     819              { 
     820                if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 
     821                  connectedDataSize_[receiverSize][serverRank] = 1; 
     822                else 
     823                  ++connectedDataSize_[receiverSize][serverRank]; 
     824              } 
     825           } 
     826         } 
     827 
     828         // Connected servers which really have index 
     829         for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
     830           connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 
     831         } 
     832 
     833         // Connected servers which have no index at all 
     834         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
     835           connectedServerRank_[receiverSize].push_back(*it); 
     836 
     837         // Even if a client has no index, it must connect to at least one server and 
     838         // send an "empty" data to this server 
     839         if (connectedServerRank_[receiverSize].empty()) 
     840          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
     841 
     842         nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
     843       } 
     844     } 
     845   } 
    494846 
    495847   /*! 
     
    503855   { 
    504856     CContext* context = CContext::getCurrent(); 
    505      CContextClient* client = context->client; 
    506  
    507      // First of all, compute distribution on client side 
    508      clientDistribution_ = new CDistributionClient(client->clientRank, this); 
    509      // Get local data index on client 
    510      storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 
    511      int nbStoreIndex = storeIndex_client.numElements(); 
    512      for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
    513      isDataDistributed_= clientDistribution_->isDataDistributed(); 
    514  
    515      connectedServerRank_.clear(); 
    516  
    517      if (!doGridHaveDataDistributed()) 
     857     if (isScalarGrid()) 
    518858     { 
    519         if (client->isServerLeader()) 
    520         { 
    521           size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
    522           const std::list<int>& ranks = client->getRanksServerLeader(); 
    523           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    524           { 
    525             connectedServerRank_.push_back(*itRank); 
    526             connectedDataSize_[*itRank] = ssize; 
    527           } 
    528         } 
    529         return; 
    530      } 
    531  
    532      // Compute mapping between client and server 
    533      std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    534      CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    535      serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    536                                                                 client->clientRank, 
    537                                                                 client->clientSize, 
    538                                                                 axis_domain_order, 
    539                                                                 getDistributedDimension()); 
    540      computeIndexByElement(indexServerOnElement, globalIndexOnServer_); 
    541  
    542      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    543      CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    544      CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    545      itGlobalMap  = itbGlobalMap = globalIndexOnServer_.begin(); 
    546      iteGlobalMap = globalIndexOnServer_.end(); 
    547  
    548      for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    549      { 
    550        int serverRank = itGlobalMap->first; 
    551        int indexSize = itGlobalMap->second.size(); 
    552        const std::vector<size_t>& indexVec = itGlobalMap->second; 
    553        for (int idx = 0; idx < indexSize; ++idx) 
     859       computeClientIndexScalarGrid(); 
     860       if (context->hasClient) 
    554861       { 
    555           itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
    556           if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
    557           { 
    558              if (connectedDataSize_.end() == connectedDataSize_.find(serverRank)) 
    559                connectedDataSize_[serverRank] = 1; 
    560              else 
    561                ++connectedDataSize_[serverRank]; 
    562           } 
     862         computeConnectedClientsScalarGrid(); 
    563863       } 
    564864     } 
    565  
    566      for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
    567        connectedServerRank_.push_back(itGlobalMap->first); 
     865     else 
     866     { 
     867       computeClientIndex(); 
     868       if (context->hasClient) 
     869       { 
     870         computeConnectedClients(); 
     871       } 
    568872     } 
    569  
    570      nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 
     873     if (CServer::serverLevel==2) 
     874     { 
     875       computeWrittenIndex() ; 
     876       if (serverDistribution_!=0) serverDistribution_->partialClear() ; 
     877       if (clientDistribution_!=0) clientDistribution_->partialClear() ; 
     878       outGlobalIndexFromClient.clear() ; 
     879     } 
    571880   } 
    572881 
     
    577886      on each element whose size is much smaller than one of whole grid. 
    578887      \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 
     888      \param [in] client contextClient 
    579889      \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 
    580890   */ 
    581891   void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
     892                                     const CContextClient* client, 
    582893                                     CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 
    583894   { 
    584      CContext* context = CContext::getCurrent(); 
    585      CContextClient* client = context->client; 
    586895     int serverSize = client->serverSize; 
     896 
    587897     std::vector<CDomain*> domList = getDomains(); 
    588898     std::vector<CAxis*> axisList = getAxis(); 
     
    667977       } 
    668978 
    669        nbIndexOnServer = 0; 
    670        for (it = itb; it != ite; ++it) 
     979     nbIndexOnServer = 0; 
     980     for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
     981     { 
     982       it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
     983       if (it != ite) 
    671984       { 
    672985         const std::vector<int>& tmp = it->second; 
     
    683996       } 
    684997     } 
     998   } 
    685999 
    6861000    // Determine server which contain global source index 
     
    9311245   } 
    9321246 
     1247/* 
    9331248   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 
    9341249   { 
     
    9601275     } 
    9611276   } 
    962  
     1277*/ 
    9631278   //---------------------------------------------------------------- 
    9641279 
     
    9781293   } 
    9791294 
    980   void CGrid::computeIndexScalarGrid() 
     1295   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 
     1296   { 
     1297      const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient(); 
     1298      const int size = localMaskedDataIndex.size(); 
     1299       
     1300      for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 
     1301   } 
     1302 
     1303 
     1304  void CGrid::computeClientIndexScalarGrid() 
     1305  { 
     1306    CContext* context = CContext::getCurrent();     
     1307//    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; // This should be changed soon 
     1308//    for (int p = 0; p < nbSrvPools; ++p) 
     1309    { 
     1310//      CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client) 
     1311//                                                    : context->client; 
     1312      CContextClient* client = context->client; 
     1313 
     1314      int rank = client->clientRank; 
     1315 
     1316      clientDistribution_ = new CDistributionClient(rank, this); 
     1317 
     1318      storeIndex_client.resize(1); 
     1319      storeIndex_client(0) = 0;       
     1320 
     1321      if (0 != serverDistribution_) 
     1322      { 
     1323        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
     1324                                               ite = outGlobalIndexFromClient.end(), it; 
     1325        for (it = itb; it != ite; ++it) 
     1326        { 
     1327          int rank = it->first; 
     1328          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
     1329          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
     1330          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
     1331          if (1 != globalIndex.numElements()) 
     1332            ERROR("void CGrid::computeClientIndexScalarGrid()", 
     1333              << "Something wrong happened. " 
     1334              << "Number of received global index on scalar grid should equal to 1"  
     1335              << "Number of received global index " << globalIndex.numElements() << "."); 
     1336 
     1337          localIndex(0) = globalIndex(0); 
     1338        } 
     1339      } 
     1340    } 
     1341  } 
     1342 
     1343  void CGrid::computeConnectedClientsScalarGrid() 
     1344  { 
     1345    CContext* context = CContext::getCurrent();     
     1346    int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 
     1347    connectedServerRank_.clear(); 
     1348    connectedDataSize_.clear(); 
     1349    nbSenders.clear(); 
     1350 
     1351    for (int p = 0; p < nbSrvPools; ++p) 
     1352    { 
     1353      CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 
     1354      int receiverSize = client->serverSize; 
     1355 
     1356//      connectedServerRank_[client].clear(); 
     1357 
     1358      if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 
     1359      { 
     1360        if (client->isServerLeader()) 
     1361        { 
     1362          const std::list<int>& ranks = client->getRanksServerLeader(); 
     1363          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1364          { 
     1365            int rank = *itRank; 
     1366            int nb = 1; 
     1367            connectedServerRank_[receiverSize].push_back(rank); 
     1368            connectedDataSize_[receiverSize][rank] = nb; 
     1369            nbSenders[receiverSize][rank] = nb; 
     1370          } 
     1371        } 
     1372        else 
     1373        { 
     1374          const std::list<int>& ranks = client->getRanksServerNotLeader(); 
     1375          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1376          { 
     1377            int rank = *itRank; 
     1378            int nb = 1; 
     1379            connectedServerRank_[receiverSize].push_back(rank); 
     1380            connectedDataSize_[receiverSize][rank] = nb; 
     1381            nbSenders[receiverSize][rank] = nb; 
     1382          } 
     1383        } 
     1384      } 
     1385      isDataDistributed_ = false; 
     1386    } 
     1387  } 
     1388 
     1389  void CGrid::sendIndexScalarGrid() 
    9811390  { 
    9821391    CContext* context = CContext::getCurrent(); 
    983     CContextClient* client=context->client; 
    984  
    985     storeIndex_client.resize(1); 
    986     storeIndex_client(0) = 0; 
    987  
    988     connectedServerRank_.clear(); 
    989  
    990     if (0 == client->clientRank) 
    991     { 
    992       for (int rank = 0; rank < client->serverSize; ++rank) 
    993       { 
    994         connectedServerRank_.push_back(rank); 
    995         connectedDataSize_[rank] = 1; 
    996         nbSenders[rank] = 1; 
    997       } 
    998     } 
    999     isDataDistributed_ = false; 
    1000   } 
    1001  
    1002   void CGrid::computeCompressedIndex() 
    1003   { 
    1004     std::map<size_t, size_t> indexes; 
    1005  
    1006     { 
    1007       std::map<int, CArray<size_t,1> >::const_iterator it = outIndexFromClient.begin(); 
    1008       std::map<int, CArray<size_t,1> >::const_iterator itEnd = outIndexFromClient.end(); 
    1009       for (; it != itEnd; ++it) 
    1010       { 
    1011         for (int i = 0; i < it->second.numElements(); ++i) 
    1012           indexes.insert(std::make_pair(it->second(i), 0)); 
    1013  
    1014         compressedOutIndexFromClient[it->first].resize(it->second.numElements()); 
    1015       } 
    1016     } 
    1017  
    1018     { 
    1019       std::map<size_t, size_t>::iterator it = indexes.begin(); 
    1020       std::map<size_t, size_t>::iterator itEnd = indexes.end(); 
    1021       for (size_t i = 0; it != itEnd; ++it, ++i) 
    1022         it->second = i; 
    1023     } 
    1024  
    1025     { 
    1026       std::map<int, CArray<size_t,1> >::iterator it = compressedOutIndexFromClient.begin(); 
    1027       std::map<int, CArray<size_t,1> >::iterator itEnd = compressedOutIndexFromClient.end(); 
    1028       for (; it != itEnd; ++it) 
    1029       { 
    1030         const CArray<size_t,1>& outIndex = outIndexFromClient[it->first]; 
    1031         for (int i = 0; i < it->second.numElements(); ++i) 
    1032           it->second(i) = indexes[outIndex(i)]; 
    1033       } 
    1034     } 
    1035   } 
    1036  
    1037   void CGrid::sendIndexScalarGrid() 
    1038   { 
    1039     CContext* context = CContext::getCurrent(); 
    1040     CContextClient* client = context->client; 
    1041  
    1042     CEventClient event(getType(), EVENT_ID_INDEX); 
    1043     list<CMessage> listMsg; 
    1044     list<CArray<size_t,1> > listOutIndex; 
    1045  
    1046     if (client->isServerLeader()) 
    1047     { 
    1048       const std::list<int>& ranks = client->getRanksServerLeader(); 
    1049       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1050       { 
    1051         int rank = *itRank; 
    1052         int nb = 1; 
    1053         storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));         
    1054         listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1055  
    1056         CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank]; 
    1057         CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1058  
    1059         for (int k = 0; k < nb; ++k) 
    1060         { 
    1061           outGlobalIndexOnServer(k) = 0; 
    1062           outLocalIndexToServer(k)  = 0; 
    1063         } 
    1064  
    1065         storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1066         listMsg.push_back(CMessage()); 
    1067         listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1068  
    1069         event.push(rank, 1, listMsg.back()); 
    1070       } 
    1071       client->sendEvent(event); 
    1072     } 
    1073     else 
    1074     { 
    1075       const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1076       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1077       { 
    1078         int rank = *itRank; 
    1079         int nb = 1;         
    1080         storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 
    1081         CArray<int, 1>& outLocalIndexToServer = storeIndex_fromSrv[rank]; 
    1082         for (int k = 0; k < nb; ++k) 
    1083         {           
    1084           outLocalIndexToServer(k)  = 0; 
    1085         } 
    1086       } 
    1087       client->sendEvent(event); 
    1088     } 
    1089   } 
    1090  
    1091   void CGrid::sendIndex(void) 
    1092   { 
    1093     CContext* context = CContext::getCurrent(); 
    1094     CContextClient* client = context->client; 
    1095  
    1096     CEventClient event(getType(), EVENT_ID_INDEX); 
    1097     int rank; 
    1098     list<CMessage> listMsg; 
    1099     list<CArray<size_t,1> > listOutIndex; 
    1100     const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    1101     CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(), 
    1102                                                            iteIndex = globalLocalIndexSendToServer.end(); 
    1103  
    1104     if (!doGridHaveDataDistributed()) 
    1105     { 
     1392    storeIndex_toSrv.clear(); 
     1393    std::list<CContextClient*>::iterator it; 
     1394 
     1395    for (it=clients.begin(); it!=clients.end(); ++it) 
     1396    { 
     1397      CContextClient* client = *it; 
     1398      int receiverSize = client->serverSize; 
     1399 
     1400      CEventClient event(getType(), EVENT_ID_INDEX); 
     1401      list<CMessage> listMsg; 
     1402      list<CArray<size_t,1> > listOutIndex; 
     1403 
    11061404      if (client->isServerLeader()) 
    11071405      { 
    1108         int indexSize = globalLocalIndexSendToServer.size(); 
    1109         CArray<size_t,1> outGlobalIndexOnServer(indexSize); 
    1110         CArray<int,1> outLocalIndexToServer(indexSize); 
    1111         for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1112         { 
    1113           outGlobalIndexOnServer(idx) = itIndex->first; 
    1114           outLocalIndexToServer(idx) = itIndex->second; 
    1115         } 
    1116  
    11171406        const std::list<int>& ranks = client->getRanksServerLeader(); 
    11181407        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    11191408        { 
    1120           storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1121           storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1122           listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
    1123  
     1409          int rank = *itRank; 
     1410          int nb = 1; 
     1411          storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 
     1412          listOutIndex.push_back(CArray<size_t,1>(nb)); 
     1413 
     1414          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
     1415          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
     1416 
     1417          for (int k = 0; k < nb; ++k) 
     1418          { 
     1419            outGlobalIndexOnServer(k) = 0; 
     1420            outLocalIndexToServer(k)  = 0; 
     1421          } 
     1422 
     1423          if (context->hasClient && !context->hasServer) 
     1424            storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
     1425 
     1426          listMsg.push_back(CMessage()); 
     1427          listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
     1428 
     1429          event.push(rank, 1, listMsg.back()); 
     1430        } 
     1431        client->sendEvent(event); 
     1432      } 
     1433      else 
     1434      { 
     1435        const std::list<int>& ranks = client->getRanksServerNotLeader(); 
     1436        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1437        { 
     1438          int rank = *itRank; 
     1439          int nb = 1;           
     1440          CArray<int, 1> outLocalIndexToServer(nb); 
     1441          for (int k = 0; k < nb; ++k) 
     1442          { 
     1443            outLocalIndexToServer(k)  = 0; 
     1444          } 
     1445 
     1446          if (context->hasClient && !context->hasServer) 
     1447            storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
     1448        } 
     1449        client->sendEvent(event); 
     1450      } 
     1451    } 
     1452  } 
     1453 
     1454  void CGrid::sendIndex(void) 
     1455  { 
     1456    CContext* context = CContext::getCurrent(); 
     1457    storeIndex_toSrv.clear(); 
     1458    std::list<CContextClient*>::iterator it; 
     1459 
     1460    for (it=clients.begin(); it!=clients.end(); ++it) 
     1461    { 
     1462      CContextClient* client = *it; 
     1463      int receiverSize = client->serverSize; 
     1464 
     1465      CEventClient event(getType(), EVENT_ID_INDEX); 
     1466      int rank; 
     1467      list<CMessage> listMsg; 
     1468      list<CArray<size_t,1> > listOutIndex; 
     1469      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
     1470      CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 
     1471                                                              iteIndex = globalLocalIndexSendToServer.end(); 
     1472      itIndex = itbIndex;                                                               
     1473 
     1474      if (!doGridHaveDataDistributed(client)) 
     1475      { 
     1476        if (client->isServerLeader()) 
     1477        { 
     1478          int indexSize = globalLocalIndexSendToServer.size(); 
     1479          CArray<size_t,1> outGlobalIndexOnServer(indexSize); 
     1480          CArray<int,1> outLocalIndexToServer(indexSize); 
     1481          for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
     1482          { 
     1483            outGlobalIndexOnServer(idx) = itIndex->first; 
     1484            outLocalIndexToServer(idx) = itIndex->second; 
     1485          } 
     1486 
     1487          const std::list<int>& ranks = client->getRanksServerLeader(); 
     1488          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1489          { 
     1490            storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
     1491            if (context->hasClient && !context->hasServer) 
     1492              storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
     1493             
     1494            listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
     1495 
     1496            listMsg.push_back(CMessage()); 
     1497            listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
     1498 
     1499            event.push(*itRank, 1, listMsg.back()); 
     1500          } 
     1501          client->sendEvent(event); 
     1502        } 
     1503        else 
     1504        { 
     1505           int indexSize = globalLocalIndexSendToServer.size(); 
     1506           CArray<int,1> outLocalIndexToServer(indexSize); 
     1507           for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
     1508           { 
     1509             outLocalIndexToServer(idx) = itIndex->second; 
     1510           } 
     1511 
     1512           const std::list<int>& ranks = client->getRanksServerNotLeader(); 
     1513           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     1514           { 
     1515             storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
     1516           } 
     1517           client->sendEvent(event); 
     1518         } 
     1519      } 
     1520      else 
     1521      { 
     1522        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
     1523        itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
     1524        iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
     1525 
     1526        std::map<int,std::vector<int> >localIndexTmp; 
     1527        std::map<int,std::vector<size_t> > globalIndexTmp; 
     1528        for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
     1529        { 
     1530          int serverRank = itGlobalMap->first; 
     1531          int indexSize = itGlobalMap->second.size(); 
     1532          const std::vector<size_t>& indexVec = itGlobalMap->second; 
     1533          for (int idx = 0; idx < indexSize; ++idx) 
     1534          { 
     1535            itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 
     1536            if (iteIndex != itIndex) 
     1537            { 
     1538              globalIndexTmp[serverRank].push_back(itIndex->first); 
     1539              localIndexTmp[serverRank].push_back(itIndex->second); 
     1540            } 
     1541          } 
     1542        } 
     1543 
     1544        for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 
     1545        { 
     1546          rank = connectedServerRank_[receiverSize][ns]; 
     1547          int nb = 0; 
     1548          if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
     1549            nb = globalIndexTmp[rank].size(); 
     1550 
     1551          storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb))); 
     1552          listOutIndex.push_back(CArray<size_t,1>(nb)); 
     1553 
     1554          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
     1555          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
     1556 
     1557          for (int k = 0; k < nb; ++k) 
     1558          { 
     1559            outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 
     1560            outLocalIndexToServer(k)  = localIndexTmp[rank].at(k); 
     1561          } 
     1562 
     1563          storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    11241564          listMsg.push_back(CMessage()); 
    11251565          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    11261566 
    1127           event.push(*itRank, 1, listMsg.back()); 
    1128         } 
     1567          event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 
     1568        } 
     1569 
    11291570        client->sendEvent(event); 
    11301571      } 
    1131       else  
    1132       { 
    1133         int indexSize = globalLocalIndexSendToServer.size();         
    1134         CArray<int,1> outLocalIndexToServer(indexSize); 
    1135         for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1136         {           
    1137           outLocalIndexToServer(idx) = itIndex->second; 
    1138         } 
    1139          
    1140         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1141         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1142         {           
    1143           storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1144         } 
    1145         client->sendEvent(event); 
    1146       } 
    1147     } 
    1148     else 
    1149     { 
    1150       CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    1151       itGlobalMap = globalIndexOnServer_.begin(); 
    1152       iteGlobalMap = globalIndexOnServer_.end(); 
    1153  
    1154       std::map<int,std::vector<int> >localIndexTmp; 
    1155       std::map<int,std::vector<size_t> > globalIndexTmp; 
    1156       for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    1157       { 
    1158         int serverRank = itGlobalMap->first; 
    1159         int indexSize = itGlobalMap->second.size(); 
    1160         const std::vector<size_t>& indexVec = itGlobalMap->second; 
    1161         for (int idx = 0; idx < indexSize; ++idx) 
    1162         { 
    1163           itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 
    1164           if (iteIndex != itIndex) 
    1165           { 
    1166             globalIndexTmp[serverRank].push_back(itIndex->first); 
    1167             localIndexTmp[serverRank].push_back(itIndex->second); 
    1168           } 
    1169         } 
    1170       } 
    1171  
    1172       for (int ns = 0; ns < connectedServerRank_.size(); ++ns) 
    1173       { 
    1174         rank = connectedServerRank_[ns]; 
    1175         int nb = 0; 
    1176         if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
    1177           nb = globalIndexTmp[rank].size(); 
    1178  
    1179         storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));         
    1180         listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1181  
    1182         CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank]; 
    1183         CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1184  
    1185         for (int k = 0; k < nb; ++k) 
    1186         { 
    1187           outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 
    1188           outLocalIndexToServer(k)  = localIndexTmp[rank].at(k); 
    1189         } 
    1190  
    1191         storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1192         listMsg.push_back(CMessage()); 
    1193         listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1194  
    1195         event.push(rank, nbSenders[rank], listMsg.back()); 
    1196       } 
    1197  
    1198       client->sendEvent(event); 
    11991572    } 
    12001573  } 
     
    12201593  { 
    12211594    CContext* context = CContext::getCurrent(); 
    1222     CContextServer* server = context->server; 
    1223     numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0; 
    1224     connectedServerRank_ = ranks; 
    1225  
    1226     for (int n = 0; n < ranks.size(); n++) 
    1227     { 
    1228       int rank = ranks[n]; 
    1229       CBufferIn& buffer = *buffers[n]; 
    1230  
    1231       buffer >> isDataDistributed_ >> isCompressible_; 
    1232       size_t dataSize = 0; 
    1233  
    1234       if (0 == serverDistribution_) 
    1235       { 
    1236         int idx = 0, numElement = axis_domain_order.numElements(); 
    1237         int ssize = numElement; 
    1238         std::vector<int> indexMap(numElement); 
    1239         for (int i = 0; i < numElement; ++i) 
    1240         { 
    1241           indexMap[i] = idx; 
    1242           if (2 == axis_domain_order(i)) 
     1595    connectedServerRankRead_ = ranks; 
     1596 
     1597    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
     1598    nbSrvPools = 1;     
     1599    nbReadSenders.clear(); 
     1600    for (int p = 0; p < nbSrvPools; ++p) 
     1601    { 
     1602      CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p]; 
     1603      CContextClient* client = context->client;   //(!context->hasClient) ? context->client : context->clientPrimServer[p]; 
     1604       
     1605      int idx = 0, numElement = axis_domain_order.numElements(); 
     1606      int ssize = numElement; 
     1607      std::vector<int> indexMap(numElement); 
     1608      for (int i = 0; i < numElement; ++i) 
     1609      { 
     1610        indexMap[i] = idx; 
     1611        if (2 == axis_domain_order(i)) 
     1612        { 
     1613          ++ssize; 
     1614          idx += 2; 
     1615        } 
     1616        else 
     1617          ++idx; 
     1618      } 
     1619 
     1620      for (int n = 0; n < ranks.size(); n++) 
     1621      { 
     1622        int rank = ranks[n]; 
     1623        CBufferIn& buffer = *buffers[n]; 
     1624 
     1625        buffer >> isDataDistributed_ >> isCompressible_; 
     1626        size_t dataSize = 0; 
     1627 
     1628        if (0 == serverDistribution_) 
     1629        { 
     1630          int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
     1631          std::vector<CDomain*> domainList = getDomains(); 
     1632          std::vector<CAxis*> axisList = getAxis(); 
     1633          std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize), nGlobElement(numElement); 
     1634          std::vector<CArray<int,1> > globalZoomIndex(numElement); 
     1635          for (int i = 0; i < numElement; ++i) 
    12431636          { 
    1244             ++ssize; 
    1245             idx += 2; 
     1637            nGlobElement[i] = globalSize; 
     1638            if (2 == axis_domain_order(i)) //domain 
     1639            { 
     1640              nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin; 
     1641              nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni; 
     1642              nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;               
     1643              nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
     1644 
     1645              nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin; 
     1646              nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj; 
     1647              nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;               
     1648              nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
     1649 
     1650              { 
     1651                int count = 0; 
     1652                globalZoomIndex[i].resize(nZoomSize[indexMap[i]]*nZoomSize[indexMap[i]+1]); 
     1653                for (int jdx = 0; jdx < nZoomSize[indexMap[i]+1]; ++jdx) 
     1654                  for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx)                 
     1655                  { 
     1656                    globalZoomIndex[i](count) = (nZoomBegin[indexMap[i]] + idx) + (nZoomBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
     1657                    ++count; 
     1658                  } 
     1659              } 
     1660 
     1661              ++domainId; 
     1662            } 
     1663            else if (1 == axis_domain_order(i)) // axis 
     1664            { 
     1665              nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin; 
     1666              nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_n; 
     1667              nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;               
     1668              nGlob[indexMap[i]] = axisList[axisId]->n_glo;      
     1669              if (axisList[axisId]->zoomByIndex()) 
     1670              { 
     1671                globalZoomIndex[i].reference(axisList[axisId]->zoom_index);                 
     1672              } 
     1673              else 
     1674              { 
     1675                globalZoomIndex[i].resize(nZoomSize[indexMap[i]]); 
     1676                for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx) 
     1677                  globalZoomIndex[i](idx) = nZoomBegin[indexMap[i]] + idx; 
     1678              } 
     1679 
     1680              ++axisId; 
     1681            } 
     1682            else // scalar 
     1683            {  
     1684              nZoomBegin[indexMap[i]] = 0; 
     1685              nZoomSize[indexMap[i]]  = 1; 
     1686              nZoomBeginGlobal[indexMap[i]] = 0;               
     1687              nGlob[indexMap[i]] = 1; 
     1688              globalZoomIndex[i].resize(1); 
     1689              globalZoomIndex[i](0) = 0; 
     1690              ++scalarId; 
     1691            } 
    12461692          } 
    1247           else 
    1248             ++idx; 
    1249         } 
    1250  
    1251         int axisId = 0, domainId = 0, scalarId = 0; 
     1693          dataSize = 1; 
     1694 
     1695          for (int i = 0; i < nZoomSize.size(); ++i) 
     1696            dataSize *= nZoomSize[i]; 
     1697          serverDistribution_ = new CDistributionServer(server->intraCommRank,  
     1698                                                        globalZoomIndex, axis_domain_order, 
     1699                                                        nZoomBegin, nZoomSize, nZoomBeginGlobal, nGlob); 
     1700        } 
     1701 
     1702        CArray<size_t,1> outIndex; 
     1703        buffer >> outIndex; 
     1704        outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex)); 
     1705        connectedDataSizeRead_[rank] = outIndex.numElements(); 
     1706 
     1707        if (doGridHaveDataDistributed(client)) 
     1708        {} 
     1709        else 
     1710        { 
     1711          // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 
     1712          // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 
     1713          dataSize = serverDistribution_->getGridSize(); 
     1714        } 
     1715        writtenDataSize_ += dataSize; 
     1716      } 
     1717 
     1718 
     1719      // Compute mask of the current grid 
     1720      { 
     1721        int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    12521722        std::vector<CDomain*> domainList = getDomains(); 
    12531723        std::vector<CAxis*> axisList = getAxis(); 
    1254         std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize); 
    1255         std::vector<CArray<int,1> > globalZoomIndex(numElement); 
     1724        int dimSize = 2 * domainList.size() + axisList.size(); 
     1725        std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);         
    12561726        for (int i = 0; i < numElement; ++i) 
    1257         { 
     1727        {           
    12581728          if (2 == axis_domain_order(i)) //domain 
    12591729          { 
    1260             nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv; 
    1261             nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni_srv; 
    1262             nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin; 
     1730            nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
     1731            nSize[indexMap[i]]  = domainList[domainId]->ni; 
     1732            nBeginGlobal[indexMap[i]] = 0;               
    12631733            nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    12641734 
    1265             nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv; 
    1266             nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv; 
    1267             nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin; 
     1735            nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
     1736            nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
     1737            nBeginGlobal[indexMap[i] + 1] = 0;               
    12681738            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    12691739 
    1270             { 
    1271               int count = 0; 
    1272               globalZoomIndex[i].resize(nZoomSize[indexMap[i]]*nZoomSize[indexMap[i]+1]); 
    1273               for (int jdx = 0; jdx < nZoomSize[indexMap[i]+1]; ++jdx) 
    1274                 for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx)                 
    1275                 { 
    1276                   globalZoomIndex[i](count) = (nZoomBegin[indexMap[i]] + idx) + (nZoomBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
    1277                   ++count; 
    1278                 } 
    1279             } 
    12801740            ++domainId; 
    12811741          } 
    12821742          else if (1 == axis_domain_order(i)) // axis 
    12831743          { 
    1284             nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv; 
    1285             nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv; 
    1286             nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin_srv; 
    1287             nGlob[indexMap[i]] = axisList[axisId]->n_glo; 
    1288             if (!axisList[axisId]->global_zoom_index.isEmpty()) 
    1289             { 
    1290               globalZoomIndex[i].reference(axisList[axisId]->zoom_index_srv);                 
    1291             } 
    1292             else 
    1293             { 
    1294               globalZoomIndex[i].resize(nZoomSize[indexMap[i]]); 
    1295               for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx) 
    1296                 globalZoomIndex[i](idx) = nZoomBegin[indexMap[i]] + idx; 
    1297             } 
    1298              
     1744            nBegin[indexMap[i]] = axisList[axisId]->begin; 
     1745            nSize[indexMap[i]]  = axisList[axisId]->n; 
     1746            nBeginGlobal[indexMap[i]] = 0;               
     1747            nGlob[indexMap[i]] = axisList[axisId]->n_glo;               
    12991748            ++axisId; 
    13001749          } 
    13011750          else // scalar 
     1751          {   
     1752          } 
     1753        } 
     1754         
     1755        if (nSize.empty()) // Scalar grid 
     1756        { 
     1757          nBegin.push_back(0); 
     1758          nSize.push_back(1); 
     1759          nBeginGlobal.push_back(0);               
     1760          nGlob.push_back(1);   
     1761        } 
     1762 
     1763        modifyMaskSize(nSize, false); 
     1764 
     1765        // These below codes are reserved for future 
     1766        CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob);  
     1767        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
     1768                                               ite = outGlobalIndexFromClient.end(), it;   
     1769        const CDistributionServer::GlobalLocalMap&  globalLocalMask = srvDist.getGlobalLocalIndex(); 
     1770        CDistributionServer::GlobalLocalMap::const_iterator itSrv; 
     1771        size_t nb = 0; 
     1772        for (it = itb; it != ite; ++it) 
     1773        { 
     1774          CArray<size_t,1>& globalInd = it->second; 
     1775          for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 
    13021776          { 
    1303             nZoomBegin[indexMap[i]] = 0; 
    1304             nZoomSize[indexMap[i]]  = 1; 
    1305             nZoomBeginGlobal[indexMap[i]] = 0; 
    1306             nGlob[indexMap[i]] = 1; 
    1307             globalZoomIndex[i].resize(1); 
    1308             globalZoomIndex[i](0) = 0; 
    1309             ++scalarId; 
     1777            if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb; 
    13101778          } 
    13111779        } 
    1312         dataSize = 1; 
    1313         for (int i = 0; i < nZoomSize.size(); ++i) 
    1314           dataSize *= nZoomSize[i]; 
    1315  
    1316 /*        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize, 
    1317                                                       nZoomBeginGlobal, nGlob);*/ 
    1318         serverDistribution_ = new CDistributionServer(server->intraCommRank,  
    1319                                                       globalZoomIndex, axis_domain_order, 
    1320                                                       nZoomBegin, nZoomSize, nZoomBeginGlobal, nGlob); 
    1321       } 
    1322  
    1323       CArray<size_t,1> outIndex; 
    1324       buffer >> outIndex; 
    1325       if (isDataDistributed_) 
    1326         serverDistribution_->computeLocalIndex(outIndex); 
    1327       else 
    1328       { 
    1329         dataSize = outIndex.numElements(); 
    1330         for (int i = 0; i < outIndex.numElements(); ++i) outIndex(i) = i; 
    1331       } 
    1332       writtenDataSize_ += dataSize; 
    1333        
    1334       outIndexFromClient.insert(std::make_pair(rank, outIndex)); 
    1335       connectedDataSize_[rank] = outIndex.numElements(); 
    1336       numberWrittenIndexes_ += outIndex.numElements(); 
    1337     } 
    1338  
    1339     // if (isScalarGrid()) return; 
    1340  
    1341     if (isDataDistributed_) 
    1342     { 
    1343       MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    1344       MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    1345       offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    1346     } 
    1347     else 
    1348       totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    1349  
    1350     nbSenders = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 
     1780         
     1781        CArray<int,1> indexToModify(nb); 
     1782        nb = 0;     
     1783        for (it = itb; it != ite; ++it) 
     1784        { 
     1785          CArray<size_t,1>& globalInd = it->second; 
     1786          for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 
     1787          { 
     1788            itSrv = globalLocalMask.find(globalInd(idx)); 
     1789            if (globalLocalMask.end() != itSrv)  
     1790            { 
     1791              indexToModify(nb) = itSrv->second; 
     1792              ++nb; 
     1793            } 
     1794          } 
     1795        } 
     1796 
     1797        modifyMask(indexToModify, true); 
     1798      } 
     1799 
     1800      if (isScalarGrid()) return; 
     1801 
     1802      nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 
     1803    } 
    13511804  } 
    13521805 
     
    13661819                                        const CArray<int,1>& axisDomainOrder) 
    13671820  { 
    1368     globalDim.resize(domains.size()*2+axis.size()+scalars.size()); 
     1821 //   globalDim.resize(domains.size()*2+axis.size()+scalars.size()); 
     1822    globalDim.resize(domains.size()*2+axis.size()); 
    13691823    int positionDimensionDistributed = 1; 
    13701824    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0; 
     
    13961850      else 
    13971851      { 
    1398         globalDim[idx] = 1; 
     1852//        globalDim[idx] = 1; 
    13991853        ++idxScalar; 
    1400         ++idx; 
     1854//        ++idx; 
    14011855      } 
    14021856    } 
     
    14841938  } 
    14851939 
    1486   bool CGrid::doGridHaveDataDistributed() 
     1940  bool CGrid::doGridHaveDataDistributed(CContextClient* client) 
    14871941  { 
    14881942    if (isScalarGrid()) return false; 
     1943    else if (0 != client) 
     1944    { 
     1945      return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize)); 
     1946    } 
    14891947    else 
    1490       return isDataDistributed_; 
     1948      return isDataDistributed_;     
    14911949  } 
    14921950 
     
    15832041   void CGrid::sendAddDomain(const string& id) 
    15842042   { 
    1585     CContext* context=CContext::getCurrent(); 
    1586  
    1587     if (! context->hasServer ) 
    1588     { 
    1589        CContextClient* client=context->client; 
    1590  
    1591        CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN); 
    1592        if (client->isServerLeader()) 
    1593        { 
    1594          CMessage msg; 
    1595          msg<<this->getId(); 
    1596          msg<<id; 
    1597          const std::list<int>& ranks = client->getRanksServerLeader(); 
    1598          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1599            event.push(*itRank,1,msg); 
    1600          client->sendEvent(event); 
    1601        } 
    1602        else client->sendEvent(event); 
    1603     } 
     2043      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN); 
    16042044   } 
    16052045 
     
    16102050   void CGrid::sendAddAxis(const string& id) 
    16112051   { 
    1612     CContext* context=CContext::getCurrent(); 
    1613  
    1614     if (! context->hasServer ) 
    1615     { 
    1616        CContextClient* client=context->client; 
    1617  
    1618        CEventClient event(this->getType(),EVENT_ID_ADD_AXIS); 
    1619        if (client->isServerLeader()) 
    1620        { 
    1621          CMessage msg; 
    1622          msg<<this->getId(); 
    1623          msg<<id; 
    1624          const std::list<int>& ranks = client->getRanksServerLeader(); 
    1625          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1626            event.push(*itRank,1,msg); 
    1627          client->sendEvent(event); 
    1628        } 
    1629        else client->sendEvent(event); 
    1630     } 
     2052      sendAddItem(id, (int)EVENT_ID_ADD_AXIS); 
    16312053   } 
    16322054 
     
    16372059   void CGrid::sendAddScalar(const string& id) 
    16382060   { 
    1639     CContext* context=CContext::getCurrent(); 
    1640  
    1641     if (! context->hasServer ) 
    1642     { 
    1643        CContextClient* client=context->client; 
    1644  
    1645        CEventClient event(this->getType(),EVENT_ID_ADD_SCALAR); 
    1646        if (client->isServerLeader()) 
    1647        { 
    1648          CMessage msg; 
    1649          msg<<this->getId(); 
    1650          msg<<id; 
    1651          const std::list<int>& ranks = client->getRanksServerLeader(); 
    1652          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1653            event.push(*itRank,1,msg); 
    1654          client->sendEvent(event); 
    1655        } 
    1656        else client->sendEvent(event); 
    1657     } 
     2061      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR); 
    16582062   } 
    16592063 
     
    17462150    { 
    17472151      CDomain* pDom = CDomain::get(*it); 
    1748       if (context->hasClient) 
     2152      if (context->hasClient && !context->hasServer)       
    17492153      { 
    17502154        pDom->solveRefInheritance(apply); 
     
    17582162    { 
    17592163      CAxis* pAxis = CAxis::get(*it); 
    1760       if (context->hasClient) 
     2164      if (context->hasClient && !context->hasServer) 
    17612165      { 
    17622166        pAxis->solveRefInheritance(apply); 
     
    17702174    { 
    17712175      CScalar* pScalar = CScalar::get(*it); 
    1772       if (context->hasClient) 
     2176      if (context->hasClient && !context->hasServer) 
    17732177      { 
    17742178        pScalar->solveRefInheritance(apply); 
     
    21452549  } 
    21462550 
     2551  void CGrid::setContextClient(CContextClient* contextClient) 
     2552  { 
     2553    if (clientsSet.find(contextClient)==clientsSet.end()) 
     2554    { 
     2555      clients.push_back(contextClient) ; 
     2556      clientsSet.insert(contextClient); 
     2557    } 
     2558    for (int i=0; i<this->getDomains().size(); i++) 
     2559        this->getDomains()[i]->setContextClient(contextClient); 
     2560    for (int i=0; i<this->getAxis().size(); i++) 
     2561        this->getAxis()[i]->setContextClient(contextClient); 
     2562  } 
     2563 
    21472564  /*! 
    21482565    Parse a grid, for now, it contains only domain, axis and scalar 
Note: See TracChangeset for help on using the changeset viewer.