source: XIOS/trunk/src/node/axis.cpp @ 676

Last change on this file since 676 was 676, checked in by rlacroix, 6 years ago

Add support for indexed output.

If the new field attribute "indexed_output" is set to true and a mask is defined (either at grid, domain or axis level), the indexed data will be outputed instead of the full data with missing values.

See http://cfconventions.org/Data/cf-conventions/cf-conventions-1.5/build/cf-conventions.html#compression-by-gathering for more information.

  • 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: 26.6 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(), baseRefObject(), areClientAttributesChecked_(false)
26      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
27      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
28      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
29   {
30   }
31
32   CAxis::CAxis(const StdString & id)
33      : CObjectTemplate<CAxis>(id)
34      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
35      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
36      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
37      , transformationMap_(), global_zoom_begin(0), global_zoom_size(0)
38   {
39   }
40
41   CAxis::~CAxis(void)
42   { /* Ne rien faire de plus */ }
43
44   ///---------------------------------------------------------------
45
46   const std::set<StdString> & CAxis::getRelFiles(void) const
47   {
48      return (this->relFiles);
49   }
50
51   bool CAxis::IsWritten(const StdString & filename) const
52   {
53      return (this->relFiles.find(filename) != this->relFiles.end());
54   }
55
56   bool CAxis::isWrittenCompressed(const StdString& filename) const
57   {
58      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
59   }
60
61   bool CAxis::isDistributed(void) const
62   {
63      return isDistributed_;
64   }
65
66   /*!
67    * Test whether the data defined on the axis can be outputted in a compressed way.
68    *
69    * \return true if and only if a mask was defined for this axis
70    */
71   bool CAxis::isCompressible(void) const
72   {
73      return isCompressible_;
74   }
75
76   void CAxis::addRelFile(const StdString & filename)
77   {
78      this->relFiles.insert(filename);
79   }
80
81   void CAxis::addRelFileCompressed(const StdString& filename)
82   {
83      this->relFilesCompressed.insert(filename);
84   }
85
86   //----------------------------------------------------------------
87
88   const std::vector<int>& CAxis::getIndexesToWrite(void) const
89   {
90     return indexesToWrite;
91   }
92
93   /*!
94     Returns the number of indexes written by each server.
95     \return the number of indexes written by each server
96   */
97   int CAxis::getNumberWrittenIndexes() const
98   {
99     return numberWrittenIndexes_;
100   }
101
102   /*!
103     Returns the total number of indexes written by the servers.
104     \return the total number of indexes written by the servers
105   */
106   int CAxis::getTotalNumberWrittenIndexes() const
107   {
108     return totalNumberWrittenIndexes_;
109   }
110
111   /*!
112     Returns the offset of indexes written by each server.
113     \return the offset of indexes written by each server
114   */
115   int CAxis::getOffsetWrittenIndexes() const
116   {
117     return offsetWrittenIndexes_;
118   }
119
120   //----------------------------------------------------------------
121
122   StdString CAxis::GetName(void)   { return (StdString("axis")); }
123   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
124   ENodeType CAxis::GetType(void)   { return (eAxis); }
125
126   //----------------------------------------------------------------
127
128   CAxis* CAxis::createAxis()
129   {
130     CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
131     return axis;
132   }
133
134   void CAxis::checkAttributes(void)
135   {
136      if (this->n_glo.isEmpty())
137         ERROR("CAxis::checkAttributes(void)",
138               << "Attribute <n_glo> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified");
139      StdSize size = this->n_glo.getValue();
140
141      isDistributed_ = !this->begin.isEmpty() || !this->n.isEmpty();
142
143      if (!this->begin.isEmpty())
144      {
145        StdSize ibegin = this->begin.getValue();
146        if ((ibegin < 0) || (ibegin > size-1))
147          ERROR("CAxis::checkAttributes(void)",
148                << "Attribute <ibegin> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size-1");
149      }
150      else this->begin.setValue(0);
151
152      if (!this->n.isEmpty())
153      {
154        StdSize ni = this->n.getValue();
155        if ((ni < 0) || (ni > size))
156          ERROR("CAxis::checkAttributes(void)",
157                << "Attribute <ni> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size");
158      }
159      else this->n.setValue(size);
160
161      StdSize true_size = value.numElements();
162      if (this->n.getValue() != true_size)
163         ERROR("CAxis::checkAttributes(void)",
164               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
165
166      this->checkData();
167      this->checkZoom();
168      this->checkMask();
169      this->checkBounds();
170   }
171
172   void CAxis::checkData()
173   {
174      if (data_begin.isEmpty()) data_begin.setValue(0);
175      if (!data_n.isEmpty() && data_n.getValue() <= 0)
176      {
177        ERROR("CAxis::checkData(void)",
178              << "Data dimension is negative (data_n).");
179      }
180      else if (data_n.isEmpty())
181        data_n.setValue(n.getValue());
182
183      if (data_index.isEmpty())
184      {
185        int dn = data_n.getValue();
186        data_index.resize(dn);
187        for (int i = 0; i < dn; ++i) data_index(i) = i;
188      }
189   }
190
191   void CAxis::checkZoom(void)
192   {
193     if (0 == global_zoom_size) global_zoom_size = this->n_glo.getValue();
194   }
195
196   void CAxis::checkMask()
197   {
198      if (!mask.isEmpty())
199      {
200         if (mask.extent(0) != n)
201            ERROR("CAxis::checkMask(void)",
202                  << "the mask has not the same size than the local axis" << endl
203                  << "Local size is " << n << "x" << endl
204                  << "Mask size is " << mask.extent(0) << "x");
205      }
206      else // (!mask.hasValue())
207      { // Si aucun masque n'est défini,
208        // on en crée un nouveau qui valide l'intégralité du domaine.
209         mask.resize(n);
210         for (int i = 0; i < n.getValue(); ++i)
211         {
212           mask(i) = true;
213         }
214      }
215   }
216
217  void CAxis::checkBounds()
218  {
219    if (!bounds.isEmpty())
220    {
221      if (bounds.extent(0) != n || bounds.extent(1) != 2)
222          ERROR("CAxis::checkAttributes(void)",
223                << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension axis size x 2" << endl
224                << "Axis size is " << n << endl
225                << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1));
226      hasBounds_ = true;
227    }
228    else hasBounds_ = false;
229  }
230
231  void CAxis::checkEligibilityForCompressedOutput()
232  {
233    // We don't check if the mask is valid here, just if a mask has been defined at this point.
234    isCompressible_ = !mask.isEmpty();
235  }
236
237  bool CAxis::dispatchEvent(CEventServer& event)
238   {
239      if (SuperClass::dispatchEvent(event)) return true;
240      else
241      {
242        switch(event.type)
243        {
244           case EVENT_ID_SERVER_ATTRIBUT :
245             recvServerAttribut(event);
246             return true;
247             break;
248           case EVENT_ID_INDEX:
249            recvIndex(event);
250            return true;
251            break;
252          case EVENT_ID_DISTRIBUTED_VALUE:
253            recvDistributedValue(event);
254            return true;
255            break;
256          case EVENT_ID_NON_DISTRIBUTED_VALUE:
257            recvNonDistributedValue(event);
258            return true;
259            break;
260           default :
261             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
262                    << "Unknown Event");
263           return false;
264         }
265      }
266   }
267
268   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
269                                       CServerDistributionDescription::ServerDistributionType distType)
270   {
271     if (this->areClientAttributesChecked_) return;
272
273     this->checkAttributes();
274
275     this->areClientAttributesChecked_ = true;
276   }
277
278   // Send all checked attributes to server
279   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
280                                     CServerDistributionDescription::ServerDistributionType distType)
281   {
282     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
283                                                                     orderPositionInGrid,
284                                                                     distType);
285     CContext* context = CContext::getCurrent();
286
287     if (this->isChecked) return;
288     if (context->hasClient)
289     {
290       sendServerAttribut(globalDim, orderPositionInGrid, distType);
291       sendValue();
292     }
293
294     this->isChecked = true;
295   }
296
297  void CAxis::sendValue()
298  {
299     if (n.getValue() == n_glo.getValue())
300     {
301       sendNonDistributedValue();
302     }
303     else
304     {
305       computeConnectedServer();
306       sendDistributedValue();
307     }
308  }
309
310  void CAxis::computeConnectedServer()
311  {
312    CContext* context = CContext::getCurrent();
313    CContextClient* client = context->client;
314    int nbServer = client->serverSize;
315    int range, clientSize = client->clientSize;
316
317    size_t ni = this->n.getValue();
318    size_t ibegin = this->begin.getValue();
319    size_t zoom_end = global_zoom_begin+global_zoom_size-1;
320    size_t nZoomCount = 0;
321    for (size_t idx = 0; idx < ni; ++idx)
322    {
323      size_t globalIndex = ibegin + idx;
324
325      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
326    }
327
328    CArray<size_t,1> globalIndexAxis(ni);
329    std::vector<size_t> globalAxisZoom(nZoomCount);
330    nZoomCount = 0;
331    for (size_t idx = 0; idx < ni; ++idx)
332    {
333      size_t globalIndex = ibegin + idx;
334      globalIndexAxis(idx) = globalIndex;
335      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
336      {
337        globalAxisZoom[nZoomCount] = globalIndex;
338        ++nZoomCount;
339      }
340    }
341
342    std::set<int> writtenInd;
343    if (isCompressible_)
344    {
345      for (int idx = 0; idx < data_index.numElements(); ++idx)
346      {
347        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
348
349        if (ind >= 0 && ind < ni && mask(ind))
350        {
351          ind += ibegin;
352          if (ind >= global_zoom_begin && ind <= zoom_end)
353            writtenInd.insert(ind);
354        }
355      }
356    }
357
358    std::vector<int> nGlobDomain(1);
359    nGlobDomain[0] = n_glo.getValue();
360
361    size_t globalSizeIndex = 1, indexBegin, indexEnd;
362    for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
363    indexBegin = 0;
364    for (int i = 0; i < clientSize; ++i)
365    {
366      range = globalSizeIndex / clientSize;
367      if (i < (globalSizeIndex%clientSize)) ++range;
368      if (i == client->clientRank) break;
369      indexBegin += range;
370    }
371    indexEnd = indexBegin + range - 1;
372
373    CServerDistributionDescription serverDescription(nGlobDomain);
374    serverDescription.computeServerGlobalIndexInRange(nbServer, std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0);
375    CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
376    clientServerMap->computeServerIndexMapping(globalIndexAxis);
377    const std::map<int, std::vector<size_t> >& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
378
379    std::map<int, std::vector<size_t> >::const_iterator it = globalIndexAxisOnServer.begin(),
380                                                       ite = globalIndexAxisOnServer.end();
381    std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
382                                        iteVec = (globalAxisZoom).end();
383    indSrv_.clear();
384    indWrittenSrv_.clear();
385    for (; it != ite; ++it)
386    {
387      int rank = it->first;
388      const std::vector<size_t>& globalIndexTmp = it->second;
389      int nb = globalIndexTmp.size();
390
391      for (int i = 0; i < nb; ++i)
392      {
393        if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
394        {
395          indSrv_[rank].push_back(globalIndexTmp[i]);
396        }
397
398        if (writtenInd.count(globalIndexTmp[i]))
399        {
400          indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
401        }
402      }
403    }
404
405    connectedServerRank_.clear();
406    for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
407      connectedServerRank_.push_back(it->first);
408    }
409
410    if (!indSrv_.empty())
411    {
412      connectedServerRank_.clear();
413      for (it = indSrv_.begin(); it != indSrv_.end(); ++it)
414        connectedServerRank_.push_back(it->first);
415    }
416    nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
417    delete clientServerMap;
418  }
419
420  void CAxis::sendNonDistributedValue()
421  {
422    CContext* context = CContext::getCurrent();
423    CContextClient* client = context->client;
424    CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_VALUE);
425
426    int zoom_end = global_zoom_begin + global_zoom_size - 1;
427    int nb = 0;
428    for (size_t idx = 0; idx < n; ++idx)
429    {
430      size_t globalIndex = begin + idx;
431      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nb;
432    }
433
434    int nbWritten = 0;
435    if (isCompressible_)
436    {
437      for (int idx = 0; idx < data_index.numElements(); ++idx)
438      {
439        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
440
441        if (ind >= 0 && ind < n && mask(ind))
442        {
443          ind += begin;
444          if (ind >= global_zoom_begin && ind <= zoom_end)
445            ++nbWritten;
446        }
447      }
448    }
449
450    CArray<double,1> val(nb);
451    nb = 0;
452    for (size_t idx = 0; idx < n; ++idx)
453    {
454      size_t globalIndex = begin + idx;
455      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
456      {
457        val(nb) = value(idx);
458        ++nb;
459      }
460    }
461
462    CArray<int, 1> writtenInd(nbWritten);
463    nbWritten = 0;
464    if (isCompressible_)
465    {
466      for (int idx = 0; idx < data_index.numElements(); ++idx)
467      {
468        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
469
470        if (ind >= 0 && ind < n && mask(ind))
471        {
472          ind += begin;
473          if (ind >= global_zoom_begin && ind <= zoom_end)
474          {
475            writtenInd(nbWritten) = ind;
476            ++nbWritten;
477          }
478        }
479      }
480    }
481
482    if (client->isServerLeader())
483    {
484      std::list<CMessage> msgs;
485
486      const std::list<int>& ranks = client->getRanksServerLeader();
487      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
488      {
489        msgs.push_back(CMessage());
490        CMessage& msg = msgs.back();
491        msg << this->getId();
492        msg << val;
493        if (isCompressible_)
494          msg << writtenInd;
495        event.push(*itRank, 1, msg);
496      }
497      client->sendEvent(event);
498    }
499    else client->sendEvent(event);
500  }
501
502  void CAxis::sendDistributedValue(void)
503  {
504    int ns, n, i, j, ind, nv, idx;
505    CContext* context = CContext::getCurrent();
506    CContextClient* client=context->client;
507
508    // send value for each connected server
509    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
510    CEventClient eventVal(getType(), EVENT_ID_DISTRIBUTED_VALUE);
511
512    list<CMessage> list_msgsIndex, list_msgsVal;
513    list<CArray<int,1> > list_indi;
514    list<CArray<int,1> > list_writtenInd;
515    list<CArray<double,1> > list_val;
516    list<CArray<double,2> > list_bounds;
517
518    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
519    iteMap = indSrv_.end();
520    for (int k = 0; k < connectedServerRank_.size(); ++k)
521    {
522      int nbData = 0;
523      int rank = connectedServerRank_[k];
524      it = indSrv_.find(rank);
525      if (iteMap != it)
526        nbData = it->second.size();
527
528      list_indi.push_back(CArray<int,1>(nbData));
529      list_val.push_back(CArray<double,1>(nbData));
530
531      if (hasBounds_)
532      {
533        list_bounds.push_back(CArray<double,2>(2,nbData));
534      }
535
536      CArray<int,1>& indi = list_indi.back();
537      CArray<double,1>& val = list_val.back();
538
539      for (n = 0; n < nbData; ++n)
540      {
541        idx = static_cast<int>(it->second[n]);
542        ind = idx - begin;
543
544        val(n) = value(ind);
545        indi(n) = idx;
546
547        if (hasBounds_)
548        {
549          CArray<double,2>& boundsVal = list_bounds.back();
550          boundsVal(0, n) = bounds(0,n);
551          boundsVal(1, n) = bounds(1,n);
552        }
553      }
554
555      list_msgsIndex.push_back(CMessage());
556      list_msgsIndex.back() << this->getId() << list_indi.back();
557
558      if (isCompressible_)
559      {
560        std::vector<int>& writtenIndSrc = indWrittenSrv_[rank];
561        list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size()));
562        CArray<int,1>& writtenInd = list_writtenInd.back();
563
564        for (n = 0; n < writtenInd.numElements(); ++n)
565          writtenInd(n) = writtenIndSrc[n];
566
567        list_msgsIndex.back() << writtenInd;
568      }
569
570      list_msgsVal.push_back(CMessage());
571      list_msgsVal.back() << this->getId() << list_val.back();
572
573      if (hasBounds_)
574      {
575        list_msgsVal.back() << list_bounds.back();
576      }
577
578      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
579      eventVal.push(rank, nbConnectedClients_[rank], list_msgsVal.back());
580    }
581
582    client->sendEvent(eventIndex);
583    client->sendEvent(eventVal);
584  }
585
586  void CAxis::recvIndex(CEventServer& event)
587  {
588    CAxis* axis;
589
590    list<CEventServer::SSubEvent>::iterator it;
591    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
592    {
593      CBufferIn* buffer = it->buffer;
594      string axisId;
595      *buffer >> axisId;
596      axis = get(axisId);
597      axis->recvIndex(it->rank, *buffer);
598    }
599
600    if (axis->isCompressible_)
601    {
602      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
603
604      CContextServer* server = CContext::getCurrent()->server;
605      axis->numberWrittenIndexes_ = axis->indexesToWrite.size();
606      MPI_Allreduce(&axis->numberWrittenIndexes_, &axis->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
607      MPI_Scan(&axis->numberWrittenIndexes_, &axis->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
608      axis->offsetWrittenIndexes_ -= axis->numberWrittenIndexes_;
609    }
610  }
611
612  void CAxis::recvIndex(int rank, CBufferIn& buffer)
613  {
614    buffer >> indiSrv_[rank];
615
616    if (isCompressible_)
617    {
618      CArray<int, 1> writtenIndexes;
619      buffer >> writtenIndexes;
620      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
621      for (int i = 0; i < writtenIndexes.numElements(); ++i)
622        indexesToWrite.push_back(writtenIndexes(i));
623    }
624  }
625
626  void CAxis::recvDistributedValue(CEventServer& event)
627  {
628    list<CEventServer::SSubEvent>::iterator it;
629    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
630    {
631      CBufferIn* buffer = it->buffer;
632      string axisId;
633      *buffer >> axisId;
634      get(axisId)->recvDistributedValue(it->rank, *buffer);
635    }
636  }
637
638  void CAxis::recvDistributedValue(int rank, CBufferIn& buffer)
639  {
640    CArray<int,1> &indi = indiSrv_[rank];
641    CArray<double,1> val;
642    CArray<double,2> boundsVal;
643
644    buffer >> val;
645    if (hasBounds_) buffer >> boundsVal;
646
647    int i, j, ind_srv;
648    for (int ind = 0; ind < indi.numElements(); ++ind)
649    {
650      i = indi(ind);
651      ind_srv = i - zoom_begin_srv;
652      value_srv(ind_srv) = val(ind);
653      if (hasBounds_)
654      {
655        bound_srv(0,ind_srv) = boundsVal(0, ind);
656        bound_srv(1,ind_srv) = boundsVal(1, ind);
657      }
658    }
659  }
660
661   void CAxis::recvNonDistributedValue(CEventServer& event)
662  {
663    CAxis* axis;
664
665    list<CEventServer::SSubEvent>::iterator it;
666    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
667    {
668      CBufferIn* buffer = it->buffer;
669      string axisId;
670      *buffer >> axisId;
671      axis = get(axisId);
672      axis->recvNonDistributedValue(it->rank, *buffer);
673    }
674
675    if (axis->isCompressible_)
676    {
677      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
678
679      axis->numberWrittenIndexes_ = axis->totalNumberWrittenIndexes_ = axis->indexesToWrite.size();
680      axis->offsetWrittenIndexes_ = 0;
681    }
682  }
683
684  void CAxis::recvNonDistributedValue(int rank, CBufferIn& buffer)
685  {
686    CArray<double,1> val;
687    buffer >> val;
688
689    for (int ind = 0; ind < val.numElements(); ++ind)
690    {
691      value_srv(ind) = val(ind);
692      if (hasBounds_)
693      {
694        bound_srv(0,ind) = bounds(0,ind);
695        bound_srv(1,ind) = bounds(1,ind);
696      }
697    }
698
699    if (isCompressible_)
700    {
701      CArray<int, 1> writtenIndexes;
702      buffer >> writtenIndexes;
703      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
704      for (int i = 0; i < writtenIndexes.numElements(); ++i)
705        indexesToWrite.push_back(writtenIndexes(i));
706    }
707  }
708
709  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
710                                 CServerDistributionDescription::ServerDistributionType distType)
711  {
712    CContext* context = CContext::getCurrent();
713    CContextClient* client = context->client;
714
715    CServerDistributionDescription serverDescription(globalDim);
716
717    int nbServer = client->serverSize;
718
719    serverDescription.computeServerDistribution(nbServer, false, distType);
720    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
721    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
722
723    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
724    if (client->isServerLeader())
725    {
726      std::list<CMessage> msgs;
727
728      const std::list<int>& ranks = client->getRanksServerLeader();
729      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
730      {
731        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
732        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
733        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
734        const int end   = begin + ni - 1;
735
736        msgs.push_back(CMessage());
737        CMessage& msg = msgs.back();
738        msg << this->getId();
739        msg << ni << begin << end;
740        msg << global_zoom_begin << global_zoom_size;
741        msg << isCompressible_;
742
743        event.push(*itRank,1,msg);
744      }
745      client->sendEvent(event);
746    }
747    else client->sendEvent(event);
748  }
749
750  void CAxis::recvServerAttribut(CEventServer& event)
751  {
752    CBufferIn* buffer = event.subEvents.begin()->buffer;
753    string axisId;
754    *buffer >> axisId;
755    get(axisId)->recvServerAttribut(*buffer);
756  }
757
758  void CAxis::recvServerAttribut(CBufferIn& buffer)
759  {
760    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_size_tmp;
761
762    buffer >> ni_srv >> begin_srv >> end_srv;
763    buffer >> global_zoom_begin_tmp >> global_zoom_size_tmp;
764    buffer >> isCompressible_;
765    global_zoom_begin = global_zoom_begin_tmp;
766    global_zoom_size  = global_zoom_size_tmp;
767    int global_zoom_end = global_zoom_begin + global_zoom_size - 1;
768
769    zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
770    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
771    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
772
773    if (zoom_size_srv<=0)
774    {
775      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
776    }
777
778    if (n_glo == n)
779    {
780      zoom_begin_srv = global_zoom_begin;
781      zoom_end_srv   = global_zoom_end; //zoom_end;
782      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
783    }
784    value_srv.resize(zoom_size_srv);
785    bound_srv.resize(2,zoom_size_srv);
786  }
787
788  bool CAxis::hasTransformation()
789  {
790    return (!transformationMap_.empty());
791  }
792
793  void CAxis::setTransformations(const TransMapTypes& axisTrans)
794  {
795    transformationMap_ = axisTrans;
796  }
797
798  CAxis::TransMapTypes CAxis::getAllTransformations(void)
799  {
800    return transformationMap_;
801  }
802
803  /*!
804    Check the validity of all transformations applied on axis
805  This functions is called AFTER all inherited attributes are solved
806  */
807  void CAxis::checkTransformations()
808  {
809    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
810                                  ite = transformationMap_.end();
811    for (it = itb; it != ite; ++it)
812    {
813      (it->second)->checkValid(this);
814    }
815  }
816
817  void CAxis::solveInheritanceTransformation()
818  {
819    if (this->hasTransformation()) return;
820
821    std::vector<CAxis*> refAxis;
822    CAxis* refer_sptr;
823    CAxis* refer_ptr = this;
824    while (refer_ptr->hasDirectAxisReference())
825    {
826      refAxis.push_back(refer_ptr);
827      refer_sptr = refer_ptr->getDirectAxisReference();
828      refer_ptr  = refer_sptr;
829      if (refer_ptr->hasTransformation()) break;
830    }
831
832    if (refer_ptr->hasTransformation())
833      for (int idx = 0; idx < refAxis.size(); ++idx)
834        refAxis[idx]->setTransformations(refer_ptr->getAllTransformations());
835  }
836
837  void CAxis::parse(xml::CXMLNode & node)
838  {
839    SuperClass::parse(node);
840
841    if (node.goToChildElement())
842    {
843      StdString inverseAxisDefRoot("inverse_axis_definition");
844      StdString inverse("inverse_axis");
845      StdString zoomAxisDefRoot("zoom_axis_definition");
846      StdString zoom("zoom_axis");
847      StdString interpAxisDefRoot("interpolate_axis_definition");
848      StdString interp("interpolate_axis");
849      do
850      {
851        if (node.getElementName() == inverse) {
852          CInverseAxis* tmp = (CInverseAxisGroup::get(inverseAxisDefRoot))->createChild();
853          tmp->parse(node);
854          transformationMap_.push_back(std::make_pair(TRANS_INVERSE_AXIS,tmp));
855        } else if (node.getElementName() == zoom) {
856          CZoomAxis* tmp = (CZoomAxisGroup::get(zoomAxisDefRoot))->createChild();
857          tmp->parse(node);
858          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_AXIS,tmp));
859        }
860        else if (node.getElementName() == interp) {
861          CInterpolateAxis* tmp = (CInterpolateAxisGroup::get(interpAxisDefRoot))->createChild();
862          tmp->parse(node);
863          transformationMap_.push_back(std::make_pair(TRANS_INTERPOLATE_AXIS,tmp));
864        }
865      } while (node.goToNextElement()) ;
866      node.goToParentElement();
867    }
868  }
869
870  DEFINE_REF_FUNC(Axis,axis)
871
872   ///---------------------------------------------------------------
873
874} // namespace xios
Note: See TracBrowser for help on using the repository browser.