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

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

Implementing interpolation (polynomial) and correct some bugs

+) Implement interpolation (polynomial)
+) Correct some minor bugs relating to memory allocation
+) Clear some redundant codes

Test
+) On Curie
+) test_client and test_complete pass

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