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

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

Seperating global index computation on client and server side

+) Create a class which do mapping in general manner, between client and server index global
+) Remove some redundant functions and variables
+) Add some comments to code

Test
+) On Curie. Only test_new_features.f90
+) Test passes and results are correct.
+) Need to change index from 1 to 0

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