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

Last change on this file since 620 was 620, checked in by mhnguyen, 9 years ago

Implementing generic transformation algorithm (local commit)

+) Implement 3 important classes:

-gridTransformation to read transformation info from grid and interface with the rest of XIOS
-transformationMapping to be in charge of sending/receiving transformation info among clients
-transformationAlgorithm to represent various algorithms

+) Make some change on field to use the new classes

Test
+) Only test_new_features with inversed axis

  • 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: 12.2 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"
[591]10#include "xios_spl.hpp"
[219]11
[335]12namespace xios {
[540]13
[219]14   /// ////////////////////// Définitions ////////////////////// ///
15
16   CAxis::CAxis(void)
17      : CObjectTemplate<CAxis>()
[567]18      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
[594]19      , isDistributed_(false)
[219]20   { /* Ne rien faire de plus */ }
21
22   CAxis::CAxis(const StdString & id)
23      : CObjectTemplate<CAxis>(id)
[567]24      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
[594]25      , isDistributed_(false)
[219]26   { /* Ne rien faire de plus */ }
27
28   CAxis::~CAxis(void)
29   { /* Ne rien faire de plus */ }
30
31   ///---------------------------------------------------------------
32
33   const std::set<StdString> & CAxis::getRelFiles(void) const
34   {
35      return (this->relFiles);
36   }
37
38   bool CAxis::IsWritten(const StdString & filename) const
39   {
40      return (this->relFiles.find(filename) != this->relFiles.end());
41   }
42
[594]43   bool CAxis::isDistributed(void) const
44   {
45      return isDistributed_;
46   }
47
[219]48   void CAxis::addRelFile(const StdString & filename)
49   {
50      this->relFiles.insert(filename);
51   }
52
53   //----------------------------------------------------------------
54
55   StdString CAxis::GetName(void)   { return (StdString("axis")); }
56   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
57   ENodeType CAxis::GetType(void)   { return (eAxis); }
58
59   //----------------------------------------------------------------
60
61   void CAxis::checkAttributes(void)
62   {
[351]63      if (this->size.isEmpty())
[566]64         ERROR("CAxis::checkAttributes(void)",
65               << "Attribute <size> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified");
[219]66      StdSize size = this->size.getValue();
[540]67
[594]68      isDistributed_ = !this->ibegin.isEmpty() || !this->ni.isEmpty();
69
[551]70      if (!this->ibegin.isEmpty())
71      {
72        StdSize ibegin = this->ibegin.getValue();
73        if ((ibegin < 0) || (ibegin > size-1))
[566]74          ERROR("CAxis::checkAttributes(void)",
75                << "Attribute <ibegin> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size-1");
[551]76      }
77      else this->ibegin.setValue(0);
78
79      if (!this->ni.isEmpty())
80      {
81        StdSize ni = this->ni.getValue();
82        if ((ni < 0) || (ni > size))
[566]83          ERROR("CAxis::checkAttributes(void)",
84                << "Attribute <ni> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size");
[551]85      }
86      else this->ni.setValue(size);
[620]87      std::cout <<  "value " <<  value <<  std::endl;
[369]88      StdSize true_size = value.numElements();
[619]89      if (this->ni.getValue() != true_size)
[219]90         ERROR("CAxis::checkAttributes(void)",
[566]91               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
[219]92
[551]93      this->checkData();
94      this->checkMask();
[567]95      this->checkZoom();
[609]96
97      if (!bounds.isEmpty())
98      {
99        if (bounds.extent(0) != size || bounds.extent(1) != 2)
100            ERROR("CAxis::checkAttributes(void)",
101                  << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension axis size x 2" << endl
102                  << "Axis size is " << size << endl
103                  << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1));
104      }
[219]105   }
106
[551]107   void CAxis::checkData()
108   {
109      if (data_begin.isEmpty()) data_begin.setValue(0);
110      if (!data_n.isEmpty() && data_n.getValue() <= 0)
111      {
112        ERROR("CAxis::checkData(void)",
[566]113              << "Data dimension is negative (data_n).");
[551]114      }
115      else if (data_n.isEmpty())
[553]116        data_n.setValue(ni.getValue());
[551]117
118      if (data_index.isEmpty())
119      {
120        int dn = data_n.getValue();
121        data_index.resize(dn);
122        for (int i = 0; i < dn; ++i) data_index(i) = (i+1);
123      }
124   }
125
[567]126   void CAxis::checkZoom(void)
127   {
[568]128      StdSize zoom_begin,zoom_end, zoom_size, axisSize;
[567]129
[595]130      zoom_begin = this->zoom_begin.isEmpty() ? 0 : this->zoom_begin.getValue();
131      zoom_size  = this->zoom_size.isEmpty() ? size.getValue() : this->zoom_size.getValue();
132      zoom_end   = this->zoom_end.isEmpty() ? (size.getValue() - 1) : this->zoom_end.getValue();
[567]133
[595]134      if (this->zoom_begin.isEmpty()) zoom_begin = zoom_end - zoom_size + 1;
135      if (this->zoom_end.isEmpty()) zoom_end = zoom_begin + zoom_size - 1;
136      if (this->zoom_size.isEmpty()) zoom_size = zoom_end - zoom_begin + 1;
[568]137      axisSize = size.getValue();
[567]138
[568]139      if ( (zoom_begin < 0) || (zoom_begin > axisSize-1) || (zoom_end<0) || (zoom_end>axisSize-1) || (zoom_size<1) || (zoom_size>axisSize) || (zoom_begin>zoom_end))
[570]140        ERROR("CAxis::checkAttributes(void)",
141              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
[567]142
[595]143      this->zoom_begin.setValue(zoom_begin);
144      this->zoom_end.setValue(zoom_end);
145      this->zoom_size.setValue(zoom_size);
[567]146   }
147
[551]148   void CAxis::checkMask()
149   {
150      int begin_mask = 0,
151          end_mask = ni.getValue()-1;
152
153      if (!zoom_begin.isEmpty())
154      {
155         int zoom_end = zoom_begin.getValue() + zoom_size.getValue() - 1;
156
157         begin_mask = std::max(ibegin.getValue(), zoom_begin.getValue());
158         end_mask   = std::min(ibegin.getValue() + ni.getValue()-1, zoom_end);
159
160         begin_mask -= ibegin.getValue();
161         end_mask   -= ibegin.getValue();
162      }
163
164
165      if (!mask.isEmpty())
166      {
167         if (mask.extent(0) != ni)
168            ERROR("CAxis::checkMask(void)",
[595]169                  << "the mask has not the same size than the local axis" << endl
170                  << "Local size is " << ni << "x" << endl
171                  << "Mask size is " << mask.extent(0) << "x");
[551]172         for (int i = 0; i < ni; ++i)
173         {
174           if (i < begin_mask && i > end_mask)  mask(i) = false;
175         }
176      }
177      else // (!mask.hasValue())
178      { // Si aucun masque n'est défini,
179        // on en crée un nouveau qui valide l'intégralité du domaine.
[566]180         mask.resize(ni);
[551]181         for (int i = 0; i < ni.getValue(); ++i)
182         {
183               if (i >= begin_mask && i <= end_mask)
184                 mask(i) = true;
185               else  mask(i) = false;
186         }
187      }
188   }
189
[567]190  bool CAxis::dispatchEvent(CEventServer& event)
191   {
[595]192      if (SuperClass::dispatchEvent(event)) return true;
[567]193      else
194      {
195        switch(event.type)
196        {
197           case EVENT_ID_SERVER_ATTRIBUT :
[595]198             recvServerAttribut(event);
199             return true;
200             break;
[567]201           default :
202             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
[595]203                    << "Unknown Event");
204           return false;
[567]205         }
206      }
207   }
208
209   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
210                                       CServerDistributionDescription::ServerDistributionType distType)
211   {
212     if (this->areClientAttributesChecked_) return;
[595]213
[567]214     this->checkAttributes();
215
216     this->areClientAttributesChecked_ = true;
217   }
218
219   // Send all checked attributes to server
220   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
221                                     CServerDistributionDescription::ServerDistributionType distType)
222   {
223     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
224                                                                     orderPositionInGrid,
225                                                                     distType);
[595]226     CContext* context = CContext::getCurrent();
[567]227
228     if (this->isChecked) return;
229     if (context->hasClient)
230     {
[595]231       sendServerAttribut(globalDim, orderPositionInGrid, distType);
[567]232     }
233
234     this->isChecked = true;
235   }
236
[595]237  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
238                                 CServerDistributionDescription::ServerDistributionType distType)
[567]239  {
[595]240    CContext* context = CContext::getCurrent();
241    CContextClient* client = context->client;
[567]242
[595]243    CServerDistributionDescription serverDescription(globalDim);
244
245    int nbServer = client->serverSize;
246
247    serverDescription.computeServerDistribution(nbServer, false, distType);
248    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
249    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
250
251    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
[567]252    if (client->isServerLeader())
253    {
[595]254      std::list<CMessage> msgs;
255
256      const std::list<int>& ranks = client->getRanksServerLeader();
257      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
258      {
259        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
260        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
261        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
262        const int end   = begin + ni - 1;
263
264        msgs.push_back(CMessage());
265        CMessage& msg = msgs.back();
266        msg << this->getId();
267        msg << ni << begin << end;
268
269        event.push(*itRank,1,msg);
270      }
271      client->sendEvent(event);
[567]272    }
[595]273    else client->sendEvent(event);
[567]274  }
275
276  void CAxis::recvServerAttribut(CEventServer& event)
277  {
[595]278    CBufferIn* buffer = event.subEvents.begin()->buffer;
279    string axisId;
280    *buffer >> axisId;
281    get(axisId)->recvServerAttribut(*buffer);
[567]282  }
283
284  void CAxis::recvServerAttribut(CBufferIn& buffer)
285  {
286    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
287    int ni_srv, begin_srv, end_srv;
288
289    buffer>>ni_srv>>begin_srv>>end_srv;
290
[595]291    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv;
292    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv;
293    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
[567]294
295    if (zoom_size_srv<=0)
296    {
[595]297      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
[567]298    }
[586]299
300    if (size == ni)
301    {
302      zoom_begin_srv = zoom_begin.getValue();
303      zoom_end_srv   = zoom_end;
[595]304      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
[586]305    }
[567]306  }
307
[619]308  bool CAxis::hasTransformation()
309  {
310    return (!transformations_.empty());
311  }
312
[620]313  void CAxis::setTransformations(const std::vector<CTransformation*>& transformations)
[619]314  {
315    transformations_ = transformations;
316  }
317
[620]318  std::vector<CTransformation*> CAxis::getAllTransformations(void)
319  {
320    if (!hasTransformation())
321      setTransformations(this->getVirtualTransformationGroup()->getAllChildren());
322
323    return transformations_;
324  }
325
[619]326  void CAxis::solveInheritanceTransformation()
327  {
328    if (this->hasTransformation()) return;
329
330    std::vector<CAxis*> refAxis;
331    CAxis* refer_sptr;
332    CAxis* refer_ptr = this;
333    while (refer_ptr->hasDirectAxisReference())
334    {
335      refAxis.push_back(refer_ptr);
336      refer_sptr = refer_ptr->getDirectAxisReference();
337      refer_ptr  = refer_sptr;
338      if (refer_ptr->hasTransformation()) break;
339    }
340
341    if (refer_ptr->hasTransformation())
342      for (int idx = 0; idx < refAxis.size(); ++idx)
[620]343        refAxis[idx]->setTransformations(refer_ptr->getAllTransformations());
[619]344  }
345
346  void CAxis::parse(xml::CXMLNode & node)
347  {
348    SuperClass::parse(node);
349
350    if (node.goToChildElement())
351    {
352      StdString tranformation("transformation");
353      do
354      {
355        if (node.getElementName() == tranformation) {
356           this->getVirtualTransformationGroup()->parseChild(node);
357        }
358      } while (node.goToNextElement()) ;
359      node.goToParentElement();
360    }
[620]361    setTransformations(this->getVirtualTransformationGroup()->getAllChildren());
[619]362  }
363
[620]364  DEFINE_REF_FUNC(Axis,axis)
[619]365
[219]366   ///---------------------------------------------------------------
367
[335]368} // namespace xios
Note: See TracBrowser for help on using the repository browser.