source: XIOS/dev/branch_yushan/src/node/axis.cpp @ 1103

Last change on this file since 1103 was 1103, checked in by yushan, 7 years ago

save modif. Todo: axis, domain, mesh, scalar, transformation

  • 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: 33.3 KB
RevLine 
[219]1#include "axis.hpp"
2
[352]3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6#include "message.hpp"
7#include "type.hpp"
[567]8#include "context.hpp"
9#include "context_client.hpp"
[676]10#include "context_server.hpp"
[591]11#include "xios_spl.hpp"
[630]12#include "inverse_axis.hpp"
13#include "zoom_axis.hpp"
14#include "interpolate_axis.hpp"
[633]15#include "server_distribution_description.hpp"
16#include "client_server_mapping_distributed.hpp"
[676]17#include "distribution_client.hpp"
[219]18
[335]19namespace xios {
[540]20
[219]21   /// ////////////////////// Définitions ////////////////////// ///
22
23   CAxis::CAxis(void)
24      : CObjectTemplate<CAxis>()
[771]25      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
[927]26      , isClientAfterTransformationChecked(false)
[676]27      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
28      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
[821]29      , transformationMap_(), hasValue(false)
[621]30   {
31   }
[219]32
33   CAxis::CAxis(const StdString & id)
34      : CObjectTemplate<CAxis>(id)
[771]35      , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
[927]36      , isClientAfterTransformationChecked(false)
[676]37      , isDistributed_(false), hasBounds_(false), isCompressible_(false)
38      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
[821]39      , transformationMap_(), hasValue(false)
[621]40   {
41   }
[219]42
43   CAxis::~CAxis(void)
44   { /* Ne rien faire de plus */ }
45
[1095]46   std::map<StdString, ETranformationType> CAxis::transformationMapList_ = std::map<StdString, ETranformationType>();
[1103]47   
48   std::map<StdString, ETranformationType> *CAxis::transformationMapList_ptr = new std::map<StdString, ETranformationType>();
49   
[1095]50   bool CAxis::dummyTransformationMapList_ = CAxis::initializeTransformationMap(CAxis::transformationMapList_);
[1103]51   //bool CAxis::dummyTransformationMapList_ = CAxis::initializeTransformationMap(*CAxis::transformationMapList_ptr);
52
[836]53   bool CAxis::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
54   {
55     m["zoom_axis"] = TRANS_ZOOM_AXIS;
56     m["interpolate_axis"] = TRANS_INTERPOLATE_AXIS;
57     m["inverse_axis"] = TRANS_INVERSE_AXIS;
[895]58     m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS;
59     m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS;
[1103]60     
61     // m.insert(m.end(), make_pair("zoom_axis", TRANS_ZOOM_AXIS)); printf("zoom_axis insert\n");
62     // m.insert(m.end(), make_pair("interpolate_axis", TRANS_INTERPOLATE_AXIS)); printf("interpolate_axis insert\n");
63     // m.insert(m.end(), make_pair("inverse_axis", TRANS_INVERSE_AXIS)); printf("inverse_axis insert\n");
64     // m.insert(m.end(), make_pair("reduce_domain", TRANS_REDUCE_DOMAIN_TO_AXIS)); printf("reduce_domain insert\n");
65     // m.insert(m.end(), make_pair("extract_domain", TRANS_EXTRACT_DOMAIN_TO_AXIS)); printf("extract_domain insert\n");
[836]66   }
67
[219]68   ///---------------------------------------------------------------
69
70   const std::set<StdString> & CAxis::getRelFiles(void) const
71   {
72      return (this->relFiles);
73   }
74
75   bool CAxis::IsWritten(const StdString & filename) const
76   {
77      return (this->relFiles.find(filename) != this->relFiles.end());
78   }
79
[676]80   bool CAxis::isWrittenCompressed(const StdString& filename) const
81   {
82      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
83   }
84
[594]85   bool CAxis::isDistributed(void) const
86   {
87      return isDistributed_;
88   }
89
[676]90   /*!
91    * Test whether the data defined on the axis can be outputted in a compressed way.
[742]92    *
[676]93    * \return true if and only if a mask was defined for this axis
94    */
95   bool CAxis::isCompressible(void) const
96   {
97      return isCompressible_;
98   }
99
[219]100   void CAxis::addRelFile(const StdString & filename)
101   {
102      this->relFiles.insert(filename);
103   }
104
[676]105   void CAxis::addRelFileCompressed(const StdString& filename)
106   {
107      this->relFilesCompressed.insert(filename);
108   }
109
[219]110   //----------------------------------------------------------------
111
[676]112   const std::vector<int>& CAxis::getIndexesToWrite(void) const
113   {
114     return indexesToWrite;
115   }
116
117   /*!
118     Returns the number of indexes written by each server.
119     \return the number of indexes written by each server
120   */
121   int CAxis::getNumberWrittenIndexes() const
122   {
123     return numberWrittenIndexes_;
124   }
125
126   /*!
127     Returns the total number of indexes written by the servers.
128     \return the total number of indexes written by the servers
129   */
130   int CAxis::getTotalNumberWrittenIndexes() const
131   {
132     return totalNumberWrittenIndexes_;
133   }
134
135   /*!
136     Returns the offset of indexes written by each server.
137     \return the offset of indexes written by each server
138   */
139   int CAxis::getOffsetWrittenIndexes() const
140   {
141     return offsetWrittenIndexes_;
142   }
143
144   //----------------------------------------------------------------
145
[731]146   /*!
147    * Compute the minimum buffer size required to send the attributes to the server(s).
148    *
149    * \return A map associating the server rank with its minimum buffer size.
150    */
151   std::map<int, StdSize> CAxis::getAttributesBufferSize()
152   {
153     CContextClient* client = CContext::getCurrent()->client;
154
155     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes();
156
157     bool isNonDistributed = (n == n_glo);
158
159     if (client->isServerLeader())
160     {
161       // size estimation for sendServerAttribut
162       size_t size = 6 * sizeof(size_t);
163       // size estimation for sendNonDistributedValue
164       if (isNonDistributed)
165         size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0));
166       size += CEventClient::headerSize + getId().size() + sizeof(size_t);
167
168       const std::list<int>& ranks = client->getRanksServerLeader();
169       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
170       {
171         if (size > attributesSizes[*itRank])
172           attributesSizes[*itRank] = size;
173       }
174     }
175
176     if (!isNonDistributed)
177     {
178       // size estimation for sendDistributedValue
179       std::map<int, std::vector<size_t> >::const_iterator it, ite = indSrv_.end();
180       for (it = indSrv_.begin(); it != ite; ++it)
181       {
182         size_t sizeIndexEvent = CArray<int,1>::size(it->second.size());
183         if (isCompressible_)
184           sizeIndexEvent += CArray<int,1>::size(indWrittenSrv_[it->first].size());
185
186         size_t sizeValEvent = CArray<double,1>::size(it->second.size());
187         if (hasBounds_)
[754]188           sizeValEvent += CArray<double,2>::size(2 * it->second.size());
[731]189
190         size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent);
191         if (size > attributesSizes[it->first])
192           attributesSizes[it->first] = size;
193       }
194     }
195
196     return attributesSizes;
197   }
198
199   //----------------------------------------------------------------
200
[219]201   StdString CAxis::GetName(void)   { return (StdString("axis")); }
202   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
203   ENodeType CAxis::GetType(void)   { return (eAxis); }
204
205   //----------------------------------------------------------------
206
[622]207   CAxis* CAxis::createAxis()
208   {
209     CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
210     return axis;
211   }
212
[775]213   void CAxis::fillInValues(const CArray<double,1>& values)
214   {
215     this->value = values;
216   }
217
[219]218   void CAxis::checkAttributes(void)
219   {
[666]220      if (this->n_glo.isEmpty())
[679]221        ERROR("CAxis::checkAttributes(void)",
222              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
223              << "The axis is wrongly defined, attribute 'n_glo' must be specified");
[666]224      StdSize size = this->n_glo.getValue();
[540]225
[970]226      if (!this->index.isEmpty())
[551]227      {
[970]228        if (n.isEmpty()) n = index.numElements();
229
230        // It's not so correct but if begin is not the first value of index
231        // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
232        if (begin.isEmpty()) begin = index(0);         
[551]233      }
[970]234      else 
235      {
236        if (!this->begin.isEmpty())
237        {
238          if (begin < 0 || begin > size - 1)
239            ERROR("CAxis::checkAttributes(void)",
240                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
241                  << "The axis is wrongly defined, attribute 'begin' (" << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").");
242        }
243        else this->begin.setValue(0);
[551]244
[970]245        if (!this->n.isEmpty())
246        {
247          if (n < 0 || n > size)
248            ERROR("CAxis::checkAttributes(void)",
249                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
250                  << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" << size << ").");
251        }
252        else this->n.setValue(size);
253
254        {
255          index.resize(n);
256          for (int i = 0; i < n; ++i) index(i) = i+begin;
257        }
[551]258      }
[624]259
[816]260      if (!this->value.isEmpty())
261      {
262        StdSize true_size = value.numElements();
263        if (this->n.getValue() != true_size)
264          ERROR("CAxis::checkAttributes(void)",
265                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
266                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
267        this->hasValue = true;
268      }
[219]269
[551]270      this->checkData();
[633]271      this->checkZoom();
[551]272      this->checkMask();
[633]273      this->checkBounds();
[970]274
275      isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) ||
276                       (!this->n.isEmpty() && (this->n != this->n_glo));
[219]277   }
278
[551]279   void CAxis::checkData()
280   {
281      if (data_begin.isEmpty()) data_begin.setValue(0);
[679]282
283      if (data_n.isEmpty())
[551]284      {
[679]285        data_n.setValue(n);
286      }
287      else if (data_n.getValue() < 0)
288      {
[551]289        ERROR("CAxis::checkData(void)",
[679]290              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
291              << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").");
[551]292      }
293
294      if (data_index.isEmpty())
295      {
[679]296        data_index.resize(data_n);
297        for (int i = 0; i < data_n; ++i) data_index(i) = i;
[551]298      }
299   }
300
[631]301   void CAxis::checkZoom(void)
302   {
[821]303     if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0);
304     if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue());
[631]305   }
[567]306
[551]307   void CAxis::checkMask()
308   {
309      if (!mask.isEmpty())
310      {
[666]311         if (mask.extent(0) != n)
[679]312           ERROR("CAxis::checkMask(void)",
313                 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
314                 << "The mask does not have the same size as the local domain." << std::endl
315                 << "Local size is " << n.getValue() << "." << std::endl
316                 << "Mask size is " << mask.extent(0) << ".");
[551]317      }
[679]318      else // (mask.isEmpty())
319      { // If no mask was defined, we create a default one without any masked point.
[666]320         mask.resize(n);
[679]321         for (int i = 0; i < n; ++i)
[551]322         {
[666]323           mask(i) = true;
[551]324         }
325      }
326   }
327
[633]328  void CAxis::checkBounds()
329  {
330    if (!bounds.isEmpty())
331    {
[713]332      if (bounds.extent(0) != 2 || bounds.extent(1) != n)
333        ERROR("CAxis::checkAttributes(void)",
334              << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
335              << "Axis size is " << n.getValue() << "." << std::endl
336              << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".");
[633]337      hasBounds_ = true;
338    }
339    else hasBounds_ = false;
340  }
341
[676]342  void CAxis::checkEligibilityForCompressedOutput()
343  {
344    // We don't check if the mask is valid here, just if a mask has been defined at this point.
345    isCompressible_ = !mask.isEmpty();
346  }
[633]347
[567]348  bool CAxis::dispatchEvent(CEventServer& event)
349   {
[595]350      if (SuperClass::dispatchEvent(event)) return true;
[567]351      else
352      {
353        switch(event.type)
354        {
355           case EVENT_ID_SERVER_ATTRIBUT :
[595]356             recvServerAttribut(event);
357             return true;
358             break;
[633]359           case EVENT_ID_INDEX:
360            recvIndex(event);
361            return true;
362            break;
363          case EVENT_ID_DISTRIBUTED_VALUE:
364            recvDistributedValue(event);
365            return true;
366            break;
367          case EVENT_ID_NON_DISTRIBUTED_VALUE:
368            recvNonDistributedValue(event);
369            return true;
370            break;
[567]371           default :
[679]372             ERROR("bool CAxis::dispatchEvent(CEventServer& event)",
[595]373                    << "Unknown Event");
374           return false;
[567]375         }
376      }
377   }
378
[742]379   void CAxis::checkAttributesOnClient()
[567]380   {
381     if (this->areClientAttributesChecked_) return;
[595]382
[567]383     this->checkAttributes();
384
385     this->areClientAttributesChecked_ = true;
386   }
387
[927]388   void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
389                                                          CServerDistributionDescription::ServerDistributionType distType)
390   {
391     CContext* context=CContext::getCurrent() ;
392
393     if (this->isClientAfterTransformationChecked) return;
394     if (context->hasClient)
395     {
396       if (n.getValue() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType);
397     }
398
399     this->isClientAfterTransformationChecked = true;
400   }
401
[567]402   // Send all checked attributes to server
403   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
404                                     CServerDistributionDescription::ServerDistributionType distType)
405   {
[742]406     if (!this->areClientAttributesChecked_) checkAttributesOnClient();
[927]407     if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(globalDim, orderPositionInGrid, distType);
[595]408     CContext* context = CContext::getCurrent();
[567]409
410     if (this->isChecked) return;
411     if (context->hasClient)
412     {
[595]413       sendServerAttribut(globalDim, orderPositionInGrid, distType);
[927]414       if (hasValue) sendValue();
[567]415     }
416
417     this->isChecked = true;
418   }
419
[927]420  void CAxis::sendValue()
[633]421  {
[666]422     if (n.getValue() == n_glo.getValue())
[633]423       sendNonDistributedValue();
424     else
425       sendDistributedValue();
426  }
427
[815]428  void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
429                                     CServerDistributionDescription::ServerDistributionType distType)
[633]430  {
431    CContext* context = CContext::getCurrent();
432    CContextClient* client = context->client;
433    int nbServer = client->serverSize;
434    int range, clientSize = client->clientSize;
[906]435    int rank = client->clientRank;
[667]436
[666]437    size_t ni = this->n.getValue();
438    size_t ibegin = this->begin.getValue();
[821]439    size_t zoom_end = global_zoom_begin+global_zoom_n-1;
[667]440    size_t nZoomCount = 0;
[817]441    size_t nbIndex = index.numElements();
442    for (size_t idx = 0; idx < nbIndex; ++idx)
[667]443    {
[817]444      size_t globalIndex = index(idx);
[667]445      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
446    }
447
[817]448    CArray<size_t,1> globalIndexAxis(nbIndex);
[667]449    std::vector<size_t> globalAxisZoom(nZoomCount);
450    nZoomCount = 0;
[817]451    for (size_t idx = 0; idx < nbIndex; ++idx)
[633]452    {
[817]453      size_t globalIndex = index(idx);
[633]454      globalIndexAxis(idx) = globalIndex;
[667]455      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
456      {
[670]457        globalAxisZoom[nZoomCount] = globalIndex;
[667]458        ++nZoomCount;
459      }
[633]460    }
461
[676]462    std::set<int> writtenInd;
463    if (isCompressible_)
464    {
465      for (int idx = 0; idx < data_index.numElements(); ++idx)
466      {
467        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
468
469        if (ind >= 0 && ind < ni && mask(ind))
470        {
471          ind += ibegin;
472          if (ind >= global_zoom_begin && ind <= zoom_end)
473            writtenInd.insert(ind);
474        }
475      }
476    }
477
[815]478    CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
479    int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
[829]480    CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
[815]481    if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
482    {
483      std::vector<int> nGlobAxis(1);
484      nGlobAxis[0] = n_glo.getValue();
[633]485
[815]486      size_t globalSizeIndex = 1, indexBegin, indexEnd;
487      for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
488      indexBegin = 0;
[906]489      if (globalSizeIndex <= clientSize)
[815]490      {
[906]491        indexBegin = rank%globalSizeIndex;
492        indexEnd = indexBegin;
[815]493      }
[906]494      else
495      {
496        for (int i = 0; i < clientSize; ++i)
497        {
498          range = globalSizeIndex / clientSize;
499          if (i < (globalSizeIndex%clientSize)) ++range;
500          if (i == client->clientRank) break;
501          indexBegin += range;
502        }
503        indexEnd = indexBegin + range - 1;
504      }
[815]505
506      CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
507      serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
508      CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
509      clientServerMap->computeServerIndexMapping(globalIndexAxis);
510      globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
511      delete clientServerMap;
512    }
513    else
[633]514    {
[815]515      std::vector<size_t> globalIndexServer(n_glo.getValue());
516      for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
517      {
518        globalIndexServer[idx] = idx;
519      }
520
521      for (int idx = 0; idx < nbServer; ++idx)
522      {
523        globalIndexAxisOnServer[idx] = globalIndexServer;
524      }
[633]525    }
526
[829]527    CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
528                                                         ite = globalIndexAxisOnServer.end();
[633]529    std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
530                                        iteVec = (globalAxisZoom).end();
531    indSrv_.clear();
[676]532    indWrittenSrv_.clear();
[633]533    for (; it != ite; ++it)
534    {
535      int rank = it->first;
536      const std::vector<size_t>& globalIndexTmp = it->second;
537      int nb = globalIndexTmp.size();
538
539      for (int i = 0; i < nb; ++i)
540      {
541        if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
542        {
543          indSrv_[rank].push_back(globalIndexTmp[i]);
544        }
[676]545
546        if (writtenInd.count(globalIndexTmp[i]))
547        {
548          indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
549        }
[633]550      }
551    }
552
553    connectedServerRank_.clear();
554    for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
555      connectedServerRank_.push_back(it->first);
556    }
557
558    if (!indSrv_.empty())
559    {
[829]560      std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
561                                                     iteIndSrv = indSrv_.end();
[633]562      connectedServerRank_.clear();
[829]563      for (; itIndSrv != iteIndSrv; ++itIndSrv)
564        connectedServerRank_.push_back(itIndSrv->first);
[633]565    }
[815]566    nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
[633]567  }
568
569  void CAxis::sendNonDistributedValue()
570  {
571    CContext* context = CContext::getCurrent();
572    CContextClient* client = context->client;
[676]573    CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_VALUE);
[633]574
[821]575    int zoom_end = global_zoom_begin + global_zoom_n - 1;
[676]576    int nb = 0;
[666]577    for (size_t idx = 0; idx < n; ++idx)
[633]578    {
[666]579      size_t globalIndex = begin + idx;
[633]580      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nb;
581    }
582
[676]583    int nbWritten = 0;
584    if (isCompressible_)
585    {
586      for (int idx = 0; idx < data_index.numElements(); ++idx)
587      {
588        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
589
590        if (ind >= 0 && ind < n && mask(ind))
591        {
592          ind += begin;
593          if (ind >= global_zoom_begin && ind <= zoom_end)
594            ++nbWritten;
595        }
596      }
597    }
598
[633]599    CArray<double,1> val(nb);
600    nb = 0;
[666]601    for (size_t idx = 0; idx < n; ++idx)
[633]602    {
[666]603      size_t globalIndex = begin + idx;
[633]604      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
605      {
606        val(nb) = value(idx);
607        ++nb;
608      }
609    }
610
[676]611    CArray<int, 1> writtenInd(nbWritten);
612    nbWritten = 0;
613    if (isCompressible_)
614    {
615      for (int idx = 0; idx < data_index.numElements(); ++idx)
616      {
617        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
618
619        if (ind >= 0 && ind < n && mask(ind))
620        {
621          ind += begin;
622          if (ind >= global_zoom_begin && ind <= zoom_end)
623          {
624            writtenInd(nbWritten) = ind;
625            ++nbWritten;
626          }
627        }
628      }
629    }
630
[633]631    if (client->isServerLeader())
632    {
633      std::list<CMessage> msgs;
634
635      const std::list<int>& ranks = client->getRanksServerLeader();
636      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
637      {
638        msgs.push_back(CMessage());
639        CMessage& msg = msgs.back();
640        msg << this->getId();
641        msg << val;
[676]642        if (isCompressible_)
643          msg << writtenInd;
644        event.push(*itRank, 1, msg);
[633]645      }
646      client->sendEvent(event);
647    }
648    else client->sendEvent(event);
649  }
650
651  void CAxis::sendDistributedValue(void)
652  {
653    int ns, n, i, j, ind, nv, idx;
654    CContext* context = CContext::getCurrent();
655    CContextClient* client=context->client;
656
657    // send value for each connected server
658    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
659    CEventClient eventVal(getType(), EVENT_ID_DISTRIBUTED_VALUE);
660
661    list<CMessage> list_msgsIndex, list_msgsVal;
662    list<CArray<int,1> > list_indi;
[676]663    list<CArray<int,1> > list_writtenInd;
[633]664    list<CArray<double,1> > list_val;
665    list<CArray<double,2> > list_bounds;
666
667    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
668    iteMap = indSrv_.end();
669    for (int k = 0; k < connectedServerRank_.size(); ++k)
670    {
671      int nbData = 0;
672      int rank = connectedServerRank_[k];
673      it = indSrv_.find(rank);
674      if (iteMap != it)
675        nbData = it->second.size();
676
677      list_indi.push_back(CArray<int,1>(nbData));
678      list_val.push_back(CArray<double,1>(nbData));
679
680      if (hasBounds_)
681      {
682        list_bounds.push_back(CArray<double,2>(2,nbData));
683      }
684
685      CArray<int,1>& indi = list_indi.back();
686      CArray<double,1>& val = list_val.back();
687
688      for (n = 0; n < nbData; ++n)
689      {
690        idx = static_cast<int>(it->second[n]);
[666]691        ind = idx - begin;
[633]692
693        val(n) = value(ind);
694        indi(n) = idx;
695
696        if (hasBounds_)
697        {
698          CArray<double,2>& boundsVal = list_bounds.back();
699          boundsVal(0, n) = bounds(0,n);
700          boundsVal(1, n) = bounds(1,n);
701        }
702      }
703
704      list_msgsIndex.push_back(CMessage());
705      list_msgsIndex.back() << this->getId() << list_indi.back();
706
[676]707      if (isCompressible_)
708      {
709        std::vector<int>& writtenIndSrc = indWrittenSrv_[rank];
710        list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size()));
711        CArray<int,1>& writtenInd = list_writtenInd.back();
712
713        for (n = 0; n < writtenInd.numElements(); ++n)
714          writtenInd(n) = writtenIndSrc[n];
715
716        list_msgsIndex.back() << writtenInd;
717      }
718
[633]719      list_msgsVal.push_back(CMessage());
720      list_msgsVal.back() << this->getId() << list_val.back();
721
722      if (hasBounds_)
723      {
724        list_msgsVal.back() << list_bounds.back();
725      }
726
727      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
728      eventVal.push(rank, nbConnectedClients_[rank], list_msgsVal.back());
729    }
730
731    client->sendEvent(eventIndex);
732    client->sendEvent(eventVal);
733  }
734
735  void CAxis::recvIndex(CEventServer& event)
736  {
[676]737    CAxis* axis;
738
[633]739    list<CEventServer::SSubEvent>::iterator it;
740    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
741    {
742      CBufferIn* buffer = it->buffer;
[676]743      string axisId;
744      *buffer >> axisId;
745      axis = get(axisId);
746      axis->recvIndex(it->rank, *buffer);
[633]747    }
[676]748
749    if (axis->isCompressible_)
750    {
751      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
752
753      CContextServer* server = CContext::getCurrent()->server;
754      axis->numberWrittenIndexes_ = axis->indexesToWrite.size();
[1053]755      ep_lib::MPI_Allreduce(&axis->numberWrittenIndexes_, &axis->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
756      ep_lib::MPI_Scan(&axis->numberWrittenIndexes_, &axis->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
[676]757      axis->offsetWrittenIndexes_ -= axis->numberWrittenIndexes_;
758    }
[633]759  }
760
761  void CAxis::recvIndex(int rank, CBufferIn& buffer)
762  {
763    buffer >> indiSrv_[rank];
[676]764
765    if (isCompressible_)
766    {
767      CArray<int, 1> writtenIndexes;
768      buffer >> writtenIndexes;
769      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
770      for (int i = 0; i < writtenIndexes.numElements(); ++i)
771        indexesToWrite.push_back(writtenIndexes(i));
772    }
[633]773  }
774
775  void CAxis::recvDistributedValue(CEventServer& event)
776  {
777    list<CEventServer::SSubEvent>::iterator it;
778    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
779    {
780      CBufferIn* buffer = it->buffer;
[676]781      string axisId;
782      *buffer >> axisId;
783      get(axisId)->recvDistributedValue(it->rank, *buffer);
[633]784    }
785  }
786
787  void CAxis::recvDistributedValue(int rank, CBufferIn& buffer)
788  {
789    CArray<int,1> &indi = indiSrv_[rank];
790    CArray<double,1> val;
791    CArray<double,2> boundsVal;
792
793    buffer >> val;
794    if (hasBounds_) buffer >> boundsVal;
795
796    int i, j, ind_srv;
797    for (int ind = 0; ind < indi.numElements(); ++ind)
798    {
799      i = indi(ind);
800      ind_srv = i - zoom_begin_srv;
801      value_srv(ind_srv) = val(ind);
802      if (hasBounds_)
803      {
804        bound_srv(0,ind_srv) = boundsVal(0, ind);
805        bound_srv(1,ind_srv) = boundsVal(1, ind);
806      }
807    }
808  }
809
810   void CAxis::recvNonDistributedValue(CEventServer& event)
811  {
[676]812    CAxis* axis;
813
[633]814    list<CEventServer::SSubEvent>::iterator it;
815    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
816    {
817      CBufferIn* buffer = it->buffer;
[676]818      string axisId;
819      *buffer >> axisId;
820      axis = get(axisId);
821      axis->recvNonDistributedValue(it->rank, *buffer);
[633]822    }
[676]823
824    if (axis->isCompressible_)
825    {
826      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
827
828      axis->numberWrittenIndexes_ = axis->totalNumberWrittenIndexes_ = axis->indexesToWrite.size();
829      axis->offsetWrittenIndexes_ = 0;
830    }
[633]831  }
832
833  void CAxis::recvNonDistributedValue(int rank, CBufferIn& buffer)
834  {
835    CArray<double,1> val;
836    buffer >> val;
837
838    for (int ind = 0; ind < val.numElements(); ++ind)
839    {
840      value_srv(ind) = val(ind);
841      if (hasBounds_)
842      {
843        bound_srv(0,ind) = bounds(0,ind);
844        bound_srv(1,ind) = bounds(1,ind);
845      }
846    }
[676]847
848    if (isCompressible_)
849    {
850      CArray<int, 1> writtenIndexes;
851      buffer >> writtenIndexes;
852      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
853      for (int i = 0; i < writtenIndexes.numElements(); ++i)
854        indexesToWrite.push_back(writtenIndexes(i));
855    }
[633]856  }
857
[595]858  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
859                                 CServerDistributionDescription::ServerDistributionType distType)
[567]860  {
[595]861    CContext* context = CContext::getCurrent();
862    CContextClient* client = context->client;
[815]863    int nbServer = client->serverSize;
[567]864
[815]865    CServerDistributionDescription serverDescription(globalDim, nbServer);
866    serverDescription.computeServerDistribution();
[595]867
868    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
869    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
870
871    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
[567]872    if (client->isServerLeader())
873    {
[595]874      std::list<CMessage> msgs;
875
876      const std::list<int>& ranks = client->getRanksServerLeader();
877      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
878      {
879        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
880        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
881        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
882        const int end   = begin + ni - 1;
883
884        msgs.push_back(CMessage());
885        CMessage& msg = msgs.back();
886        msg << this->getId();
887        msg << ni << begin << end;
[821]888        msg << global_zoom_begin.getValue() << global_zoom_n.getValue();
[676]889        msg << isCompressible_;
[595]890
891        event.push(*itRank,1,msg);
892      }
893      client->sendEvent(event);
[567]894    }
[595]895    else client->sendEvent(event);
[567]896  }
897
898  void CAxis::recvServerAttribut(CEventServer& event)
899  {
[595]900    CBufferIn* buffer = event.subEvents.begin()->buffer;
901    string axisId;
902    *buffer >> axisId;
903    get(axisId)->recvServerAttribut(*buffer);
[567]904  }
905
906  void CAxis::recvServerAttribut(CBufferIn& buffer)
907  {
[821]908    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp;
[567]909
[676]910    buffer >> ni_srv >> begin_srv >> end_srv;
[821]911    buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;
[676]912    buffer >> isCompressible_;
[623]913    global_zoom_begin = global_zoom_begin_tmp;
[821]914    global_zoom_n  = global_zoom_n_tmp;
915    int global_zoom_end = global_zoom_begin + global_zoom_n - 1;
[567]916
[623]917    zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
918    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
[595]919    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
[567]920
921    if (zoom_size_srv<=0)
922    {
[595]923      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
[567]924    }
[586]925
[666]926    if (n_glo == n)
[586]927    {
[623]928      zoom_begin_srv = global_zoom_begin;
929      zoom_end_srv   = global_zoom_end; //zoom_end;
[595]930      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
[586]931    }
[816]932    if (hasValue)
933    {
934      value_srv.resize(zoom_size_srv);
935      if (hasBounds_)  bound_srv.resize(2,zoom_size_srv);
936    }
[567]937  }
938
[836]939  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id)
940  {
941    transformationMap_.push_back(std::make_pair(transType, CTransformation<CAxis>::createTransformation(transType,id)));
942    return transformationMap_.back().second;
943  }
944
[619]945  bool CAxis::hasTransformation()
946  {
[621]947    return (!transformationMap_.empty());
[619]948  }
949
[621]950  void CAxis::setTransformations(const TransMapTypes& axisTrans)
[619]951  {
[621]952    transformationMap_ = axisTrans;
[619]953  }
954
[621]955  CAxis::TransMapTypes CAxis::getAllTransformations(void)
[620]956  {
[621]957    return transformationMap_;
958  }
[620]959
[621]960  /*!
961    Check the validity of all transformations applied on axis
962  This functions is called AFTER all inherited attributes are solved
963  */
964  void CAxis::checkTransformations()
965  {
966    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
967                                  ite = transformationMap_.end();
[895]968//    for (it = itb; it != ite; ++it)
969//    {
970//      (it->second)->checkValid(this);
971//    }
[620]972  }
973
[823]974  void CAxis::duplicateTransformation(CAxis* src)
975  {
976    if (src->hasTransformation())
977    {
978      this->setTransformations(src->getAllTransformations());
979    }
980  }
981
[747]982  /*!
983   * Go through the hierarchy to find the axis from which the transformations must be inherited
984   */
[619]985  void CAxis::solveInheritanceTransformation()
986  {
[747]987    if (hasTransformation() || !hasDirectAxisReference())
988      return;
[619]989
[747]990    CAxis* axis = this;
[619]991    std::vector<CAxis*> refAxis;
[747]992    while (!axis->hasTransformation() && axis->hasDirectAxisReference())
[619]993    {
[747]994      refAxis.push_back(axis);
995      axis = axis->getDirectAxisReference();
[619]996    }
997
[747]998    if (axis->hasTransformation())
999      for (size_t i = 0; i < refAxis.size(); ++i)
1000        refAxis[i]->setTransformations(axis->getAllTransformations());
[619]1001  }
1002
1003  void CAxis::parse(xml::CXMLNode & node)
1004  {
1005    SuperClass::parse(node);
1006
1007    if (node.goToChildElement())
1008    {
[836]1009      StdString nodeElementName;
[619]1010      do
1011      {
[784]1012        StdString nodeId("");
1013        if (node.getAttributes().end() != node.getAttributes().find("id"))
1014        { nodeId = node.getAttributes()["id"]; }
1015
[836]1016        nodeElementName = node.getElementName();
[1095]1017        std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
1018        it = transformationMapList_.find(nodeElementName);
[836]1019        if (ite != it)
1020        {
1021          transformationMap_.push_back(std::make_pair(it->second, CTransformation<CAxis>::createTransformation(it->second,
1022                                                                                                               nodeId,
1023                                                                                                               &node)));
[786]1024        }
[968]1025        else
1026        {
1027          ERROR("void CAxis::parse(xml::CXMLNode & node)",
1028                << "The transformation " << nodeElementName << " has not been supported yet.");
1029        }
[619]1030      } while (node.goToNextElement()) ;
1031      node.goToParentElement();
1032    }
1033  }
1034
[620]1035  DEFINE_REF_FUNC(Axis,axis)
[619]1036
[219]1037   ///---------------------------------------------------------------
1038
[335]1039} // namespace xios
Note: See TracBrowser for help on using the repository browser.