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

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

Change the definition of non distributed axis and domain.

Axis and domain were considered non distributed if the local domain matched the full domain. Instead allow the local domain definition to be ommited and consider the axis or domain to be non distributed in this case.

  • 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: 10.1 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
12namespace xios {
13
14   /// ////////////////////// Définitions ////////////////////// ///
15
16   CAxis::CAxis(void)
17      : CObjectTemplate<CAxis>()
18      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
19      , isDistributed_(false)
20   { /* Ne rien faire de plus */ }
21
22   CAxis::CAxis(const StdString & id)
23      : CObjectTemplate<CAxis>(id)
24      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
25      , isDistributed_(false)
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
43   bool CAxis::isDistributed(void) const
44   {
45      return isDistributed_;
46   }
47
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   {
63      if (this->size.isEmpty())
64         ERROR("CAxis::checkAttributes(void)",
65               << "Attribute <size> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified");
66      StdSize size = this->size.getValue();
67
68      isDistributed_ = !this->ibegin.isEmpty() || !this->ni.isEmpty();
69
70      if (!this->ibegin.isEmpty())
71      {
72        StdSize ibegin = this->ibegin.getValue();
73        if ((ibegin < 0) || (ibegin > size-1))
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");
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))
83          ERROR("CAxis::checkAttributes(void)",
84                << "Attribute <ni> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size");
85      }
86      else this->ni.setValue(size);
87
88      StdSize true_size = value.numElements();
89      if (size != true_size)
90         ERROR("CAxis::checkAttributes(void)",
91               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
92
93      this->checkData();
94      this->checkMask();
95      this->checkZoom();
96   }
97
98   void CAxis::checkData()
99   {
100      if (data_begin.isEmpty()) data_begin.setValue(0);
101      if (!data_n.isEmpty() && data_n.getValue() <= 0)
102      {
103        ERROR("CAxis::checkData(void)",
104              << "Data dimension is negative (data_n).");
105      }
106      else if (data_n.isEmpty())
107        data_n.setValue(ni.getValue());
108
109      if (data_index.isEmpty())
110      {
111        int dn = data_n.getValue();
112        data_index.resize(dn);
113        for (int i = 0; i < dn; ++i) data_index(i) = (i+1);
114      }
115   }
116
117   void CAxis::checkZoom(void)
118   {
119      StdSize zoom_begin,zoom_end, zoom_size, axisSize;
120
121      zoom_begin = (this->zoom_begin.isEmpty()) ?  0 : this->zoom_begin.getValue() ;
122      zoom_size  = (this->zoom_size.isEmpty()) ?  size.getValue() : this->zoom_size.getValue() ;
123      zoom_end   = (this->zoom_end.isEmpty()) ?  (size.getValue() - 1) : this->zoom_end.getValue() ;
124
125      if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
126      if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
127      if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
128      axisSize = size.getValue();
129
130      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))
131        ERROR("CAxis::checkAttributes(void)",
132              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
133
134      this->zoom_begin.setValue(zoom_begin) ;
135      this->zoom_end.setValue(zoom_end) ;
136      this->zoom_size.setValue(zoom_size) ;
137   }
138
139   void CAxis::checkMask()
140   {
141      int begin_mask = 0,
142          end_mask = ni.getValue()-1;
143
144      if (!zoom_begin.isEmpty())
145      {
146         int zoom_end = zoom_begin.getValue() + zoom_size.getValue() - 1;
147
148         begin_mask = std::max(ibegin.getValue(), zoom_begin.getValue());
149         end_mask   = std::min(ibegin.getValue() + ni.getValue()-1, zoom_end);
150
151         begin_mask -= ibegin.getValue();
152         end_mask   -= ibegin.getValue();
153      }
154
155
156      if (!mask.isEmpty())
157      {
158         if (mask.extent(0) != ni)
159            ERROR("CAxis::checkMask(void)",
160                  <<"the mask has not the same size than the local axis"<<endl
161                  <<"Local size is "<<ni<<"x"<<endl
162                  <<"Mask size is "<<mask.extent(0)<<"x");
163         for (int i = 0; i < ni; ++i)
164         {
165           if (i < begin_mask && i > end_mask)  mask(i) = false;
166         }
167      }
168      else // (!mask.hasValue())
169      { // Si aucun masque n'est défini,
170        // on en crée un nouveau qui valide l'intégralité du domaine.
171         mask.resize(ni);
172         for (int i = 0; i < ni.getValue(); ++i)
173         {
174               if (i >= begin_mask && i <= end_mask)
175                 mask(i) = true;
176               else  mask(i) = false;
177         }
178      }
179   }
180
181  bool CAxis::dispatchEvent(CEventServer& event)
182   {
183      if (SuperClass::dispatchEvent(event)) return true ;
184      else
185      {
186        switch(event.type)
187        {
188           case EVENT_ID_SERVER_ATTRIBUT :
189             recvServerAttribut(event) ;
190             return true ;
191             break ;
192           default :
193             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
194                    <<"Unknown Event") ;
195           return false ;
196         }
197      }
198   }
199
200   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
201                                       CServerDistributionDescription::ServerDistributionType distType)
202   {
203     if (this->areClientAttributesChecked_) return;
204     this->checkAttributes();
205
206     CContext* context=CContext::getCurrent() ;
207     if (context->hasClient)
208     {
209       computeServerIndex(globalDim, orderPositionInGrid, distType);
210     }
211
212     this->areClientAttributesChecked_ = true;
213   }
214
215   void CAxis::computeServerIndex(const std::vector<int>& globalDim, int orderPositionInGrid,
216                                  CServerDistributionDescription::ServerDistributionType distType)
217   {
218     CServerDistributionDescription serverDescription(globalDim);
219
220     CContext* context=CContext::getCurrent() ;
221     CContextClient* client=context->client ;
222     int nbServer=client->serverSize ;
223     int serverRank=client->getServerLeader() ;
224
225     serverDescription.computeServerDistribution(nbServer, false, distType);
226     std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
227     std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
228     begin_srv = (serverIndexBegin[serverRank])[orderPositionInGrid];
229     ni_srv = serverDimensionSizes[serverRank][orderPositionInGrid];
230     end_srv = begin_srv+ni_srv-1;
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() ;
246     }
247
248     this->isChecked = true;
249   }
250
251  void CAxis::sendServerAttribut(void)
252  {
253    CContext* context=CContext::getCurrent();
254    CContextClient* client=context->client;
255
256    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT) ;
257    if (client->isServerLeader())
258    {
259      CMessage msg ;
260      msg<<this->getId() ;
261      msg<<ni_srv<<begin_srv<<end_srv;
262      event.push(client->getServerLeader(),1,msg) ;
263      client->sendEvent(event) ;
264    }
265    else client->sendEvent(event) ;
266  }
267
268  void CAxis::recvServerAttribut(CEventServer& event)
269  {
270    CBufferIn* buffer=event.subEvents.begin()->buffer;
271    string axisId ;
272    *buffer>>axisId ;
273    get(axisId)->recvServerAttribut(*buffer) ;
274  }
275
276  void CAxis::recvServerAttribut(CBufferIn& buffer)
277  {
278    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
279    int ni_srv, begin_srv, end_srv;
280
281    buffer>>ni_srv>>begin_srv>>end_srv;
282
283    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv ;
284    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv ;
285    zoom_size_srv  = zoom_end_srv-zoom_begin_srv+1 ;
286
287    if (zoom_size_srv<=0)
288    {
289      zoom_begin_srv=0 ; zoom_end_srv=0 ; zoom_size_srv=0 ;
290    }
291
292    if (size == ni)
293    {
294      zoom_begin_srv = zoom_begin.getValue();
295      zoom_end_srv   = zoom_end;
296      zoom_size_srv  = zoom_end_srv-zoom_begin_srv+1 ;
297    }
298  }
299
300   DEFINE_REF_FUNC(Axis,axis)
301
302   ///---------------------------------------------------------------
303
304} // namespace xios
Note: See TracBrowser for help on using the repository browser.