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
axis.cpp
Aller à la documentation de ce fichier.
1 #include "axis.hpp"
2 
3 #include "attribute_template.hpp"
4 #include "object_template.hpp"
5 #include "group_template.hpp"
6 #include "message.hpp"
7 #include "type.hpp"
8 #include "context.hpp"
9 #include "context_client.hpp"
10 #include "context_server.hpp"
11 #include "xios_spl.hpp"
14 #include "distribution_client.hpp"
15 
16 namespace xios {
17 
19 
22  , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
23  , isClientAfterTransformationChecked(false)
24  , hasBounds(false), isCompressible_(false)
25  , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_()
26  , transformationMap_(), hasValue(false), hasLabel(false)
27  , computedWrittenIndex_(false)
28  , clients()
29  {
30  }
31 
32  CAxis::CAxis(const StdString & id)
33  : CObjectTemplate<CAxis>(id)
34  , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false)
35  , isClientAfterTransformationChecked(false)
36  , hasBounds(false), isCompressible_(false)
37  , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_()
38  , transformationMap_(), hasValue(false), hasLabel(false)
39  , computedWrittenIndex_(false)
40  , clients()
41  {
42  }
43 
45  { /* Ne rien faire de plus */ }
46 
47  std::map<StdString, ETranformationType> CAxis::transformationMapList_ = std::map<StdString, ETranformationType>();
49  bool CAxis::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
50  TRY
51  {
52  m["zoom_axis"] = TRANS_ZOOM_AXIS;
53  m["interpolate_axis"] = TRANS_INTERPOLATE_AXIS;
54  m["extract_axis"] = TRANS_EXTRACT_AXIS;
55  m["inverse_axis"] = TRANS_INVERSE_AXIS;
56  m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS;
57  m["reduce_axis"] = TRANS_REDUCE_AXIS_TO_AXIS;
58  m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS;
59  m["temporal_splitting"] = TRANS_TEMPORAL_SPLITTING;
60  m["duplicate_scalar"] = TRANS_DUPLICATE_SCALAR_TO_AXIS;
61 
62  }
63  CATCH
64 
66 
67  const std::set<StdString> & CAxis::getRelFiles(void) const
68  TRY
69  {
70  return (this->relFiles);
71  }
72  CATCH
73 
74  bool CAxis::IsWritten(const StdString & filename) const
75  TRY
76  {
77  return (this->relFiles.find(filename) != this->relFiles.end());
78  }
79  CATCH
80 
81  bool CAxis::isWrittenCompressed(const StdString& filename) const
82  TRY
83  {
84  return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
85  }
86  CATCH
87 
88  bool CAxis::isDistributed(void) const
89  TRY
90  {
91  bool distributed = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) ||
92  (!this->n.isEmpty() && (this->n != this->n_glo));
93  // A condition to make sure that if there is only one client, axis
94  // should be considered to be distributed. This should be a temporary solution
95  distributed |= (1 == CContext::getCurrent()->client->clientSize);
96  return distributed;
97  }
98  CATCH
99 
105  bool CAxis::isCompressible(void) const
106  TRY
107  {
108  return isCompressible_;
109  }
110  CATCH
111 
112  void CAxis::addRelFile(const StdString & filename)
113  TRY
114  {
115  this->relFiles.insert(filename);
116  }
118 
120  TRY
121  {
122  this->relFilesCompressed.insert(filename);
123  }
125 
126  //----------------------------------------------------------------
127 
132  int CAxis::getNumberWrittenIndexes(MPI_Comm writtenCom)
133  TRY
134  {
135  int writtenSize;
136  MPI_Comm_size(writtenCom, &writtenSize);
137  return numberWrittenIndexes_[writtenSize];
138  }
140 
145  int CAxis::getTotalNumberWrittenIndexes(MPI_Comm writtenCom)
146  TRY
147  {
148  int writtenSize;
149  MPI_Comm_size(writtenCom, &writtenSize);
150  return totalNumberWrittenIndexes_[writtenSize];
151  }
153 
158  int CAxis::getOffsetWrittenIndexes(MPI_Comm writtenCom)
159  TRY
160  {
161  int writtenSize;
162  MPI_Comm_size(writtenCom, &writtenSize);
163  return offsetWrittenIndexes_[writtenSize];
164  }
166 
168  TRY
169  {
170  int writtenSize;
171  MPI_Comm_size(writtenCom, &writtenSize);
172  return compressedIndexToWriteOnServer[writtenSize];
173  }
175 
176  //----------------------------------------------------------------
177 
183  std::map<int, StdSize> CAxis::getAttributesBufferSize(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid,
185  TRY
186  {
187 
188  std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client);
189 
190 // bool isNonDistributed = (n_glo == n);
191  bool isDistributed = (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType))
192  || (index.numElements() != n_glo);
193 
194  if (client->isServerLeader())
195  {
196  // size estimation for sendServerAttribut
197  size_t size = 6 * sizeof(size_t);
198  // size estimation for sendNonDistributedValue
199  if (!isDistributed)
200  {
201 // size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0));
202  size += CArray<int,1>::size(n_glo);
203  size += CArray<int,1>::size(n_glo);
204  size += CArray<bool,1>::size(n_glo);
205  size += CArray<double,1>::size(n_glo);
206  if (hasBounds)
207  size += CArray<double,2>::size(2*n_glo);
208  if (hasLabel)
209  size += CArray<StdString,1>::size(n_glo);
210  }
211  size += CEventClient::headerSize + getId().size() + sizeof(size_t);
212 
213  const std::list<int>& ranks = client->getRanksServerLeader();
214  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
215  {
216  if (size > attributesSizes[*itRank])
217  attributesSizes[*itRank] = size;
218  }
219  const std::list<int>& ranksNonLeaders = client->getRanksServerNotLeader();
220  for (std::list<int>::const_iterator itRank = ranksNonLeaders.begin(), itRankEnd = ranksNonLeaders.end(); itRank != itRankEnd; ++itRank)
221  {
222  if (size > attributesSizes[*itRank])
223  attributesSizes[*itRank] = size;
224  }
225 
226  }
227 
228  if (isDistributed)
229  {
230  // size estimation for sendDistributedValue
231  std::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_[client->serverSize].end();
232  for (it = indSrv_[client->serverSize].begin(); it != ite; ++it)
233  {
234  size_t size = 6 * sizeof(size_t);
235  size += CArray<int,1>::size(it->second.size());
236  size += CArray<int,1>::size(it->second.size());
237  size += CArray<bool,1>::size(it->second.size());
238  size += CArray<double,1>::size(it->second.size());
239  if (hasBounds)
240  size += CArray<double,2>::size(2 * it->second.size());
241  if (hasLabel)
242  size += CArray<StdString,1>::size(it->second.size());
243 
244  size += CEventClient::headerSize + getId().size() + sizeof(size_t);
245  if (size > attributesSizes[it->first])
246  attributesSizes[it->first] = size;
247  }
248  }
249  return attributesSizes;
250  }
252 
253  //----------------------------------------------------------------
254 
255  StdString CAxis::GetName(void) { return (StdString("axis")); }
257  ENodeType CAxis::GetType(void) { return (eAxis); }
258 
259  //----------------------------------------------------------------
260 
262  TRY
263  {
264  CAxis* axis = CAxisGroup::get("axis_definition")->createChild();
265  return axis;
266  }
267  CATCH
268 
274  TRY
275  {
276  CContext* context=CContext::getCurrent();
277 
278  if (this->n_glo.isEmpty())
279  ERROR("CAxis::checkAttributes(void)",
280  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
281  << "The axis is wrongly defined, attribute 'n_glo' must be specified");
282  StdSize size = this->n_glo.getValue();
283 
284  if (!this->index.isEmpty())
285  {
286  if (n.isEmpty()) n = index.numElements();
287 
288  // It's not so correct but if begin is not the first value of index
289  // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
290  if (begin.isEmpty()) begin = index(0);
291  }
292  else
293  {
294  if (!this->begin.isEmpty())
295  {
296  if (begin < 0 || begin > size - 1)
297  ERROR("CAxis::checkAttributes(void)",
298  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
299  << "The axis is wrongly defined, attribute 'begin' (" << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").");
300  }
301  else this->begin.setValue(0);
302 
303  if (!this->n.isEmpty())
304  {
305  if (n < 0 || n > size)
306  ERROR("CAxis::checkAttributes(void)",
307  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
308  << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" << size << ").");
309  }
310  else this->n.setValue(size);
311 
312  {
313  index.resize(n);
314  for (int i = 0; i < n; ++i) index(i) = i+begin;
315  }
316  }
317 
318  if (!this->value.isEmpty())
319  {
320  // Avoid this check at writing because it fails in case of a hole
321  if (context->hasClient)
322  {
323  StdSize true_size = value.numElements();
324  if (this->n.getValue() != true_size)
325  ERROR("CAxis::checkAttributes(void)",
326  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
327  << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
328  << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
329  }
330  this->hasValue = true;
331  }
332 
333  this->checkBounds();
334 
335  if (context->hasClient)
336  {
337  this->checkMask();
338  this->checkData();
339  this->checkLabel();
340  }
341  }
343 
348  TRY
349  {
350  if (data_begin.isEmpty()) data_begin.setValue(0);
351 
352  if (data_n.isEmpty())
353  {
354  data_n.setValue(n);
355  }
356  else if (data_n.getValue() < 0)
357  {
358  ERROR("CAxis::checkData(void)",
359  << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
360  << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").");
361  }
362 
363  if (data_index.isEmpty())
364  {
365  data_index.resize(data_n);
366  for (int i = 0; i < data_n; ++i)
367  {
368  if ((i+data_begin) >= 0 && (i+data_begin<n))
369  {
370  if (mask(i+data_begin))
371  data_index(i) = i+data_begin;
372  else
373  data_index(i) = -1;
374  }
375  else
376  data_index(i) = -1;
377  }
378  }
379  else
380  {
381  if (data_index.numElements() != data_n)
382  {
383  ERROR("CAxis::checkData(void)",
384  << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
385  << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ").");
386  }
387  for (int i = 0; i < data_n; ++i)
388  {
389  if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin))
390  data_index(i) = -1;
391  }
392  }
393 
394  }
396 
398  {
399  return n_glo ;
400  }
401 
406  TRY
407  {
408  if (!mask.isEmpty())
409  {
410  if (mask.extent(0) != n)
411  {
412  ERROR("CAxis::checkMask(void)",
413  << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
414  << "The mask does not have the same size as the local domain." << std::endl
415  << "Local size is " << n.getValue() << "." << std::endl
416  << "Mask size is " << mask.extent(0) << ".");
417  }
418  }
419  else
420  {
421  mask.resize(n);
422  mask = true;
423  }
424  }
426 
431  TRY
432  {
433  if (!bounds.isEmpty())
434  {
435  if (bounds.extent(0) != 2 || bounds.extent(1) != n)
436  ERROR("CAxis::checkAttributes(void)",
437  << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
438  << "Axis size is " << n.getValue() << "." << std::endl
439  << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".");
440  hasBounds = true;
441  }
442  else hasBounds = false;
443  }
445 
447  TRY
448  {
449  if (!label.isEmpty())
450  {
451  if (label.extent(0) != n)
452  ERROR("CAxis::checkLabel(void)",
453  << "The label array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension of axis size." << std::endl
454  << "Axis size is " << n.getValue() << "." << std::endl
455  << "label size is "<< label.extent(0)<< " .");
456  hasLabel = true;
457  }
458  else hasLabel = false;
459  }
461 
466  TRY
467  {
468  // We don't check if the mask is valid here, just if a mask has been defined at this point.
469  isCompressible_ = !mask.isEmpty();
470  }
472 
477  TRY
478  {
479  if (SuperClass::dispatchEvent(event)) return true;
480  else
481  {
482  switch(event.type)
483  {
484  case EVENT_ID_DISTRIBUTION_ATTRIBUTE :
485  recvDistributionAttribute(event);
486  return true;
487  break;
488  case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES:
489  recvNonDistributedAttributes(event);
490  return true;
491  break;
492  case EVENT_ID_DISTRIBUTED_ATTRIBUTES:
493  recvDistributedAttributes(event);
494  return true;
495  break;
496  default :
497  ERROR("bool CAxis::dispatchEvent(CEventServer& event)",
498  << "Unknown Event");
499  return false;
500  }
501  }
502  }
503  CATCH
504 
509  TRY
510  {
511  if (this->areClientAttributesChecked_) return;
512 
513  CContext* context=CContext::getCurrent();
514  if (context->hasClient && !context->hasServer) this->checkAttributes();
515 
516  this->areClientAttributesChecked_ = true;
517  }
519 
520  /*
521  The (spatial) transformation sometimes can change attributes of an axis (e.g zoom can change mask or generate can change whole attributes)
522  Therefore, we should recheck them.
523  */
524  void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
526  TRY
527  {
528  CContext* context=CContext::getCurrent() ;
529 
530  if (this->isClientAfterTransformationChecked) return;
531  if (context->hasClient)
532  {
533  if (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType))
534  computeConnectedClients(globalDim, orderPositionInGrid, distType);
535  else if (index.numElements() != n_glo) computeConnectedClients(globalDim, orderPositionInGrid, CServerDistributionDescription::ROOT_DISTRIBUTION);
536  }
537 
538  this->isClientAfterTransformationChecked = true;
539  }
541 
542  /*
543  Send all checked attributes to server? (We dont have notion of server any more so client==server)
544  \param [in] globalDim global dimension of grid containing this axis
545  \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2)
546  \param [in] distType distribution type of the server. For now, we only have band distribution.
547 
548  */
549  void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
551  TRY
552  {
553  if (!this->areClientAttributesChecked_) checkAttributesOnClient();
554  if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(globalDim, orderPositionInGrid, distType);
555  CContext* context = CContext::getCurrent();
556 
557  if (this->isChecked) return;
558  if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType);
559 
560  this->isChecked = true;
561  }
563 
569  void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
571  TRY
572  {
573  sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
574 
575  // if (index.numElements() == n_glo.getValue())
576  if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType))
577  || (index.numElements() != n_glo))
578  {
579  sendDistributedAttributes();
580  }
581  else
582  {
583  sendNonDistributedAttributes();
584  }
585  }
587 
588  /*
589  Compute the connection between group of clients (or clients/servers).
590  (E.g: Suppose we have 2 group of clients in two model: A (client role) connect to B (server role),
591  this function calculate number of clients B connect to one client of A)
592  \param [in] globalDim global dimension of grid containing this axis
593  \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2)
594  \param [in] distType distribution type of the server. For now, we only have band distribution.
595  */
596  void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid,
598  TRY
599  {
600  CContext* context = CContext::getCurrent();
601 
602  int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
603 
604  connectedServerRank_.clear();
605  nbSenders.clear();
606 
607  for (int p = 0; p < nbSrvPools; ++p)
608  {
609  CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
610  int nbServer = client->serverSize;
611  int range, clientSize = client->clientSize;
612  int rank = client->clientRank;
613 
614  if (connectedServerRank_.find(nbServer) == connectedServerRank_.end())
615  {
616  size_t ni = this->n.getValue();
617  size_t ibegin = this->begin.getValue();
618  size_t nbIndex = index.numElements();
619 
620  // First of all, we should compute the mapping of the global index and local index of the current client
621  if (globalLocalIndexMap_.empty())
622  {
623  for (size_t idx = 0; idx < nbIndex; ++idx)
624  {
625  globalLocalIndexMap_[index(idx)] = idx;
626  }
627  }
628 
629  // Calculate the compressed index if any
630 // std::set<int> writtenInd;
631 // if (isCompressible_)
632 // {
633 // for (int idx = 0; idx < data_index.numElements(); ++idx)
634 // {
635 // int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
636 //
637 // if (ind >= 0 && ind < ni && mask(ind))
638 // {
639 // ind += ibegin;
640 // writtenInd.insert(ind);
641 // }
642 // }
643 // }
644 
645  // Compute the global index of the current client (process) hold
646  std::vector<int> nGlobAxis(1);
647  nGlobAxis[0] = n_glo.getValue();
648 
649  size_t globalSizeIndex = 1, indexBegin, indexEnd;
650  for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
651  indexBegin = 0;
652  if (globalSizeIndex <= clientSize)
653  {
654  indexBegin = rank%globalSizeIndex;
655  indexEnd = indexBegin;
656  }
657  else
658  {
659  for (int i = 0; i < clientSize; ++i)
660  {
661  range = globalSizeIndex / clientSize;
662  if (i < (globalSizeIndex%clientSize)) ++range;
663  if (i == client->clientRank) break;
664  indexBegin += range;
665  }
666  indexEnd = indexBegin + range - 1;
667  }
668 
669  CArray<size_t,1> globalIndex(index.numElements());
670  for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
671  globalIndex(idx) = index(idx);
672 
673  // Describe the distribution of server side
674 
675  CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType);
676 
677  std::vector<int> serverZeroIndex;
678  serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0);
679 
680  std::list<int> serverZeroIndexLeader;
681  std::list<int> serverZeroIndexNotLeader;
682  CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
683  for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
684  *it = serverZeroIndex[*it];
685 
686  // Find out the connection between client and server side
687  CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
688  clientServerMap->computeServerIndexMapping(globalIndex, nbServer);
689  CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
690 
691  indSrv_[nbServer].swap(globalIndexAxisOnServer);
692 
694  {
695  for(int i=1; i<nbServer; ++i) indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ;
696  serverZeroIndexLeader.clear() ;
697  }
698 
699  CClientServerMapping::GlobalIndexMap::const_iterator it = indSrv_[nbServer].begin(),
700  ite = indSrv_[nbServer].end();
701 
702  for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first);
703 
704  for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
705  connectedServerRank_[nbServer].push_back(*it);
706 
707  // Even if a client has no index, it must connect to at least one server and
708  // send an "empty" data to this server
709  if (connectedServerRank_[nbServer].empty())
710  connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
711 
712  nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
713 
714  delete clientServerMap;
715  }
716  }
717  }
719 
720  /*
721  Compute the index of data to write into file
722  (Different from the previous version, this version of XIOS allows data be written into file (classical role),
723  or transfered to another clients)
724  */
726  TRY
727  {
728  if (computedWrittenIndex_) return;
729  computedWrittenIndex_ = true;
730 
731  CContext* context=CContext::getCurrent();
732  CContextServer* server = context->server;
733 
734  // We describe the distribution of client (server) on which data are written
735  std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1);
736  nBegin[0] = begin;
737  nSize[0] = n;
738  nBeginGlobal[0] = 0;
739  nGlob[0] = n_glo;
740  CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);
741  const CArray<size_t,1>& writtenGlobalIndex = srvDist.getGlobalIndex();
742 
743  // Because all written data are local on a client,
744  // we need to compute the local index on the server from its corresponding global index
745  size_t nbWritten = 0, indGlo;
746  std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
747  ite = globalLocalIndexMap_.end(), it;
748  CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
749  itSrve = writtenGlobalIndex.end(), itSrv;
750 
751  localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
752  nbWritten = 0;
753  for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
754  {
755  indGlo = *itSrv;
756  if (ite != globalLocalIndexMap_.find(indGlo))
757  {
758  localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
759  }
760  else
761  {
762  localIndexToWriteOnServer(nbWritten) = -1;
763  }
764  ++nbWritten;
765  }
766 
767  }
769 
770  void CAxis::computeWrittenCompressedIndex(MPI_Comm writtenComm)
771  TRY
772  {
773  int writtenCommSize;
774  MPI_Comm_size(writtenComm, &writtenCommSize);
775  if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end())
776  return;
777 
778  if (isCompressible())
779  {
780  size_t nbWritten = 0, indGlo;
781  CContext* context=CContext::getCurrent();
782  CContextServer* server = context->server;
783 
784  // We describe the distribution of client (server) on which data are written
785  std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1);
786  nBegin[0] = 0;
787  nSize[0] = n;
788  nBeginGlobal[0] = 0;
789  nGlob[0] = n_glo;
790  CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);
791  const CArray<size_t,1>& writtenGlobalIndex = srvDist.getGlobalIndex();
792  std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
793  ite = globalLocalIndexMap_.end(), it;
794 
795  CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
796  itSrve = writtenGlobalIndex.end(), itSrv;
797  std::unordered_map<size_t,size_t> localGlobalIndexMap;
798  for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
799  {
800  indGlo = *itSrv;
801  if (ite != globalLocalIndexMap_.find(indGlo))
802  {
803  localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
804  ++nbWritten;
805  }
806  }
807 //
808 // nbWritten = 0;
809 // for (int idx = 0; idx < data_index.numElements(); ++idx)
810 // {
811 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
812 // {
813 // ++nbWritten;
814 // }
815 // }
816 //
817 // compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten);
818 // nbWritten = 0;
819 // for (int idx = 0; idx < data_index.numElements(); ++idx)
820 // {
821 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
822 // {
823 // compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)];
824 // ++nbWritten;
825 // }
826 // }
827 
828  nbWritten = 0;
829  for (int idx = 0; idx < data_index.numElements(); ++idx)
830  {
831  if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
832  {
833  ++nbWritten;
834  }
835  }
836 
837  compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten);
838  nbWritten = 0;
839  for (int idx = 0; idx < data_index.numElements(); ++idx)
840  {
841  if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
842  {
843  compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)];
844  ++nbWritten;
845  }
846  }
847 
848  numberWrittenIndexes_[writtenCommSize] = nbWritten;
849 
850  bool distributed_glo, distributed=isDistributed() ;
851  MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, writtenComm) ;
852  if (distributed_glo)
853  {
854 
855  MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm);
856  MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm);
857  offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize];
858  }
859  else
860  totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize];
861  }
862  }
864 
872  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
874  TRY
875  {
876  std::list<CContextClient*>::iterator it;
877  for (it=clients.begin(); it!=clients.end(); ++it)
878  {
879  CContextClient* client = *it;
880  int nbServer = client->serverSize;
881 
882  CServerDistributionDescription serverDescription(globalDim, nbServer);
883  serverDescription.computeServerDistribution();
884 
885  std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
886  std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
887 
888  CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE);
889  if (client->isServerLeader())
890  {
891  std::list<CMessage> msgs;
892 
893  const std::list<int>& ranks = client->getRanksServerLeader();
894  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
895  {
896  // Use const int to ensure CMessage holds a copy of the value instead of just a reference
897  const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
898  const int ni = serverDimensionSizes[*itRank][orderPositionInGrid];
899 
900  msgs.push_back(CMessage());
901  CMessage& msg = msgs.back();
902  msg << this->getId();
903  msg << ni << begin;
904  msg << isCompressible_;
905 
906  event.push(*itRank,1,msg);
907  }
908  client->sendEvent(event);
909  }
910  else client->sendEvent(event);
911  }
912  }
914 
915  /*
916  Receive distribution attribute from another client
917  \param [in] event event containing data of these attributes
918  */
920  TRY
921  {
922  CBufferIn* buffer = event.subEvents.begin()->buffer;
923  string axisId;
924  *buffer >> axisId;
925  get(axisId)->recvDistributionAttribute(*buffer);
926  }
927  CATCH
928 
929  /*
930  Receive distribution attribute from another client
931  \param [in] buffer buffer containing data of these attributes
932  */
934  TRY
935  {
936  int ni_srv, begin_srv;
937  buffer >> ni_srv >> begin_srv;
938  buffer >> isCompressible_;
939 
940  // Set up new local size of axis on the receiving clients
941  n.setValue(ni_srv);
942  begin.setValue(begin_srv);
943  }
945 
946  /*
947  Send attributes of axis from a group of client to other group of clients/servers
948  on supposing that these attributes are not distributed among the sending group
949  In the future, if new attributes are added, they should also be processed in this function
950  */
952  TRY
953  {
954  std::list<CContextClient*>::iterator it;
955  for (it=clients.begin(); it!=clients.end(); ++it)
956  {
957  CContextClient* client = *it;
958 
960  size_t nbIndex = index.numElements();
961  size_t nbDataIndex = 0;
962 
963  for (int idx = 0; idx < data_index.numElements(); ++idx)
964  {
965  int ind = data_index(idx);
966  if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
967  }
968 
969  CArray<int,1> dataIndex(nbDataIndex);
970  nbDataIndex = 0;
971  for (int idx = 0; idx < data_index.numElements(); ++idx)
972  {
973  int ind = data_index(idx);
974  if (ind >= 0 && ind < nbIndex)
975  {
976  dataIndex(nbDataIndex) = ind;
977  ++nbDataIndex;
978  }
979  }
980 
981  if (client->isServerLeader())
982  {
983  std::list<CMessage> msgs;
984 
985  const std::list<int>& ranks = client->getRanksServerLeader();
986  for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
987  {
988  msgs.push_back(CMessage());
989  CMessage& msg = msgs.back();
990  msg << this->getId();
991  msg << index.getValue() << dataIndex << mask.getValue();
992  msg << hasValue;
993  if (hasValue) msg << value.getValue();
994  msg << hasBounds;
995  if (hasBounds) msg << bounds.getValue();
996  msg << hasLabel;
997  if (hasLabel) msg << label.getValue();
998 
999  event.push(*itRank, 1, msg);
1000  }
1001  client->sendEvent(event);
1002  }
1003  else client->sendEvent(event);
1004  }
1005  }
1007 
1008  /*
1009  Receive the non-distributed attributes from another group of clients
1010  \param [in] event event containing data of these attributes
1011  */
1013  TRY
1014  {
1015  list<CEventServer::SSubEvent>::iterator it;
1016  for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1017  {
1018  CBufferIn* buffer = it->buffer;
1019  string axisId;
1020  *buffer >> axisId;
1021  get(axisId)->recvNonDistributedAttributes(it->rank, *buffer);
1022  }
1023  }
1024  CATCH
1025 
1026  /*
1027  Receive the non-distributed attributes from another group of clients
1028  \param [in] rank rank of the sender
1029  \param [in] buffer buffer containing data sent from the sender
1030  */
1032  TRY
1033  {
1034  CArray<int,1> tmp_index, tmp_data_index;
1035  CArray<bool,1> tmp_mask;
1036  CArray<double,1> tmp_val;
1037  CArray<double,2> tmp_bnds;
1038  CArray<string,1> tmp_label;
1039 
1040  buffer >> tmp_index;
1041  index.reference(tmp_index);
1042  buffer >> tmp_data_index;
1043  data_index.reference(tmp_data_index);
1044  buffer >> tmp_mask;
1045  mask.reference(tmp_mask);
1046 
1047  buffer >> hasValue;
1048  if (hasValue)
1049  {
1050  buffer >> tmp_val;
1051  value.reference(tmp_val);
1052  }
1053 
1054  buffer >> hasBounds;
1055  if (hasBounds)
1056  {
1057  buffer >> tmp_bnds;
1058  bounds.reference(tmp_bnds);
1059  }
1060 
1061  buffer >> hasLabel;
1062  if (hasLabel)
1063  {
1064  buffer >> tmp_label;
1065  label.reference(tmp_label);
1066  }
1067 
1068  // Some value should be reset here
1069  data_begin.setValue(0);
1070  globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
1071 // for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx);
1072  for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[index(idx)] = idx;
1073  }
1075 
1076  /*
1077  Send axis attributes from a group of clients to another group of clients/servers
1078  supposing that these attributes are distributed among the clients of the sending group
1079  In future, if new attributes are added, they should also be processed in this function
1080  */
1082  TRY
1083  {
1084  int ind, idx;
1085  std::list<CContextClient*>::iterator it;
1086 
1087  for (it=clients.begin(); it!=clients.end(); ++it)
1088  {
1089  CContextClient* client = *it;
1090  int nbServer = client->serverSize;
1091 
1093 
1094  list<CMessage> listData;
1095  list<CArray<int,1> > list_indi, list_dataInd;
1096  list<CArray<double,1> > list_val;
1097  list<CArray<double,2> > list_bounds;
1098  list<CArray<string,1> > list_label;
1099 
1100  // Cut off the ghost points
1101  int nbIndex = index.numElements();
1102  CArray<int,1> dataIndex(nbIndex);
1103  dataIndex = -1;
1104  for (idx = 0; idx < data_index.numElements(); ++idx)
1105  {
1106  if (0 <= data_index(idx) && data_index(idx) < nbIndex)
1107  dataIndex(data_index(idx)) = 1;
1108  }
1109 
1110  std::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
1111  iteMap = indSrv_[nbServer].end();
1112  for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k)
1113  {
1114  int nbData = 0, nbDataCount = 0;
1115  int rank = connectedServerRank_[nbServer][k];
1116  it = indSrv_[nbServer].find(rank);
1117  if (iteMap != it)
1118  nbData = it->second.size();
1119 
1120  list_indi.push_back(CArray<int,1>(nbData));
1121  list_dataInd.push_back(CArray<int,1>(nbData));
1122 
1123  if (hasValue)
1124  list_val.push_back(CArray<double,1>(nbData));
1125 
1126  if (hasBounds)
1127  list_bounds.push_back(CArray<double,2>(2,nbData));
1128 
1129  if (hasLabel)
1130  list_label.push_back(CArray<string,1>(nbData));
1131 
1132  CArray<int,1>& indi = list_indi.back();
1133  CArray<int,1>& dataIndi = list_dataInd.back();
1134  dataIndi = -1;
1135 
1136  for (int n = 0; n < nbData; ++n)
1137  {
1138  idx = static_cast<int>(it->second[n]);
1139  indi(n) = idx;
1140 
1141  ind = globalLocalIndexMap_[idx];
1142  dataIndi(n) = dataIndex(ind);
1143 
1144  if (hasValue)
1145  {
1146  CArray<double,1>& val = list_val.back();
1147  val(n) = value(ind);
1148  }
1149 
1150  if (hasBounds)
1151  {
1152  CArray<double,2>& boundsVal = list_bounds.back();
1153  boundsVal(0, n) = bounds(0,ind);
1154  boundsVal(1, n) = bounds(1,ind);
1155  }
1156 
1157  if (hasLabel)
1158  {
1159  CArray<string,1>& labelVal = list_label.back();
1160  labelVal(n) = label(ind);
1161  }
1162  }
1163 
1164  listData.push_back(CMessage());
1165  listData.back() << this->getId()
1166  << list_indi.back() << list_dataInd.back();
1167 
1168  listData.back() << hasValue;
1169  if (hasValue)
1170  listData.back() << list_val.back();
1171 
1172  listData.back() << hasBounds;
1173  if (hasBounds)
1174  listData.back() << list_bounds.back();
1175 
1176  listData.back() << hasLabel;
1177  if (hasLabel)
1178  listData.back() << list_label.back();
1179 
1180  eventData.push(rank, nbSenders[nbServer][rank], listData.back());
1181  }
1182 
1183  client->sendEvent(eventData);
1184  }
1185  }
1187 
1188  /*
1189  Receive the distributed attributes from another group of clients
1190  \param [in] event event containing data of these attributes
1191  */
1193  TRY
1194  {
1195  string axisId;
1196  vector<int> ranks;
1197  vector<CBufferIn*> buffers;
1198 
1199  list<CEventServer::SSubEvent>::iterator it;
1200  for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1201  {
1202  ranks.push_back(it->rank);
1203  CBufferIn* buffer = it->buffer;
1204  *buffer >> axisId;
1205  buffers.push_back(buffer);
1206  }
1207  get(axisId)->recvDistributedAttributes(ranks, buffers);
1208  }
1209  CATCH
1210 
1211  /*
1212  Receive the non-distributed attributes from another group of clients
1213  \param [in] ranks rank of the sender
1214  \param [in] buffers buffer containing data sent from the sender
1215  */
1216  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
1217  TRY
1218  {
1219  int nbReceived = ranks.size(), idx, ind, gloInd, locInd;
1220  vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived);
1221  vector<CArray<double,1> > vec_val(nbReceived);
1222  vector<CArray<double,2> > vec_bounds(nbReceived);
1223  vector<CArray<string,1> > vec_label(nbReceived);
1224 
1225  for (idx = 0; idx < nbReceived; ++idx)
1226  {
1227  CBufferIn& buffer = *buffers[idx];
1228  buffer >> vec_indi[idx];
1229  buffer >> vec_dataInd[idx];
1230 
1231  buffer >> hasValue;
1232  if (hasValue)
1233  buffer >> vec_val[idx];
1234 
1235  buffer >> hasBounds;
1236  if (hasBounds)
1237  buffer >> vec_bounds[idx];
1238 
1239  buffer >> hasLabel;
1240  if (hasLabel)
1241  buffer >> vec_label[idx];
1242  }
1243 
1244  // Estimate size of index array
1245  int nbIndexGlob = 0;
1246  for (idx = 0; idx < nbReceived; ++idx)
1247  {
1248  nbIndexGlob += vec_indi[idx].numElements();
1249  }
1250 
1251  // Recompute global index
1252  // Take account of the overlapped index
1253  index.resize(nbIndexGlob);
1254  globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
1255  nbIndexGlob = 0;
1256  int nbIndLoc = 0;
1257  for (idx = 0; idx < nbReceived; ++idx)
1258  {
1259  CArray<int,1>& tmp = vec_indi[idx];
1260  for (ind = 0; ind < tmp.numElements(); ++ind)
1261  {
1262  gloInd = tmp(ind);
1263  nbIndLoc = (gloInd % n_glo)-begin;
1264  if (0 == globalLocalIndexMap_.count(gloInd))
1265  {
1266  index(nbIndexGlob) = gloInd % n_glo;
1267  globalLocalIndexMap_[gloInd] = nbIndexGlob;
1268  ++nbIndexGlob;
1269  }
1270  }
1271  }
1272 
1273  // Resize index to its real size
1274  if (nbIndexGlob==0) index.resize(nbIndexGlob) ;
1275  else index.resizeAndPreserve(nbIndexGlob);
1276 
1277  int nbData = nbIndexGlob;
1278  CArray<int,1> nonCompressedData(nbData);
1279  nonCompressedData = -1;
1280  // Mask is incorporated into data_index and is not sent/received anymore
1281  mask.resize(0);
1282  if (hasValue)
1283  value.resize(nbData);
1284  if (hasBounds)
1285  bounds.resize(2,nbData);
1286  if (hasLabel)
1287  label.resize(nbData);
1288 
1289  nbData = 0;
1290  for (idx = 0; idx < nbReceived; ++idx)
1291  {
1292  CArray<int,1>& indi = vec_indi[idx];
1293  CArray<int,1>& dataIndi = vec_dataInd[idx];
1294  int nb = indi.numElements();
1295  for (int n = 0; n < nb; ++n)
1296  {
1297  locInd = globalLocalIndexMap_[size_t(indi(n))];
1298 
1299  nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd);
1300 
1301  if (hasValue)
1302  value(locInd) = vec_val[idx](n);
1303 
1304  if (hasBounds)
1305  {
1306  bounds(0,locInd) = vec_bounds[idx](0,n);
1307  bounds(1,locInd) = vec_bounds[idx](1,n);
1308  }
1309 
1310  if (hasLabel)
1311  label(locInd) = vec_label[idx](n);
1312  }
1313  }
1314 
1315  int nbCompressedData = 0;
1316  for (idx = 0; idx < nonCompressedData.numElements(); ++idx)
1317  {
1318  if (0 <= nonCompressedData(idx))
1319  ++nbCompressedData;
1320  }
1321 
1322  data_index.resize(nbCompressedData);
1323  nbCompressedData = 0;
1324  for (idx = 0; idx < nonCompressedData.numElements(); ++idx)
1325  {
1326  if (0 <= nonCompressedData(idx))
1327  {
1328  data_index(nbCompressedData) = idx % n;
1329  ++nbCompressedData;
1330  }
1331  }
1332 
1333  data_begin.setValue(0);
1334  data_n.setValue(data_index.numElements());
1335  }
1337 
1346  TRY
1347  {
1348  vector<StdString> excludedAttr;
1349  excludedAttr.push_back("axis_ref");
1350 
1351  bool objEqual = SuperClass::isEqual(obj, excludedAttr);
1352  if (!objEqual) return objEqual;
1353 
1354  TransMapTypes thisTrans = this->getAllTransformations();
1355  TransMapTypes objTrans = obj->getAllTransformations();
1356 
1357  TransMapTypes::const_iterator it, itb, ite;
1358  std::vector<ETranformationType> thisTransType, objTransType;
1359  for (it = thisTrans.begin(); it != thisTrans.end(); ++it)
1360  thisTransType.push_back(it->first);
1361  for (it = objTrans.begin(); it != objTrans.end(); ++it)
1362  objTransType.push_back(it->first);
1363 
1364  if (thisTransType.size() != objTransType.size()) return false;
1365  for (int idx = 0; idx < thisTransType.size(); ++idx)
1366  objEqual &= (thisTransType[idx] == objTransType[idx]);
1367 
1368  return objEqual;
1369  }
1371 
1372  /*
1373  Add transformation into axis. This function only servers for Fortran interface
1374  \param [in] transType transformation type
1375  \param [in] id identifier of the transformation object
1376  */
1378  TRY
1379  {
1380  transformationMap_.push_back(std::make_pair(transType, CTransformation<CAxis>::createTransformation(transType,id)));
1381  return transformationMap_.back().second;
1382  }
1384 
1385  /*
1386  Check whether an axis has (spatial) transformation
1387  */
1389  TRY
1390  {
1391  return (!transformationMap_.empty());
1392  }
1394 
1395  /*
1396  Set transformation
1397  \param [in] axisTrans transformation to set
1398  */
1400  TRY
1401  {
1402  transformationMap_ = axisTrans;
1403  }
1405 
1406  /*
1407  Return all transformation held by the axis
1408  \return transformation the axis has
1409  */
1411  TRY
1412  {
1413  return transformationMap_;
1414  }
1416 
1417  /*
1418  Duplicate transformation of another axis
1419  \param [in] src axis whose transformations are copied
1420  */
1422  TRY
1423  {
1424  if (src->hasTransformation())
1425  {
1426  this->setTransformations(src->getAllTransformations());
1427  }
1428  }
1430 
1435  TRY
1436  {
1437  if (hasTransformation() || !hasDirectAxisReference())
1438  return;
1439 
1440  CAxis* axis = this;
1441  std::vector<CAxis*> refAxis;
1442  while (!axis->hasTransformation() && axis->hasDirectAxisReference())
1443  {
1444  refAxis.push_back(axis);
1445  axis = axis->getDirectAxisReference();
1446  }
1447 
1448  if (axis->hasTransformation())
1449  for (size_t i = 0; i < refAxis.size(); ++i)
1450  refAxis[i]->setTransformations(axis->getAllTransformations());
1451  }
1453 
1455  TRY
1456  {
1457  if (clientsSet.find(contextClient)==clientsSet.end())
1458  {
1459  clients.push_back(contextClient) ;
1460  clientsSet.insert(contextClient);
1461  }
1462  }
1464 
1466  TRY
1467  {
1468  SuperClass::parse(node);
1469 
1470  if (node.goToChildElement())
1471  {
1472  StdString nodeElementName;
1473  do
1474  {
1475  StdString nodeId("");
1476  if (node.getAttributes().end() != node.getAttributes().find("id"))
1477  { nodeId = node.getAttributes()["id"]; }
1478 
1479  nodeElementName = node.getElementName();
1480  std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
1481  it = transformationMapList_.find(nodeElementName);
1482  if (ite != it)
1483  {
1484  transformationMap_.push_back(std::make_pair(it->second, CTransformation<CAxis>::createTransformation(it->second,
1485  nodeId,
1486  &node)));
1487  }
1488  else
1489  {
1490  ERROR("void CAxis::parse(xml::CXMLNode & node)",
1491  << "The transformation " << nodeElementName << " has not been supported yet.");
1492  }
1493  } while (node.goToNextElement()) ;
1494  node.goToParentElement();
1495  }
1496  }
1498 
1499  DEFINE_REF_FUNC(Axis,axis)
1500 
1501 
1502 
1503 } // namespace xios
#define CATCH_DUMP_ATTR
Definition: exception.hpp:156
This class contains information that describe distribution of servers.
static const size_t headerSize
virtual void parse(xml::CXMLNode &node)
Definition: axis.cpp:1465
CATCH CDomainAlgorithmReorder::CDomainAlgorithmReorder(CDomain *domainDestination, CDomain *domainSource, CReorderDomain *reorderDomain if)(domainDestination->type!=CDomain::type_attr::rectilinear)
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.
CArray< int, 1 > & getCompressedIndexToWriteOnServer(MPI_Comm writtenCom)
Definition: axis.cpp:167
int getNumberWrittenIndexes(MPI_Comm writtenCom)
Returns the number of indexes written by each server.
Definition: axis.cpp:132
static void recvDistributionAttribute(CEventServer &event)
Definition: axis.cpp:919
static StdString GetName(void)
Accesseurs statiques ///.
Definition: axis.cpp:255
MPI_Comm intraComm
Communicator of client group.
virtual size_t size(void) const
Definition: array_new.hpp:548
std::map< int, std::unordered_map< int, vector< size_t > > > indSrv_
Definition: axis.hpp:168
static bool dispatchEvent(CEventServer &event)
Dispatch event from the lower communication layer then process event according to its type...
Definition: axis.cpp:476
#define DEFINE_REF_FUNC(type, name_)
void checkAttributesOnClient()
Check attributes on client side (This name is still adequate???)
Definition: axis.cpp:508
bool hasLabel
Definition: axis.hpp:126
enum xios::transformation_type ETranformationType
////////////////////// Définitions ////////////////////// ///
void solveInheritanceTransformation()
Go through the hierarchy to find the axis from which the transformations must be inherited.
Definition: axis.cpp:1434
bool isEqual(CAxis *axis)
Compare two axis objects.
Definition: axis.cpp:1345
bool isCompressible_
True if and only if the data defined on the axis can be outputted in a compressed way...
Definition: axis.hpp:166
int getTotalNumberWrittenIndexes(MPI_Comm writtenCom)
Returns the total number of indexes written by the servers.
Definition: axis.cpp:145
void computeConnectedClients(const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType distType)
Definition: axis.cpp:596
int getOffsetWrittenIndexes(MPI_Comm writtenCom)
Returns the offset of indexes written by each server.
Definition: axis.cpp:158
void addRelFile(const StdString &filename)
Mutateur ///.
Definition: axis.cpp:112
#define TRY
Definition: exception.hpp:154
int clientSize
Size of client group.
std::vector< CContextClient * > clientPrimServer
Definition: context.hpp:253
static CAxis * createAxis()
Definition: axis.cpp:261
CContextServer * server
Concrete context server.
Definition: context.hpp:250
bool hasValue
Definition: axis.hpp:124
std::vector< int > computeServerGlobalIndexInRange(const std::pair< size_t, size_t > &indexBeginEnd, int positionDimensionDistributed=1)
Compute global index assigned to a server with a range.E.g: if a grid has 100 points and there are 2 ...
void sendAttributes(const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType distType)
Send attributes from one client to other clients.
Definition: axis.cpp:569
void checkEligibilityForCompressedOutput()
Check whether we can do compressed output.
Definition: axis.cpp:465
std::vector< std::vector< int > > getServerDimensionSizes() const
Get size of each dimension on distributed server.
bool isCompressible(void) const
Test whether the data defined on the axis can be outputted in a compressed way.
Definition: axis.cpp:105
CTransformation< CAxis >::TransformationMapTypes TransMapTypes
Definition: axis.hpp:56
static bool initializeTransformationMap(std::map< StdString, ETranformationType > &m)
Definition: axis.cpp:49
std::list< CContextClient * > clients
Definition: axis.hpp:157
void sendDistributedAttributes(void)
Definition: axis.cpp:1081
bool hasTransformation()
Definition: axis.cpp:1388
std::string StdString
Definition: xios_spl.hpp:48
const std::list< int > & getRanksServerLeader(void) const
Get leading server in the group of connected server.
#define xios(arg)
virtual ~CAxis(void)
Destructeur ///.
Definition: axis.cpp:44
const StdString & getId(void) const
Accesseurs ///.
Definition: object.cpp:26
Description of index distribution on server(s).
std::vector< std::vector< int > > getServerIndexBegin() const
Get index begin of each dimension on distributed server.
const GlobalIndexMap & getGlobalIndexOnServer() const
Return global index of data on each connected server.
CTransformation< CAxis > * addTransformation(ETranformationType transType, const StdString &id="")
Definition: axis.cpp:1377
bool isDistributed(void) const
Definition: axis.cpp:88
void checkAttributes(void)
Vérifications ///.
Definition: axis.cpp:273
void computeWrittenIndex()
Definition: axis.cpp:725
This class computes index of data which are sent to server as well as index of data on server side...
static bool dummyTransformationMapList_
Definition: axis.hpp:180
const CArray< size_t, 1 > & getGlobalIndex() const
Get rank of current process.
static StdString GetDefName(void)
Definition: axis.cpp:256
void checkMask()
Check validity of mask info and fill in values if any.
Definition: axis.cpp:405
static void recvNonDistributedAttributes(CEventServer &event)
Definition: axis.cpp:1012
static void recvDistributedAttributes(CEventServer &event)
Definition: axis.cpp:1192
virtual void computeServerIndexMapping(const CArray< size_t, 1 > &globalIndexOnClient, int nbServer)=0
CArray< int, 1 > localIndexToWriteOnServer
Definition: axis.hpp:128
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())
A context can be both on client and on server side.
////////////////////// Déclarations ////////////////////// ///
void push(int rank, int nbSender, CMessage &msg)
void checkData()
Check the validity of data, fill in values if any, and apply mask.
Definition: axis.cpp:347
const std::set< StdString > & getRelFiles(void) const
Accesseurs ///.
Definition: axis.cpp:67
CMessage & push(const CBaseType &type)
Definition: message.cpp:12
std::size_t StdSize
Definition: xios_spl.hpp:49
std::map< int, map< int, int > > nbSenders
Definition: axis.hpp:167
int clientRank
Rank of current client.
void setContextClient(CContextClient *contextClient)
Definition: axis.cpp:1454
void sendCheckedAttributes(const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType disType=CServerDistributionDescription::BAND_DISTRIBUTION)
Definition: axis.cpp:549
std::map< int, std::vector< int > > connectedServerRank_
Definition: axis.hpp:174
size_t getGlobalWrittenSize(void)
Definition: axis.cpp:397
int serverSize
Size of server group.
void addRelFileCompressed(const StdString &filename)
Definition: axis.cpp:119
static ENodeType GetType(void)
Definition: axis.cpp:257
static std::map< StdString, ETranformationType > transformationMapList_
Definition: axis.hpp:179
void resize(int extent)
Definition: array_new.hpp:320
std::map< int, StdSize > getAttributesBufferSize(CContextClient *client, const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType disType=CServerDistributionDescription::BAND_DISTRIBUTION)
Compute the minimum buffer size required to send the attributes to the server(s). ...
Definition: axis.cpp:183
void computeServerDistribution(bool doComputeGlobalIndex=false, int positionDimensionDistributed=1)
Compute pre-defined global index distribution of server(s).
Index distribution on client side.
void checkBounds()
Check validity of bounds info and fill in values if any.
Definition: axis.cpp:430
enum xios::_node_type ENodeType
////////////////////// Définitions ////////////////////// ///
void sendDistributionAttribute(const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType distType)
Send distribution information from a group of client (client role) to another group of client (server...
Definition: axis.cpp:872
std::unordered_map< size_t, size_t > globalLocalIndexMap_
Definition: axis.hpp:170
which implements a simple distributed hashed table; Moreover, by extending with hierarchical structur...
TransMapTypes transformationMap_
Definition: axis.hpp:164
void computeWrittenCompressedIndex(MPI_Comm)
Definition: axis.cpp:770
bool areClientAttributesChecked_
Definition: axis.hpp:161
bool isWrittenCompressed(const StdString &filename) const
Definition: axis.cpp:81
const std::unordered_map< size_t, int > & getGlobalIndexRange() const
Get global index calculated by computeServerGlobalIndexInRange.
TransMapTypes getAllTransformations()
Definition: axis.cpp:1410
bool hasBounds
Definition: axis.hpp:125
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...
CAxis(void)
Constructeurs ///.
Definition: axis.cpp:20
#define CATCH
Definition: exception.hpp:155
void sendNonDistributedAttributes(void)
Definition: axis.cpp:951
static int defaultDistributedDimension(int gridDimension, ServerDistributionType serType=BAND_DISTRIBUTION)
ENodeType getType(void) const
Accesseurs ///.
bool IsWritten(const StdString &filename) const
Test ///.
Definition: axis.cpp:74
bool computedWrittenIndex_
Definition: axis.hpp:175
void checkLabel()
Definition: axis.cpp:446
The class, for now, plays a role of computing local index for writing data on server.
std::set< StdString > relFiles
Definition: axis.hpp:163
void setTransformations(const TransMapTypes &)
Definition: axis.cpp:1399
void checkAttributesOnClientAfterTransformation(const std::vector< int > &globalDim, int orderPositionInGrid, CServerDistributionDescription::ServerDistributionType distType=CServerDistributionDescription::BAND_DISTRIBUTION)
Definition: axis.cpp:524
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 StdString & GetCurrentContextId(void)
Accesseurs ///.
void reference(const CArray< T_numtype, N_rank > &array)
Definition: array_new.hpp:292