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
distribution_client.cpp
Aller à la documentation de ce fichier.
1 
10 
11 namespace xios {
12 
14  : CDistribution(rank, 0)
15  , axisDomainOrder_()
16  , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_()
17  , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_()
18  , gridMask_(), indexMap_()
19  , isDataDistributed_(true), axisNum_(0), domainNum_(0)
20  , localDataIndex_(), localMaskIndex_()
21  , globalLocalDataSendToServerMap_()
22  , infoIndex_(), isComputed_(false)
23  , elementLocalIndex_(), elementGlobalIndex_(), elementIndexData_()
24  , elementNLocal_(), elementNGlobal_()
25 {
28 }
29 
31 { /* Nothing to do */ }
32 
34 {
35  GlobalLocalMap void1 ;
36  GlobalLocalMap void2 ;
37  std::vector<int> void3 ;
38  std::vector<bool> void4 ;
39 
41  globalDataIndex_.swap(void2) ;
42  localDataIndex_.swap(void3);
43  localMaskIndex_.swap(void4) ;
44 }
45 
53 {
54  std::vector<CDomain*> domList = grid->getDomains();
55  std::vector<CAxis*> axisList = grid->getAxis();
56  std::vector<CScalar*> scalarList = grid->getScalars();
57  CArray<int,1> axisDomainOrder = grid->axis_domain_order;
58 
59  readDistributionInfo(domList, axisList, scalarList, axisDomainOrder);
60 
61  // Then check mask of grid
62  int gridDim = domList.size() * 2 + axisList.size();
63  switch (gridDim) {
64  case 0:
65  gridMask_.resize(1);
66  gridMask_(0) = true;
67  break;
68  case 1:
69  if (!grid->mask_1d.isEmpty()) readGridMaskInfo(grid->mask_1d);
70  break;
71  case 2:
72  if (!grid->mask_2d.isEmpty()) readGridMaskInfo(grid->mask_2d);
73  break;
74  case 3:
75  if (!grid->mask_3d.isEmpty()) readGridMaskInfo(grid->mask_3d);
76  break;
77  case 4:
78  if (!grid->mask_4d.isEmpty()) readGridMaskInfo(grid->mask_4d);
79  break;
80  case 5:
81  if (!grid->mask_5d.isEmpty()) readGridMaskInfo(grid->mask_5d);
82  break;
83  case 6:
84  if (!grid->mask_6d.isEmpty()) readGridMaskInfo(grid->mask_6d);
85  break;
86  case 7:
87  if (!grid->mask_7d.isEmpty()) readGridMaskInfo(grid->mask_7d);
88  break;
89  default:
90  break;
91  }
92 }
93 
106 void CDistributionClient::readDistributionInfo(const std::vector<CDomain*>& domList,
107  const std::vector<CAxis*>& axisList,
108  const std::vector<CScalar*>& scalarList,
109  const CArray<int,1>& axisDomainOrder)
110 {
111  domainNum_ = domList.size();
112  axisNum_ = axisList.size();
113  numElement_ = axisDomainOrder.numElements(); // Number of element, e.x: Axis, Domain
114 
116  axisDomainOrder_ = axisDomainOrder;
117 
118  // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
119  // their position should be specified. In axisDomainOrder, domain == true, axis == false
120  int idx = 0;
121  indexMap_.resize(numElement_);
122  this->dims_ = numElement_;
123  for (int i = 0; i < numElement_; ++i)
124  {
125  indexMap_[i] = idx;
126  if (2 == axisDomainOrder(i))
127  {
128  ++(this->dims_);
129  idx += 2;
130  }
131  else ++idx;
132  }
133 
134  // Size of each dimension (local and global)
135  nLocal_.resize(this->dims_);
136  nGlob_.resize(this->dims_);
137  nBeginLocal_.resize(this->dims_,0);
138  nBeginGlobal_.resize(this->dims_,0);
139 
140  // Data_n_index of domain or axis (For now, axis uses its size as data_n_index
141  dataNIndex_.resize(numElement_);
142  dataDims_.resize(numElement_);
143  dataBegin_.resize(this->dims_);
144 
145  // Data_*_index of each dimension
146  dataIndex_.resize(this->dims_);
147  infoIndex_.resize(this->dims_);
148 
149  // A trick to determine position of each domain in domainList
150  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
151  idx = 0;
152 
153  elementLocalIndex_.resize(numElement_);
154  elementGlobalIndex_.resize(numElement_);
155  elementIndexData_.resize(numElement_);
156  elementNLocal_.resize(numElement_);
157  elementNGlobal_.resize(numElement_);
158  elementNLocal_[0] = 1;
159  elementNGlobal_[0] = 1;
160  size_t localSize = 1, globalSize = 1;
161 
162  isDataDistributed_ = false;
163  // Update all the vectors above
164  for (idx = 0; idx < numElement_; ++idx)
165  {
166  int eleDim = axisDomainOrder(idx);
167  elementNLocal_[idx] = localSize;
168  elementNGlobal_[idx] = globalSize;
169 
170  // If this is a domain
171  if (2 == eleDim)
172  {
173  // On the j axis
174  nLocal_.at(indexMap_[idx]+1) = domList[domIndex]->nj.getValue();
175  nGlob_.at(indexMap_[idx]+1) = domList[domIndex]->nj_glo.getValue();
176  nBeginLocal_.at(indexMap_[idx]+1) = 0;
177  nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
178 
179  dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue();
180  dataIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->data_j_index);
181  infoIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->j_index);
182 
183  // On the i axis
184  nLocal_.at(indexMap_[idx]) = domList[domIndex]->ni.getValue();
185  nGlob_.at(indexMap_[idx]) = domList[domIndex]->ni_glo.getValue();
186  nBeginLocal_.at(indexMap_[idx]) = 0;
187  nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
188 
189  dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
190  dataIndex_.at(indexMap_[idx]).reference(domList[domIndex]->data_i_index);
191  infoIndex_.at(indexMap_[idx]).reference(domList[domIndex]->i_index);
192 
193  dataNIndex_.at(idx) = domList[domIndex]->data_i_index.numElements();
194  dataDims_.at(idx) = domList[domIndex]->data_dim.getValue();
195 
196  isDataDistributed_ |= domList[domIndex]->isDistributed();
197 
198  localSize *= nLocal_.at(indexMap_[idx]+1)* nLocal_.at(indexMap_[idx]);
199  globalSize *= nGlob_.at(indexMap_[idx]+1)* nGlob_.at(indexMap_[idx]);
200  ++domIndex;
201  }
202  else if (1 == eleDim)// So it's an axis
203  {
204  nLocal_.at(indexMap_[idx]) = axisList[axisIndex]->n.getValue();
205  nGlob_.at(indexMap_[idx]) = axisList[axisIndex]->n_glo.getValue();
206  nBeginLocal_.at(indexMap_[idx]) = 0;
207  nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->begin.getValue();
208 
209  dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
210  dataIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->data_index);
211  infoIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->index);
212  dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
213  dataDims_.at(idx) = 1;
214 
215  isDataDistributed_ |= axisList[axisIndex]->isDistributed();
216 
217  localSize *= nLocal_.at(indexMap_[idx]);
218  globalSize *= nGlob_.at(indexMap_[idx]);
219 
220  ++axisIndex;
221  }
222  else // scalar
223  {
224  nLocal_.at(indexMap_[idx]) = 1;
225  nGlob_.at(indexMap_[idx]) = 1;
226  nBeginLocal_.at(indexMap_[idx]) = 0;
227  nBeginGlobal_.at(indexMap_[idx]) = 1;
228 
229  dataBegin_.at(indexMap_[idx]) = 0;
230  dataIndex_.at(indexMap_[idx]).resize(1); dataIndex_.at(indexMap_[idx])(0) = 0;
231  infoIndex_.at(indexMap_[idx]).resize(1); infoIndex_.at(indexMap_[idx])(0) = 0;
232  dataNIndex_.at(idx) = 1;
233  dataDims_.at(idx) = 1;
234 
235  isDataDistributed_ |= false;
236 
237  localSize *= nLocal_.at(indexMap_[idx]);
238  globalSize *= nGlob_.at(indexMap_[idx]);
239 
240  ++scalarIndex;
241  }
242  }
243 }
244 
252 {
253  int idxDomain = 0;
254  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
255  {
256  if (2 == axisDomainOrder_(i))
257  {
258  elementIndexData_[i].resize(dataNIndex_[i]);
259  elementIndexData_[i] = false;
260  int iIdx, jIdx = 0, count = 0, localIndex;
261  for (int j = 0; j < dataNIndex_[i]; ++j)
262  {
263  iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
265  dataDims_[i], nLocal_[indexMap_[i]], jIdx);
266 
267  if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
268  (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]))
269  {
270  ++count;
271  elementIndexData_[i](j) = true;
272  }
273  }
274 
275  elementLocalIndex_[i].resize(count);
276  elementGlobalIndex_[i].resize(count);
277  count = 0;
278  CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
279  CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
280  CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
281  for (int j = 0; j < dataNIndex_[i]; ++j)
282  {
283  if (tmpIndexElementData(j))
284  {
285  iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
287  dataDims_[i], nLocal_[indexMap_[i]], jIdx);
288  localIndex = tmpLocalElementIndex(count) = iIdx + jIdx * nLocal_[indexMap_[i]];
289  tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(localIndex) + ((infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
290  ++count;
291  }
292  }
293  ++idxDomain;
294  }
295  }
296 }
297 
302 {
303  int idxAxis = 0;
304  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
305  {
306  if (1 == axisDomainOrder_(i))
307  {
308  elementIndexData_[i].resize(dataNIndex_[i]);
309  elementIndexData_[i] = false;
310  int iIdx = 0, count = 0;
311  for (int j = 0; j < dataNIndex_[i]; ++j)
312  {
314  if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
315  (iIdx < nLocal_[indexMap_[i]]) )//&& (axisMasks_[idxAxis](iIdx)))
316  {
317  ++count;
318  elementIndexData_[i](j) = true;
319  }
320  }
321 
322  elementLocalIndex_[i].resize(count);
323  elementGlobalIndex_[i].resize(count);
324  count = 0;
325  CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
326  CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
327  CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
328  for (int j = 0; j < dataNIndex_[i]; ++j)
329  {
330  if (tmpIndexElementData(j))
331  {
332  iIdx = tmpLocalElementIndex(count) = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
333  tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(iIdx);
334  ++count;
335  }
336  }
337  ++idxAxis;
338  }
339  }
340 }
341 
346 {
347  int idxAxis = 0;
348  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
349  {
350  if (0 == axisDomainOrder_(i))
351  {
352  elementIndexData_[i].resize(dataNIndex_[i]);
353  elementIndexData_[i] = true;
354  int count = 1;
355 
356  elementLocalIndex_[i].resize(count);
357  elementLocalIndex_[i] = 0;
358  elementGlobalIndex_[i].resize(count);
359  elementGlobalIndex_[i] = 0;
360  }
361  }
362 }
363 
373 {
374  if (isComputed_) return;
375  isComputed_ = true;
379 
380  int idxDomain = 0, idxAxis = 0;
381  std::vector<int> eachElementSize(numElement_);
382 
383  // Precompute size of the loop
384  for (int i = 0; i < numElement_; ++i)
385  {
386  eachElementSize[i] = elementLocalIndex_[i].numElements();
387  }
388 
389  // Compute size of the global index on client
390  std::vector<StdSize> idxLoop(numElement_,0);
391  std::vector<StdSize> currentIndex(numElement_,0);
392  std::vector<StdSize> currentGlobalIndex(numElement_,0);
393  int innerLoopSize = eachElementSize[0];
394  size_t idx = 0, indexLocalDataOnClientCount = 0;
395  size_t ssize = 1;
396 
397  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
398 
399  localDataIndex_.resize(ssize);
400  if (!gridMask_.isEmpty()) localMaskIndex_.resize(ssize);
401  localMaskedDataIndex_.resize(ssize);
402  globalDataIndex_.rehash(std::ceil(ssize/globalDataIndex_.max_load_factor()));
403  globalLocalDataSendToServerMap_.rehash(std::ceil(ssize/globalLocalDataSendToServerMap_.max_load_factor()));
404 
405 
406  // We need to loop with data index
407  idxLoop.assign(numElement_,0);
408  idx = indexLocalDataOnClientCount = 0;
409  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
410  innerLoopSize = dataNIndex_[0];
411  int countLocalData = 0;
412  std::vector<int> correctIndexOfElement(numElement_,0);
413  bool isOuterIndexCorrect = true;
414  while (idx < ssize)
415  {
416  for (int i = 0; i < numElement_-1; ++i)
417  {
418  if (idxLoop[i] == dataNIndex_[i])
419  {
420  idxLoop[i] = 0;
421  correctIndexOfElement[i] = 0;
422  ++idxLoop[i+1];
423  if (isOuterIndexCorrect) ++correctIndexOfElement[i+1];
424  }
425  }
426 
427  // Depending the inner-most element axis or domain,
428  // The outer loop index begins correspondingly at one (1) or zero (0)
429  bool isIndexElementDataCorrect = true;
430  for (int i = 1; i < numElement_; ++i)
431  {
432  if (elementIndexData_[i](idxLoop[i]))
433  {
434  currentIndex[i] = elementLocalIndex_[i](correctIndexOfElement[i]);
435  currentGlobalIndex[i] = elementGlobalIndex_[i](correctIndexOfElement[i]);
436  isIndexElementDataCorrect &= true;
437  }
438  else isIndexElementDataCorrect = false;
439  }
440 
441  isOuterIndexCorrect = isIndexElementDataCorrect;
442 
443  if (isOuterIndexCorrect)
444  {
445  // Inner most index
446  int correctIndexInnerElement = 0;
447  for (int i = 0; i < innerLoopSize; ++i)
448  {
449  bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
450  if (elementIndexData_[0](i))
451  {
452  currentIndex[0] = elementLocalIndex_[0](correctIndexInnerElement);
453  currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexInnerElement);
454  isCurrentIndexDataCorrect &= true;
455  ++correctIndexInnerElement;
456  }
457  else isCurrentIndexDataCorrect = false;
458 
459  if (isCurrentIndexDataCorrect)
460  {
461  bool maskTmp = true;
462  bool maskGridTmp = true;
463  size_t globalIndex = 0;
464  for (int k = 0; k < numElement_; ++k)
465  {
466  globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
467  }
468  globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
469  localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
470  globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
471  localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
472 
473  // Grid mask: unmasked values will be replaces by NaN and then all values will be sent
474  if (!gridMask_.isEmpty())
475  {
476  int gridMaskIndex = 0;
477  for (int k = 0; k < this->numElement_; ++k)
478  {
479  gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
480  }
481  maskGridTmp = gridMask_(gridMaskIndex);
482  if (maskGridTmp)
483  localMaskIndex_[indexLocalDataOnClientCount] = true;
484  else
485  localMaskIndex_[indexLocalDataOnClientCount] = false;
486  }
487 
488  ++indexLocalDataOnClientCount;
489 
490  }
491  ++countLocalData;
492  correctIndexOfElement[0] = correctIndexInnerElement;;
493  }
494  }
495  else countLocalData+=innerLoopSize ;
496 
497  idxLoop[0] += innerLoopSize;
498  idx += innerLoopSize;
499  }
500 }
501 
503 {
504 }
505 
520 int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
521  const int& dataIBegin, const int& dataJBegin,
522  const int& dataDim, const int& ni, int& j)
523 {
524  int i;
525  int tempI = dataIIndex + dataIBegin,
526  tempJ = (dataJIndex + dataJBegin);
527  if (ni == 0)
528  {
529  i = -1;
530  j = -1;
531  return i;
532  }
533  if ((tempI < 0) || (tempJ < 0))
534  {
535  i = -1;
536  j = -1;
537  return i;
538  }
539  else
540  {
541  i = (dataDim == 1) ? (tempI) % ni : (tempI) ;
542  j = (dataDim == 1) ? (tempI) / ni : (tempJ) ;
543  }
544  return i;
545 }
546 
554 int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
555 {
556  if (ni == 0)
557  {
558  return -1;
559  }
560  int tempI = dataIndex;
561  if ((tempI < 0) || (tempI > ni))
562  return -1;
563  else
564  return tempI;
565 }
566 
571 {
574 }
575 
577 {
579  return globalDataIndex_;
580 }
581 
586 {
588  return localDataIndex_;
589 }
590 
595 {
597  return localMaskIndex_;
598 }
599 
604 {
606  return localMaskedDataIndex_;
607 }
608 
609 } // namespace xios
const std::vector< int > & getLocalMaskedDataIndexOnClient()
Return local mask index of client.
void createLocalDomainDataIndex()
Create local index of a domain.
void readGridMaskInfo(const CArray< bool, N > &gridMask)
A grid can have multiple dimension, so can its mask in the form of multi-dimension array...
void createLocalScalarDataIndex()
Create local index of a scalar.
std::vector< int > indexMap_
Mapping element index to dimension index.
void createLocalAxisDataIndex()
Create local index of an axis.
int count
Definition: tracer.cpp:26
std::vector< size_t > elementNLocal_
virtual const std::vector< int > & getLocalDataIndexOnClient()
Return local data index of client.
std::vector< size_t > elementNGlobal_
(Only for grid with one axis or scalar)Flag to determine whether data is distributed or not ...
The parent class of CDistributionClient and CDistributionServer, which declares and defines some basi...
std::vector< int > localMaskedDataIndex_
CArray< int, 1 > & i_index
GlobalLocalDataMap & getGlobalLocalDataSendToServer()
Return global local data mapping of client.
std::vector< CArray< int, 1 > > infoIndex_
i_index, j_index
std::vector< CArray< int, 1 > > elementLocalIndex_
Local index of each element.
CArray< int, 1 > axisDomainOrder_
Order of axis and domain of a grid.
std::vector< int > localDataIndex_
Array holding masked data indexes.
std::vector< int > dataBegin_
Data begin (data_ibegin, data_jbegin, etc)
std::vector< CDomain * > getDomains()
Get the list of domain pointers.
Definition: grid.cpp:2410
#define xios(arg)
std::vector< CScalar * > getScalars()
Get the list of axis pointers.
Definition: grid.cpp:2441
GlobalLocalDataMap & getGlobalDataIndexOnClient()
void readDistributionInfo(CGrid *grid)
Read information of a grid to generate distribution.
static int getAxisIndex(const int &dataIndex, const int &dataBegin, const int &ni)
Retrieve index of an axis from its data index.
GlobalLocalDataMap globalDataIndex_
std::vector< int > dataNIndex_
Data_n_index in case of domain.
std::vector< CArray< bool, 1 > > elementIndexData_
// The correct index of a domain has true value, the ghost one has false value
std::vector< CAxis * > getAxis()
Get the list of axis pointers.
Definition: grid.cpp:2426
virtual bool isEmpty(void) const
Definition: array_new.hpp:547
CArray< bool, 1 > gridMask_
Mask of grid.
CDistributionClient(int rank, CGrid *grid)
std::vector< int > nGlob_
Global size of each dimension (e.x: ni_glo, nj_glo, etc, ...)
std::vector< int > nBeginLocal_
Begin index of each dimension (e.x: for domain, it&#39;s always 0, for axis, it&#39;s zoom_begin, ...)
int numElement_
Domains and axis are considered elements.
std::vector< bool > localMaskIndex_
Array holding grid mask.
std::vector< int > nLocal_
Local size of each dimension (ni, nj, etc, ...)
void createGlobalIndexSendToServer()
Create global index on client In order to do the mapping between client-server, each client creates i...
GlobalLocalDataMap globalLocalDataSendToServerMap_
&lt; LocalData index on client
void createGlobalIndex()
clear heavy sized attibutes
void resize(int extent)
Definition: array_new.hpp:320
std::vector< int > dataDims_
Data_dim, domain can have data_dim == 1 or 2.
std::vector< CArray< size_t, 1 > > elementGlobalIndex_
Global index of each element.
Index distribution on client side.
std::unordered_map< size_t, int > GlobalLocalMap
std::vector< int > nBeginGlobal_
Begin index of each dimension (e.x: ibegin, jbegin, ...)
CDistribution::GlobalLocalMap GlobalLocalDataMap
const std::vector< bool > & getLocalMaskIndexOnClient()
Return local mask index of client.
static int getDomainIndex(const int &dataIIndex, const int &dataJIndex, const int &dataIBegin, const int &dataJBegin, const int &dataDim, const int &ni, int &j)
Retrieve index i and index j of a domain from its data index Data contains not only true data...
std::vector< CArray< int, 1 > > dataIndex_
Data index.