XIOS  1.0
Xml I/O Server
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Définitions de type Énumérations Valeurs énumérées Amis Macros
grid.cpp
Aller à la documentation de ce fichier.
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 "xios_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"
17 #include "distribution_client.hpp"
18 #include "grid_transformation.hpp"
19 #include "grid_generate.hpp"
20 #include "server.hpp"
21 
22 namespace xios {
23 
25 
27  : CObjectTemplate<CGrid>(), CGridAttributes()
28  , isChecked(false), isDomainAxisChecked(false)
29  , vDomainGroup_(), domList_(), isDomListSet(false)
30  , vAxisGroup_(), axisList_(), isAxisListSet(false)
31  , vScalarGroup_(), scalarList_(), isScalarListSet(false)
32  , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
33  , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
34  , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
35  , isDataDistributed_(true), isCompressible_(false)
36  , transformations_(0), isTransformed_(false)
37  , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
38  , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
39  , computedWrittenIndex_(false)
40  , clients()
41  {
42  setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
43  setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
44  setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
45  }
46 
48  : CObjectTemplate<CGrid>(id), CGridAttributes()
49  , isChecked(false), isDomainAxisChecked(false)
50  , vDomainGroup_(), domList_(), isDomListSet(false)
51  , vAxisGroup_(), axisList_(), isAxisListSet(false)
52  , vScalarGroup_(), scalarList_(), isScalarListSet(false)
53  , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
54  , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
55  , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
56  , isDataDistributed_(true), isCompressible_(false)
57  , transformations_(0), isTransformed_(false)
58  , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
59  , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
60  , computedWrittenIndex_(false)
61  , clients()
62  {
63  setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
64  setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
65  setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
66  }
67 
69  {
72  if (0 != clientServerMap_) delete clientServerMap_;
73  if (0 != transformations_) delete transformations_;
74  }
75 
77 
78  StdString CGrid::GetName(void) { return StdString("grid"); }
80  ENodeType CGrid::GetType(void) { return eGrid; }
81 
82 
84  TRY
85  {
86  return getGlobalDimension().size();
87  }
89 
90  //---------------------------------------------------------------
91 
93  TRY
94  {
95  StdSize retvalue = 1;
96  if (!isScalarGrid())
97  {
98  std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
99  for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
100  }
101  return retvalue;
102  }
103  CATCH
104 
111  std::map<int, StdSize> CGrid::getAttributesBufferSize(CContextClient* client, bool bufferForWriting)
112  TRY
113  {
114  std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client);
115 
116  // The grid indexes require a similar size as the actual data
117  std::map<int, StdSize> dataSizes = getDataBufferSize(client, "", bufferForWriting);
118  std::map<int, StdSize>::iterator it, itE = dataSizes.end();
119  for (it = dataSizes.begin(); it != itE; ++it)
120  {
121  it->second += 2 * sizeof(bool);
122  if (it->second > attributesSizes[it->first])
123  attributesSizes[it->first] = it->second;
124  }
125 
126  // Account for the axis attributes
127  std::vector<CAxis*> axisList = getAxis();
128  for (size_t i = 0; i < axisList.size(); ++i)
129  {
130  std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]);
131  for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it)
132  {
133  it->second += 2 * sizeof(bool);
134  if (it->second > attributesSizes[it->first])
135  attributesSizes[it->first] = it->second;
136  }
137  }
138 
139  // Account for the domain attributes
140  std::vector<CDomain*> domList = getDomains();
141  for (size_t i = 0; i < domList.size(); ++i)
142  {
143  std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize(client);
144  for (it = domAttBuffSize.begin(), itE = domAttBuffSize.end(); it != itE; ++it)
145  {
146  it->second += 2 * sizeof(bool);
147  if (it->second > attributesSizes[it->first])
148  attributesSizes[it->first] = it->second;
149  }
150  }
151 
152  return attributesSizes;
153  }
155 
163  std::map<int, StdSize> CGrid::getDataBufferSize(CContextClient* client, const std::string& id /*= ""*/, bool bufferForWriting /*= "false"*/)
164  TRY
165  {
166  // The record index is sometimes sent along with the data but we always
167  // include it in the size calculation for the sake of simplicity
168  const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size()
169  + 2 * sizeof(size_t)
170  + sizeof(size_t);
171 
172  std::map<int, StdSize> dataSizes;
173  int receiverSize = client->serverSize;
174  std::map<int,size_t>& dataSizeMap = bufferForWriting ? connectedDataSize_[receiverSize]: connectedDataSizeRead_;
175  std::vector<int>& connectedServerRanks = bufferForWriting ? connectedServerRank_[receiverSize] : connectedServerRankRead_;
176 
177  std::map<int, size_t>::const_iterator itEnd = dataSizeMap.end();
178  for (size_t k = 0; k < connectedServerRanks.size(); ++k)
179  {
180  int rank = connectedServerRanks[k];
181  std::map<int, size_t>::const_iterator it = dataSizeMap.find(rank);
182  size_t count = (it != itEnd) ? it->second : 0;
183 
184  dataSizes.insert(std::make_pair(rank, extraSize + CArray<double,1>::size(count)));
185  }
186 
187  return dataSizes;
188  }
190 
192  TRY
193  {
194  std::vector<CDomain*> domainP = this->getDomains();
195  std::vector<CAxis*> axisP = this->getAxis();
196 
197  size_t globalGridSize=1 ;
198  for (std::vector<CDomain*>::iterator it=domainP.begin(); it!=domainP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ;
199  for (std::vector<CAxis*>::iterator it=axisP.begin(); it!=axisP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ;
200  return globalGridSize ;
201  }
203 
205  TRY
206  {
207  setAxisList();
208  std::vector<CAxis*> axisListP = this->getAxis();
209  if (!axisListP.empty())
210  {
211  int idx = 0;
212  axisPositionInGrid_.resize(0);
213  for (int i = 0; i < axis_domain_order.numElements(); ++i)
214  {
215  int elementDimension = axis_domain_order(i);
216  if (1 == elementDimension)
217  {
218  axisPositionInGrid_.push_back(idx);
219  ++idx;
220  }
221  else if (2 == elementDimension) idx += 2;
222  }
223 
224  for (int i = 0; i < axisListP.size(); ++i)
225  {
226  axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]);
227  }
228  }
229 
230  setDomainList();
231  std::vector<CDomain*> domListP = this->getDomains();
232  if (!domListP.empty())
233  {
234  for (int i = 0; i < domListP.size(); ++i)
235  {
236  domListP[i]->checkAttributesOnClientAfterTransformation();
237  }
238  }
239  }
241 
242  //---------------------------------------------------------------
243 
249  bool CGrid::isCompressible(void) const
250  TRY
251  {
252  return isCompressible_;
253  }
254  CATCH
255 
256  //---------------------------------------------------------------
257 
259  TRY
260  {
261  this->relFilesCompressed.insert(filename);
262  }
264 
265  bool CGrid::isWrittenCompressed(const StdString& filename) const
266  TRY
267  {
268  return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
269  }
270  CATCH
271 
272  //---------------------------------------------------------------
273  /*
274  Find all reference of grid's components and inherite attributes if necessary
275  */
276  void CGrid::solveDomainAxisRef(bool areAttributesChecked)
277  TRY
278  {
279  if (this->isDomainAxisChecked) return;
280 
281  this->solveScalarRef(areAttributesChecked);
282  this->solveAxisRef(areAttributesChecked);
283  this->solveDomainRef(areAttributesChecked);
284  this->isDomainAxisChecked = areAttributesChecked;
285  }
287 
288  /*
289  Go up hierachy reference and fill in the base reference with attributes of the children
290  This function should be only used after reading component's attributes from file
291  */
293  TRY
294  {
295  if (this->hasDomainAxisBaseRef_) return;
296  // Account for the scalar attributes
297  std::vector<CScalar*> scalarList = getScalars();
298  for (size_t i = 0; i < scalarList.size(); ++i)
299  {
300  scalarList[i]->setAttributesReference();
301  }
302 
303  // Account for the axis attributes
304  std::vector<CAxis*> axisList = getAxis();
305  for (size_t i = 0; i < axisList.size(); ++i)
306  {
307  axisList[i]->setAttributesReference();
308  }
309 
310  // Account for the domain attributes
311  std::vector<CDomain*> domList = getDomains();
312  for (size_t i = 0; i < domList.size(); ++i)
313  {
314  domList[i]->setAttributesReference();
315  }
316 
317  this->hasDomainAxisBaseRef_ = true;
318  }
320 
322  TRY
323  {
324  // We don't check if the mask is valid here, just if a mask has been defined at this point.
325  isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty();
326  }
328 
329  void CGrid::checkMaskIndex(bool doSendingIndex)
330  TRY
331  {
332  CContext* context = CContext::getCurrent();
333  int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
334  nbSrvPools = 1;
335  for (int p = 0; p < nbSrvPools; ++p)
336  {
337  if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent)
338  {
339  if (isScalarGrid())
340  sendIndexScalarGrid();
341  else
342  sendIndex();
343  this->isIndexSent = true;
344  }
345 
346  // Not sure about this
347  //if (!(this->hasTransform() && !this->isTransformed()))
348  // this->isChecked = true;
349  //return;
350  }
351 
352  if (this->isChecked) return;
353  this->checkAttributesAfterTransformation();
354 
355  // TODO: Transfer grid attributes
356  //if (!context->hasClient && context->hasServer) this->createMask();
357  this->computeIndex();
358 
359  if (!(this->hasTransform() && !this->isTransformed()))
360  this->isChecked = true;
361 
362  if (!(this->hasTransform() && (!this->isGenerated())))
363  this->isChecked = true;
364  }
366  bool CGrid::hasMask() const
367  TRY
368  {
369  return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() ||
370  !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty());
371  }
372  CATCH
373 
374  /*
375  Create mask of grid from mask of its components
376  */
377  void CGrid::createMask(void)
378  TRY
379  {
380  using namespace std;
381  std::vector<CDomain*> domainP = this->getDomains();
382  std::vector<CAxis*> axisP = this->getAxis();
383  int dim = domainP.size() * 2 + axisP.size();
384 
385  std::vector<CArray<bool,1>* > domainMasks(domainP.size());
386  for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask);
387  std::vector<CArray<bool,1>* > axisMasks(axisP.size());
388  for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
389 
390  switch (dim) {
391  case 1:
392  checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true);
393  break;
394  case 2:
395  checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true);
396  break;
397  case 3:
398  checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true);
399  break;
400  case 4:
401  checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true);
402  break;
403  case 5:
404  checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true);
405  break;
406  case 6:
407  checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true);
408  break;
409  case 7:
410  checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true);
411  break;
412  default:
413  break;
414  }
415  }
417 
418  /*
419  Check validity of grid's mask by using the masks of its components
420  */
421  void CGrid::checkMask(void)
422  TRY
423  {
424  using namespace std;
425  std::vector<CDomain*> domainP = this->getDomains();
426  std::vector<CAxis*> axisP = this->getAxis();
427  int dim = domainP.size() * 2 + axisP.size();
428 
429  std::vector<CArray<bool,1>* > domainMasks(domainP.size());
430  for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask);
431  std::vector<CArray<bool,1>* > axisMasks(axisP.size());
432  for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
433 
434  switch (dim) {
435  case 1:
436  checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order);
437  break;
438  case 2:
439  checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order);
440  break;
441  case 3:
442  checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order);
443  break;
444  case 4:
445  checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order);
446  break;
447  case 5:
448  checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order);
449  break;
450  case 6:
451  checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order);
452  break;
453  case 7:
454  checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order);
455  break;
456  default:
457  break;
458  }
459  }
461 
462  /*
463  Modify value of mask in a certain index
464  This function can be used to correct the mask of grid after being constructed with createMask
465  \param [in] indexToModify
466  \param [in] modifyValue
467  */
468  void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue)
469  TRY
470  {
471  using namespace std;
472  std::vector<CDomain*> domainP = this->getDomains();
473  std::vector<CAxis*> axisP = this->getAxis();
474  int dim = domainP.size() * 2 + axisP.size();
475 
476  switch (dim) {
477  case 0:
478  modifyGridMask(mask_0d, indexToModify, modifyValue);
479  break;
480  case 1:
481  modifyGridMask(mask_1d, indexToModify, modifyValue);
482  break;
483  case 2:
484  modifyGridMask(mask_2d, indexToModify, modifyValue);
485  break;
486  case 3:
487  modifyGridMask(mask_3d, indexToModify, modifyValue);
488  break;
489  case 4:
490  modifyGridMask(mask_4d, indexToModify, modifyValue);
491  break;
492  case 5:
493  modifyGridMask(mask_5d, indexToModify, modifyValue);
494  break;
495  case 6:
496  modifyGridMask(mask_6d, indexToModify, modifyValue);
497  break;
498  case 7:
499  modifyGridMask(mask_7d, indexToModify, modifyValue);
500  break;
501  default:
502  break;
503  }
504  }
506 
507  /*
508  Change the mask size. This function is used on reconstructing mask in server side
509  \param [in] newDimensionSize
510  \param [in] newValue
511  */
512  void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue)
513  TRY
514  {
515  std::vector<CDomain*> domainP = this->getDomains();
516  std::vector<CAxis*> axisP = this->getAxis();
517  int dim = domainP.size() * 2 + axisP.size();
518 
519  switch (dim) {
520  case 0:
521  modifyGridMaskSize(mask_0d, newDimensionSize, newValue);
522  break;
523  case 1:
524  modifyGridMaskSize(mask_1d, newDimensionSize, newValue);
525  break;
526  case 2:
527  modifyGridMaskSize(mask_2d, newDimensionSize, newValue);
528  break;
529  case 3:
530  modifyGridMaskSize(mask_3d, newDimensionSize, newValue);
531  break;
532  case 4:
533  modifyGridMaskSize(mask_4d, newDimensionSize, newValue);
534  break;
535  case 5:
536  modifyGridMaskSize(mask_5d, newDimensionSize, newValue);
537  break;
538  case 6:
539  modifyGridMaskSize(mask_6d, newDimensionSize, newValue);
540  break;
541  case 7:
542  modifyGridMaskSize(mask_7d, newDimensionSize, newValue);
543  break;
544  default:
545  break;
546  }
547  }
549 
550  //---------------------------------------------------------------
551 
552  void CGrid::solveDomainRef(bool sendAtt)
553  TRY
554  {
555  setDomainList();
556  std::vector<CDomain*> domListP = this->getDomains();
557  if (!domListP.empty())
558  {
559  for (int i = 0; i < domListP.size(); ++i)
560  {
561  if (sendAtt) domListP[i]->sendCheckedAttributes();
562  else domListP[i]->checkAttributesOnClient();
563  }
564  }
565  }
567 
568  //---------------------------------------------------------------
569 
570  void CGrid::solveAxisRef(bool sendAtt)
571  TRY
572  {
573  setAxisList();
574  std::vector<CAxis*> axisListP = this->getAxis();
575  if (!axisListP.empty())
576  {
577  int idx = 0;
578  axisPositionInGrid_.resize(0);
579  for (int i = 0; i < axis_domain_order.numElements(); ++i)
580  {
581  int elementDimension = axis_domain_order(i);
582  if (1 == elementDimension)
583  {
584  axisPositionInGrid_.push_back(idx);
585  ++idx;
586  }
587  else if (2 == elementDimension) idx += 2;
588  }
589 
590  for (int i = 0; i < axisListP.size(); ++i)
591  {
592  if (sendAtt)
593  axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]);
594  else
595  axisListP[i]->checkAttributesOnClient();
596  }
597  }
598  }
600 
601  //---------------------------------------------------------------
602 
603  void CGrid::solveScalarRef(bool sendAtt)
604  TRY
605  {
606  setScalarList();
607  std::vector<CScalar*> scalarListP = this->getScalars();
608  if (!scalarListP.empty())
609  {
610  for (int i = 0; i < scalarListP.size(); ++i)
611  {
612  /*Nothing to do for now */
613 // if (sendAtt) scalarListP[i]->sendCheckedAttributes();
614 // else scalarListP[i]->checkAttributesOnClient();
615  }
616  }
617  }
619 
624  TRY
625  {
626  if (computedWrittenIndex_) return;
627  computedWrittenIndex_ = true;
628 
629  if (isScalarGrid())
630  {
631  size_t nbWritten = 1;
632  int writtenIndex = 0;
633 
634  localIndexToWriteOnClient.resize(nbWritten);
636  localIndexToWriteOnServer(0) = writtenIndex;
637  localIndexToWriteOnClient(0) = writtenIndex;
638 
639  return;
640  }
641 
642  size_t nbWritten = 0, indGlo;
644  CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(),
645  ite = globalDataIndex.end(), it;
647  CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(),
648  itSrve = globalLocalIndex.end(), itSrv;
649  for (it = itb; it != ite; ++it)
650  {
651  indGlo = it->first;
652  if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;
653  }
654 
655  localIndexToWriteOnClient.resize(nbWritten);
657 
658  {
659  numberWrittenIndexes_ = nbWritten;
660  if (isDataDistributed_)
661  {
663  MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
664  MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
666  }
667  else
669  }
670 
671  nbWritten = 0;
672  for (it = itb; it != ite; ++it)
673  {
674  indGlo = it->first;
675  itSrv = globalLocalIndex.find(indGlo);
676  if (itSrve != itSrv)
677  {
678  localIndexToWriteOnServer(nbWritten) = itSrv->second;
679  localIndexToWriteOnClient(nbWritten) = it->second;
680  ++nbWritten;
681  }
682  }
683  }
685 
686  //---------------------------------------------------------------
687 
688  /*
689  Compute the global index and its local index taking account mask and data index.
690  These global indexes will be used to compute the connection of this client (sender) to its servers (receivers)
691  (via function computeConnectedClient)
692  These global indexes also correspond to data sent to servers (if any)
693  */
695  TRY
696  {
697  CContext* context = CContext::getCurrent();
698 
699  CContextClient* client = context->client;
700  int rank = client->clientRank;
701 
702  clientDistribution_ = new CDistributionClient(rank, this);
703  // Get local data index on client
704  int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size();
705  int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size();
706  // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise
707  storeIndex_client.resize(nbStoreIndex);
708  storeMask_client.resize(nbStoreGridMask);
709  for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
710  for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx];
711 
713  else
714  {
715  // Mapping global index received from clients to the storeIndex_client
717  CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
718  map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
719  ite = outGlobalIndexFromClient.end(), it;
720 
721  for (it = itb; it != ite; ++it)
722  {
723  int rank = it->first;
724  CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
725  outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
726  CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank];
727  size_t nbIndex = 0;
728 
729  // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance
730  for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
731  {
732  if (itGloe != globalDataIndex.find(globalIndex(idx)))
733  {
734  ++nbIndex;
735  }
736  }
737 
738  if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements()))
739  ERROR("void CGrid::computeClientIndex()",
740  << "Number of local index on client is different from number of received global index"
741  << "Rank of sent client " << rank <<"."
742  << "Number of local index " << nbIndex << ". "
743  << "Number of received global index " << localIndex.numElements() << ".");
744 
745  nbIndex = 0;
746  for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
747  {
748  if (itGloe != globalDataIndex.find(globalIndex(idx)))
749  {
750  localIndex(idx) = globalDataIndex[globalIndex(idx)];
751  }
752  }
753  }
754  }
755  }
757 
762  TRY
763  {
764  CContext* context = CContext::getCurrent();
765  int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size();
766  connectedServerRank_.clear();
767  connectedDataSize_.clear();
768  globalIndexOnServer_.clear();
769  nbSenders.clear();
770 
771  for (int p = 0; p < nbSrvPools; ++p)
772  {
773  CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p];
774  int receiverSize = client->serverSize;
775 // connectedServerRank_[client].clear();
776 
777  if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end())
778  {
779  if (!doGridHaveDataDistributed(client))
780  {
781  if (client->isServerLeader())
782  {
783  size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
784  const std::list<int>& ranks = client->getRanksServerLeader();
785  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
786  {
787  connectedServerRank_[receiverSize].push_back(*itRank);
788  connectedDataSize_[receiverSize][*itRank] = ssize;
789  }
790  }
791  return;
792  }
793 
794  // Compute mapping between client and server
795  std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
796  CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize);
797  std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
798  client->clientRank,
799  client->clientSize,
800  axis_domain_order,
802 
803  // Even if servers have no index, they must received something from client
804  // We only use several client to send "empty" message to these servers
805  std::list<int> serverZeroIndexLeader;
806  std::list<int> serverZeroIndexNotLeader;
807  CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
808  for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
809  *it = serverZeroIndex[*it];
810 
811  if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end())
812  computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]);
813 
815  CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
816  CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
817  itbGlobalMap = globalIndexOnServer_[receiverSize].begin();
818  iteGlobalMap = globalIndexOnServer_[receiverSize].end();
819 
820  for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
821  {
822  int serverRank = itGlobalMap->first;
823  int indexSize = itGlobalMap->second.size();
824  const std::vector<size_t>& indexVec = itGlobalMap->second;
825  for (int idx = 0; idx < indexSize; ++idx)
826  {
827  itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
828  if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
829  {
830  if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank))
831  connectedDataSize_[receiverSize][serverRank] = 1;
832  else
833  ++connectedDataSize_[receiverSize][serverRank];
834  }
835  }
836  }
837 
838  // Connected servers which really have index
839  for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
840  connectedServerRank_[receiverSize].push_back(itGlobalMap->first);
841  }
842 
843  // Connected servers which have no index at all
844  for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
845  connectedServerRank_[receiverSize].push_back(*it);
846 
847  // Even if a client has no index, it must connect to at least one server and
848  // send an "empty" data to this server
849  if (connectedServerRank_[receiverSize].empty())
850  connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize);
851 
852  // Now check if all servers have data to receive. If not, master client will send empty data.
853  // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
854  std::vector<int> counts (client->clientSize);
855  std::vector<int> displs (client->clientSize);
856  displs[0] = 0;
857  int localCount = connectedServerRank_[receiverSize].size() ;
858  MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
859  for (int i = 0; i < client->clientSize-1; ++i)
860  {
861  displs[i+1] = displs[i] + counts[i];
862  }
863  std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]);
864  MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
865 
866  if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0))
867  {
868  std::vector<bool> isSrvConnected (receiverSize, false);
869  for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
870  for (int i = 0; i < receiverSize; ++i)
871  {
872  if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i);
873  }
874  }
875 
876  nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
877  }
878  }
879  }
881 
890  TRY
891  {
892  CContext* context = CContext::getCurrent();
893  if (isScalarGrid())
894  {
896  if (context->hasClient)
897  {
899  }
900  }
901  else
902  {
904  if (context->hasClient)
905  {
907  }
908  }
909  if (CServer::serverLevel==2)
910  {
914  outGlobalIndexFromClient.clear() ;
915  }
916  }
918 
928  void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
929  const CContextClient* client,
930  CClientServerMapping::GlobalIndexMap& globalIndexOnServer)
931  TRY
932  {
933  int serverSize = client->serverSize;
934 
935  std::vector<CDomain*> domList = getDomains();
936  std::vector<CAxis*> axisList = getAxis();
937 
938  // Some pre-calculations of global index on each element of current grid.
939  int nbElement = axis_domain_order.numElements();
940  std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
941  int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
942  std::vector<size_t> elementNGlobal(nbElement);
943  elementNGlobal[0] = 1;
944  size_t globalSize = 1;
945  for (int idx = 0; idx < nbElement; ++idx)
946  {
947  elementNGlobal[idx] = globalSize;
948  size_t elementSize;
949  size_t elementGlobalSize = 1;
950  if (2 == axis_domain_order(idx)) // This is domain
951  {
952  elementSize = domList[domainIdx]->i_index.numElements();
953  globalIndexElement[idx].resize(elementSize);
954  for (int jdx = 0; jdx < elementSize; ++jdx)
955  {
956  globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx);
957  }
958  elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue();
959  ++domainIdx;
960  }
961  else if (1 == axis_domain_order(idx)) // This is axis
962  {
963  elementSize = axisList[axisIdx]->index.numElements();
964  globalIndexElement[idx].resize(elementSize);
965  for (int jdx = 0; jdx < elementSize; ++jdx)
966  {
967  globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx);
968  }
969  elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
970  ++axisIdx;
971  }
972  else // Of course, this is scalar
973  {
974  globalIndexElement[idx].resize(1);
975  globalIndexElement[idx](0) = 0;
976  elementGlobalSize = 1;
977  }
978  globalSize *= elementGlobalSize;
979  }
980 
981  std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false));
982  std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement);
983  CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server
984  // Number of temporary distributed global index held by each client for each server
985  // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank
986  CArray<int,1> nbIndexOnServerTmp(serverSize);
987  for (int idx = 0; idx < nbElement; ++idx)
988  {
989  nbIndexOnServer = 0;
990  const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx];
991  const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx];
992  CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm);
993  clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient);
994  const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap();
995  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(),
996  ite = globalIndexElementOnServerMap.end(), it;
997  for (it = itb; it != ite; ++it)
998  {
999  const std::vector<int>& tmp = it->second;
1000  nbIndexOnServerTmp = 0;
1001  for (int i = 0; i < tmp.size(); ++i)
1002  {
1003  if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]);
1004  }
1005  nbIndexOnServer += nbIndexOnServerTmp;
1006  }
1007 
1008  for (int i = 0; i < serverSize; ++i)
1009  {
1010  if (0 != nbIndexOnServer(i))
1011  {
1012  globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i));
1013  elementOnServer[idx][i] = true;
1014  }
1015  }
1016 
1017  nbIndexOnServer = 0;
1018  for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j)
1019  {
1020  it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j));
1021  if (it != ite)
1022  {
1023  const std::vector<int>& tmp = it->second;
1024  nbIndexOnServerTmp = 0;
1025  for (int i = 0; i < tmp.size(); ++i)
1026  {
1027  if (0 == nbIndexOnServerTmp(tmp[i]))
1028  {
1029  globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first;
1030  ++nbIndexOnServerTmp(tmp[i]);
1031  }
1032  }
1033  nbIndexOnServer += nbIndexOnServerTmp;
1034  }
1035  }
1036  }
1037 
1038  // Determine server which contain global source index
1039  std::vector<bool> intersectedProc(serverSize, true);
1040  for (int idx = 0; idx < nbElement; ++idx)
1041  {
1042  std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(),
1043  intersectedProc.begin(), intersectedProc.begin(),
1044  std::logical_and<bool>());
1045  }
1046 
1047  std::vector<int> srcRank;
1048  for (int idx = 0; idx < serverSize; ++idx)
1049  {
1050  if (intersectedProc[idx]) srcRank.push_back(idx);
1051  }
1052 
1053  // Compute the global index of grid from global index of each element.
1054  for (int i = 0; i < srcRank.size(); ++i)
1055  {
1056  size_t ssize = 1;
1057  int rankSrc = srcRank[i];
1058  std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement);
1059  std::vector<size_t> currentIndex(nbElement,0);
1060  for (int idx = 0; idx < nbElement; ++idx)
1061  {
1062  ssize *= (globalElementIndexOnServer[idx][rankSrc]).size();
1063  globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]);
1064  }
1065  globalIndexOnServer[rankSrc].resize(ssize);
1066 
1067  std::vector<int> idxLoop(nbElement,0);
1068  int innnerLoopSize = (globalIndexOfElementTmp[0])->size();
1069  size_t idx = 0;
1070  while (idx < ssize)
1071  {
1072  for (int ind = 0; ind < nbElement; ++ind)
1073  {
1074  if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size())
1075  {
1076  idxLoop[ind] = 0;
1077  ++idxLoop[ind+1];
1078  }
1079 
1080  currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]];
1081  }
1082 
1083  for (int ind = 0; ind < innnerLoopSize; ++ind)
1084  {
1085  currentIndex[0] = (*globalIndexOfElementTmp[0])[ind];
1086  size_t globalSrcIndex = 0;
1087  for (int idxElement = 0; idxElement < nbElement; ++idxElement)
1088  {
1089  globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement];
1090  }
1091  globalIndexOnServer[rankSrc][idx] = globalSrcIndex;
1092  ++idx;
1093  ++idxLoop[0];
1094  }
1095  }
1096  }
1097  }
1099 //----------------------------------------------------------------
1100 
1102  TRY
1103  {
1104  std::vector<CDomain*> vecDom(1, domain);
1105  std::vector<CAxis*> vecAxis;
1106 
1107  return createGrid(vecDom, vecAxis);
1108  }
1109  CATCH
1110 
1112  TRY
1113  {
1114  std::vector<CDomain*> vecDom(1, domain);
1115  std::vector<CAxis*> vecAxis(1, axis);
1116 
1117  return createGrid(vecDom, vecAxis);
1118  }
1119  CATCH
1120 
1121  CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1122  const CArray<int,1>& axisDomainOrder)
1123  TRY
1124  {
1125  std::vector<CScalar*> vecScalar;
1126  return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
1127  }
1128  CATCH
1129 
1130  CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1131  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1132  TRY
1133  {
1134  return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
1135  }
1136  CATCH
1137 
1138  CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1139  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1140  TRY
1141  {
1142  if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
1143  ERROR("CGrid* CGrid::createGrid(...)",
1144  << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
1145  << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
1146 
1147  CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
1148  grid->setDomainList(domains);
1149  grid->setAxisList(axis);
1150  grid->setScalarList(scalars);
1151 
1152  // By default, domains are always the first elements of a grid
1153  if (0 == axisDomainOrder.numElements())
1154  {
1155  int size = domains.size() + axis.size() + scalars.size();
1156  int nb = 0;
1157  grid->axis_domain_order.resize(size);
1158  for (int i = 0; i < size; ++i)
1159  {
1160  if (i < domains.size()) {
1161  grid->axis_domain_order(i) = 2;
1162 
1163  }
1164  else if ((scalars.size() < (size-nb)) < size) {
1165  grid->axis_domain_order(i) = 1;
1166  }
1167  else
1168  grid->axis_domain_order(i) = 0;
1169  ++nb;
1170  }
1171  }
1172  else
1173  {
1174  grid->axis_domain_order.resize(axisDomainOrder.numElements());
1175  grid->axis_domain_order = axisDomainOrder;
1176  }
1177 
1178  grid->solveDomainAxisRefInheritance(true);
1179 
1180  return grid;
1181  }
1182  CATCH
1183 
1184  CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
1185  TRY
1186  {
1187  std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
1188  std::vector<CAxis*> axisSrcTmp = gridSrc->getAxis(), axisSrc;
1189  std::vector<CScalar*> scalarSrcTmp = gridSrc->getScalars(), scalarSrc;
1190 
1191  for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
1192  {
1193  CDomain* domain = CDomain::createDomain();
1194  domain->duplicateAttributes(domainSrcTmp[idx]);
1195  domain->duplicateTransformation(domainSrcTmp[idx]);
1196  domain->solveRefInheritance(true);
1198  domainSrc.push_back(domain);
1199  }
1200 
1201  for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
1202  {
1203  CAxis* axis = CAxis::createAxis();
1204  axis->duplicateAttributes(axisSrcTmp[idx]);
1205  axis->duplicateTransformation(axisSrcTmp[idx]);
1206  axis->solveRefInheritance(true);
1208  axisSrc.push_back(axis);
1209  }
1210 
1211  for (int idx = 0; idx < scalarSrcTmp.size(); ++idx)
1212  {
1213  CScalar* scalar = CScalar::createScalar();
1214  scalar->duplicateAttributes(scalarSrcTmp[idx]);
1215  scalar->duplicateTransformation(scalarSrcTmp[idx]);
1216  scalar->solveRefInheritance(true);
1218  scalarSrc.push_back(scalar);
1219  }
1220 
1221  CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, scalarSrc, gridSrc->axis_domain_order);
1222 
1223  return grid;
1224  }
1225  CATCH
1226 
1227  StdString CGrid::generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1228  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1229  TRY
1230  {
1231  if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
1232  ERROR("CGrid* CGrid::generateId(...)",
1233  << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
1234  << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
1235 
1236  std::ostringstream id;
1237 
1238  if (domains.empty() && axis.empty() && !scalars.empty())
1239  id << "__scalar_";
1240 
1241  if (0 != (domains.size() + axis.size() + scalars.size()))
1242  {
1243  id << "__grid";
1244 
1245  if (0 == axisDomainOrder.numElements())
1246  {
1247  for (size_t i = 0; i < domains.size(); ++i) id << "_" << domains[i]->getId();
1248  for (size_t i = 0; i < axis.size(); ++i) id << "_" << axis[i]->getId();
1249  for (size_t i = 0; i < scalars.size(); ++i) id << "_" << scalars[i]->getId();
1250  }
1251  else
1252  {
1253  size_t iDomain = 0, iAxis = 0, iScalar = 0;
1254  for (size_t i = 0; i < axisDomainOrder.numElements(); ++i)
1255  {
1256  if (2 == axisDomainOrder(i))
1257  id << "_" << domains[iDomain++]->getId();
1258  else if (1 == axisDomainOrder(i))
1259  id << "_" << axis[iAxis++]->getId();
1260  else
1261  id << "_" << scalars[iScalar++]->getId();
1262  }
1263  }
1264 
1265  id << "__";
1266  }
1267 
1268  return id.str();
1269  }
1270  CATCH
1271 
1272  StdString CGrid::generateId(const CGrid* gridSrc, const CGrid* gridDest)
1273  TRY
1274  {
1275  StdString idSrc = gridSrc->getId();
1276  StdString idDest = gridDest->getId();
1277 
1278  std::ostringstream id;
1279  id << idSrc << "__" << idDest;
1280 
1281  return id.str();
1282  }
1283  CATCH
1284 
1285  //----------------------------------------------------------------
1286 
1287  CDomainGroup* CGrid::getVirtualDomainGroup() const
1288  TRY
1289  {
1290  return this->vDomainGroup_;
1291  }
1292  CATCH
1293 
1294  CAxisGroup* CGrid::getVirtualAxisGroup() const
1295  TRY
1296  {
1297  return this->vAxisGroup_;
1298  }
1299  CATCH
1300 
1301  CScalarGroup* CGrid::getVirtualScalarGroup() const
1302  TRY
1303  {
1304  return this->vScalarGroup_;
1305  }
1306  CATCH
1307 
1308 /*
1309  void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
1310  {
1311  const CArray<size_t,1>& out_i = outIndexFromClient[rank];
1312  StdSize numElements = stored.numElements();
1313  for (StdSize n = 0; n < numElements; ++n)
1314  {
1315  field[out_i(n)] = stored(n);
1316  }
1317  }
1318 
1319  void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
1320  {
1321  const CArray<size_t,1>& out_i = outIndexFromClient[rank];
1322  StdSize numElements = stored.numElements();
1323  for (StdSize n = 0; n < numElements; ++n)
1324  {
1325  stored(n) = field[out_i(n)];
1326  }
1327  }
1328 
1329  void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field)
1330  {
1331  const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank];
1332  StdSize numElements = stored.numElements();
1333  for (StdSize n = 0; n < numElements; ++n)
1334  {
1335  field[out_i(n)] = stored(n);
1336  }
1337  }
1338 */
1339  //----------------------------------------------------------------
1340 
1341  void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
1342  TRY
1343  {
1344  const StdSize size = storeIndex_client.numElements();
1345 
1346  stored.resize(size);
1347  for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
1348  }
1349  CATCH
1350 
1351  void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
1352  TRY
1353  {
1354  const StdSize size = storeIndex_client.numElements();
1355 
1356  for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
1357  }
1358  CATCH
1359 
1360  void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const
1361  {
1362  const StdSize size = storeIndex_client.numElements();
1363  stored.resize(size);
1364  const double nanValue = std::numeric_limits<double>::quiet_NaN();
1365 
1366  if (storeMask_client.numElements() != 0)
1367  for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue;
1368  else
1369  for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
1370  }
1371 
1372  void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const
1373  TRY
1374  {
1375  const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient();
1376  const int size = localMaskedDataIndex.size();
1377  for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i];
1378  }
1379  CATCH
1380 
1382  TRY
1383  {
1384  CContext* context = CContext::getCurrent();
1385  {
1386  CContextClient* client = context->client;
1387 
1388  int rank = client->clientRank;
1389 
1390  clientDistribution_ = new CDistributionClient(rank, this);
1391 
1393  storeIndex_client(0) = 0;
1394 
1395  if (0 != serverDistribution_)
1396  {
1397  map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
1398  ite = outGlobalIndexFromClient.end(), it;
1399  for (it = itb; it != ite; ++it)
1400  {
1401  int rank = it->first;
1402  CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
1403  outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
1404  CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank];
1405  if (1 != globalIndex.numElements())
1406  ERROR("void CGrid::computeClientIndexScalarGrid()",
1407  << "Something wrong happened. "
1408  << "Number of received global index on scalar grid should equal to 1"
1409  << "Number of received global index " << globalIndex.numElements() << ".");
1410 
1411  localIndex(0) = globalIndex(0);
1412  }
1413  }
1414  }
1415  }
1417 
1419  TRY
1420  {
1421  CContext* context = CContext::getCurrent();
1422  int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size();
1423  connectedServerRank_.clear();
1424  connectedDataSize_.clear();
1425  nbSenders.clear();
1426 
1427  for (int p = 0; p < nbSrvPools; ++p)
1428  {
1429  CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p];
1430  int receiverSize = client->serverSize;
1431 
1432 // connectedServerRank_[client].clear();
1433 
1434  if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end())
1435  {
1436  if (client->isServerLeader())
1437  {
1438  const std::list<int>& ranks = client->getRanksServerLeader();
1439  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1440  {
1441  int rank = *itRank;
1442  int nb = 1;
1443  connectedServerRank_[receiverSize].push_back(rank);
1444  connectedDataSize_[receiverSize][rank] = nb;
1445  nbSenders[receiverSize][rank] = nb;
1446  }
1447  }
1448  else
1449  {
1450  const std::list<int>& ranks = client->getRanksServerNotLeader();
1451  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1452  {
1453  int rank = *itRank;
1454  int nb = 1;
1455  connectedServerRank_[receiverSize].push_back(rank);
1456  connectedDataSize_[receiverSize][rank] = nb;
1457  nbSenders[receiverSize][rank] = nb;
1458  }
1459  }
1460  }
1461  isDataDistributed_ = false;
1462  }
1463  }
1465 
1467  TRY
1468  {
1469  CContext* context = CContext::getCurrent();
1470  storeIndex_toSrv.clear();
1471  std::list<CContextClient*>::iterator it;
1472 
1473  for (it=clients.begin(); it!=clients.end(); ++it)
1474  {
1475  CContextClient* client = *it;
1476  int receiverSize = client->serverSize;
1477 
1479  list<CMessage> listMsg;
1480  list<CArray<size_t,1> > listOutIndex;
1481 
1482  if (client->isServerLeader())
1483  {
1484  const std::list<int>& ranks = client->getRanksServerLeader();
1485  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1486  {
1487  int rank = *itRank;
1488  int nb = 1;
1489  storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb)));
1490  listOutIndex.push_back(CArray<size_t,1>(nb));
1491 
1492  CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank];
1493  CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1494 
1495  for (int k = 0; k < nb; ++k)
1496  {
1497  outGlobalIndexOnServer(k) = 0;
1498  outLocalIndexToServer(k) = 0;
1499  }
1500 
1501  if (context->hasClient && !context->hasServer)
1502  storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1503 
1504  listMsg.push_back(CMessage());
1505  listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
1506 
1507  event.push(rank, 1, listMsg.back());
1508  }
1509  client->sendEvent(event);
1510  }
1511  else
1512  {
1513  const std::list<int>& ranks = client->getRanksServerNotLeader();
1514  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1515  {
1516  int rank = *itRank;
1517  int nb = 1;
1518  CArray<int, 1> outLocalIndexToServer(nb);
1519  for (int k = 0; k < nb; ++k)
1520  {
1521  outLocalIndexToServer(k) = 0;
1522  }
1523 
1524  if (context->hasClient && !context->hasServer)
1525  storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1526  }
1527  client->sendEvent(event);
1528  }
1529  }
1530  }
1532 
1533  void CGrid::sendIndex(void)
1534  TRY
1535  {
1536  CContext* context = CContext::getCurrent();
1537  storeIndex_toSrv.clear();
1538  std::list<CContextClient*>::iterator it;
1539 
1540  for (it=clients.begin(); it!=clients.end(); ++it)
1541  {
1542  CContextClient* client = *it;
1543  int receiverSize = client->serverSize;
1544 
1546  int rank;
1547  list<CMessage> listMsg;
1548  list<CArray<size_t,1> > listOutIndex;
1550  CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex,
1551  iteIndex = globalLocalIndexSendToServer.end();
1552  itIndex = itbIndex;
1553 
1554  if (!doGridHaveDataDistributed(client))
1555  {
1556  if (client->isServerLeader())
1557  {
1558  int indexSize = globalLocalIndexSendToServer.size();
1559  CArray<size_t,1> outGlobalIndexOnServer(indexSize);
1560  CArray<int,1> outLocalIndexToServer(indexSize);
1561  for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1562  {
1563  outGlobalIndexOnServer(idx) = itIndex->first;
1564  outLocalIndexToServer(idx) = itIndex->second;
1565  }
1566 
1567  const std::list<int>& ranks = client->getRanksServerLeader();
1568  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1569  {
1570  storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1571  if (context->hasClient && !context->hasServer)
1572  storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1573 
1574  listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
1575 
1576  listMsg.push_back(CMessage());
1577  listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1578 
1579  event.push(*itRank, 1, listMsg.back());
1580  }
1581  client->sendEvent(event);
1582  }
1583  else
1584  {
1585  int indexSize = globalLocalIndexSendToServer.size();
1586  CArray<int,1> outLocalIndexToServer(indexSize);
1587  for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1588  {
1589  outLocalIndexToServer(idx) = itIndex->second;
1590  }
1591 
1592  const std::list<int>& ranks = client->getRanksServerNotLeader();
1593  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1594  {
1595  storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1596  }
1597  client->sendEvent(event);
1598  }
1599  }
1600  else
1601  {
1602  CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
1603  itGlobalMap = globalIndexOnServer_[receiverSize].begin();
1604  iteGlobalMap = globalIndexOnServer_[receiverSize].end();
1605 
1606  std::map<int,std::vector<int> >localIndexTmp;
1607  std::map<int,std::vector<size_t> > globalIndexTmp;
1608  for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
1609  {
1610  int serverRank = itGlobalMap->first;
1611  int indexSize = itGlobalMap->second.size();
1612  const std::vector<size_t>& indexVec = itGlobalMap->second;
1613  for (int idx = 0; idx < indexSize; ++idx)
1614  {
1615  itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
1616  if (iteIndex != itIndex)
1617  {
1618  globalIndexTmp[serverRank].push_back(itIndex->first);
1619  localIndexTmp[serverRank].push_back(itIndex->second);
1620  }
1621  }
1622  }
1623 
1624  for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns)
1625  {
1626  rank = connectedServerRank_[receiverSize][ns];
1627  int nb = 0;
1628  if (globalIndexTmp.end() != globalIndexTmp.find(rank))
1629  nb = globalIndexTmp[rank].size();
1630 
1631  storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb)));
1632  listOutIndex.push_back(CArray<size_t,1>(nb));
1633 
1634  CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank];
1635  CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1636 
1637  for (int k = 0; k < nb; ++k)
1638  {
1639  outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
1640  outLocalIndexToServer(k) = localIndexTmp[rank].at(k);
1641  }
1642 
1643  storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1644  listMsg.push_back(CMessage());
1645  listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1646 
1647  event.push(rank, nbSenders[receiverSize][rank], listMsg.back());
1648  }
1649 
1650  client->sendEvent(event);
1651  }
1652  }
1653  }
1655 
1657  TRY
1658  {
1659  string gridId;
1660  vector<int> ranks;
1661  vector<CBufferIn*> buffers;
1662 
1663  list<CEventServer::SSubEvent>::iterator it;
1664  for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1665  {
1666  ranks.push_back(it->rank);
1667  CBufferIn* buffer = it->buffer;
1668  *buffer >> gridId;
1669  buffers.push_back(buffer);
1670  }
1671  get(gridId)->recvIndex(ranks, buffers);
1672  }
1673  CATCH
1674 
1675  void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers)
1676  TRY
1677  {
1678  CContext* context = CContext::getCurrent();
1679  connectedServerRankRead_ = ranks;
1680 
1681  int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
1682  nbSrvPools = 1;
1683  nbReadSenders.clear();
1684  for (int p = 0; p < nbSrvPools; ++p)
1685  {
1686  CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p];
1687  CContextClient* client = context->client; //(!context->hasClient) ? context->client : context->clientPrimServer[p];
1688 
1689  int idx = 0, numElement = axis_domain_order.numElements();
1690  int ssize = numElement;
1691  std::vector<int> indexMap(numElement);
1692  for (int i = 0; i < numElement; ++i)
1693  {
1694  indexMap[i] = idx;
1695  if (2 == axis_domain_order(i))
1696  {
1697  ++ssize;
1698  idx += 2;
1699  }
1700  else
1701  ++idx;
1702  }
1703 
1704  for (int n = 0; n < ranks.size(); n++)
1705  {
1706  int rank = ranks[n];
1707  CBufferIn& buffer = *buffers[n];
1708 
1709  buffer >> isDataDistributed_ >> isCompressible_;
1710  size_t dataSize = 0;
1711 
1712  if (0 == serverDistribution_)
1713  {
1714  int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
1715  std::vector<CDomain*> domainList = getDomains();
1716  std::vector<CAxis*> axisList = getAxis();
1717  std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement);
1718  std::vector<CArray<int,1> > globalIndex(numElement);
1719  for (int i = 0; i < numElement; ++i)
1720  {
1721  nGlobElement[i] = globalSize;
1722  if (2 == axis_domain_order(i)) //domain
1723  {
1724  nBegin[indexMap[i]] = domainList[domainId]->ibegin;
1725  nSize[indexMap[i]] = domainList[domainId]->ni;
1726  nBeginGlobal[indexMap[i]] = 0;
1727  nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
1728 
1729  nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;
1730  nSize[indexMap[i] + 1] = domainList[domainId]->nj;
1731  nBeginGlobal[indexMap[i] + 1] = 0;
1732  nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
1733 
1734  {
1735  int count = 0;
1736  globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]);
1737  for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx)
1738  for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)
1739  {
1740  globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]];
1741  ++count;
1742  }
1743  }
1744 
1745  ++domainId;
1746  }
1747  else if (1 == axis_domain_order(i)) // axis
1748  {
1749  nBegin[indexMap[i]] = axisList[axisId]->begin;
1750  nSize[indexMap[i]] = axisList[axisId]->n;
1751  nBeginGlobal[indexMap[i]] = 0;
1752  nGlob[indexMap[i]] = axisList[axisId]->n_glo;
1753  globalIndex[i].resize(nSize[indexMap[i]]);
1754  for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)
1755  globalIndex[i](idx) = nBegin[indexMap[i]] + idx;
1756 
1757  ++axisId;
1758  }
1759  else // scalar
1760  {
1761  nBegin[indexMap[i]] = 0;
1762  nSize[indexMap[i]] = 1;
1763  nBeginGlobal[indexMap[i]] = 0;
1764  nGlob[indexMap[i]] = 1;
1765  globalIndex[i].resize(1);
1766  globalIndex[i](0) = 0;
1767  ++scalarId;
1768  }
1769  }
1770  dataSize = 1;
1771 
1772  for (int i = 0; i < nSize.size(); ++i)
1773  dataSize *= nSize[i];
1775  globalIndex, axis_domain_order,
1776  nBegin, nSize, nBeginGlobal, nGlob);
1777  }
1778 
1779  CArray<size_t,1> outIndex;
1780  buffer >> outIndex;
1781  outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex));
1782  connectedDataSizeRead_[rank] = outIndex.numElements();
1783 
1784  if (doGridHaveDataDistributed(client))
1785  {}
1786  else
1787  {
1788  // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER
1789  // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar)
1790  dataSize = serverDistribution_->getGridSize();
1791  }
1792  writtenDataSize_ += dataSize;
1793  }
1794 
1795 
1796  // Compute mask of the current grid
1797  {
1798  int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
1799  std::vector<CDomain*> domainList = getDomains();
1800  std::vector<CAxis*> axisList = getAxis();
1801  int dimSize = 2 * domainList.size() + axisList.size();
1802  std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);
1803  for (int i = 0; i < numElement; ++i)
1804  {
1805  if (2 == axis_domain_order(i)) //domain
1806  {
1807  nBegin[indexMap[i]] = domainList[domainId]->ibegin;
1808  nSize[indexMap[i]] = domainList[domainId]->ni;
1809  nBeginGlobal[indexMap[i]] = 0;
1810  nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
1811 
1812  nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;
1813  nSize[indexMap[i] + 1] = domainList[domainId]->nj;
1814  nBeginGlobal[indexMap[i] + 1] = 0;
1815  nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
1816 
1817  ++domainId;
1818  }
1819  else if (1 == axis_domain_order(i)) // axis
1820  {
1821  nBegin[indexMap[i]] = axisList[axisId]->begin;
1822  nSize[indexMap[i]] = axisList[axisId]->n;
1823  nBeginGlobal[indexMap[i]] = 0;
1824  nGlob[indexMap[i]] = axisList[axisId]->n_glo;
1825  ++axisId;
1826  }
1827  else // scalar
1828  {
1829  }
1830  }
1831 
1832  if (nSize.empty()) // Scalar grid
1833  {
1834  nBegin.push_back(0);
1835  nSize.push_back(1);
1836  nBeginGlobal.push_back(0);
1837  nGlob.push_back(1);
1838  }
1839  }
1840 
1841  if (isScalarGrid()) return;
1842 
1844  }
1845  }
1847 
1848  /*
1849  Compute on the fly the global dimension of a grid with its elements
1850  \param[in/out] globalDim global dimension of grid
1851  \param[in] domains list of its domains
1852  \param[in] axiss list of its axis
1853  \param[in] scalars list of its scalars
1854  \param[in] axisDomainOrder the order of element in a grid (e.g: scalar then axis)
1855  \return The dimension of which we do distribution (often for server)
1856  */
1857  int CGrid::computeGridGlobalDimension(std::vector<int>& globalDim,
1858  const std::vector<CDomain*> domains,
1859  const std::vector<CAxis*> axis,
1860  const std::vector<CScalar*> scalars,
1861  const CArray<int,1>& axisDomainOrder)
1862  TRY
1863  {
1864  // globalDim.resize(domains.size()*2+axis.size()+scalars.size());
1865  globalDim.resize(domains.size()*2+axis.size());
1866  int positionDimensionDistributed = 1;
1867  int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0;
1868  for (int i = 0; i < axisDomainOrder.numElements(); ++i)
1869  {
1870  if (2 == axisDomainOrder(i))
1871  {
1872  if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
1873  {
1874  positionDimensionDistributed = idx;
1875  }
1876  else
1877  {
1878  positionDimensionDistributed = idx +1;
1879  }
1880 
1881  globalDim[idx] = domains[idxDomain]->ni_glo.getValue();
1882  globalDim[idx+1] = domains[idxDomain]->nj_glo.getValue();
1883 
1884  ++idxDomain;
1885  idx += 2;
1886  }
1887  else if (1 == axisDomainOrder(i))
1888  {
1889  globalDim[idx] = axis[idxAxis]->n_glo.getValue();
1890  ++idxAxis;
1891  ++idx;
1892  }
1893  else
1894  {
1895 // globalDim[idx] = 1;
1896  ++idxScalar;
1897 // ++idx;
1898  }
1899  }
1900 
1901  return positionDimensionDistributed;
1902  }
1904 
1905  // Retrieve the global dimension of grid
1906  std::vector<int> CGrid::getGlobalDimension()
1907  TRY
1908  {
1909  std::vector<int> globalDim;
1910  computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);
1911 
1912  return globalDim;
1913  }
1915 
1916  // Retrieve dimension on which we do distribution (Very often, it should be 2nd dimension)
1918  TRY
1919  {
1920  std::vector<int> globalDim;
1921  return computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);
1922  }
1924 
1925  bool CGrid::isScalarGrid() const
1926  TRY
1927  {
1928  return (axisList_.empty() && domList_.empty());
1929  }
1930  CATCH
1931 
1938  TRY
1939  {
1940  return (0 != writtenDataSize_);
1941  }
1943 
1951  TRY
1952  {
1953  return writtenDataSize_;
1954  }
1955  CATCH
1956 
1962  TRY
1963  {
1964  return numberWrittenIndexes_;
1965  }
1966  CATCH
1967 
1973  TRY
1974  {
1976  }
1977  CATCH
1978 
1984  TRY
1985  {
1986  return offsetWrittenIndexes_;
1987  }
1988  CATCH
1989 
1991  TRY
1992  {
1993  return serverDistribution_;
1994  }
1996 
1998  TRY
1999  {
2000  return clientDistribution_;
2001  }
2003 
2005  TRY
2006  {
2007  if (isScalarGrid()) return false;
2008  else if (0 != client)
2009  {
2010  return (isDataDistributed_ || (1 != client->clientSize) || (1 != client->serverSize));
2011  }
2012  else
2013  return isDataDistributed_;
2014  }
2016 
2025  TRY
2026  {
2027 
2028  if (SuperClass::dispatchEvent(event)) return true;
2029  else
2030  {
2031  switch(event.type)
2032  {
2033  case EVENT_ID_INDEX :
2034  recvIndex(event);
2035  return true;
2036  break;
2037 
2038  case EVENT_ID_ADD_DOMAIN :
2039  recvAddDomain(event);
2040  return true;
2041  break;
2042 
2043  case EVENT_ID_ADD_AXIS :
2044  recvAddAxis(event);
2045  return true;
2046  break;
2047 
2048  case EVENT_ID_ADD_SCALAR :
2049  recvAddScalar(event);
2050  return true;
2051  break;
2052  default :
2053  ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
2054  << "Unknown Event");
2055  return false;
2056  }
2057  }
2058  }
2059  CATCH
2060 
2062 
2063  CDomain* CGrid::addDomain(const std::string& id)
2064  TRY
2065  {
2066  order_.push_back(2);
2067  axis_domain_order.resize(order_.size());
2068  for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
2069  return vDomainGroup_->createChild(id);
2070  }
2072 
2073  CAxis* CGrid::addAxis(const std::string& id)
2074  TRY
2075  {
2076  order_.push_back(1);
2077  axis_domain_order.resize(order_.size());
2078  for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
2079  return vAxisGroup_->createChild(id);
2080  }
2082 
2083  CScalar* CGrid::addScalar(const std::string& id)
2084  TRY
2085  {
2086  order_.push_back(0);
2087  axis_domain_order.resize(order_.size());
2088  for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
2089  return vScalarGroup_->createChild(id);
2090  }
2092 
2094  void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
2095  TRY
2096  {
2097  this->vDomainGroup_ = newVDomainGroup;
2098  }
2100 
2102  void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
2103  TRY
2104  {
2105  this->vAxisGroup_ = newVAxisGroup;
2106  }
2108 
2110  void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
2111  TRY
2112  {
2113  this->vScalarGroup_ = newVScalarGroup;
2114  }
2116 
2121  void CGrid::sendAddDomain(const string& id)
2122  TRY
2123  {
2124  sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN);
2125  }
2127 
2132  void CGrid::sendAddAxis(const string& id)
2133  TRY
2134  {
2135  sendAddItem(id, (int)EVENT_ID_ADD_AXIS);
2136  }
2138 
2143  void CGrid::sendAddScalar(const string& id)
2144  TRY
2145  {
2146  sendAddItem(id, (int)EVENT_ID_ADD_SCALAR);
2147  }
2149 
2155  TRY
2156  {
2157 
2158  CBufferIn* buffer = event.subEvents.begin()->buffer;
2159  string id;
2160  *buffer >> id;
2161  get(id)->recvAddDomain(*buffer);
2162  }
2163  CATCH
2164 
2170  TRY
2171  {
2172  string id;
2173  buffer >> id;
2174  addDomain(id);
2175  }
2177 
2183  TRY
2184  {
2185 
2186  CBufferIn* buffer = event.subEvents.begin()->buffer;
2187  string id;
2188  *buffer >> id;
2189  get(id)->recvAddAxis(*buffer);
2190  }
2191  CATCH
2192 
2198  TRY
2199  {
2200  string id;
2201  buffer >> id;
2202  addAxis(id);
2203  }
2205 
2211  TRY
2212  {
2213 
2214  CBufferIn* buffer = event.subEvents.begin()->buffer;
2215  string id;
2216  *buffer >> id;
2217  get(id)->recvAddScalar(*buffer);
2218  }
2219  CATCH
2220 
2226  TRY
2227  {
2228  string id;
2229  buffer >> id;
2230  addScalar(id);
2231  }
2233 
2241  TRY
2242  {
2243  CContext* context = CContext::getCurrent();
2244  unsigned int vecSize, i;
2245  std::vector<StdString>::iterator it, itE;
2246  setDomainList();
2247  it = domList_.begin(); itE = domList_.end();
2248  for (; it != itE; ++it)
2249  {
2250  CDomain* pDom = CDomain::get(*it);
2251  if (context->hasClient && !context->hasServer)
2252  {
2253  pDom->solveRefInheritance(apply);
2255  }
2256  }
2257 
2258  setAxisList();
2259  it = axisList_.begin(); itE = axisList_.end();
2260  for (; it != itE; ++it)
2261  {
2262  CAxis* pAxis = CAxis::get(*it);
2263  if (context->hasClient && !context->hasServer)
2264  {
2265  pAxis->solveRefInheritance(apply);
2267  }
2268  }
2269 
2270  setScalarList();
2271  it = scalarList_.begin(); itE = scalarList_.end();
2272  for (; it != itE; ++it)
2273  {
2274  CScalar* pScalar = CScalar::get(*it);
2275  if (context->hasClient && !context->hasServer)
2276  {
2277  pScalar->solveRefInheritance(apply);
2278  pScalar->solveInheritanceTransformation();
2279  }
2280  }
2281  }
2283 
2285  TRY
2286  {
2287  return isTransformed_;
2288  }
2290 
2292  TRY
2293  {
2294  isTransformed_ = true;
2295  }
2297 
2299  TRY
2300  {
2301  return transformations_;
2302  }
2304 
2306  TRY
2307  {
2308  if (gridSrc_.end() == gridSrc_.find(gridSrc))
2309  gridSrc_.insert(make_pair(gridSrc,make_pair(false,"")));
2310  }
2312 
2313  std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource()
2314  TRY
2315  {
2316  return gridSrc_;
2317  }
2319 
2324  void CGrid::completeGrid(CGrid* transformGridSrc)
2325  TRY
2326  {
2327  if (0 != transformGridSrc)
2328  {
2329  if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
2330  {
2331  ERROR("CGrid::completeGrid(CGrid* transformGridSrc)",
2332  << "Two grids have different number of elements. " << std::endl
2333  << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
2334  << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
2335  }
2336  }
2337 
2338  if (isGenerated()) return;
2339  setGenerated();
2340 
2341  CGridGenerate gridGenerate(this, transformGridSrc);
2342  gridGenerate.completeGrid();
2343  }
2345 
2347  TRY
2348  {
2349  return isGenerated_;
2350  }
2351  CATCH
2352 
2354  TRY
2355  {
2356  isGenerated_ = true;
2357  }
2359 
2360  void CGrid::transformGrid(CGrid* transformGridSrc)
2361  TRY
2362  {
2363  if (!transformGridSrc)
2364  ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
2365  << "Impossible to transform grid '" << getId() << "', the source grid is null.");
2366 
2367  if (isTransformed()) return;
2368  setTransformed();
2369  if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
2370  {
2371  ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
2372  << "Two grids have different number of elements. " << std::endl
2373  << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
2374  << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
2375  }
2376  else
2377  {
2378  }
2379 
2380  transformations_ = new CGridTransformation(this, transformGridSrc);
2382  if (0 < transformations_->getNbAlgo()) hasTransform_ = true;
2383 
2384  // Ok, now need to compute index of grid source
2385  transformGridSrc->checkMaskIndex(false);
2386  }
2388 
2390  TRY
2391  {
2392  if (hasTransform_) return hasTransform_;
2393 
2394  std::vector<CDomain*> domList = getDomains();
2395  std::vector<CAxis*> axisList = getAxis();
2396  std::vector<CScalar*> scalarList = getScalars();
2397 
2398  for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation();
2399  for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation();
2400  for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation();
2401 
2402  return hasTransform_;
2403  }
2405 
2410  std::vector<CDomain*> CGrid::getDomains()
2411  TRY
2412  {
2413  std::vector<CDomain*> domList;
2414  if (!domList_.empty())
2415  {
2416  for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
2417  }
2418  return domList;
2419  }
2421 
2426  std::vector<CAxis*> CGrid::getAxis()
2427  TRY
2428  {
2429  std::vector<CAxis*> aList;
2430  if (!axisList_.empty())
2431  for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
2432 
2433  return aList;
2434  }
2436 
2441  std::vector<CScalar*> CGrid::getScalars()
2442  TRY
2443  {
2444  std::vector<CScalar*> sList;
2445  if (!scalarList_.empty())
2446  for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
2447 
2448  return sList;
2449  }
2451 
2456  CDomain* CGrid::getDomain(int domainIndex)
2457  TRY
2458  {
2459  std::vector<CDomain*> domainListP = this->getDomains();
2460  if (domainListP.empty())
2461  {
2462  ERROR("CGrid::getDomain(int domainIndex)",
2463  << "No domain associated to this grid. " << std::endl
2464  << "Grid id = " << this->getId());
2465  }
2466 
2467  if (domainIndex >= domainListP.size() || (domainIndex < 0))
2468  ERROR("CGrid::getDomain(int domainIndex)",
2469  << "Domain with the index doesn't exist " << std::endl
2470  << "Grid id = " << this->getId() << std::endl
2471  << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
2472 
2473  return domainListP[domainIndex];
2474  }
2476 
2481  CAxis* CGrid::getAxis(int axisIndex)
2482  TRY
2483  {
2484  std::vector<CAxis*> axisListP = this->getAxis();
2485  if (axisListP.empty())
2486  {
2487  ERROR("CGrid::getDomain(int axisIndex)",
2488  << "No axis associated to this grid. " << std::endl
2489  << "Grid id = " << this->getId());
2490  }
2491 
2492  if (axisIndex >= axisListP.size() || (axisIndex < 0))
2493  ERROR("CGrid::getDomain(int axisIndex)",
2494  << "Domain with the index doesn't exist " << std::endl
2495  << "Grid id = " << this->getId() << std::endl
2496  << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
2497 
2498  return axisListP[axisIndex];
2499  }
2501 
2506  CScalar* CGrid::getScalar(int scalarIndex)
2507  TRY
2508  {
2509  std::vector<CScalar*> scalarListP = this->getScalars();
2510  if (scalarListP.empty())
2511  {
2512  ERROR("CGrid::getScalar(int scalarIndex)",
2513  << "No scalar associated to this grid. " << std::endl
2514  << "Grid id = " << this->getId());
2515  }
2516 
2517  if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
2518  ERROR("CGrid::getScalar(int scalarIndex)",
2519  << "Scalar with the index doesn't exist " << std::endl
2520  << "Grid id = " << this->getId() << std::endl
2521  << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
2522 
2523  return scalarListP[scalarIndex];
2524  }
2526 
2531  void CGrid::setDomainList(const std::vector<CDomain*> domains)
2532  TRY
2533  {
2534  if (isDomListSet) return;
2535  std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
2536  if (!domains.empty() && domList.empty())
2537  {
2538  for (int i = 0; i < domains.size(); ++i)
2539  this->getVirtualDomainGroup()->addChild(domains[i]);
2540  domList = this->getVirtualDomainGroup()->getAllChildren();
2541  }
2542 
2543  if (!domList.empty())
2544  {
2545  int sizeDom = domList.size();
2546  domList_.resize(sizeDom);
2547  for (int i = 0; i < sizeDom; ++i)
2548  {
2549  domList_[i] = domList[i]->getId();
2550  }
2551  isDomListSet = true;
2552  }
2553  }
2555 
2560  void CGrid::setAxisList(const std::vector<CAxis*> axis)
2561  TRY
2562  {
2563  if (isAxisListSet) return;
2564  std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
2565  if (!axis.empty() && aList.empty())
2566  {
2567  for (int i = 0; i < axis.size(); ++i)
2568  this->getVirtualAxisGroup()->addChild(axis[i]);
2569  aList = this->getVirtualAxisGroup()->getAllChildren();
2570  }
2571 
2572  if (!aList.empty())
2573  {
2574  int sizeAxis = aList.size();
2575  axisList_.resize(sizeAxis);
2576  for (int i = 0; i < sizeAxis; ++i)
2577  {
2578  axisList_[i] = aList[i]->getId();
2579  }
2580  isAxisListSet = true;
2581  }
2582  }
2584 
2589  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
2590  TRY
2591  {
2592  if (isScalarListSet) return;
2593  std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2594  if (!scalars.empty() && sList.empty())
2595  {
2596  for (int i = 0; i < scalars.size(); ++i)
2597  this->getVirtualScalarGroup()->addChild(scalars[i]);
2598  sList = this->getVirtualScalarGroup()->getAllChildren();
2599  }
2600 
2601  if (!sList.empty())
2602  {
2603  int sizeScalar = sList.size();
2604  scalarList_.resize(sizeScalar);
2605  for (int i = 0; i < sizeScalar; ++i)
2606  {
2607  scalarList_[i] = sList[i]->getId();
2608  }
2609  isScalarListSet = true;
2610  }
2611  }
2613 
2618  std::vector<StdString> CGrid::getDomainList()
2619  TRY
2620  {
2621  setDomainList();
2622  return domList_;
2623  }
2624  CATCH
2625 
2630  std::vector<StdString> CGrid::getAxisList()
2631  TRY
2632  {
2633  setAxisList();
2634  return axisList_;
2635  }
2636  CATCH
2637 
2642  std::vector<StdString> CGrid::getScalarList()
2643  TRY
2644  {
2645  setScalarList();
2646  return scalarList_;
2647  }
2648  CATCH
2649 
2654  TRY
2655  {
2656  std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
2657  int dSize = domList.size();
2658  for (int i = 0; i < dSize; ++i)
2659  {
2660  sendAddDomain(domList[i]->getId());
2661  domList[i]->sendAllAttributesToServer();
2662  }
2663  }
2665 
2670  TRY
2671  {
2672  std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
2673  int aSize = aList.size();
2674 
2675  for (int i = 0; i < aSize; ++i)
2676  {
2677  sendAddAxis(aList[i]->getId());
2678  aList[i]->sendAllAttributesToServer();
2679  }
2680  }
2682 
2687  TRY
2688  {
2689  std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2690  int sSize = sList.size();
2691 
2692  for (int i = 0; i < sSize; ++i)
2693  {
2694  sendAddScalar(sList[i]->getId());
2695  sList[i]->sendAllAttributesToServer();
2696  }
2697  }
2699 
2701  TRY
2702  {
2703  if (clientsSet.find(contextClient)==clientsSet.end())
2704  {
2705  clients.push_back(contextClient) ;
2706  clientsSet.insert(contextClient);
2707  }
2708  for (int i=0; i<this->getDomains().size(); i++)
2709  this->getDomains()[i]->setContextClient(contextClient);
2710  for (int i=0; i<this->getAxis().size(); i++)
2711  this->getAxis()[i]->setContextClient(contextClient);
2712  }
2714 
2719  TRY
2720  {
2721  SuperClass::parse(node);
2722 
2723  if (node.goToChildElement())
2724  {
2725  StdString domainName("domain");
2726  StdString axisName("axis");
2727  StdString scalarName("scalar");
2728  do
2729  {
2730  if (node.getElementName() == domainName) {
2731  order_.push_back(2);
2732  this->getVirtualDomainGroup()->parseChild(node);
2733  }
2734  if (node.getElementName() == axisName) {
2735  order_.push_back(1);
2736  this->getVirtualAxisGroup()->parseChild(node);
2737  }
2738  if (node.getElementName() == scalarName) {
2739  order_.push_back(0);
2740  this->getVirtualScalarGroup()->parseChild(node);
2741  }
2742  } while (node.goToNextElement());
2743  node.goToParentElement();
2744  }
2745 
2746  if (!order_.empty())
2747  {
2748  int sizeOrd = order_.size();
2749  axis_domain_order.resize(sizeOrd);
2750  for (int i = 0; i < sizeOrd; ++i)
2751  {
2752  axis_domain_order(i) = order_[i];
2753  }
2754  }
2755 
2756  setDomainList();
2757  setAxisList();
2758  setScalarList();
2759  }
2761 
2762 } // namespace xios
#define CATCH_DUMP_ATTR
Definition: exception.hpp:156
const std::vector< int > & getLocalMaskedDataIndexOnClient()
Return local mask index of client.
This class contains information that describe distribution of servers.
void setVirtualScalarGroup(CScalarGroup *newVScalarGroup)
Change virtual variable group to new one.
Definition: grid.cpp:2110
static const size_t headerSize
CATCH CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis *axisDestination, CAxis *axisSource, CInterpolateAxis *interpAxis order_)
CATCH CDomainAlgorithmReorder::CDomainAlgorithmReorder(CDomain *domainDestination, CDomain *domainSource, CReorderDomain *reorderDomain if)(domainDestination->type!=CDomain::type_attr::rectilinear)
void modifyGridMask(CArray< bool, N > &gridMask, const CArray< int, 1 > &indexToModify, bool valueToModify)
static void computeLeader(int clientRank, int clientSize, int serverSize, std::list< int > &rankRecvLeader, std::list< int > &rankRecvNotLeader)
void sendEvent(CEventClient &event)
In case of attached mode, the current context must be reset to context for client.
void sendAllAxis()
Send all attributes of axis from client to server.
Definition: grid.cpp:2669
size_t writtenDataSize_
Definition: grid.hpp:330
MPI_Comm intraComm
Communicator of client group.
CDomain * addDomain(const std::string &id=StdString())
Definition: grid.cpp:2063
int totalNumberWrittenIndexes_
Definition: grid.hpp:331
int numberWrittenIndexes_
Definition: grid.hpp:331
void setVirtualDomainGroup(CDomainGroup *newVDomainGroup)
Change virtual field group to a new one.
Definition: grid.cpp:2094
std::map< int, StdSize > getDataBufferSize(CContextClient *client, const std::string &id="", bool bufferForWriting=false)
Compute the minimum buffer size required to send the data.
Definition: grid.cpp:163
map< int, CArray< int, 1 > > storeIndex_fromSrv
Definition: grid.hpp:219
void checkMask(void)
Definition: grid.cpp:421
CAxisGroup * getVirtualAxisGroup() const
Definition: grid.cpp:1294
int count
Definition: tracer.cpp:26
static void recvAddScalar(CEventServer &event)
Receive a message annoucing the creation of an scalar on server side.
Definition: grid.cpp:2210
void sendAllScalars()
Send all attributes of scalars from client to server.
Definition: grid.cpp:2686
void solveDomainAxisRef(bool areAttributesChecked)
Definition: grid.cpp:276
void solveAxisRef(bool checkAtt)
Definition: grid.cpp:570
void solveInheritanceTransformation()
Go through the hierarchy to find the axis from which the transformations must be inherited.
Definition: axis.cpp:1434
static bool dispatchEvent(CEventServer &event)
CDomain * getDomain(int domainIndex)
Get domain pointer with index.
Definition: grid.cpp:2456
CArray< size_t, 1 > localIndexToWriteOnServer
Definition: grid.hpp:240
CScalarGroup * vScalarGroup_
Definition: grid.hpp:319
virtual const std::vector< int > & getLocalDataIndexOnClient()
Return local data index of client.
std::map< int, std::map< int, int > > nbSenders
Definition: grid.hpp:215
const GlobalLocalMap & getGlobalLocalIndex() const
bool isDomListSet
Definition: grid.hpp:321
std::map< int, std::vector< int > > connectedServerRank_
Definition: grid.hpp:335
static StdString GetName(void)
Accesseurs statiques ///.
Definition: grid.cpp:78
void checkEligibilityForCompressedOutput()
Traitements ///.
Definition: grid.cpp:321
void setScalarList(const std::vector< CScalar * > scalars=std::vector< CScalar * >())
Set scalar(s) of a grid from a list.
Definition: grid.cpp:2589
void sendIndexScalarGrid()
Definition: grid.cpp:1466
CGridTransformation * getTransformations()
Definition: grid.cpp:2298
std::map< CContextClient *, map< int, CArray< int, 1 > > > storeIndex_toSrv
Definition: grid.hpp:212
void sendAddItem(const string &id, int itemType)
#define TRY
Definition: exception.hpp:154
int clientSize
Size of client group.
void storeField_arr(const double *const data, CArray< double, 1 > &stored) const
Definition: grid.cpp:1341
Interface for all transformations.
bool isGenerated_
Definition: grid.hpp:352
CArray< int, 1 > & i_index
std::vector< CContextClient * > clientPrimServer
Definition: context.hpp:253
static CAxis * createAxis()
Definition: axis.cpp:261
std::set< CContextClient * > clientsSet
Definition: grid.hpp:311
StdSize getDimension(void)
Accesseurs ///.
Definition: grid.cpp:83
CContextServer * server
Concrete context server.
Definition: context.hpp:250
GlobalLocalDataMap & getGlobalLocalDataSendToServer()
Return global local data mapping of client.
void solveInheritanceTransformation()
Go through the hierarchy to find the domain from which the transformations must be inherited...
Definition: domain.cpp:3029
void computeConnectedClientsScalarGrid()
Definition: grid.cpp:1418
std::list< CContextClient * > clients
Definition: grid.hpp:310
int getGridSize() const
Get the size of grid index in server (e.x: sizeGrid *= size of each dimensiion)
std::map< int, size_t > connectedDataSizeRead_
Definition: grid.hpp:345
bool isTransformed_
Definition: grid.hpp:352
void computeGridGlobalDimension(const std::vector< CDomain * > &domains, const std::vector< CAxis * > &axis, const std::vector< CScalar * > &scalars, const CArray< int, 1 > &axisDomainOrder)
const std::list< int > & getRanksServerNotLeader(void) const
Get leading server in the group of connected server.
void completeGrid(CGrid *transformGridSrc=0)
Complete all the necessary (and lacking) attributes of a grid This function is similar to gridTransfo...
Definition: grid.cpp:2324
void addRelFileCompressed(const StdString &filename)
Definition: grid.cpp:258
void computeConnectedClients()
Compute connected receivers and indexes to be sent to these receivers.
Definition: grid.cpp:761
void modifyMask(const CArray< int, 1 > &indexToModify, bool valueToModify=false)
Definition: grid.cpp:468
This class provides the similar features like.
std::map< CContextClient *, std::map< int, int > > nbReadSenders
Definition: grid.hpp:217
void checkMaskIndex(bool doCalculateIndex)
Definition: grid.cpp:329
std::vector< int > connectedServerRankRead_
Definition: grid.hpp:342
CScalarGroup * getVirtualScalarGroup() const
Definition: grid.cpp:1301
static int serverLevel
Definition: server.hpp:35
static CGrid * cloneGrid(const StdString &idNewGrid, CGrid *gridSrc)
Definition: grid.cpp:1184
std::vector< CDomain * > getDomains()
Get the list of domain pointers.
Definition: grid.cpp:2410
void maskField_arr(const double *const data, CArray< double, 1 > &stored) const
Definition: grid.cpp:1360
std::string StdString
Definition: xios_spl.hpp:48
bool isScalarListSet
Definition: grid.hpp:321
const std::list< int > & getRanksServerLeader(void) const
Get leading server in the group of connected server.
#define xios(arg)
void duplicateTransformation(CDomain *)
Definition: domain.cpp:3016
const StdString & getId(void) const
Accesseurs ///.
Definition: object.cpp:26
std::vector< CScalar * > getScalars()
Get the list of axis pointers.
Definition: grid.cpp:2441
int getNumberWrittenIndexes() const
Returns the number of indexes written by each server.
Definition: grid.cpp:1961
Description of index distribution on server(s).
std::map< int, std::map< int, size_t > > connectedDataSize_
Definition: grid.hpp:339
GlobalLocalDataMap & getGlobalDataIndexOnClient()
bool doGridHaveDataToWrite()
Verify whether one server need to write data There are some cases on which one server has nodata to w...
Definition: grid.cpp:1937
std::vector< std::string > axisList_
Definition: grid.hpp:320
void computeWrittenIndex()
Compute the index to for write data into a file.
Definition: grid.cpp:623
CDistributionServer * serverDistribution_
Definition: grid.hpp:327
int offsetWrittenIndexes_
Definition: grid.hpp:331
void solveDomainAxisBaseRef()
Definition: grid.cpp:292
bool isCompressible_
True if and only if the data defined on the grid can be outputted in a compressed way...
Definition: grid.hpp:349
map< int, CArray< size_t, 1 > > outGlobalIndexFromClient
Definition: grid.hpp:226
void modifyMaskSize(const std::vector< int > &newDimensionSize, bool newValue=false)
Definition: grid.cpp:512
bool isWrittenCompressed(const StdString &filename) const
Definition: grid.cpp:265
virtual ~CGrid(void)
Destructeur ///.
Definition: grid.cpp:68
void solveDomainRef(bool checkAtt)
Definition: grid.cpp:552
void uncompressField_arr(const double *const data, CArray< double, 1 > &outData) const
Definition: grid.cpp:1372
std::map< int, StdSize > getAttributesBufferSize(CContextClient *client, bool bufferForWriting=false)
Compute the minimum buffer size required to send the attributes to the server(s). ...
Definition: grid.cpp:111
bool isTransformed()
Definition: grid.cpp:2284
void sendAddAxis(const std::string &id="")
Send a message to create an axis on server side.
Definition: grid.cpp:2132
CDistributionClient * getDistributionClient()
Definition: grid.cpp:1997
CAxis * addAxis(const std::string &id=StdString())
Definition: grid.cpp:2073
This class is an interface for all transformations to interact with the rest of XIOS.
StdSize getDataSize(void) const
Definition: grid.cpp:92
bool hasDomainAxisBaseRef_
Definition: grid.hpp:356
bool hasTransform()
Definition: grid.cpp:2389
CDomainGroup * getVirtualDomainGroup() const
Definition: grid.cpp:1287
std::unordered_map< int, std::vector< size_t > > GlobalIndexMap
CATCH CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar *scalarDestination, CScalar *scalarSource, CReduceScalarToScalar *algo ERROR)("CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar* scalarDestination, CScalar* scalarSource, CReduceScalarToScalar* algo)",<< "Operation must be defined."<< "Scalar source "<< scalarSource->getId()<< std::endl<< "Scalar destination "<< scalarDestination->getId())
std::vector< int > order_
Definition: grid.hpp:368
void computeClientIndex()
Definition: grid.cpp:694
A context can be both on client and on server side.
std::vector< StdString > getScalarList()
Get list of id of scalar.
Definition: grid.cpp:2642
void setTransformed()
Definition: grid.cpp:2291
bool isDataDistributed_
Definition: grid.hpp:347
void solveScalarRef(bool checkAtt)
Definition: grid.cpp:603
////////////////////// Déclarations ////////////////////// ///
void createMask(void)
Definition: grid.cpp:377
virtual void parse(xml::CXMLNode &node)
Parse a grid, for now, it contains only domain, axis and scalar.
Definition: grid.cpp:2718
std::vector< int > axisPositionInGrid_
Definition: grid.hpp:354
std::vector< CAxis * > getAxis()
Get the list of axis pointers.
Definition: grid.cpp:2426
void checkGridMask(CArray< bool, N > &gridMask, const std::vector< CArray< bool, 1 > * > &domainMasks, const std::vector< CArray< bool, 1 > * > &axisMasks, const CArray< int, 1 > &axisDomainOrder, bool createMask=false)
std::map< CGrid *, std::pair< bool, StdString > > & getTransGridSource()
Definition: grid.cpp:2313
bool isAxisListSet
Definition: grid.hpp:321
size_t getWrittenDataSize() const
Return size of data which is written on each server Whatever dimension of a grid, data which are writ...
Definition: grid.cpp:1950
////////////////////// Déclarations ////////////////////// ///
Definition: array.hpp:25
bool hasTransform_
Definition: grid.hpp:358
void sendAddScalar(const std::string &id="")
Send a message to create a scalar on server side.
Definition: grid.cpp:2143
std::size_t StdSize
Definition: xios_spl.hpp:49
int getTotalNumberWrittenIndexes() const
Returns the total number of indexes written by the servers.
Definition: grid.cpp:1972
map< int, CArray< size_t, 1 > > outLocalIndexStoreOnClient
Definition: grid.hpp:235
int clientRank
Rank of current client.
std::vector< int > getGlobalDimension()
Definition: grid.cpp:1906
CArray< size_t, 1 > localIndexToWriteOnClient
Definition: grid.hpp:245
void modifyGridMaskSize(CArray< bool, N > &gridMask, const std::vector< int > &eachDimSize, bool newValue)
CScalar * getScalar(int scalarIndex)
Get the a scalar pointer.
Definition: grid.cpp:2506
bool hasMask(void) const
Definition: grid.cpp:366
static bool dispatchEvent(CEventServer &event)
Dispatch event received from client Whenever a message is received in buffer of server, it will be processed depending on its event type.
Definition: grid.cpp:2024
std::vector< CContextServer * > serverPrimServer
Definition: context.hpp:252
void computeClientIndexScalarGrid()
Definition: grid.cpp:1381
bool isGenerated()
Definition: grid.cpp:2346
std::vector< std::string > scalarList_
Definition: grid.hpp:320
int serverSize
Size of server group.
static void recvAddDomain(CEventServer &event)
Receive a message annoucing the creation of a domain on server side.
Definition: grid.cpp:2154
CGridTransformation * transformations_
Definition: grid.hpp:355
CClientServerMapping * clientServerMap_
Definition: grid.hpp:329
virtual void parse(xml::CXMLNode &node)
int getDistributedDimension()
Definition: grid.cpp:1917
void solveDomainAxisRefInheritance(bool apply=true)
Solve domain and axis references As field, domain and axis can refer to other domains or axis...
Definition: grid.cpp:2240
void solveInheritanceTransformation()
Go through the hierarchy to find the scalar from which the transformations must be inherited...
Definition: scalar.cpp:131
CDistributionClient * clientDistribution_
Definition: grid.hpp:324
void checkAttributesAfterTransformation()
Definition: grid.cpp:204
bool computedWrittenIndex_
Definition: grid.hpp:353
static CGrid * createGrid(CDomain *domain)
Instanciateurs Statiques ///.
Definition: grid.cpp:1101
void sendAddDomain(const std::string &id="")
Send a message to create a domain on server side.
Definition: grid.cpp:2121
CArray< bool, 1 > storeMask_client
Definition: grid.hpp:209
std::unordered_map< size_t, std::vector< InfoType > > Index2VectorInfoTypeMap
static StdString GetDefName(void)
Definition: grid.cpp:79
void resize(int extent)
Definition: array_new.hpp:320
bool isCompressible(void) const
Tests ///.
Definition: grid.cpp:249
CArray< int, 1 > storeIndex_client
Definition: grid.hpp:208
CAxisGroup * vAxisGroup_
Definition: grid.hpp:318
void duplicateTransformation(CScalar *)
Definition: scalar.cpp:120
Index distribution on client side.
std::map< CGrid *, std::pair< bool, StdString > > gridSrc_
Definition: grid.hpp:357
static StdString generateId(const std::vector< CDomain * > &domains, const std::vector< CAxis * > &axis, const std::vector< CScalar * > &scalars, const CArray< int, 1 > &axisDomainOrder=CArray< int, 1 >())
Definition: grid.cpp:1227
void transformGrid(CGrid *transformGridSrc)
Definition: grid.cpp:2360
void computeAll(const std::vector< CArray< double, 1 > * > &dataAuxInput=std::vector< CArray< double, 1 > * >(), Time timeStamp=0)
Perform all transformations For each transformation, there are some things to do: -) Chose the correc...
enum xios::_node_type ENodeType
////////////////////// Définitions ////////////////////// ///
void setVirtualAxisGroup(CAxisGroup *newVAxisGroup)
Change virtual variable group to new one.
Definition: grid.cpp:2102
std::unordered_map< size_t, int > GlobalLocalMap
void setContextClient(CContextClient *contextClient)
Definition: grid.cpp:2700
static void recvAddAxis(CEventServer &event)
Receive a message annoucing the creation of an axis on server side.
Definition: grid.cpp:2182
CDomainGroup * vDomainGroup_
Definition: grid.hpp:317
A special transformation to generate a grid.
This class bases on the knowledge of distribution on client side (decided by users) to calculate the ...
CGrid(void)
Constructeurs ///.
Definition: grid.cpp:26
void setGenerated()
Definition: grid.cpp:2353
void addTransGridSource(CGrid *gridSrc)
Definition: grid.cpp:2305
void sendIndex(void)
Definition: grid.cpp:1533
void setDomainList(const std::vector< CDomain * > domains=std::vector< CDomain * >())
Set domain(s) of a grid from a list.
Definition: grid.cpp:2531
static ENodeType GetType(void)
Definition: grid.cpp:80
std::vector< int > getDataNIndex()
bool doGridHaveDataDistributed(CContextClient *client=0)
Definition: grid.cpp:2004
static std::map< int, int > computeConnectedClients(int nbServer, int nbClient, MPI_Comm &clientIntraComm, const std::vector< int > &connectedServerRank)
Compute how many clients each server will receive data from On client can send data to several server...
CDistributionServer * getDistributionServer()
Definition: grid.cpp:1990
const Index2VectorInfoTypeMap & getInfoIndexMap() const
void computeIndexByElement(const std::vector< std::unordered_map< size_t, std::vector< int > > > &indexServerOnElement, const CContextClient *client, CClientServerMapping::GlobalIndexMap &globalIndexOnServer)
Compute the global of (client) grid to send to server with the global index of each element of grid E...
Definition: grid.cpp:928
void computeIndex(void)
Compute the global index of grid to send to server as well as the connected server of the current cli...
Definition: grid.cpp:889
int getOffsetWrittenIndexes() const
Returns the offset of indexes written by each server.
Definition: grid.cpp:1983
CDistribution::GlobalLocalMap GlobalLocalDataMap
#define CATCH
Definition: exception.hpp:155
std::vector< int > computeServerGlobalByElement(std::vector< std::unordered_map< size_t, std::vector< int > > > &indexServerOnElement, int rank, int clientSize, const CArray< int, 1 > &axisDomainOrder, int positionDimensionDistributed=1)
Compute the global index of grid elements (domain, axis) and their associated server rank...
std::vector< StdString > getAxisList()
Get list of id of axis.
Definition: grid.cpp:2630
StdString id
Propriétés ///.
Definition: object.hpp:51
ENodeType getType(void) const
Accesseurs ///.
void computeIndexInfoMapping(const CArray< size_t, 1 > &indices)
Compute mapping between indices and information corresponding to these indices.
This class creates a grid from scratch, e.g: only global dimension of grid and its type are provided...
void duplicateAttributes(const CAttributeMap *const _parent)
Duplicate attribute map with a specific attribute map.
static CScalar * createScalar()
Definition: scalar.cpp:43
void sendAllDomains()
Send all attributes of domains from client to server.
Definition: grid.cpp:2653
const std::vector< bool > & getLocalMaskIndexOnClient()
Return local mask index of client.
The class, for now, plays a role of computing local index for writing data on server.
void restoreField_arr(const CArray< double, 1 > &stored, double *const data) const
Definition: grid.cpp:1351
std::vector< StdString > getDomainList()
Get list of id of domains.
Definition: grid.cpp:2618
std::map< int, CClientServerMapping::GlobalIndexMap > globalIndexOnServer_
Definition: grid.hpp:364
void setAxisList(const std::vector< CAxis * > axis=std::vector< CAxis * >())
Set axis(s) of a grid from a list.
Definition: grid.cpp:2560
bool isScalarGrid() const
Definition: grid.cpp:1925
static CContext * getCurrent(void)
Get current context.
Definition: context.cpp:2018
CContextClient * client
Concrete contex client.
Definition: context.hpp:251
bool isServerLeader(void) const
Check if client connects to leading server.
void duplicateTransformation(CAxis *)
Definition: axis.cpp:1421
static CDomain * createDomain()
Definition: domain.cpp:66
CScalar * addScalar(const std::string &id=StdString())
Definition: grid.cpp:2083
size_t getGlobalWrittenSize(void)
Definition: grid.cpp:191
static void recvIndex(CEventServer &event)
Definition: grid.cpp:1656
std::vector< std::string > domList_
Definition: grid.hpp:320