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

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

Doing some cleans and improving a little bit performance of creating local index on server

+) Add some comments, add some initialization
+) Change the way to calculate local index on server

Test
+) On Curie

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