source: XIOS/trunk/src/node/grid.cpp @ 568

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

Implementing discovering algorithm of server index

+) Implement the algorithm with only one level
+) Remove some redundant functions, corrects some interface

Test
+) On Curie
+) Test 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
File size: 31.7 KB
Line 
1
2#include "grid.hpp"
3
4#include "attribute_template.hpp"
5#include "object_template.hpp"
6#include "group_template.hpp"
7#include "message.hpp"
8#include <iostream>
9#include "xmlioserver_spl.hpp"
10#include "type.hpp"
11#include "context.hpp"
12#include "context_client.hpp"
13#include "context_server.hpp"
14#include "array_new.hpp"
15#include "client_server_mapping_distributed.hpp"
16
17namespace xios {
18
19   /// ////////////////////// Définitions ////////////////////// ///
20
21   CGrid::CGrid(void)
22      : CObjectTemplate<CGrid>(), CGridAttributes()
23      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
24      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
25      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(0), writtenDataSize_(0), globalDim_()
26   {
27     setVirtualDomainGroup();
28     setVirtualAxisGroup();
29   }
30
31   CGrid::CGrid(const StdString & id)
32      : CObjectTemplate<CGrid>(id), CGridAttributes()
33      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
34      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
35      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(0), writtenDataSize_(0), globalDim_()
36   {
37     setVirtualDomainGroup();
38     setVirtualAxisGroup();
39   }
40
41   CGrid::~CGrid(void)
42   {
43    deque< CArray<int, 1>* >::iterator it ;
44
45    for(deque< CArray<int,1>* >::iterator it=storeIndex.begin(); it!=storeIndex.end();it++)  delete *it ;
46    for(map<int,CArray<size_t,1>* >::iterator it=outIndexFromClient.begin();it!=outIndexFromClient.end();++it) delete (it->second);
47
48    if (0 != clientDistribution_) delete clientDistribution_;
49    if (0 != serverDistribution_) delete serverDistribution_;
50    if (0 != serverDistributionDescription_) delete serverDistributionDescription_;
51   }
52
53   ///---------------------------------------------------------------
54
55   StdString CGrid::GetName(void)    { return (StdString("grid")); }
56   StdString CGrid::GetDefName(void) { return (CGrid::GetName()); }
57   ENodeType CGrid::GetType(void)    { return (eGrid); }
58
59   //----------------------------------------------------------------
60
61   const std::deque< CArray<int,1>* > & CGrid::getStoreIndex(void) const
62   {
63      return (this->storeIndex );
64   }
65
66   //---------------------------------------------------------------
67//
68//   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
69//   {
70//      return (this->out_i_index );
71//   }
72//
73//   //---------------------------------------------------------------
74//
75//   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
76//   {
77//      return (this->out_j_index );
78//   }
79//
80//   //---------------------------------------------------------------
81//
82//   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
83//   {
84//      return (this->out_l_index );
85//   }
86//
87//   //---------------------------------------------------------------
88//
89//   const CAxis*   CGrid::getRelAxis  (void) const
90//   {
91//      return (this->axis );
92//   }
93
94//   //---------------------------------------------------------------
95//
96//   const CDomain* CGrid::getRelDomain(void) const
97//   {
98//      return (this->domain );
99//   }
100
101   //---------------------------------------------------------------
102
103//   bool CGrid::hasAxis(void) const
104//   {
105//      return (this->withAxis);
106//   }
107
108   //---------------------------------------------------------------
109
110   StdSize CGrid::getDimension(void) const
111   {
112      return (globalDim_.size());
113   }
114
115   //---------------------------------------------------------------
116
117/*
118   std::vector<StdSize> CGrid::getLocalShape(void) const
119   {
120      std::vector<StdSize> retvalue;
121      retvalue.push_back(domain->zoom_ni_loc.getValue());
122      retvalue.push_back(domain->zoom_nj_loc.getValue());
123      if (this->withAxis)
124         retvalue.push_back(this->axis->zoom_size.getValue());
125      return (retvalue);
126   }
127*/
128   //---------------------------------------------------------------
129
130/*
131   StdSize CGrid::getLocalSize(void) const
132   {
133      StdSize retvalue = 1;
134      std::vector<StdSize> shape_ = this->getLocalShape();
135      for (StdSize s = 0; s < shape_.size(); s++)
136         retvalue *= shape_[s];
137      return (retvalue);
138   }
139*/
140   //---------------------------------------------------------------
141/*
142   std::vector<StdSize> CGrid::getGlobalShape(void) const
143   {
144      std::vector<StdSize> retvalue;
145      retvalue.push_back(domain->ni.getValue());
146      retvalue.push_back(domain->nj.getValue());
147      if (this->withAxis)
148         retvalue.push_back(this->axis->size.getValue());
149      return (retvalue);
150   }
151*/
152   //---------------------------------------------------------------
153
154/*
155   StdSize CGrid::getGlobalSize(void) const
156   {
157      StdSize retvalue = 1;
158      std::vector<StdSize> shape_ = this->getGlobalShape();
159      for (StdSize s = 0; s < shape_.size(); s++)
160         retvalue *= shape_[s];
161      return (retvalue);
162   }
163*/
164   StdSize CGrid::getDataSize(void) const
165   {
166      std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
167      StdSize retvalue = 1;
168      for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
169      return (retvalue);
170   }
171
172   std::map<int, StdSize> CGrid::getConnectedServerDataSize()
173   {
174     double secureFactor = 2.5 * sizeof(double) * CXios::bufferServerFactorSize;
175     StdSize retVal;
176     std::map<int, StdSize> ret;
177     const std::map<int, std::vector<int> >& distribution = clientServerMap_->getLocalIndexSendToServer();
178     std::map<int, std::vector<int> >::const_iterator it = distribution.begin(), itE = distribution.end();
179     for (; it != itE; ++it)
180     {
181        retVal = it->second.size();
182        retVal *= secureFactor;
183        ret.insert(std::make_pair<int,StdSize>(it->first, retVal));
184     }
185
186     return ret;
187   }
188
189
190   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
191   {
192     if (this->isDomainAxisChecked) return;
193
194     this->solveDomainRef(areAttributesChecked);
195     this->solveAxisRef(areAttributesChecked);
196
197     this->isDomainAxisChecked = areAttributesChecked;
198   }
199
200   void CGrid::checkMaskIndex(bool doSendingIndex)
201   {
202     CContext* context = CContext::getCurrent() ;
203     CContextClient* client=context->client ;
204
205     if (context->hasClient)
206      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
207
208     if (this->isChecked) return;
209
210     if (context->hasClient)
211     {
212        checkMask() ;
213        this->computeIndex() ;
214        this->storeIndex.push_front(new CArray<int,1>() );
215     }
216     this->isChecked = true;
217   }
218
219   void CGrid::checkMask(void)
220   {
221      using namespace std;
222      std::vector<CDomain*> domainP = this->getDomains();
223      std::vector<CAxis*> axisP = this->getAxis();
224      int dim = domainP.size() * 2 + axisP.size();
225
226      std::vector<CArray<bool,2>* > domainMasks(domainP.size());
227      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask);
228      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
229      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
230
231      switch (dim) {
232        case 1:
233          checkGridMask(mask1, domainMasks, axisMasks, axisDomainOrder);
234          break;
235        case 2:
236          checkGridMask(mask2, domainMasks, axisMasks, axisDomainOrder);
237          break;
238        case 3:
239          checkGridMask(mask3, domainMasks, axisMasks, axisDomainOrder);
240          break;
241//        case 4:
242//          checkGridMask(mask4, domainMasks, axisMasks, axisDomainOrder);
243//          break;
244//        case 5:
245//          checkGridMask(mask5, domainMasks, axisMasks, axisDomainOrder);
246//          break;
247//        case 6:
248//          checkGridMask(mask6, domainMasks, axisMasks, axisDomainOrder);
249//          break;
250//        case 7:
251//          checkGridMask(mask7, domainMasks, axisMasks, axisDomainOrder);
252//          break;
253        default:
254          break;
255      }
256   }
257   //---------------------------------------------------------------
258
259   void CGrid::solveDomainRef(bool sendAtt)
260   {
261      setDomainList();
262      std::vector<CDomain*> domListP = this->getDomains();
263      if (!domListP.empty())
264      {
265        computeGridGlobalDimension(getDomains(), getAxis(), axisDomainOrder);
266        for (int i = 0; i < domListP.size(); ++i)
267        {
268          if (sendAtt) domListP[i]->sendCheckedAttributes();
269          else domListP[i]->checkAttributesOnClient();
270        }
271      }
272   }
273
274   //---------------------------------------------------------------
275
276   void CGrid::solveAxisRef(bool sendAtt)
277   {
278      setAxisList();
279      std::vector<CAxis*> axisListP = this->getAxis();
280      if (!axisListP.empty())
281      {
282        int idx = 0;
283        std::vector<int> axisPositionMap;
284        for (int i = 0; i < axisDomainOrder.numElements(); ++i)
285        {
286          if (false == axisDomainOrder(i))
287          {
288            axisPositionMap.push_back(idx);
289            ++idx;
290          }
291          else idx += 2;
292        }
293
294        computeGridGlobalDimension(getDomains(), getAxis(), axisDomainOrder);
295        for (int i = 0; i < axisListP.size(); ++i)
296        {
297          if (sendAtt)
298            axisListP[i]->sendCheckedAttributes(globalDim_,axisPositionMap[i]);
299          else
300            axisListP[i]->checkAttributesOnClient(globalDim_,axisPositionMap[i]);
301          ++idx;
302        }
303
304      }
305   }
306
307   //---------------------------------------------------------------
308
309   void CGrid::computeIndex(void)
310   {
311     CContext* context = CContext::getCurrent() ;
312     CContextClient* client=context->client ;
313
314     // First of all, compute distribution on client side
315     clientDistribution_ = new CDistributionClient(client->clientRank, this);
316     size_t globalSizeIndex = 1, indexBegin, indexEnd;
317     int range, clientSize = client->clientSize;
318     for (int i = 0; i < globalDim_.size(); ++i) globalSizeIndex *= globalDim_[i];
319     indexBegin = 0;
320     for (int i = 0; i < clientSize; ++i)
321     {
322       range = globalSizeIndex / clientSize;
323       if (i < (globalSizeIndex%clientSize)) ++range;
324       if (i == client->clientRank) break;
325       indexBegin += range;
326     }
327     indexEnd = indexBegin + range - 1;
328
329     // Then compute distribution on server side
330     serverDistributionDescription_ = new CServerDistributionDescription(clientDistribution_->getNGlob());
331     serverDistributionDescription_->computeServerDistribution(client->serverSize, true);
332     serverDistributionDescription_->computeServerGlobalIndexInRange(client->serverSize,
333                                                                     std::make_pair<size_t,size_t>(indexBegin, indexEnd));
334
335     // Finally, compute index mapping between client(s) and server(s)
336     clientServerMap_ = new CClientServerMappingDistributed(serverDistributionDescription_->getGlobalIndexRange(),
337                                                            client->intraComm);
338
339     clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex(),
340                                                 clientDistribution_->getLocalDataIndexSendToServerOnClient());
341
342//     clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex(),
343//                                                 clientDistribution_->getLocalDataIndexSendToServerOnClient(),
344//                                                 serverDistributionDescription_->getGlobalIndex());
345     const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
346     std::vector<int> connectedServerRank;
347     for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
348       connectedServerRank.push_back(it->first);
349     }
350     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank);
351
352     // Get local data index on client
353     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().numElements());
354     storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
355
356   }
357
358   //----------------------------------------------------------------
359
360   CGrid* CGrid::createGrid(CDomain* domain)
361   {
362      std::vector<CDomain*> vecDom(1,domain);
363      std::vector<CAxis*> vecAxis;
364
365      CGrid* grid = createGrid(vecDom, vecAxis);
366
367      return (grid);
368   }
369
370   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
371   {
372      std::vector<CDomain*> vecDom(1,domain);
373      std::vector<CAxis*> vecAxis(1,axis);
374      CGrid* grid = createGrid(vecDom, vecAxis);
375
376      return (grid);
377   }
378
379   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
380   {
381      StdString new_id = StdString("__");
382      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
383      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_") ;
384      new_id += StdString("_");
385
386      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
387      grid->setDomainList(domains);
388      grid->setAxisList(axis);
389
390      //By default, domains are always the first ones of a grid
391      if (grid->axisDomainOrder.isEmpty())
392      {
393        int size = domains.size()+axis.size();
394        grid->axisDomainOrder.resize(size);
395        for (int i = 0; i < size; ++i)
396        {
397          if (i < domains.size()) grid->axisDomainOrder(i) = true;
398          else grid->axisDomainOrder(i) = false;
399        }
400      }
401
402      grid->computeGridGlobalDimension(domains, axis, grid->axisDomainOrder);
403
404      return (grid);
405   }
406
407   CDomainGroup* CGrid::getVirtualDomainGroup() const
408   {
409     return (this->vDomainGroup_);
410   }
411
412   CAxisGroup* CGrid::getVirtualAxisGroup() const
413   {
414     return (this->vAxisGroup_);
415   }
416
417   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
418   {
419     CArray<size_t,1>& out_i=*outIndexFromClient[rank];
420     StdSize numElements = stored.numElements();
421     for (StdSize n = 0; n < numElements; ++n)
422     {
423       *(field+out_i(n)) = stored(n);
424     }
425   }
426
427   //----------------------------------------------------------------
428
429
430   void CGrid::storeField_arr
431      (const double * const data, CArray<double, 1>& stored) const
432   {
433      const StdSize size = storeIndex_client.numElements() ;
434
435      stored.resize(size) ;
436      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ;
437   }
438
439  void CGrid::sendIndex(void)
440  {
441    CContext* context = CContext::getCurrent() ;
442    CContextClient* client=context->client ;
443
444    CEventClient event(getType(),EVENT_ID_INDEX) ;
445    int rank ;
446    list<shared_ptr<CMessage> > list_msg ;
447    list< CArray<size_t,1>* > listOutIndex;
448    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
449    const std::map<int, std::vector<int> >& localIndexSendToServer  = clientServerMap_->getLocalIndexSendToServer();
450
451    std::map<int, std::vector<size_t> >::const_iterator iteMap, itbMap, itGlobal;
452    std::map<int, std::vector<int> >::const_iterator itLocal;
453    itbMap = itGlobal = globalIndexOnServer.begin();
454    iteMap = globalIndexOnServer.end();
455    itLocal = localIndexSendToServer.begin();
456
457    if (!doGridHaveDataDistributed())
458    {
459      if (0 == client->getClientRank())
460      {
461       for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
462        {
463          rank = itGlobal->first;
464          int nb = (itGlobal->second).size();
465
466          CArray<size_t, 1> outGlobalIndexOnServer(nb);
467          CArray<int, 1> outLocalIndexToServer(nb);
468          for (int k = 0; k < nb; ++k)
469          {
470            outGlobalIndexOnServer(k) = itGlobal->second.at(k);
471            outLocalIndexToServer(k)  = itLocal->second.at(k);
472          }
473
474          storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
475          listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
476
477          list_msg.push_back(shared_ptr<CMessage>(new CMessage));
478          *list_msg.back()<<getId()<<*listOutIndex.back();
479          event.push(rank, 1, *list_msg.back());
480        }
481        client->sendEvent(event);
482      } else client->sendEvent(event);
483    }
484    else
485    {
486      for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
487      {
488        rank = itGlobal->first;
489        int nb = (itGlobal->second).size();
490
491        CArray<size_t, 1> outGlobalIndexOnServer(nb);
492        CArray<int, 1> outLocalIndexToServer(nb);
493        for (int k = 0; k < nb; ++k)
494        {
495          outGlobalIndexOnServer(k) = itGlobal->second.at(k);
496          outLocalIndexToServer(k)  = itLocal->second.at(k);
497        }
498
499        storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
500        listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
501
502        list_msg.push_back(shared_ptr<CMessage>(new CMessage));
503        *list_msg.back()<<getId()<<*listOutIndex.back();
504        event.push(rank, nbSenders[rank], *list_msg.back());
505      }
506      client->sendEvent(event);
507    }
508
509    for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
510  }
511
512  void CGrid::recvIndex(CEventServer& event)
513  {
514    list<CEventServer::SSubEvent>::iterator it ;
515    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
516    {
517      int rank=it->rank;
518      CBufferIn* buffer=it->buffer;
519      string gridId ;
520      *buffer>>gridId ;
521      get(gridId)->recvIndex(rank,*buffer) ;
522    }
523  }
524
525  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
526                                         const std::vector<CAxis*>& axis,
527                                         const CArray<bool,1>& axisDomainOrder)
528  {
529    globalDim_.resize(domains.size()*2+axis.size());
530    int idx = 0, idxDomain = 0, idxAxis = 0;
531    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
532    {
533      if (axisDomainOrder(i))
534      {
535        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
536        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
537        ++idxDomain;
538        idx += 2;
539      }
540      else
541      {
542        globalDim_[idx] = axis[idxAxis]->size.getValue();
543        ++idxAxis;
544        ++idx;
545      }
546    }
547  }
548
549  std::vector<int> CGrid::getGlobalDimension()
550  {
551    return globalDim_;
552  }
553
554  /*!
555    Verify whether one server need to write data
556    There are some cases on which one server has nodata to write. For example, when we
557  just only want to zoom on a domain.
558  */
559  bool CGrid::doGridHaveDataToWrite()
560  {
561    return (0 != serverDistribution_);
562  }
563
564  /*!
565    Return size of data which is written on each server
566    Whatever dimension of a grid, data which are written on server must be presented as
567  an one dimension array.
568  \return size of data written on server
569  */
570  size_t CGrid::getWrittenDataSize() const
571  {
572    return writtenDataSize_;
573  }
574
575
576  const CDistributionServer* CGrid::getDistributionServer() const
577  {
578    return serverDistribution_;
579  }
580
581  bool CGrid::doGridHaveDataDistributed()
582  {
583    return clientDistribution_->isDataDistributed();
584  }
585
586  void CGrid::recvIndex(int rank, CBufferIn& buffer)
587  {
588     if (0 == serverDistribution_)
589     {
590       CContext* context = CContext::getCurrent() ;
591       CContextServer* server=context->server ;
592       int idx = 0, numElement = axisDomainOrder.numElements();
593       int ssize = numElement;
594       std::vector<int> indexMap(numElement);
595       for (int i = 0; i < numElement; ++i)
596       {
597         indexMap[i] = idx;
598         if (true == axisDomainOrder(i))
599         {
600            ++ssize;
601            idx += 2;
602         }
603         else
604          ++idx;
605       }
606
607       int axisId = 0, domainId = 0;
608       std::vector<CDomain*> domainList = getDomains();
609       std::vector<CAxis*> axisList = getAxis();
610       std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
611       for (int i = 0; i < numElement; ++i)
612       {
613         if (axisDomainOrder(i))
614         {
615            nZoomBegin[indexMap[i]]   = domainList[domainId]->zoom_ibegin_srv;
616            nZoomSize[indexMap[i]]    = domainList[domainId]->zoom_ni_srv;
617            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->zoom_ibegin;
618            nGlob[indexMap[i]]    = domainList[domainId]->ni_glo;
619
620            nZoomBegin[indexMap[i]+1] = domainList[domainId]->zoom_jbegin_srv;
621            nZoomSize[indexMap[i]+1]  = domainList[domainId]->zoom_nj_srv;
622            nZoomBeginGlobal[indexMap[i]+1] = domainList[domainId]->zoom_jbegin;
623            nGlob[indexMap[i]+1]    = domainList[domainId]->nj_glo;
624            ++domainId;
625         }
626         else
627         {
628            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
629            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
630            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->zoom_begin;
631            nGlob[indexMap[i]]      = axisList[axisId]->size;
632            ++axisId;
633         }
634       }
635       writtenDataSize_ = 1;
636       for (int i = 0; i < nZoomSize.size(); ++i)
637        writtenDataSize_ *= nZoomSize[i];
638
639       serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
640                                                     nZoomBeginGlobal, nGlob);
641     }
642
643     CArray<size_t,1> outIndex;
644     buffer>>outIndex;
645     serverDistribution_->computeLocalIndex(outIndex);
646     outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
647  }
648
649   /*!
650   \brief Dispatch event received from client
651      Whenever a message is received in buffer of server, it will be processed depending on
652   its event type. A new event type should be added in the switch list to make sure
653   it processed on server side.
654   \param [in] event: Received message
655   */
656  bool CGrid::dispatchEvent(CEventServer& event)
657  {
658
659    if (SuperClass::dispatchEvent(event)) return true ;
660    else
661    {
662      switch(event.type)
663      {
664        case EVENT_ID_INDEX :
665          recvIndex(event) ;
666          return true ;
667          break ;
668
669         case EVENT_ID_ADD_DOMAIN :
670           recvAddDomain(event) ;
671           return true ;
672           break ;
673
674         case EVENT_ID_ADD_AXIS :
675           recvAddAxis(event) ;
676           return true ;
677           break ;
678        default :
679          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
680                <<"Unknown Event") ;
681          return false ;
682      }
683    }
684  }
685
686   void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const
687   {
688      if ((this->storeIndex.size()-1 ) != storedClient.size())
689         ERROR("void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const",
690                << "[ Expected received field = " << (this->storeIndex.size()-1) << ", "
691                << "[ received fiedl = "    << storedClient.size() << "] "
692                << "Data from clients are missing!") ;
693      storedServer.resize(storeIndex[0]->numElements());
694
695      for (StdSize i = 0, n = 0; i < storedClient.size(); i++)
696         for (StdSize j = 0; j < storedClient[i]->numElements(); j++)
697            storedServer(n++) = (*storedClient[i])(j);
698   }
699
700   void CGrid::outputFieldToServer(CArray<double,1>& fieldIn, int rank, CArray<double,1>& fieldOut)
701   {
702     CArray<int,1>& index = *storeIndex_toSrv[rank] ;
703     int nb=index.numElements() ;
704     fieldOut.resize(nb) ;
705
706     for(int k=0;k<nb;k++) fieldOut(k)=fieldIn(index(k)) ;
707    }
708   ///---------------------------------------------------------------
709
710   CDomain* CGrid::addDomain(const std::string& id)
711   {
712     return vDomainGroup_->createChild(id) ;
713   }
714
715   CAxis* CGrid::addAxis(const std::string& id)
716   {
717     return vAxisGroup_->createChild(id) ;
718   }
719
720   //! Change virtual field group to a new one
721   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
722   {
723      this->vDomainGroup_ = newVDomainGroup;
724   }
725
726   //! Change virtual variable group to new one
727   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
728   {
729      this->vAxisGroup_ = newVAxisGroup;
730   }
731
732   //----------------------------------------------------------------
733   //! Create virtual field group, which is done normally on initializing file
734   void CGrid::setVirtualDomainGroup(void)
735   {
736      this->setVirtualDomainGroup(CDomainGroup::create());
737   }
738
739   //! Create virtual variable group, which is done normally on initializing file
740   void CGrid::setVirtualAxisGroup(void)
741   {
742      this->setVirtualAxisGroup(CAxisGroup::create());
743   }
744
745   /*!
746   \brief Send a message to create a domain on server side
747   \param[in] id String identity of domain that will be created on server
748   */
749   void CGrid::sendAddDomain(const string& id)
750   {
751    CContext* context=CContext::getCurrent() ;
752
753    if (! context->hasServer )
754    {
755       CContextClient* client=context->client ;
756
757       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN) ;
758       if (client->isServerLeader())
759       {
760         CMessage msg ;
761         msg<<this->getId() ;
762         msg<<id ;
763         event.push(client->getServerLeader(),1,msg) ;
764         client->sendEvent(event) ;
765       }
766       else client->sendEvent(event) ;
767    }
768   }
769
770   /*!
771   \brief Send a message to create an axis on server side
772   \param[in] id String identity of axis that will be created on server
773   */
774   void CGrid::sendAddAxis(const string& id)
775   {
776    CContext* context=CContext::getCurrent() ;
777
778    if (! context->hasServer )
779    {
780       CContextClient* client=context->client ;
781
782       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS) ;
783       if (client->isServerLeader())
784       {
785         CMessage msg ;
786         msg<<this->getId() ;
787         msg<<id ;
788         event.push(client->getServerLeader(),1,msg) ;
789         client->sendEvent(event) ;
790       }
791       else client->sendEvent(event) ;
792    }
793   }
794
795   /*!
796   \brief Receive a message annoucing the creation of a domain on server side
797   \param[in] event Received event
798   */
799   void CGrid::recvAddDomain(CEventServer& event)
800   {
801
802      CBufferIn* buffer=event.subEvents.begin()->buffer;
803      string id;
804      *buffer>>id ;
805      get(id)->recvAddDomain(*buffer) ;
806   }
807
808   /*!
809   \brief Receive a message annoucing the creation of a domain on server side
810   \param[in] buffer Buffer containing message
811   */
812   void CGrid::recvAddDomain(CBufferIn& buffer)
813   {
814      string id ;
815      buffer>>id ;
816      addDomain(id) ;
817   }
818
819   /*!
820   \brief Receive a message annoucing the creation of an axis on server side
821   \param[in] event Received event
822   */
823   void CGrid::recvAddAxis(CEventServer& event)
824   {
825
826      CBufferIn* buffer=event.subEvents.begin()->buffer;
827      string id;
828      *buffer>>id ;
829      get(id)->recvAddAxis(*buffer) ;
830   }
831
832   /*!
833   \brief Receive a message annoucing the creation of an axis on server side
834   \param[in] buffer Buffer containing message
835   */
836   void CGrid::recvAddAxis(CBufferIn& buffer)
837   {
838      string id ;
839      buffer>>id ;
840      addAxis(id) ;
841   }
842
843  /*!
844  \brief Solve domain and axis references
845  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
846  all attributes from their parents, they should be processed with this function
847  \param[in] apply inherit all attributes of parents (true)
848  */
849  void CGrid::solveDomainAxisRefInheritance(bool apply)
850  {
851    CContext* context = CContext::getCurrent();
852    unsigned int vecSize, i;
853    std::vector<StdString>::iterator it, itE;
854    setDomainList();
855    it = domList_.begin(); itE = domList_.end();
856    for (; it != itE; ++it)
857    {
858      CDomain* pDom = CDomain::get(*it);
859      if (context->hasClient)
860      {
861        pDom->solveRefInheritance(apply);
862        pDom->solveBaseReference();
863        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
864          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
865      }
866    }
867
868    setAxisList();
869    it = axisList_.begin(); itE = axisList_.end();
870    for (; it != itE; ++it)
871    {
872      CAxis* pAxis = CAxis::get(*it);
873      if (context->hasClient)
874      {
875        pAxis->solveRefInheritance(apply);
876        pAxis->solveBaseReference();
877        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
878          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
879      }
880    }
881  }
882
883  /*!
884  \brief Get the list of domain pointers
885  \return list of domain pointers
886  */
887  std::vector<CDomain*> CGrid::getDomains()
888  {
889    std::vector<CDomain*> domList;
890    if (!domList_.empty())
891    {
892      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
893    }
894    return domList;
895  }
896
897  /*!
898  \brief Get the list of  axis pointers
899  \return list of axis pointers
900  */
901  std::vector<CAxis*> CGrid::getAxis()
902  {
903    std::vector<CAxis*> aList;
904    if (!axisList_.empty())
905      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
906
907    return aList;
908  }
909
910  /*!
911  \brief Set domain(s) of a grid from a list
912  \param[in] domains list of domains
913  */
914  void CGrid::setDomainList(const std::vector<CDomain*> domains)
915  {
916    if (isDomListSet) return;
917    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
918    if (!domains.empty() && domList.empty()) domList = domains;
919    if (!domList.empty())
920    {
921      int sizeDom = domList.size();
922      domList_.resize(sizeDom);
923      for (int i = 0 ; i < sizeDom; ++i)
924      {
925        domList_[i] = domList[i]->getId();
926      }
927      isDomListSet = true;
928    }
929
930  }
931
932  /*!
933  \brief Set axis(s) of a grid from a list
934  \param[in] axis list of axis
935  */
936  void CGrid::setAxisList(const std::vector<CAxis*> axis)
937  {
938    if (isAxisListSet) return;
939    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
940    if (!axis.empty() && aList.empty()) aList = axis;
941    if (!aList.empty())
942    {
943      int sizeAxis = aList.size();
944      axisList_.resize(sizeAxis);
945      for (int i = 0; i < sizeAxis; ++i)
946      {
947        axisList_[i] = aList[i]->getId();
948      }
949      isAxisListSet = true;
950    }
951  }
952
953  /*!
954  \brief Get list of id of domains
955  \return id list of domains
956  */
957  std::vector<StdString> CGrid::getDomainList()
958  {
959    setDomainList();
960    return domList_;
961  }
962
963  /*!
964  \brief Get list of id of axis
965  \return id list of axis
966  */
967  std::vector<StdString> CGrid::getAxisList()
968  {
969    setAxisList();
970    return axisList_;
971  }
972
973  void CGrid::sendAllDomains()
974  {
975    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
976    int dSize = domList.size();
977    for (int i = 0; i < dSize; ++i)
978    {
979      sendAddDomain(domList[i]->getId());
980      domList[i]->sendAllAttributesToServer();
981    }
982  }
983
984  void CGrid::sendAllAxis()
985  {
986    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
987    int aSize = aList.size();
988
989    for (int i = 0; i < aSize; ++i)
990    {
991      sendAddAxis(aList[i]->getId());
992      aList[i]->sendAllAttributesToServer();
993    }
994  }
995
996  void CGrid::parse(xml::CXMLNode & node)
997  {
998    SuperClass::parse(node);
999
1000    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
1001    std::vector<bool> order;
1002
1003    if (node.goToChildElement())
1004    {
1005      StdString domainName("domain");
1006      StdString axisName("axis");
1007      do
1008      {
1009        if (node.getElementName() == domainName) {
1010          order.push_back(true);
1011          this->getVirtualDomainGroup()->parseChild(node);
1012        }
1013        if (node.getElementName() == axisName) {
1014          order.push_back(false);
1015          this->getVirtualAxisGroup()->parseChild(node);
1016        }
1017      } while (node.goToNextElement()) ;
1018      node.goToParentElement();
1019    }
1020
1021    if (!order.empty())
1022    {
1023      int sizeOrd = order.size();
1024      axisDomainOrder.resize(sizeOrd);
1025      for (int i = 0; i < sizeOrd; ++i)
1026      {
1027        axisDomainOrder(i) = order[i];
1028      }
1029    }
1030
1031    setDomainList();
1032    setAxisList();
1033   }
1034
1035} // namespace xios
Note: See TracBrowser for help on using the repository browser.