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

Last change on this file since 1054 was 1054, checked in by oabramkina, 5 years ago

dev: intermediate commit.

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