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

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

Implementing new hash algorithm and fixing bug related to zoom

+) Replace boost hash with hash algorithm of Jenkins
+) Domain, if an attribute is non-empty for one client, it should also be non-empty for others inspite of zoom
+) Replace the way to find the number of client connecting to a server to make sure every server receive a message

Test
+) On Curie
+) test_client: passed and results are same like before
+) test_complete: passed, results are partially the same, the different part comes from added working operation

  • 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.5 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
340     clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex());
341     const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
342     const CArray<size_t,1>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
343
344     std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
345     itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
346     iteGlobalMap = globalIndexOnServer.end();
347
348     int nbGlobalIndex = globalIndexSendToServer.numElements();
349    for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
350    {
351      int serverRank = itGlobalMap->first;
352      std::vector<size_t>::const_iterator itbVecGlobal = (itGlobalMap->second).begin(), itVecGlobal,
353                                          iteVecGlobal = (itGlobalMap->second).end();
354      for (int i = 0; i < nbGlobalIndex; ++i)
355      {
356        if (iteVecGlobal != std::find(itbVecGlobal, iteVecGlobal, globalIndexSendToServer(i)))
357        {
358          if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
359            connectedDataSize_[serverRank] = 0;
360          else
361            ++connectedDataSize_[serverRank];
362        }
363      }
364    }
365
366   connectedServerRank_.clear();
367   for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
368     connectedServerRank_.push_back(it->first);
369   }
370   if (!connectedDataSize_.empty())
371   {
372     connectedServerRank_.clear();
373     for (std::map<int,size_t>::const_iterator it = connectedDataSize_.begin(); it != connectedDataSize_.end(); ++it)
374       connectedServerRank_.push_back(it->first);
375   }
376
377    nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
378
379     // Get local data index on client
380     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().numElements());
381     storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
382   }
383
384   //----------------------------------------------------------------
385
386   CGrid* CGrid::createGrid(CDomain* domain)
387   {
388      std::vector<CDomain*> vecDom(1,domain);
389      std::vector<CAxis*> vecAxis;
390
391      CGrid* grid = createGrid(vecDom, vecAxis);
392
393      return (grid);
394   }
395
396   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
397   {
398      std::vector<CDomain*> vecDom(1,domain);
399      std::vector<CAxis*> vecAxis(1,axis);
400      CGrid* grid = createGrid(vecDom, vecAxis);
401
402      return (grid);
403   }
404
405   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
406   {
407      StdString new_id = StdString("__");
408      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
409      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_") ;
410      new_id += StdString("_");
411
412      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
413      grid->setDomainList(domains);
414      grid->setAxisList(axis);
415
416      //By default, domains are always the first ones of a grid
417      if (grid->axis_domain_order.isEmpty())
418      {
419        int size = domains.size()+axis.size();
420        grid->axis_domain_order.resize(size);
421        for (int i = 0; i < size; ++i)
422        {
423          if (i < domains.size()) grid->axis_domain_order(i) = true;
424          else grid->axis_domain_order(i) = false;
425        }
426      }
427
428      grid->computeGridGlobalDimension(domains, axis, grid->axis_domain_order);
429
430      return (grid);
431   }
432
433   CDomainGroup* CGrid::getVirtualDomainGroup() const
434   {
435     return (this->vDomainGroup_);
436   }
437
438   CAxisGroup* CGrid::getVirtualAxisGroup() const
439   {
440     return (this->vAxisGroup_);
441   }
442
443   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
444   {
445     CArray<size_t,1>& out_i=*outIndexFromClient[rank];
446     StdSize numElements = stored.numElements();
447     for (StdSize n = 0; n < numElements; ++n)
448     {
449       *(field+out_i(n)) = stored(n);
450     }
451   }
452
453   //----------------------------------------------------------------
454
455
456   void CGrid::storeField_arr
457      (const double * const data, CArray<double, 1>& stored) const
458   {
459      const StdSize size = storeIndex_client.numElements() ;
460
461      stored.resize(size) ;
462      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ;
463   }
464
465  void CGrid::sendIndex(void)
466  {
467    CContext* context = CContext::getCurrent() ;
468    CContextClient* client=context->client ;
469
470    CEventClient event(getType(),EVENT_ID_INDEX) ;
471    int rank ;
472    list<shared_ptr<CMessage> > list_msg ;
473    list< CArray<size_t,1>* > listOutIndex;
474    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
475    const CArray<int,1>& localIndexSendToServer = clientDistribution_->getLocalDataIndexSendToServer();
476    const CArray<size_t,1>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
477
478    std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
479    itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
480    iteGlobalMap = globalIndexOnServer.end();
481
482    int nbGlobalIndex = globalIndexSendToServer.numElements();
483    std::map<int,std::vector<int> >localIndexTmp;
484    std::map<int,std::vector<size_t> > globalIndexTmp;
485    for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
486    {
487      int serverRank = itGlobalMap->first;
488      std::vector<size_t>::const_iterator itbVecGlobal = (itGlobalMap->second).begin(),
489                                          iteVecGlobal = (itGlobalMap->second).end();
490      for (int i = 0; i < nbGlobalIndex; ++i)
491      {
492        if (iteVecGlobal != std::find(itbVecGlobal, iteVecGlobal, globalIndexSendToServer(i)))
493        {
494          globalIndexTmp[serverRank].push_back(globalIndexSendToServer(i));
495          localIndexTmp[serverRank].push_back(localIndexSendToServer(i));
496        }
497      }
498    }
499
500
501    if (!doGridHaveDataDistributed())
502    {
503//      if (0 == client->clientRank)
504//      {
505//       for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
506//        {
507//          rank = itGlobal->first;
508//          int nb = (itGlobal->second).size();
509//
510//          CArray<size_t, 1> outGlobalIndexOnServer(nb);
511//          CArray<int, 1> outLocalIndexToServer(nb);
512//          for (int k = 0; k < nb; ++k)
513//          {
514//            outGlobalIndexOnServer(k) = itGlobal->second.at(k);
515//            outLocalIndexToServer(k)  = itLocal->second.at(k);
516//          }
517//
518//          storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
519//          listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
520//
521//          list_msg.push_back(shared_ptr<CMessage>(new CMessage));
522//          *list_msg.back()<<getId()<<*listOutIndex.back();
523//          event.push(rank, 1, *list_msg.back());
524//        }
525//        client->sendEvent(event);
526//      } else client->sendEvent(event);
527    }
528    else
529    {
530      for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
531      {
532        rank = connectedServerRank_[ns];
533        int nb = 0;
534        if (globalIndexTmp.end() != globalIndexTmp.find(rank))
535          nb = globalIndexTmp[rank].size();
536
537        CArray<size_t, 1> outGlobalIndexOnServer(nb);
538        CArray<int, 1> outLocalIndexToServer(nb);
539        for (int k = 0; k < nb; ++k)
540        {
541          outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
542          outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
543        }
544
545        storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
546        listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
547
548        list_msg.push_back(shared_ptr<CMessage>(new CMessage));
549        *list_msg.back()<<getId()<<*listOutIndex.back();
550
551        event.push(rank, nbSenders[rank], *list_msg.back());
552      }
553
554      client->sendEvent(event);
555    }
556
557    for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
558  }
559
560  void CGrid::recvIndex(CEventServer& event)
561  {
562    list<CEventServer::SSubEvent>::iterator it ;
563    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
564    {
565      int rank=it->rank;
566      CBufferIn* buffer=it->buffer;
567      string gridId ;
568      *buffer>>gridId ;
569      get(gridId)->recvIndex(rank,*buffer) ;
570    }
571  }
572
573  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
574                                         const std::vector<CAxis*>& axis,
575                                         const CArray<bool,1>& axisDomainOrder)
576  {
577    globalDim_.resize(domains.size()*2+axis.size());
578    int idx = 0, idxDomain = 0, idxAxis = 0;
579    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
580    {
581      if (axisDomainOrder(i))
582      {
583        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
584        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
585        ++idxDomain;
586        idx += 2;
587      }
588      else
589      {
590        globalDim_[idx] = axis[idxAxis]->size.getValue();
591        ++idxAxis;
592        ++idx;
593      }
594    }
595  }
596
597  std::vector<int> CGrid::getGlobalDimension()
598  {
599    return globalDim_;
600  }
601
602  /*!
603    Verify whether one server need to write data
604    There are some cases on which one server has nodata to write. For example, when we
605  just only want to zoom on a domain.
606  */
607  bool CGrid::doGridHaveDataToWrite()
608  {
609//    return (0 != serverDistribution_);
610    return (0 != writtenDataSize_);
611  }
612
613  /*!
614    Return size of data which is written on each server
615    Whatever dimension of a grid, data which are written on server must be presented as
616  an one dimension array.
617  \return size of data written on server
618  */
619  size_t CGrid::getWrittenDataSize() const
620  {
621    return writtenDataSize_;
622  }
623
624
625  const CDistributionServer* CGrid::getDistributionServer() const
626  {
627    return serverDistribution_;
628  }
629
630  bool CGrid::doGridHaveDataDistributed()
631  {
632    return clientDistribution_->isDataDistributed();
633  }
634
635  void CGrid::recvIndex(int rank, CBufferIn& buffer)
636  {
637     if (0 == serverDistribution_)
638     {
639       CContext* context = CContext::getCurrent() ;
640       CContextServer* server=context->server ;
641       int idx = 0, numElement = axis_domain_order.numElements();
642       int ssize = numElement;
643       std::vector<int> indexMap(numElement);
644       for (int i = 0; i < numElement; ++i)
645       {
646         indexMap[i] = idx;
647         if (true == axis_domain_order(i))
648         {
649            ++ssize;
650            idx += 2;
651         }
652         else
653          ++idx;
654       }
655
656       int axisId = 0, domainId = 0;
657       std::vector<CDomain*> domainList = getDomains();
658       std::vector<CAxis*> axisList = getAxis();
659       std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
660       for (int i = 0; i < numElement; ++i)
661       {
662         if (axis_domain_order(i))
663         {
664            nZoomBegin[indexMap[i]]   = domainList[domainId]->zoom_ibegin_srv;
665            nZoomSize[indexMap[i]]    = domainList[domainId]->zoom_ni_srv;
666            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->zoom_ibegin;
667            nGlob[indexMap[i]]    = domainList[domainId]->ni_glo;
668
669            nZoomBegin[indexMap[i]+1] = domainList[domainId]->zoom_jbegin_srv;
670            nZoomSize[indexMap[i]+1]  = domainList[domainId]->zoom_nj_srv;
671            nZoomBeginGlobal[indexMap[i]+1] = domainList[domainId]->zoom_jbegin;
672            nGlob[indexMap[i]+1]    = domainList[domainId]->nj_glo;
673            ++domainId;
674         }
675         else
676         {
677            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
678            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
679            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->zoom_begin;
680            nGlob[indexMap[i]]      = axisList[axisId]->size;
681            ++axisId;
682         }
683       }
684       writtenDataSize_ = 1;
685       for (int i = 0; i < nZoomSize.size(); ++i)
686        writtenDataSize_ *= nZoomSize[i];
687
688       serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
689                                                     nZoomBeginGlobal, nGlob);
690     }
691
692     CArray<size_t,1> outIndex;
693     buffer>>outIndex;
694     serverDistribution_->computeLocalIndex(outIndex);
695     outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
696  }
697
698   /*!
699   \brief Dispatch event received from client
700      Whenever a message is received in buffer of server, it will be processed depending on
701   its event type. A new event type should be added in the switch list to make sure
702   it processed on server side.
703   \param [in] event: Received message
704   */
705  bool CGrid::dispatchEvent(CEventServer& event)
706  {
707
708    if (SuperClass::dispatchEvent(event)) return true ;
709    else
710    {
711      switch(event.type)
712      {
713        case EVENT_ID_INDEX :
714          recvIndex(event) ;
715          return true ;
716          break ;
717
718         case EVENT_ID_ADD_DOMAIN :
719           recvAddDomain(event) ;
720           return true ;
721           break ;
722
723         case EVENT_ID_ADD_AXIS :
724           recvAddAxis(event) ;
725           return true ;
726           break ;
727        default :
728          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
729                <<"Unknown Event") ;
730          return false ;
731      }
732    }
733  }
734
735   void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const
736   {
737      if ((this->storeIndex.size()-1 ) != storedClient.size())
738         ERROR("void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const",
739                << "[ Expected received field = " << (this->storeIndex.size()-1) << ", "
740                << "[ received fiedl = "    << storedClient.size() << "] "
741                << "Data from clients are missing!") ;
742      storedServer.resize(storeIndex[0]->numElements());
743
744      for (StdSize i = 0, n = 0; i < storedClient.size(); i++)
745         for (StdSize j = 0; j < storedClient[i]->numElements(); j++)
746            storedServer(n++) = (*storedClient[i])(j);
747   }
748
749   void CGrid::outputFieldToServer(CArray<double,1>& fieldIn, int rank, CArray<double,1>& fieldOut)
750   {
751     CArray<int,1>& index = *storeIndex_toSrv[rank] ;
752     int nb=index.numElements() ;
753     fieldOut.resize(nb) ;
754
755     for(int k=0;k<nb;k++) fieldOut(k)=fieldIn(index(k)) ;
756    }
757   ///---------------------------------------------------------------
758
759   CDomain* CGrid::addDomain(const std::string& id)
760   {
761     return vDomainGroup_->createChild(id) ;
762   }
763
764   CAxis* CGrid::addAxis(const std::string& id)
765   {
766     return vAxisGroup_->createChild(id) ;
767   }
768
769   //! Change virtual field group to a new one
770   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
771   {
772      this->vDomainGroup_ = newVDomainGroup;
773   }
774
775   //! Change virtual variable group to new one
776   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
777   {
778      this->vAxisGroup_ = newVAxisGroup;
779   }
780
781   //----------------------------------------------------------------
782   //! Create virtual field group, which is done normally on initializing file
783   void CGrid::setVirtualDomainGroup(void)
784   {
785      this->setVirtualDomainGroup(CDomainGroup::create());
786   }
787
788   //! Create virtual variable group, which is done normally on initializing file
789   void CGrid::setVirtualAxisGroup(void)
790   {
791      this->setVirtualAxisGroup(CAxisGroup::create());
792   }
793
794   /*!
795   \brief Send a message to create a domain on server side
796   \param[in] id String identity of domain that will be created on server
797   */
798   void CGrid::sendAddDomain(const string& id)
799   {
800    CContext* context=CContext::getCurrent() ;
801
802    if (! context->hasServer )
803    {
804       CContextClient* client=context->client ;
805
806       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN) ;
807       if (client->isServerLeader())
808       {
809         CMessage msg ;
810         msg<<this->getId() ;
811         msg<<id ;
812         event.push(client->getServerLeader(),1,msg) ;
813         client->sendEvent(event) ;
814       }
815       else client->sendEvent(event) ;
816    }
817   }
818
819   /*!
820   \brief Send a message to create an axis on server side
821   \param[in] id String identity of axis that will be created on server
822   */
823   void CGrid::sendAddAxis(const string& id)
824   {
825    CContext* context=CContext::getCurrent() ;
826
827    if (! context->hasServer )
828    {
829       CContextClient* client=context->client ;
830
831       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS) ;
832       if (client->isServerLeader())
833       {
834         CMessage msg ;
835         msg<<this->getId() ;
836         msg<<id ;
837         event.push(client->getServerLeader(),1,msg) ;
838         client->sendEvent(event) ;
839       }
840       else client->sendEvent(event) ;
841    }
842   }
843
844   /*!
845   \brief Receive a message annoucing the creation of a domain on server side
846   \param[in] event Received event
847   */
848   void CGrid::recvAddDomain(CEventServer& event)
849   {
850
851      CBufferIn* buffer=event.subEvents.begin()->buffer;
852      string id;
853      *buffer>>id ;
854      get(id)->recvAddDomain(*buffer) ;
855   }
856
857   /*!
858   \brief Receive a message annoucing the creation of a domain on server side
859   \param[in] buffer Buffer containing message
860   */
861   void CGrid::recvAddDomain(CBufferIn& buffer)
862   {
863      string id ;
864      buffer>>id ;
865      addDomain(id) ;
866   }
867
868   /*!
869   \brief Receive a message annoucing the creation of an axis on server side
870   \param[in] event Received event
871   */
872   void CGrid::recvAddAxis(CEventServer& event)
873   {
874
875      CBufferIn* buffer=event.subEvents.begin()->buffer;
876      string id;
877      *buffer>>id ;
878      get(id)->recvAddAxis(*buffer) ;
879   }
880
881   /*!
882   \brief Receive a message annoucing the creation of an axis on server side
883   \param[in] buffer Buffer containing message
884   */
885   void CGrid::recvAddAxis(CBufferIn& buffer)
886   {
887      string id ;
888      buffer>>id ;
889      addAxis(id) ;
890   }
891
892  /*!
893  \brief Solve domain and axis references
894  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
895  all attributes from their parents, they should be processed with this function
896  \param[in] apply inherit all attributes of parents (true)
897  */
898  void CGrid::solveDomainAxisRefInheritance(bool apply)
899  {
900    CContext* context = CContext::getCurrent();
901    unsigned int vecSize, i;
902    std::vector<StdString>::iterator it, itE;
903    setDomainList();
904    it = domList_.begin(); itE = domList_.end();
905    for (; it != itE; ++it)
906    {
907      CDomain* pDom = CDomain::get(*it);
908      if (context->hasClient)
909      {
910        pDom->solveRefInheritance(apply);
911        pDom->solveBaseReference();
912        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
913          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
914      }
915    }
916
917    setAxisList();
918    it = axisList_.begin(); itE = axisList_.end();
919    for (; it != itE; ++it)
920    {
921      CAxis* pAxis = CAxis::get(*it);
922      if (context->hasClient)
923      {
924        pAxis->solveRefInheritance(apply);
925        pAxis->solveBaseReference();
926        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
927          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
928      }
929    }
930  }
931
932  /*!
933  \brief Get the list of domain pointers
934  \return list of domain pointers
935  */
936  std::vector<CDomain*> CGrid::getDomains()
937  {
938    std::vector<CDomain*> domList;
939    if (!domList_.empty())
940    {
941      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
942    }
943    return domList;
944  }
945
946  /*!
947  \brief Get the list of  axis pointers
948  \return list of axis pointers
949  */
950  std::vector<CAxis*> CGrid::getAxis()
951  {
952    std::vector<CAxis*> aList;
953    if (!axisList_.empty())
954      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
955
956    return aList;
957  }
958
959  /*!
960  \brief Set domain(s) of a grid from a list
961  \param[in] domains list of domains
962  */
963  void CGrid::setDomainList(const std::vector<CDomain*> domains)
964  {
965    if (isDomListSet) return;
966    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
967    if (!domains.empty() && domList.empty()) domList = domains;
968    if (!domList.empty())
969    {
970      int sizeDom = domList.size();
971      domList_.resize(sizeDom);
972      for (int i = 0 ; i < sizeDom; ++i)
973      {
974        domList_[i] = domList[i]->getId();
975      }
976      isDomListSet = true;
977    }
978
979  }
980
981  /*!
982  \brief Set axis(s) of a grid from a list
983  \param[in] axis list of axis
984  */
985  void CGrid::setAxisList(const std::vector<CAxis*> axis)
986  {
987    if (isAxisListSet) return;
988    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
989    if (!axis.empty() && aList.empty()) aList = axis;
990    if (!aList.empty())
991    {
992      int sizeAxis = aList.size();
993      axisList_.resize(sizeAxis);
994      for (int i = 0; i < sizeAxis; ++i)
995      {
996        axisList_[i] = aList[i]->getId();
997      }
998      isAxisListSet = true;
999    }
1000  }
1001
1002  /*!
1003  \brief Get list of id of domains
1004  \return id list of domains
1005  */
1006  std::vector<StdString> CGrid::getDomainList()
1007  {
1008    setDomainList();
1009    return domList_;
1010  }
1011
1012  /*!
1013  \brief Get list of id of axis
1014  \return id list of axis
1015  */
1016  std::vector<StdString> CGrid::getAxisList()
1017  {
1018    setAxisList();
1019    return axisList_;
1020  }
1021
1022  void CGrid::sendAllDomains()
1023  {
1024    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1025    int dSize = domList.size();
1026    for (int i = 0; i < dSize; ++i)
1027    {
1028      sendAddDomain(domList[i]->getId());
1029      domList[i]->sendAllAttributesToServer();
1030    }
1031  }
1032
1033  void CGrid::sendAllAxis()
1034  {
1035    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1036    int aSize = aList.size();
1037
1038    for (int i = 0; i < aSize; ++i)
1039    {
1040      sendAddAxis(aList[i]->getId());
1041      aList[i]->sendAllAttributesToServer();
1042    }
1043  }
1044
1045  void CGrid::parse(xml::CXMLNode & node)
1046  {
1047    SuperClass::parse(node);
1048
1049    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
1050    std::vector<bool> order;
1051
1052    if (node.goToChildElement())
1053    {
1054      StdString domainName("domain");
1055      StdString axisName("axis");
1056      do
1057      {
1058        if (node.getElementName() == domainName) {
1059          order.push_back(true);
1060          this->getVirtualDomainGroup()->parseChild(node);
1061        }
1062        if (node.getElementName() == axisName) {
1063          order.push_back(false);
1064          this->getVirtualAxisGroup()->parseChild(node);
1065        }
1066      } while (node.goToNextElement()) ;
1067      node.goToParentElement();
1068    }
1069
1070    if (!order.empty())
1071    {
1072      int sizeOrd = order.size();
1073      axis_domain_order.resize(sizeOrd);
1074      for (int i = 0; i < sizeOrd; ++i)
1075      {
1076        axis_domain_order(i) = order[i];
1077      }
1078    }
1079
1080    setDomainList();
1081    setAxisList();
1082   }
1083
1084} // namespace xios
Note: See TracBrowser for help on using the repository browser.