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

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