source: XIOS/dev/dev_olga/src/node/axis.cpp @ 1143

Last change on this file since 1143 was 1143, checked in by mhnguyen, 7 years ago

Updating compressed index output on using 2-level server

+) Update compressed index output with new grid distribution

Test
+) On Curie
+) test_complete:

  • Mode: classical and 2 level server
  • config: 4 clients + 4 servers
  • passed
  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
  • Property svn:executable set to *
File size: 45.8 KB
Line 
1#include "axis.hpp"
2
3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6#include "message.hpp"
7#include "type.hpp"
8#include "context.hpp"
9#include "context_client.hpp"
10#include "context_server.hpp"
11#include "xios_spl.hpp"
12#include "inverse_axis.hpp"
13#include "zoom_axis.hpp"
14#include "interpolate_axis.hpp"
15#include "server_distribution_description.hpp"
16#include "client_server_mapping_distributed.hpp"
17#include "distribution_client.hpp"
18
19namespace xios {
20
21   /// ////////////////////// Définitions ////////////////////// ///
22
23   CAxis::CAxis(void)
24      : CObjectTemplate<CAxis>()
25      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
26      , isClientAfterTransformationChecked(false)
27      , hasBounds_(false), isCompressible_(false)
28      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
29      , transformationMap_(), hasValue(false), doZoomByIndex_(false)
30      , computedWrittenIndex_(false)
31   {
32   }
33
34   CAxis::CAxis(const StdString & id)
35      : CObjectTemplate<CAxis>(id)
36      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
37      , isClientAfterTransformationChecked(false)
38      , hasBounds_(false), isCompressible_(false)
39      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
40      , transformationMap_(), hasValue(false), doZoomByIndex_(false)
41      , computedWrittenIndex_(false)
42   {
43   }
44
45   CAxis::~CAxis(void)
46   { /* Ne rien faire de plus */ }
47
48   std::map<StdString, ETranformationType> CAxis::transformationMapList_ = std::map<StdString, ETranformationType>();
49   bool CAxis::dummyTransformationMapList_ = CAxis::initializeTransformationMap(CAxis::transformationMapList_);
50   bool CAxis::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
51   {
52     m["zoom_axis"] = TRANS_ZOOM_AXIS;
53     m["interpolate_axis"] = TRANS_INTERPOLATE_AXIS;
54     m["inverse_axis"] = TRANS_INVERSE_AXIS;
55     m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS;
56     m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS;
57   }
58
59   ///---------------------------------------------------------------
60
61   const std::set<StdString> & CAxis::getRelFiles(void) const
62   {
63      return (this->relFiles);
64   }
65
66   bool CAxis::IsWritten(const StdString & filename) const
67   {
68      return (this->relFiles.find(filename) != this->relFiles.end());
69   }
70
71   bool CAxis::isWrittenCompressed(const StdString& filename) const
72   {
73      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
74   }
75
76   bool CAxis::isDistributed(void) const
77   {
78      return (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) ||
79             (!this->n.isEmpty() && (this->n != this->n_glo));;
80   }
81
82   /*!
83    * Test whether the data defined on the axis can be outputted in a compressed way.
84    *
85    * \return true if and only if a mask was defined for this axis
86    */
87   bool CAxis::isCompressible(void) const
88   {
89      return isCompressible_;
90   }
91
92   void CAxis::addRelFile(const StdString & filename)
93   {
94      this->relFiles.insert(filename);
95   }
96
97   void CAxis::addRelFileCompressed(const StdString& filename)
98   {
99      this->relFilesCompressed.insert(filename);
100   }
101
102   //----------------------------------------------------------------
103
104   const std::vector<int>& CAxis::getIndexesToWrite(void) const
105   {
106     return indexesToWrite;
107   }
108
109   /*!
110     Returns the number of indexes written by each server.
111     \return the number of indexes written by each server
112   */
113   int CAxis::getNumberWrittenIndexes() const
114   {
115     return numberWrittenIndexes_;
116   }
117
118   /*!
119     Returns the total number of indexes written by the servers.
120     \return the total number of indexes written by the servers
121   */
122   int CAxis::getTotalNumberWrittenIndexes() const
123   {
124     return totalNumberWrittenIndexes_;
125   }
126
127   /*!
128     Returns the offset of indexes written by each server.
129     \return the offset of indexes written by each server
130   */
131   int CAxis::getOffsetWrittenIndexes() const
132   {
133     return offsetWrittenIndexes_;
134   }
135
136   //----------------------------------------------------------------
137
138   /*!
139    * Compute the minimum buffer size required to send the attributes to the server(s).
140    *
141    * \return A map associating the server rank with its minimum buffer size.
142    */
143   std::map<int, StdSize> CAxis::getAttributesBufferSize()
144   {
145//     CContextClient* client = CContext::getCurrent()->client;
146     // For now the assumption is that secondary server pools consist of the same number of procs.
147     // CHANGE the line below if the assumption changes.
148     CContext* context = CContext::getCurrent();
149     CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[0] : context->client;
150
151     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes();
152
153     bool isNonDistributed = (n == n_glo);
154
155     if (client->isServerLeader())
156     {
157       // size estimation for sendServerAttribut
158       size_t size = 6 * sizeof(size_t);
159       // size estimation for sendNonDistributedValue
160       if (isNonDistributed)
161         size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0));
162       size += CEventClient::headerSize + getId().size() + sizeof(size_t);
163
164       const std::list<int>& ranks = client->getRanksServerLeader();
165       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
166       {
167         if (size > attributesSizes[*itRank])
168           attributesSizes[*itRank] = size;
169       }
170     }
171
172     if (!isNonDistributed)
173     {
174       // size estimation for sendDistributedValue
175       boost::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_.end();
176       for (it = indSrv_.begin(); it != ite; ++it)
177       {
178         size_t sizeIndexEvent = CArray<int,1>::size(it->second.size());
179         if (isCompressible_)
180           sizeIndexEvent += CArray<int,1>::size(indWrittenSrv_[it->first].size());
181
182         size_t sizeValEvent = CArray<double,1>::size(it->second.size());
183         if (hasBounds_)
184           sizeValEvent += CArray<double,2>::size(2 * it->second.size());
185
186         size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent);
187         if (size > attributesSizes[it->first])
188           attributesSizes[it->first] = size;
189       }
190     }
191
192     return attributesSizes;
193   }
194
195   //----------------------------------------------------------------
196
197   StdString CAxis::GetName(void)   { return (StdString("axis")); }
198   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
199   ENodeType CAxis::GetType(void)   { return (eAxis); }
200
201   //----------------------------------------------------------------
202
203   CAxis* CAxis::createAxis()
204   {
205     CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
206     return axis;
207   }
208
209   void CAxis::fillInValues(const CArray<double,1>& values)
210   {
211     this->value = values;
212   }
213
214   void CAxis::checkAttributes(void)
215   {
216      if (this->n_glo.isEmpty())
217        ERROR("CAxis::checkAttributes(void)",
218              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
219              << "The axis is wrongly defined, attribute 'n_glo' must be specified");
220      StdSize size = this->n_glo.getValue();
221
222      if (!this->index.isEmpty())
223      {
224        if (n.isEmpty()) n = index.numElements();
225
226        // It's not so correct but if begin is not the first value of index
227        // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
228        if (begin.isEmpty()) begin = index(0);         
229      }
230      else 
231      {
232        if (!this->begin.isEmpty())
233        {
234          if (begin < 0 || begin > size - 1)
235            ERROR("CAxis::checkAttributes(void)",
236                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
237                  << "The axis is wrongly defined, attribute 'begin' (" << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").");
238        }
239        else this->begin.setValue(0);
240
241        if (!this->n.isEmpty())
242        {
243          if (n < 0 || n > size)
244            ERROR("CAxis::checkAttributes(void)",
245                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
246                  << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" << size << ").");
247        }
248        else this->n.setValue(size);
249
250        {
251          index.resize(n);
252          for (int i = 0; i < n; ++i) index(i) = i+begin;
253        }
254      }
255
256      if (!this->value.isEmpty())
257      {
258        StdSize true_size = value.numElements();
259        if (this->n.getValue() != true_size)
260          ERROR("CAxis::checkAttributes(void)",
261                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
262                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
263        this->hasValue = true;
264      }
265
266      this->checkData();
267      this->checkZoom();
268      this->checkMask();
269      this->checkBounds();     
270   }
271
272   void CAxis::checkData()
273   {
274      if (data_begin.isEmpty()) data_begin.setValue(0);
275
276      if (data_n.isEmpty())
277      {
278        data_n.setValue(n);
279      }
280      else if (data_n.getValue() < 0)
281      {
282        ERROR("CAxis::checkData(void)",
283              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
284              << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").");
285      }
286
287      if (data_index.isEmpty())
288      {
289        data_index.resize(data_n);
290        for (int i = 0; i < data_n; ++i) data_index(i) = i;
291      }
292   }
293
294   void CAxis::checkZoom(void)
295   {
296     if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0);
297     if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue());
298     if (zoom_index.isEmpty())
299     {
300       zoom_index.setValue(index.getValue());
301     }
302     if (zoom_n.isEmpty()) zoom_n.setValue(n);
303     if (zoom_begin.isEmpty()) zoom_begin.setValue(begin);
304   }
305
306   void CAxis::checkMask()
307   {
308      if (!mask.isEmpty())
309      {
310         if (mask.extent(0) != n)
311           ERROR("CAxis::checkMask(void)",
312                 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
313                 << "The mask does not have the same size as the local domain." << std::endl
314                 << "Local size is " << n.getValue() << "." << std::endl
315                 << "Mask size is " << mask.extent(0) << ".");
316      }
317      else // (mask.isEmpty())
318      { // If no mask was defined, we create a default one without any masked point.
319         mask.resize(n);
320         for (int i = 0; i < n; ++i)
321         {
322           mask(i) = true;
323         }
324      }
325   }
326
327  void CAxis::checkBounds()
328  {
329    if (!bounds.isEmpty())
330    {
331      if (bounds.extent(0) != 2 || bounds.extent(1) != n)
332        ERROR("CAxis::checkAttributes(void)",
333              << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
334              << "Axis size is " << n.getValue() << "." << std::endl
335              << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".");
336      hasBounds_ = true;
337    }
338    else hasBounds_ = false;
339  }
340
341  void CAxis::checkEligibilityForCompressedOutput()
342  {
343    // We don't check if the mask is valid here, just if a mask has been defined at this point.
344    isCompressible_ = !mask.isEmpty();
345  }
346
347  bool CAxis::dispatchEvent(CEventServer& event)
348   {
349      if (SuperClass::dispatchEvent(event)) return true;
350      else
351      {
352        switch(event.type)
353        {
354           case EVENT_ID_DISTRIBUTION_ATTRIBUTE :
355             recvDistributionAttribute(event);
356             return true;
357             break;
358          //  case EVENT_ID_INDEX:
359          //   recvIndex(event);
360          //   return true;
361          //   break;
362          case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES:
363            recvNonDistributedAttributes(event);
364            return true;
365            break;
366          case EVENT_ID_DISTRIBUTED_ATTRIBUTES:
367            recvDistributedAttributes(event);
368            return true;
369            break;
370           default :
371             ERROR("bool CAxis::dispatchEvent(CEventServer& event)",
372                    << "Unknown Event");
373           return false;
374         }
375      }
376   }
377
378   void CAxis::checkAttributesOnClient()
379   {
380     if (this->areClientAttributesChecked_) return;
381
382     this->checkAttributes();
383
384     this->areClientAttributesChecked_ = true;
385   }
386
387   void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
388                                                          CServerDistributionDescription::ServerDistributionType distType)
389   {
390     CContext* context=CContext::getCurrent() ;
391
392     if (this->isClientAfterTransformationChecked) return;
393     if (context->hasClient)
394     {
395       if (index.numElements() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType);
396     }
397
398     this->isClientAfterTransformationChecked = true;
399   }
400
401   // Send all checked attributes to server
402   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
403                                     CServerDistributionDescription::ServerDistributionType distType)
404   {
405     if (!this->areClientAttributesChecked_) checkAttributesOnClient();
406     if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(globalDim, orderPositionInGrid, distType);
407     CContext* context = CContext::getCurrent();
408
409     if (this->isChecked) return;
410     if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType);   
411
412     this->isChecked = true;
413   }
414
415  void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
416                             CServerDistributionDescription::ServerDistributionType distType)
417  {
418     if (index.numElements() == n_glo.getValue())
419       sendNonDistributedAttributes();
420     else
421     {
422       sendDistributedAttributes();       
423     }
424     sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
425  }
426
427  void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
428                                     CServerDistributionDescription::ServerDistributionType distType)
429  {
430    CContext* context = CContext::getCurrent();
431
432    // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
433    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
434    for (int p = 0; p < nbSrvPools; ++p)
435    {
436      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
437      int nbServer = client->serverSize;
438      int range, clientSize = client->clientSize;
439      int rank = client->clientRank;
440
441      size_t ni = this->n.getValue();
442      size_t ibegin = this->begin.getValue();
443      size_t global_zoom_end = global_zoom_begin+global_zoom_n-1;
444      size_t nZoomCount = 0;
445      size_t nbIndex = index.numElements();
446
447      if (doZoomByIndex_) 
448      {
449        nZoomCount = zoom_index.numElements();
450      }
451      else
452      {
453        for (size_t idx = 0; idx < nbIndex; ++idx)
454        {
455          globalLocalIndexMap_[index(idx)] = idx;
456          size_t globalIndex = index(idx);
457          if (globalIndex >= global_zoom_begin && globalIndex <= global_zoom_end) ++nZoomCount;
458        }
459      }
460
461
462      CArray<size_t,1> globalIndexAxis(nbIndex);
463      std::vector<size_t> globalAxisZoom(nZoomCount);
464      nZoomCount = 0;
465      if (doZoomByIndex_) 
466      {
467        int nbIndexZoom = zoom_index.numElements();       
468        for (int i = 0; i < nbIndexZoom; ++i)
469        {   
470          globalIndexAxis(i) = zoom_index(i);
471        }
472      }
473      else 
474      {
475        for (size_t idx = 0; idx < nbIndex; ++idx)
476        {
477          size_t globalIndex = index(idx);
478          globalIndexAxis(idx) = globalIndex;
479          if (globalIndex >= global_zoom_begin && globalIndex <= global_zoom_end)
480          {
481            globalAxisZoom[nZoomCount] = globalIndex;
482            ++nZoomCount;
483          }
484        }
485
486        int end       = begin + n -1;       
487        zoom_begin    = global_zoom_begin > begin ? global_zoom_begin : begin;
488        int zoom_end  = global_zoom_end < end ? zoom_end : end;
489        zoom_n        = zoom_end-zoom_begin+1;
490      }
491
492      std::set<int> writtenInd;
493      if (isCompressible_)
494      {
495        for (int idx = 0; idx < data_index.numElements(); ++idx)
496        {
497          int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
498
499          if (ind >= 0 && ind < ni && mask(ind))
500          {
501            ind += ibegin;
502            if (ind >= global_zoom_begin && ind <= global_zoom_end)
503              writtenInd.insert(ind);
504          }
505        }
506      }
507
508      CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer, distType);
509      int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
510      CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
511      if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
512      {
513        std::vector<int> nGlobAxis(1);
514        nGlobAxis[0] = n_glo.getValue();
515
516        size_t globalSizeIndex = 1, indexBegin, indexEnd;
517        for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
518        indexBegin = 0;
519        if (globalSizeIndex <= clientSize)
520        {
521          indexBegin = rank%globalSizeIndex;
522          indexEnd = indexBegin;
523        }
524        else
525        {
526          for (int i = 0; i < clientSize; ++i)
527          {
528            range = globalSizeIndex / clientSize;
529            if (i < (globalSizeIndex%clientSize)) ++range;
530            if (i == client->clientRank) break;
531            indexBegin += range;
532          }
533          indexEnd = indexBegin + range - 1;
534        }
535
536        CArray<size_t,1> globalIndex(index.numElements());
537        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
538          globalIndex(idx) = index(idx);
539
540        CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
541        serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
542        CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
543        clientServerMap->computeServerIndexMapping(globalIndex);
544        globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
545        delete clientServerMap;
546      }
547      else
548      {
549        std::vector<size_t> globalIndexServer(n_glo.getValue());
550        for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
551        {
552          globalIndexServer[idx] = idx;
553        }
554
555        for (int idx = 0; idx < nbServer; ++idx)
556        {
557          globalIndexAxisOnServer[idx] = globalIndexServer;
558        }
559      }
560
561      indSrv_.swap(globalIndexAxisOnServer);
562
563      // CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
564      //                                                      ite = globalIndexAxisOnServer.end();
565      CClientServerMapping::GlobalIndexMap::const_iterator it = indSrv_.begin(),
566                                                           ite = indSrv_.end();
567      // std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
568      //                                     iteVec = (globalAxisZoom).end();
569      // indSrv_.clear();
570      // indWrittenSrv_.clear();
571      // for (; it != ite; ++it)
572      // {
573      //   int rank = it->first;
574      //   const std::vector<size_t>& globalIndexTmp = it->second;
575      //   int nb = globalIndexTmp.size();
576
577      //   for (int i = 0; i < nb; ++i)
578      //   {
579      //     if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
580      //     {
581      //       indSrv_[rank].push_back(globalIndexTmp[i]);
582      //     }
583
584      //     if (writtenInd.count(globalIndexTmp[i]))
585      //     {
586      //       indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
587      //     }
588      //   }
589      // }
590
591      connectedServerRank_.clear();
592      for (it = indSrv_.begin(); it != ite; ++it) {
593        connectedServerRank_.push_back(it->first);
594      }
595
596      // if (!indSrv_.empty())
597      // {
598      //   std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
599      //                                                  iteIndSrv = indSrv_.end();
600      //   connectedServerRank_.clear();
601      //   for (; itIndSrv != iteIndSrv; ++itIndSrv)
602      //     connectedServerRank_.push_back(itIndSrv->first);
603      // }
604      nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
605    }
606  }
607
608   void CAxis::computeWrittenIndex()
609   { 
610      if (computedWrittenIndex_) return;
611      computedWrittenIndex_ = true;
612
613      CContext* context=CContext::getCurrent();     
614      CContextServer* server = context->server; 
615
616      std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1);
617      nBegin[0]       = zoom_begin;
618      nSize[0]        = zoom_n;   
619      nBeginGlobal[0] = 0; 
620      nGlob[0]        = n_glo;
621      CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob); 
622      const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex();
623
624      size_t nbWritten = 0, indGlo;     
625      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
626                                                          ite = globalLocalIndexMap_.end(), it;         
627      CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
628                                       itSrve = writtenGlobalIndex.end(), itSrv;     
629
630      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
631      {
632        indGlo = *itSrv;
633        if (ite != globalLocalIndexMap_.find(indGlo))
634        {         
635          ++nbWritten;
636        }                 
637      }
638
639      localIndexToWriteOnServer.resize(nbWritten);
640
641      nbWritten = 0;
642      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
643      {
644        indGlo = *itSrv;
645        if (ite != globalLocalIndexMap_.find(indGlo))
646        {
647          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
648          ++nbWritten;
649        }                 
650      }
651
652      if (isCompressible())
653      {
654        nbWritten = 0;
655        boost::unordered_map<size_t,size_t> localGlobalIndexMap;
656        for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
657        {
658          indGlo = *itSrv;
659          if (ite != globalLocalIndexMap_.find(indGlo))
660          {
661            localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
662            ++nbWritten;
663          }                 
664        }
665
666        nbWritten = 0;
667        for (int idx = 0; idx < data_index.numElements(); ++idx)
668        {
669          if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
670          {
671            ++nbWritten;
672          }
673        }
674
675        compressedIndexToWriteOnServer.resize(nbWritten);
676        nbWritten = 0;
677        for (int idx = 0; idx < data_index.numElements(); ++idx)
678        {
679          if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
680          {
681            compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_index(idx)];
682            ++nbWritten;
683          }
684        }
685
686        numberWrittenIndexes_ = nbWritten;
687        if (isDistributed())
688        {
689               
690          MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
691          MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
692          offsetWrittenIndexes_ -= numberWrittenIndexes_;
693        }
694        else
695          totalNumberWrittenIndexes_ = numberWrittenIndexes_;
696      }
697
698   }
699
700
701
702  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
703                                        CServerDistributionDescription::ServerDistributionType distType)
704  {
705    CContext* context = CContext::getCurrent();
706
707    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
708    for (int i = 0; i < nbSrvPools; ++i)
709    {
710      CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
711                                                                         : context->client;
712      int nbServer = contextClientTmp->serverSize;
713
714      CServerDistributionDescription serverDescription(globalDim, nbServer);
715      serverDescription.computeServerDistribution();
716
717      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
718      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
719
720      globalDimGrid.resize(globalDim.size());
721      for (int idx = 0; idx < globalDim.size(); ++idx) globalDimGrid(idx) = globalDim[idx];
722
723      CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE);
724      if (contextClientTmp->isServerLeader())
725      {
726        std::list<CMessage> msgs;
727
728        const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
729        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
730        {
731          // Use const int to ensure CMessage holds a copy of the value instead of just a reference
732          const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
733          const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
734          const int end   = begin + ni - 1;
735
736          msgs.push_back(CMessage());
737          CMessage& msg = msgs.back();
738          msg << this->getId();
739          msg << ni << begin << end;
740          msg << global_zoom_begin.getValue() << global_zoom_n.getValue();
741          msg << isCompressible_;
742          msg << orderPositionInGrid;
743          msg << globalDimGrid;
744
745          event.push(*itRank,1,msg);
746        }
747        contextClientTmp->sendEvent(event);
748      }
749      else contextClientTmp->sendEvent(event);
750    }
751  }
752
753  // void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
754  //                                    CServerDistributionDescription::ServerDistributionType distType)
755  // {
756  //   CContext* context = CContext::getCurrent();
757  //   CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
758  //   int nbServer = client->serverSize;
759  //   int range, clientSize = client->clientSize;
760  //   int rank = client->clientRank;
761
762  //   size_t ni = this->n.getValue();
763  //   size_t ibegin = this->begin.getValue();
764  //   size_t zoom_end = global_zoom_begin+global_zoom_n-1;
765  //   size_t nZoomCount = 0;
766  //   size_t nbIndex = index.numElements();
767  //   for (size_t idx = 0; idx < nbIndex; ++idx)
768  //   {
769  //     size_t globalIndex = index(idx);
770  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
771  //   }
772
773  //   CArray<size_t,1> globalIndexAxis(nbIndex);
774  //   std::vector<size_t> globalAxisZoom(nZoomCount);
775  //   nZoomCount = 0;
776  //   for (size_t idx = 0; idx < nbIndex; ++idx)
777  //   {
778  //     size_t globalIndex = index(idx);
779  //     globalIndexAxis(idx) = globalIndex;
780  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
781  //     {
782  //       globalAxisZoom[nZoomCount] = globalIndex;
783  //       ++nZoomCount;
784  //     }
785  //   }
786
787  //   std::set<int> writtenInd;
788  //   if (isCompressible_)
789  //   {
790  //     for (int idx = 0; idx < data_index.numElements(); ++idx)
791  //     {
792  //       int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
793
794  //       if (ind >= 0 && ind < ni && mask(ind))
795  //       {
796  //         ind += ibegin;
797  //         if (ind >= global_zoom_begin && ind <= zoom_end)
798  //           writtenInd.insert(ind);
799  //       }
800  //     }
801  //   }
802
803  //   CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
804  //   int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
805  //   CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
806  //   if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
807  //   {
808  //     std::vector<int> nGlobAxis(1);
809  //     nGlobAxis[0] = n_glo.getValue();
810
811  //     size_t globalSizeIndex = 1, indexBegin, indexEnd;
812  //     for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
813  //     indexBegin = 0;
814  //     if (globalSizeIndex <= clientSize)
815  //     {
816  //       indexBegin = rank%globalSizeIndex;
817  //       indexEnd = indexBegin;
818  //     }
819  //     else
820  //     {
821  //       for (int i = 0; i < clientSize; ++i)
822  //       {
823  //         range = globalSizeIndex / clientSize;
824  //         if (i < (globalSizeIndex%clientSize)) ++range;
825  //         if (i == client->clientRank) break;
826  //         indexBegin += range;
827  //       }
828  //       indexEnd = indexBegin + range - 1;
829  //     }
830
831  //     CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
832  //     serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
833  //     CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
834  //     clientServerMap->computeServerIndexMapping(globalIndexAxis);
835  //     globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
836  //     delete clientServerMap;
837  //   }
838  //   else
839  //   {
840  //     std::vector<size_t> globalIndexServer(n_glo.getValue());
841  //     for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
842  //     {
843  //       globalIndexServer[idx] = idx;
844  //     }
845
846  //     for (int idx = 0; idx < nbServer; ++idx)
847  //     {
848  //       globalIndexAxisOnServer[idx] = globalIndexServer;
849  //     }
850  //   }
851
852  //   CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
853  //                                                        ite = globalIndexAxisOnServer.end();
854  //   std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
855  //                                       iteVec = (globalAxisZoom).end();
856  //   indSrv_.clear();
857  //   indWrittenSrv_.clear();
858  //   for (; it != ite; ++it)
859  //   {
860  //     int rank = it->first;
861  //     const std::vector<size_t>& globalIndexTmp = it->second;
862  //     int nb = globalIndexTmp.size();
863
864  //     for (int i = 0; i < nb; ++i)
865  //     {
866  //       if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
867  //       {
868  //         indSrv_[rank].push_back(globalIndexTmp[i]);
869  //       }
870
871  //       if (writtenInd.count(globalIndexTmp[i]))
872  //       {
873  //         indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
874  //       }
875  //     }
876  //   }
877
878  //   connectedServerRank_.clear();
879  //   for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
880  //     connectedServerRank_.push_back(it->first);
881  //   }
882
883  //   if (!indSrv_.empty())
884  //   {
885  //     std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
886  //                                                    iteIndSrv = indSrv_.end();
887  //     connectedServerRank_.clear();
888  //     for (; itIndSrv != iteIndSrv; ++itIndSrv)
889  //       connectedServerRank_.push_back(itIndSrv->first);
890  //   }
891  //   nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
892  // }
893
894  void CAxis::sendNonDistributedAttributes()
895  {
896    CContext* context = CContext::getCurrent();
897
898    // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
899    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
900    for (int p = 0; p < nbSrvPools; ++p)
901    {
902      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
903
904      CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES);
905      size_t nbIndex = index.numElements();
906      size_t nbDataIndex = 0;
907
908      for (int idx = 0; idx < data_index.numElements(); ++idx)
909      {
910        int ind = data_index(idx);
911        if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
912      }
913
914      CArray<int,1> dataIndex(nbDataIndex);
915      nbDataIndex = 0;
916      for (int idx = 0; idx < data_index.numElements(); ++idx)
917      {
918        int ind = data_index(idx);
919        if (ind >= 0 && ind < nbIndex)
920        {
921          dataIndex(nbDataIndex) = ind;
922          ++nbDataIndex;
923        }
924      }
925
926      if (client->isServerLeader())
927      {
928        std::list<CMessage> msgs;
929
930        const std::list<int>& ranks = client->getRanksServerLeader();
931        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
932        {
933          msgs.push_back(CMessage());
934          CMessage& msg = msgs.back();
935          msg << this->getId();
936          msg << index.getValue() << dataIndex << mask.getValue();
937
938          msg << doZoomByIndex_;
939          if (doZoomByIndex_) msg << zoom_index.getValue();
940          msg << hasValue;
941          if (hasValue) msg << value.getValue();
942          msg << hasBounds_;
943          if (hasBounds_) msg << bounds.getValue();
944
945          event.push(*itRank, 1, msg);
946        }
947        client->sendEvent(event);
948      }
949      else client->sendEvent(event);
950    }
951  }
952
953  void CAxis::recvNonDistributedAttributes(CEventServer& event)
954  {
955    list<CEventServer::SSubEvent>::iterator it;
956    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
957    {
958      CBufferIn* buffer = it->buffer;
959      string axisId;
960      *buffer >> axisId;
961      get(axisId)->recvNonDistributedAttributes(it->rank, *buffer);
962    }
963  }
964
965  void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer)
966  { 
967    CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index;
968    CArray<bool,1> tmp_mask;
969    CArray<double,1> tmp_val;
970    CArray<double,2> tmp_bnds;
971
972    buffer >> tmp_index;
973    index.reference(tmp_index);
974    buffer >> tmp_data_index;
975    data_index.reference(tmp_data_index);
976    buffer >> tmp_mask;
977    mask.reference(tmp_mask);
978
979    buffer >> doZoomByIndex_;
980    if (doZoomByIndex_)
981    {
982      buffer >> tmp_zoom_index;
983      zoom_index.reference(tmp_zoom_index);
984    }
985
986    buffer >> hasValue;
987    if (hasValue)
988    {
989      buffer >> tmp_val;
990      value.reference(tmp_val);
991    }
992
993    buffer >> hasBounds_;
994    if (hasBounds_)
995    {
996      buffer >> tmp_bnds;
997      bounds.reference(tmp_bnds);
998    }
999
1000    data_begin.setValue(0);
1001    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
1002    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx);
1003  }
1004
1005  void CAxis::sendDistributedAttributes(void)
1006  {
1007    int ns, n, i, j, ind, nv, idx;
1008    CContext* context = CContext::getCurrent();
1009
1010    //int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
1011    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
1012    for (int p = 0; p < nbSrvPools; ++p)
1013    {
1014      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
1015
1016      CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES);
1017
1018      list<CMessage> listData;
1019      list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd;
1020      list<CArray<bool,1> > list_mask;
1021      list<CArray<double,1> > list_val;
1022      list<CArray<double,2> > list_bounds;
1023
1024      int nbIndex = index.numElements();
1025      CArray<int,1> dataIndex(nbIndex);
1026      dataIndex = -1;
1027      for (int inx = 0; inx < data_index.numElements(); ++inx)
1028      {
1029        if (0 <= data_index(inx) && data_index(inx) < nbIndex)
1030          dataIndex(inx) = data_index(inx);
1031      }
1032
1033      boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
1034      iteMap = indSrv_.end();
1035      for (int k = 0; k < connectedServerRank_.size(); ++k)
1036      {
1037        int nbData = 0;
1038        int rank = connectedServerRank_[k];
1039        int nbSendingClient = nbConnectedClients_[rank];
1040        it = indSrv_.find(rank);
1041        if (iteMap != it)
1042          nbData = it->second.size();
1043
1044        list_indi.push_back(CArray<int,1>(nbData));
1045        list_dataInd.push_back(CArray<int,1>(nbData));       
1046        list_mask.push_back(CArray<bool,1>(nbData));
1047
1048        if (doZoomByIndex_)
1049          list_zoomInd.push_back(CArray<int,1>(nbData));
1050
1051        if (hasValue)
1052          list_val.push_back(CArray<double,1>(nbData));
1053
1054        if (hasBounds_)
1055        {
1056          list_bounds.push_back(CArray<double,2>(2,nbData));
1057        }
1058
1059        CArray<int,1>& indi = list_indi.back();
1060        CArray<int,1>& dataIndi = list_dataInd.back();       
1061        CArray<bool,1>& maskIndi = list_mask.back();
1062
1063        for (n = 0; n < nbData; ++n)
1064        {
1065          idx = static_cast<int>(it->second[n]);
1066          indi(n) = idx;
1067
1068          ind = globalLocalIndexMap_[idx];
1069          dataIndi(n) = dataIndex(ind);
1070          maskIndi(n) = mask(ind);
1071
1072          if (doZoomByIndex_)
1073          {
1074            CArray<int,1>& zoomIndi = list_zoomInd.back();
1075            zoomIndi(n) = zoom_index(ind);
1076          }
1077
1078          if (hasValue)
1079          {
1080            CArray<double,1>& val = list_val.back();
1081            val(n) = value(ind);
1082          }
1083
1084          if (hasBounds_)
1085          {
1086            CArray<double,2>& boundsVal = list_bounds.back();
1087            boundsVal(0, n) = bounds(0,n);
1088            boundsVal(1, n) = bounds(1,n);
1089          }
1090        }
1091
1092        listData.push_back(CMessage());
1093        listData.back() << this->getId()
1094                        << list_indi.back() << list_dataInd.back() << list_mask.back();
1095
1096        listData.back() << doZoomByIndex_;           
1097        if (doZoomByIndex_)
1098          listData.back() << list_zoomInd.back();
1099
1100        listData.back() << hasValue;
1101        if (hasValue)
1102          listData.back() << list_val.back();
1103
1104        listData.back() << hasBounds_;
1105        if (hasBounds_)
1106          listData.back() << list_bounds.back();
1107
1108        eventData.push(rank, nbConnectedClients_[rank], listData.back());
1109      }
1110
1111      client->sendEvent(eventData);
1112    }
1113  }
1114
1115  void CAxis::recvDistributedAttributes(CEventServer& event)
1116  {
1117    string axisId;
1118    vector<int> ranks;
1119    vector<CBufferIn*> buffers;
1120
1121    list<CEventServer::SSubEvent>::iterator it;
1122    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1123    {
1124      ranks.push_back(it->rank);
1125      CBufferIn* buffer = it->buffer;
1126      *buffer >> axisId;
1127      buffers.push_back(buffer);
1128    }
1129    get(axisId)->recvDistributedAttributes(ranks, buffers);
1130  }
1131
1132
1133  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
1134  {
1135    int nbReceived = ranks.size();
1136    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);   
1137    vector<CArray<bool,1> > vec_mask(nbReceived);
1138    vector<CArray<double,1> > vec_val(nbReceived);
1139    vector<CArray<double,2> > vec_bounds(nbReceived);
1140   
1141    for (int idx = 0; idx < nbReceived; ++idx)
1142    {     
1143      CBufferIn& buffer = *buffers[idx];
1144      buffer >> vec_indi[idx];
1145      buffer >> vec_dataInd[idx];     
1146      buffer >> vec_mask[idx];
1147
1148      buffer >> doZoomByIndex_;
1149      if (doZoomByIndex_)
1150        buffer >> vec_zoomInd[idx];
1151
1152      buffer >> hasValue;
1153      if (hasValue)
1154        buffer >> vec_val[idx];
1155
1156      buffer >> hasBounds_;
1157      if (hasBounds_)
1158        buffer >> vec_bounds[idx];
1159    }
1160
1161    int nbData = 0;
1162    for (int idx = 0; idx < nbReceived; ++idx)
1163    {
1164      nbData += vec_indi[idx].numElements();
1165    }
1166
1167    index.resize(nbData);
1168    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
1169    CArray<int,1> nonCompressedData(nbData);   
1170    mask.resize(nbData);
1171    if (hasValue)
1172      value.resize(nbData);
1173    if (hasBounds_)
1174      bounds.resize(2,nbData);
1175
1176    nbData = 0;
1177    for (int idx = 0; idx < nbReceived; ++idx)
1178    {
1179      CArray<int,1>& indi = vec_indi[idx];
1180      CArray<int,1>& dataIndi = vec_dataInd[idx];
1181      CArray<bool,1>& maskIndi = vec_mask[idx];
1182      int nb = indi.numElements();
1183      for (int n = 0; n < nb; ++n)
1184      {
1185        index(nbData) = indi(n);
1186        globalLocalIndexMap_[indi(n)] = nbData;
1187        nonCompressedData(nbData) = (0 <= dataIndi(n)) ? nbData : -1;
1188        mask(nbData) = maskIndi(n);
1189        if (hasValue)
1190          value(nbData) = vec_val[idx](n);
1191        if (hasBounds_)
1192        {
1193          bounds(0,nbData) = vec_bounds[idx](0,n);
1194          bounds(1,nbData) = vec_bounds[idx](1,n);
1195        }
1196        ++nbData;
1197      }
1198    }
1199
1200    int nbIndex = index.numElements();
1201    int nbCompressedData = 0; 
1202    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
1203    {
1204      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
1205        ++nbCompressedData;       
1206    }
1207
1208    data_index.resize(nbCompressedData);
1209    nbCompressedData = 0;
1210    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
1211    {
1212      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
1213      {
1214        data_index(nbCompressedData) = nonCompressedData(idx);
1215        ++nbCompressedData;       
1216      }
1217    }
1218    data_begin.setValue(0);
1219
1220    if (doZoomByIndex_)
1221    {
1222      int nbZoomIndex = 0;
1223      for (int idx = 0; idx < nbReceived; ++idx)
1224      {
1225        nbZoomIndex += vec_zoomInd[idx].numElements();
1226      }
1227
1228      zoom_index.resize(nbZoomIndex);
1229      nbZoomIndex = 0;     
1230      for (int idx = 0; idx < nbReceived; ++idx)
1231      {     
1232        CArray<int,1>& tmp = vec_zoomInd[idx];
1233        for (int i = 0; i < tmp.size(); ++i)
1234        {
1235          zoom_index(nbZoomIndex) = tmp(i);
1236          ++nbZoomIndex;
1237        }       
1238      }
1239    }
1240  }
1241
1242  void CAxis::recvDistributionAttribute(CEventServer& event)
1243  {
1244    CBufferIn* buffer = event.subEvents.begin()->buffer;
1245    string axisId;
1246    *buffer >> axisId;
1247    get(axisId)->recvDistributionAttribute(*buffer);
1248  }
1249
1250  void CAxis::recvDistributionAttribute(CBufferIn& buffer)
1251  {
1252    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp;
1253
1254    buffer >> ni_srv >> begin_srv >> end_srv;
1255    buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;
1256    buffer >> isCompressible_;
1257    buffer >> orderPosInGrid;
1258    buffer >> globalDimGrid;
1259
1260    n.setValue(ni_srv);
1261    begin.setValue(begin_srv);
1262    global_zoom_begin = global_zoom_begin_tmp;
1263    global_zoom_n  = global_zoom_n_tmp;
1264    int global_zoom_end = global_zoom_begin + global_zoom_n - 1;
1265
1266    zoom_begin = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
1267    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
1268    zoom_n  = zoom_end_srv - zoom_begin_srv + 1;
1269
1270    if (zoom_n<=0)
1271    {
1272      zoom_begin = 0; zoom_end_srv = 0; zoom_n = 0;
1273    }
1274
1275    if (n_glo == n)
1276    {
1277      zoom_begin = global_zoom_begin;
1278      zoom_end_srv   = global_zoom_end; //zoom_end;
1279      zoom_n     = zoom_end_srv - zoom_begin + 1;
1280    }
1281  }
1282
1283
1284  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id)
1285  {
1286    transformationMap_.push_back(std::make_pair(transType, CTransformation<CAxis>::createTransformation(transType,id)));
1287    return transformationMap_.back().second;
1288  }
1289
1290  bool CAxis::hasTransformation()
1291  {
1292    return (!transformationMap_.empty());
1293  }
1294
1295  void CAxis::setTransformations(const TransMapTypes& axisTrans)
1296  {
1297    transformationMap_ = axisTrans;
1298  }
1299
1300  CAxis::TransMapTypes CAxis::getAllTransformations(void)
1301  {
1302    return transformationMap_;
1303  }
1304
1305  void CAxis::duplicateTransformation(CAxis* src)
1306  {
1307    if (src->hasTransformation())
1308    {
1309      this->setTransformations(src->getAllTransformations());
1310    }
1311  }
1312
1313  /*!
1314   * Go through the hierarchy to find the axis from which the transformations must be inherited
1315   */
1316  void CAxis::solveInheritanceTransformation()
1317  {
1318    if (hasTransformation() || !hasDirectAxisReference())
1319      return;
1320
1321    CAxis* axis = this;
1322    std::vector<CAxis*> refAxis;
1323    while (!axis->hasTransformation() && axis->hasDirectAxisReference())
1324    {
1325      refAxis.push_back(axis);
1326      axis = axis->getDirectAxisReference();
1327    }
1328
1329    if (axis->hasTransformation())
1330      for (size_t i = 0; i < refAxis.size(); ++i)
1331        refAxis[i]->setTransformations(axis->getAllTransformations());
1332  }
1333
1334  void CAxis::parse(xml::CXMLNode & node)
1335  {
1336    SuperClass::parse(node);
1337
1338    if (node.goToChildElement())
1339    {
1340      StdString nodeElementName;
1341      do
1342      {
1343        StdString nodeId("");
1344        if (node.getAttributes().end() != node.getAttributes().find("id"))
1345        { nodeId = node.getAttributes()["id"]; }
1346
1347        nodeElementName = node.getElementName();
1348        std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
1349        it = transformationMapList_.find(nodeElementName);
1350        if (ite != it)
1351        {
1352          transformationMap_.push_back(std::make_pair(it->second, CTransformation<CAxis>::createTransformation(it->second,
1353                                                                                                               nodeId,
1354                                                                                                               &node)));
1355        }
1356        else
1357        {
1358          ERROR("void CAxis::parse(xml::CXMLNode & node)",
1359                << "The transformation " << nodeElementName << " has not been supported yet.");
1360        }
1361      } while (node.goToNextElement()) ;
1362      node.goToParentElement();
1363    }
1364  }
1365
1366  DEFINE_REF_FUNC(Axis,axis)
1367
1368   ///---------------------------------------------------------------
1369
1370} // namespace xios
Note: See TracBrowser for help on using the repository browser.