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

Last change on this file since 679 was 679, checked in by rlacroix, 9 years ago

Improve the error messages for axis and domains.

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