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

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

Allow using more servers than clients.

This will be useful later when implementing server to client communications.

  • 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.2 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
205     this->checkAttributes();
206
207     this->areClientAttributesChecked_ = true;
208   }
209
210   // Send all checked attributes to server
211   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
212                                     CServerDistributionDescription::ServerDistributionType distType)
213   {
214     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
215                                                                     orderPositionInGrid,
216                                                                     distType);
217     CContext* context = CContext::getCurrent();
218
219     if (this->isChecked) return;
220     if (context->hasClient)
221     {
222       sendServerAttribut(globalDim, orderPositionInGrid, distType);
223     }
224
225     this->isChecked = true;
226   }
227
228  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
229                                 CServerDistributionDescription::ServerDistributionType distType)
230  {
231    CContext* context = CContext::getCurrent();
232    CContextClient* client = context->client;
233
234    CServerDistributionDescription serverDescription(globalDim);
235
236    int nbServer = client->serverSize;
237
238    serverDescription.computeServerDistribution(nbServer, false, distType);
239    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
240    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
241
242    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
243    if (client->isServerLeader())
244    {
245      std::list<CMessage> msgs;
246
247      const std::list<int>& ranks = client->getRanksServerLeader();
248      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
249      {
250        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
251        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
252        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
253        const int end   = begin + ni - 1;
254
255        msgs.push_back(CMessage());
256        CMessage& msg = msgs.back();
257        msg << this->getId();
258        msg << ni << begin << end;
259
260        event.push(*itRank,1,msg);
261      }
262      client->sendEvent(event);
263    }
264    else client->sendEvent(event);
265  }
266
267  void CAxis::recvServerAttribut(CEventServer& event)
268  {
269    CBufferIn* buffer = event.subEvents.begin()->buffer;
270    string axisId;
271    *buffer >> axisId;
272    get(axisId)->recvServerAttribut(*buffer);
273  }
274
275  void CAxis::recvServerAttribut(CBufferIn& buffer)
276  {
277    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
278    int ni_srv, begin_srv, end_srv;
279
280    buffer>>ni_srv>>begin_srv>>end_srv;
281
282    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv;
283    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv;
284    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
285
286    if (zoom_size_srv<=0)
287    {
288      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
289    }
290
291    if (size == ni)
292    {
293      zoom_begin_srv = zoom_begin.getValue();
294      zoom_end_srv   = zoom_end;
295      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
296    }
297  }
298
299   DEFINE_REF_FUNC(Axis,axis)
300
301   ///---------------------------------------------------------------
302
303} // namespace xios
Note: See TracBrowser for help on using the repository browser.