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

Last change on this file since 567 was 567, checked in by mhnguyen, 7 years ago

Implementing a grid formed by only one axis or group of axis

+) Add several new attributes to axis. From now on, each axis can be distributed on client side
+) Modify mask of grid to make it more flexible to different dimension
+) Fix some bugs relating to calculation of local data index on client
+) Clean some redundant codes

Test
+) On Curie, only test_new_features.f90
+) Test cases:

  • Grid composed of: 1 domain and 1 axis, 3 axis, 1 axis
  • Mode: Attached and connected
  • No of client-server: 6-2(Connected), 2 (Attached)

+) All tests passed and results are correct

  • 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 "xmlioserver_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   { /* Ne rien faire de plus */ }
20
21   CAxis::CAxis(const StdString & id)
22      : CObjectTemplate<CAxis>(id)
23      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
24   { /* Ne rien faire de plus */ }
25
26   CAxis::~CAxis(void)
27   { /* Ne rien faire de plus */ }
28
29   ///---------------------------------------------------------------
30
31   const std::set<StdString> & CAxis::getRelFiles(void) const
32   {
33      return (this->relFiles);
34   }
35
36   bool CAxis::IsWritten(const StdString & filename) const
37   {
38      return (this->relFiles.find(filename) != this->relFiles.end());
39   }
40
41   void CAxis::addRelFile(const StdString & filename)
42   {
43      this->relFiles.insert(filename);
44   }
45
46   //----------------------------------------------------------------
47
48   StdString CAxis::GetName(void)   { return (StdString("axis")); }
49   StdString CAxis::GetDefName(void){ return (CAxis::GetName()); }
50   ENodeType CAxis::GetType(void)   { return (eAxis); }
51
52   //----------------------------------------------------------------
53
54   void CAxis::checkAttributes(void)
55   {
56      if (this->size.isEmpty())
57         ERROR("CAxis::checkAttributes(void)",
58               << "Attribute <size> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be specified");
59      StdSize size = this->size.getValue();
60
61      if (!this->ibegin.isEmpty())
62      {
63        StdSize ibegin = this->ibegin.getValue();
64        if ((ibegin < 0) || (ibegin > size-1))
65          ERROR("CAxis::checkAttributes(void)",
66                << "Attribute <ibegin> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size-1");
67      }
68      else this->ibegin.setValue(0);
69
70      if (!this->ni.isEmpty())
71      {
72        StdSize ni = this->ni.getValue();
73        if ((ni < 0) || (ni > size))
74          ERROR("CAxis::checkAttributes(void)",
75                << "Attribute <ni> of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be non-negative and smaller than size");
76      }
77      else this->ni.setValue(size);
78
79              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
80      StdSize true_size = value.numElements();
81      if (size != true_size)
82         ERROR("CAxis::checkAttributes(void)",
83               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
84
85      this->checkData();
86      this->checkMask();
87      this->checkZoom();
88   }
89
90   void CAxis::checkData()
91   {
92      if (data_begin.isEmpty()) data_begin.setValue(0);
93      if (!data_n.isEmpty() && data_n.getValue() <= 0)
94      {
95        ERROR("CAxis::checkData(void)",
96              << "Data dimension is negative (data_n).");
97      }
98      else if (data_n.isEmpty())
99        data_n.setValue(ni.getValue());
100
101      if (data_index.isEmpty())
102      {
103        int dn = data_n.getValue();
104        data_index.resize(dn);
105        for (int i = 0; i < dn; ++i) data_index(i) = (i+1);
106      }
107   }
108
109   void CAxis::checkZoom(void)
110   {
111      StdSize zoom_begin,zoom_end, zoom_size;
112
113      zoom_begin = (this->zoom_begin.isEmpty()) ?  0 : this->zoom_begin.getValue() ;
114      zoom_size  = (this->zoom_size.isEmpty()) ?  size.getValue() : this->zoom_size.getValue() ;
115      zoom_end   = (this->zoom_end.isEmpty()) ?  (size.getValue() - 1) : this->zoom_end.getValue() ;
116
117      if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
118      if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
119      if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
120
121      if ( (zoom_begin < 0) || (zoom_begin > size-1) || (zoom_end<0) || (zoom_end>size-1) || (zoom_size<1) || (zoom_size>size) || (zoom_begin>zoom_end))
122        ERROR("CAxis::checkAttributes(void)",<< "One or more attribut of <zoom_begin>, <zoom_end>, <zoom_size>, are not well specified") ;
123
124      this->zoom_begin.setValue(zoom_begin) ;
125      this->zoom_end.setValue(zoom_end) ;
126      this->zoom_size.setValue(zoom_size) ;
127
128      // compute client zoom indices
129//      zoom_begin_client = ibegin_client > zoom_begin ? begin_client : zoom_begin ;
130//      zoom_end_client   = iend_client < zoom_end ? iend_client : zoom_end ;
131//      zoom_size_client  = zoom_end_client-zoom_begin_client+1 ;
132//      if (zoom_ni_client<0) zoom_ni_client=0 ;
133   }
134
135   void CAxis::checkMask()
136   {
137      int begin_mask = 0,
138          end_mask = ni.getValue()-1;
139
140      if (!zoom_begin.isEmpty())
141      {
142         int zoom_end = zoom_begin.getValue() + zoom_size.getValue() - 1;
143
144         begin_mask = std::max(ibegin.getValue(), zoom_begin.getValue());
145         end_mask   = std::min(ibegin.getValue() + ni.getValue()-1, zoom_end);
146
147         begin_mask -= ibegin.getValue();
148         end_mask   -= ibegin.getValue();
149      }
150
151
152      if (!mask.isEmpty())
153      {
154         if (mask.extent(0) != ni)
155            ERROR("CAxis::checkMask(void)",
156                  <<"the mask has not the same size than the local axis"<<endl
157                  <<"Local size is "<<ni<<"x"<<endl
158                  <<"Mask size is "<<mask.extent(0)<<"x");
159         for (int i = 0; i < ni; ++i)
160         {
161           if (i < begin_mask && i > end_mask)  mask(i) = false;
162         }
163      }
164      else // (!mask.hasValue())
165      { // Si aucun masque n'est défini,
166        // on en crée un nouveau qui valide l'intégralité du domaine.
167         mask.resize(ni);
168         for (int i = 0; i < ni.getValue(); ++i)
169         {
170               if (i >= begin_mask && i <= end_mask)
171                 mask(i) = true;
172               else  mask(i) = false;
173         }
174      }
175   }
176
177  bool CAxis::dispatchEvent(CEventServer& event)
178   {
179      if (SuperClass::dispatchEvent(event)) return true ;
180      else
181      {
182        switch(event.type)
183        {
184           case EVENT_ID_SERVER_ATTRIBUT :
185             recvServerAttribut(event) ;
186             return true ;
187             break ;
188           default :
189             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
190                    <<"Unknown Event") ;
191           return false ;
192         }
193      }
194   }
195
196   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
197                                       CServerDistributionDescription::ServerDistributionType distType)
198   {
199     if (this->areClientAttributesChecked_) return;
200     this->checkAttributes();
201
202     CContext* context=CContext::getCurrent() ;
203     if (context->hasClient)
204     {
205       computeServerIndex(globalDim, orderPositionInGrid, distType);
206     }
207
208     this->areClientAttributesChecked_ = true;
209   }
210
211   void CAxis::computeServerIndex(const std::vector<int>& globalDim, int orderPositionInGrid,
212                                  CServerDistributionDescription::ServerDistributionType distType)
213   {
214     CServerDistributionDescription serverDescription(globalDim);
215
216     CContext* context=CContext::getCurrent() ;
217     CContextClient* client=context->client ;
218     int nbServer=client->serverSize ;
219     int serverRank=client->getServerLeader() ;
220
221     serverDescription.computeServerDistribution(nbServer, false, distType);
222     std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
223     std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
224     begin_srv = (serverIndexBegin[serverRank])[orderPositionInGrid];
225     ni_srv = serverDimensionSizes[serverRank][orderPositionInGrid];
226     end_srv = begin_srv+ni_srv-1;
227   }
228
229   // Send all checked attributes to server
230   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
231                                     CServerDistributionDescription::ServerDistributionType distType)
232   {
233     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
234                                                                     orderPositionInGrid,
235                                                                     distType);
236     CContext* context=CContext::getCurrent() ;
237
238     if (this->isChecked) return;
239     if (context->hasClient)
240     {
241       sendServerAttribut() ;
242     }
243
244     this->isChecked = true;
245   }
246
247  void CAxis::sendServerAttribut(void)
248  {
249    CContext* context=CContext::getCurrent();
250    CContextClient* client=context->client;
251
252    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT) ;
253    if (client->isServerLeader())
254    {
255      CMessage msg ;
256      msg<<this->getId() ;
257      msg<<ni_srv<<begin_srv<<end_srv;
258      event.push(client->getServerLeader(),1,msg) ;
259      client->sendEvent(event) ;
260    }
261    else client->sendEvent(event) ;
262  }
263
264  void CAxis::recvServerAttribut(CEventServer& event)
265  {
266    CBufferIn* buffer=event.subEvents.begin()->buffer;
267    string axisId ;
268    *buffer>>axisId ;
269    get(axisId)->recvServerAttribut(*buffer) ;
270  }
271
272  void CAxis::recvServerAttribut(CBufferIn& buffer)
273  {
274    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
275    int ni_srv, begin_srv, end_srv;
276
277    buffer>>ni_srv>>begin_srv>>end_srv;
278
279    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv ;
280    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv ;
281    zoom_size_srv  = zoom_end_srv-zoom_begin_srv+1 ;
282
283    if (zoom_size_srv<=0)
284    {
285      zoom_begin_srv=0 ; zoom_end_srv=0 ; zoom_size_srv=0 ;
286    }
287  }
288
289   DEFINE_REF_FUNC(Axis,axis)
290
291   ///---------------------------------------------------------------
292
293} // namespace xios
Note: See TracBrowser for help on using the repository browser.