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

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

Modifying some functions to make sure zoom working even with grid not distributed

+) Change some code in sendIndex to make sure non-distributed grid work with zoom

Test
+) On Curie
+) test_client: passed and results are same like on the branchs
+) test_complete: there is a difference of output because of zoom index offset

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