source: XIOS/trunk/src/distribution_client.cpp @ 1562

Last change on this file since 1562 was 1562, checked in by oabramkina, 6 years ago

Some cleaning related to zoom.

File size: 20.7 KB
Line 
1/*!
2   \file distribution_client.cpp
3   \author Ha NGUYEN
4   \since 13 Jan 2015
5   \date 09 Mars 2015
6
7   \brief Index distribution on client side.
8 */
9#include "distribution_client.hpp"
10
11namespace xios {
12
13CDistributionClient::CDistributionClient(int rank, CGrid* grid)
14   : CDistribution(rank, 0)
15   , axisDomainOrder_()
16   , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_()
17   , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_()
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{
26  readDistributionInfo(grid);
27  createGlobalIndex();
28}
29
30CDistributionClient::~CDistributionClient()
31{ /* Nothing to do */ }
32
33void CDistributionClient::partialClear()
34{
35  GlobalLocalMap void1 ;
36  GlobalLocalMap void2 ;
37  std::vector<int> void3 ;
38  std::vector<int> void4 ;
39
40  globalLocalDataSendToServerMap_.swap(void1) ;
41  globalDataIndex_.swap(void2) ;
42  localDataIndex_.swap(void3);
43  localMaskIndex_.swap(void4) ;
44}
45
46/*!
47  Read information of a grid to generate distribution.
48  Every grid is composed of several axis or/and domain(s). Their information are processed
49stored and used to calculate index distribution between client and server
50  \param [in] grid Grid to read
51*/
52void CDistributionClient::readDistributionInfo(CGrid* grid)
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  grid->checkMask();
64  switch (gridDim) {
65    case 0:
66      gridMask_.resize(1);
67      gridMask_(0) = true;
68      break;
69    case 1:
70      readGridMaskInfo(grid->mask_1d);
71      break;
72    case 2:
73      readGridMaskInfo(grid->mask_2d);
74      break;
75    case 3:
76      readGridMaskInfo(grid->mask_3d);
77      break;
78    case 4:
79      readGridMaskInfo(grid->mask_4d);
80      break;
81    case 5:
82      readGridMaskInfo(grid->mask_5d);
83      break;
84    case 6:
85      readGridMaskInfo(grid->mask_6d);
86      break;
87    case 7:
88      readGridMaskInfo(grid->mask_7d);
89      break;
90    default:
91      break;
92  }
93}
94
95/*!
96  Read information from domain(s) and axis to generate distribution.
97  All information related to domain, e.g ibegin, jbegin, ni, nj, ni_glo, nj_glo
98as well as related to axis, e.g dataNIndex, dataIndex will be stored to compute
99the distribution between clients and servers. Till now, every data structure of domain has been kept
100like before, e.g: data_n_index to make sure a compability, however, it should be changed?
101  \param [in] domList List of domains of grid
102  \param [in] axisList List of axis of grid
103  \param [in] scalarList List of scalar of grid
104  \param [in] axisDomainOrder order of axis and domain inside a grid. 2 if domain, 1 if axis and zero if scalar
105//  \param [in] gridMask Mask of grid, for now, keep it 3 dimension, but it needs changing
106*/
107void CDistributionClient::readDistributionInfo(const std::vector<CDomain*>& domList,
108                                               const std::vector<CAxis*>& axisList,
109                                               const std::vector<CScalar*>& scalarList,
110                                               const CArray<int,1>& axisDomainOrder)
111{
112  domainNum_ = domList.size();
113  axisNum_   = axisList.size();
114  numElement_ = axisDomainOrder.numElements(); // Number of element, e.x: Axis, Domain
115
116  axisDomainOrder_.resize(numElement_);
117  axisDomainOrder_ = axisDomainOrder;
118
119  // Each domain or axis has its mask, of course
120  domainMasks_.resize(domainNum_);
121  for (int i = 0; i < domainNum_;++i)
122  {
123    domainMasks_[i].resize(domList[i]->domainMask.numElements());
124    domainMasks_[i] = domList[i]->domainMask;
125  }
126
127  axisMasks_.resize(axisNum_);
128  for (int i = 0; i < axisNum_; ++i)
129  {
130    axisMasks_[i].resize(axisList[i]->mask.numElements());
131    axisMasks_[i] = axisList[i]->mask;
132  }
133
134  // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
135  // their position should be specified. In axisDomainOrder, domain == true, axis == false
136  int idx = 0;
137  indexMap_.resize(numElement_);
138  this->dims_ = numElement_;
139  for (int i = 0; i < numElement_; ++i)
140  {
141    indexMap_[i] = idx;
142    if (2 == axisDomainOrder(i))
143    {
144      ++(this->dims_);
145      idx += 2;
146    }
147    else ++idx;
148  }
149
150  // Size of each dimension (local and global)
151  nLocal_.resize(this->dims_);
152  nGlob_.resize(this->dims_);
153  nBeginLocal_.resize(this->dims_,0);
154  nBeginGlobal_.resize(this->dims_,0);
155
156  // Data_n_index of domain or axis (For now, axis uses its size as data_n_index
157  dataNIndex_.resize(numElement_);
158  dataDims_.resize(numElement_);
159  dataBegin_.resize(this->dims_);
160
161  // Data_*_index of each dimension
162  dataIndex_.resize(this->dims_);
163  infoIndex_.resize(this->dims_);
164
165  // A trick to determine position of each domain in domainList
166  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
167  idx = 0;
168
169  elementLocalIndex_.resize(numElement_);
170  elementGlobalIndex_.resize(numElement_);
171  elementIndexData_.resize(numElement_);
172  elementNLocal_.resize(numElement_);
173  elementNGlobal_.resize(numElement_);
174  elementNLocal_[0] = 1;
175  elementNGlobal_[0] = 1;
176  size_t localSize = 1, globalSize = 1;
177
178  isDataDistributed_ = false;
179  // Update all the vectors above
180  for (idx = 0; idx < numElement_; ++idx)
181  {
182    int eleDim = axisDomainOrder(idx);
183    elementNLocal_[idx] = localSize;
184    elementNGlobal_[idx] = globalSize;
185
186    // If this is a domain
187    if (2 == eleDim)
188    {
189      // On the j axis
190      nLocal_.at(indexMap_[idx]+1) = domList[domIndex]->nj.getValue();
191      nGlob_.at(indexMap_[idx]+1)  = domList[domIndex]->nj_glo.getValue();
192      nBeginLocal_.at(indexMap_[idx]+1) = 0;
193      nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
194
195      dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue();
196      dataIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->data_j_index);
197      infoIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->j_index);
198
199      // On the i axis
200      nLocal_.at(indexMap_[idx]) = domList[domIndex]->ni.getValue();
201      nGlob_.at(indexMap_[idx]) = domList[domIndex]->ni_glo.getValue();
202      nBeginLocal_.at(indexMap_[idx]) = 0;
203      nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
204
205      dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
206      dataIndex_.at(indexMap_[idx]).reference(domList[domIndex]->data_i_index);
207      infoIndex_.at(indexMap_[idx]).reference(domList[domIndex]->i_index);
208
209      dataNIndex_.at(idx) = domList[domIndex]->data_i_index.numElements();
210      dataDims_.at(idx) = domList[domIndex]->data_dim.getValue();
211
212      isDataDistributed_ |= domList[domIndex]->isDistributed();
213
214      localSize *= nLocal_.at(indexMap_[idx]+1)* nLocal_.at(indexMap_[idx]);
215      globalSize *= nGlob_.at(indexMap_[idx]+1)* nGlob_.at(indexMap_[idx]);
216      ++domIndex;
217    }
218    else if (1 == eleDim)// So it's an axis
219    {
220      nLocal_.at(indexMap_[idx]) = axisList[axisIndex]->n.getValue();
221      nGlob_.at(indexMap_[idx]) = axisList[axisIndex]->n_glo.getValue();
222      nBeginLocal_.at(indexMap_[idx]) = 0;
223      nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->begin.getValue();
224
225      dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
226      dataIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->data_index);
227      infoIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->index);
228      dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
229      dataDims_.at(idx) = 1;
230
231      isDataDistributed_ |= axisList[axisIndex]->isDistributed();
232
233      localSize *= nLocal_.at(indexMap_[idx]);
234      globalSize *= nGlob_.at(indexMap_[idx]);
235
236      ++axisIndex;
237    }
238    else // scalar
239    {
240      nLocal_.at(indexMap_[idx]) = 1;
241      nGlob_.at(indexMap_[idx]) = 1;
242      nBeginLocal_.at(indexMap_[idx]) = 0;
243      nBeginGlobal_.at(indexMap_[idx]) = 1;
244
245      dataBegin_.at(indexMap_[idx]) = 0;
246      dataIndex_.at(indexMap_[idx]).resize(1); dataIndex_.at(indexMap_[idx])(0) = 0;
247      infoIndex_.at(indexMap_[idx]).resize(1); infoIndex_.at(indexMap_[idx])(0) = 0;
248      dataNIndex_.at(idx) = 1;
249      dataDims_.at(idx) = 1;
250
251      isDataDistributed_ |= false;
252
253      localSize *= nLocal_.at(indexMap_[idx]);
254      globalSize *= nGlob_.at(indexMap_[idx]);
255
256      ++scalarIndex;
257    }
258  }
259}
260
261/*!
262  Create local index of domain(s).
263  A domain can have data index which even contains the "ghost" points. Very often, these
264data surround the true data. In order to send correct data to server,
265a client need to know index of the true data.
266*/
267void CDistributionClient::createLocalDomainDataIndex()
268{
269  int idxDomain = 0;
270  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
271  {
272    if (2 == axisDomainOrder_(i))
273    {
274      elementIndexData_[i].resize(dataNIndex_[i]);
275      elementIndexData_[i] = false;
276      int iIdx, jIdx = 0, count = 0, localIndex;
277      for (int j = 0; j < dataNIndex_[i]; ++j)
278      {
279        iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
280                              dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
281                              dataDims_[i], nLocal_[indexMap_[i]], jIdx);
282
283        if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
284           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
285           (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]])))
286        {
287          ++count;
288          elementIndexData_[i](j) = true;
289        }
290      }
291
292      elementLocalIndex_[i].resize(count);
293      elementGlobalIndex_[i].resize(count);
294      count = 0;
295      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
296      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
297      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
298      for (int j = 0; j < dataNIndex_[i]; ++j)
299      {
300        if (tmpIndexElementData(j))
301        {
302          iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
303                                dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
304                                dataDims_[i], nLocal_[indexMap_[i]], jIdx);
305          localIndex = tmpLocalElementIndex(count) = iIdx + jIdx * nLocal_[indexMap_[i]];
306          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(localIndex) + ((infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
307          ++count;
308        }
309      }
310      ++idxDomain;
311    }
312  }
313}
314
315/*!
316  Create local index of axis.
317*/
318void CDistributionClient::createLocalAxisDataIndex()
319{
320  int idxAxis = 0;
321  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
322  {
323    if (1 == axisDomainOrder_(i))
324    {
325      elementIndexData_[i].resize(dataNIndex_[i]);
326      elementIndexData_[i] = false;
327      int iIdx = 0, count = 0, localIndex = 0;
328      for (int j = 0; j < dataNIndex_[i]; ++j)
329      {
330        iIdx = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
331        if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
332           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
333        {
334          ++count;
335          elementIndexData_[i](j) = true;
336        }
337      }
338
339      elementLocalIndex_[i].resize(count);
340      elementGlobalIndex_[i].resize(count);
341      count = 0;
342      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
343      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
344      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
345      for (int j = 0; j < dataNIndex_[i]; ++j)
346      {
347        if (tmpIndexElementData(j))
348        {
349          iIdx = tmpLocalElementIndex(count) = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
350          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(iIdx);
351          ++count;
352        }
353      }
354      ++idxAxis;
355    }
356  }
357}
358
359/*!
360  Create local index of scalar.
361*/
362void CDistributionClient::createLocalScalarDataIndex()
363{
364  int idxAxis = 0;
365  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
366  {
367    if (0 == axisDomainOrder_(i))
368    {
369      elementIndexData_[i].resize(dataNIndex_[i]);
370      elementIndexData_[i] = true;
371      int count = 1;
372
373      elementLocalIndex_[i].resize(count);
374      elementLocalIndex_[i] = 0;
375      elementGlobalIndex_[i].resize(count);
376      elementGlobalIndex_[i] = 0;
377    }
378  }
379}
380
381/*!
382   Create global index on client
383   In order to do the mapping between client-server, each client creates its own
384global index of sending data. This global index is then used to calculate to which server
385the client needs to send it data as well as which part of data belongs to the server.
386So as to make clients and server coherent in order of index, global index is calculated by
387take into account of C-convention, the rightmost dimension varies faster.
388*/
389void CDistributionClient::createGlobalIndexSendToServer()
390{
391  if (isComputed_) return;
392  isComputed_ = true;
393  createLocalDomainDataIndex();
394  createLocalAxisDataIndex();
395  createLocalScalarDataIndex();
396
397  int idxDomain = 0, idxAxis = 0;
398  std::vector<int> eachElementSize(numElement_);
399
400  // Precompute size of the loop
401  for (int i = 0; i < numElement_; ++i)
402  {
403    eachElementSize[i] = elementLocalIndex_[i].numElements();
404  }
405
406  //   Compute size of the global index on client
407  std::vector<StdSize> idxLoop(numElement_,0);
408  std::vector<StdSize> currentIndex(numElement_,0);
409  std::vector<StdSize> currentGlobalIndex(numElement_,0);
410  int innerLoopSize = eachElementSize[0];
411  size_t idx = 0, indexLocalDataOnClientCount = 0;
412  size_t ssize = 1;
413  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
414  while (idx < ssize)
415  {
416    for (int i = 0; i < numElement_-1; ++i)
417    {
418      if (idxLoop[i] == eachElementSize[i])
419      {
420        idxLoop[i] = 0;
421        ++idxLoop[i+1];
422      }
423    }
424
425    // Find out outer index
426    // Depending the inner-most element is axis or domain,
427    // The outer loop index begins correspondingly at one (1) or zero (0)
428    for (int i = 1; i < numElement_; ++i)
429    {
430      currentIndex[i] = elementLocalIndex_[i](idxLoop[i]);
431    }
432
433    // Inner most index
434    for (int i = 0; i < innerLoopSize; ++i)
435    {
436      int gridMaskIndex = 0;
437      currentIndex[0] = elementLocalIndex_[0](i);
438      for (int k = 0; k < this->numElement_; ++k)
439      {
440        gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
441      }
442
443      if (gridMask_(gridMaskIndex))
444      {
445        ++indexLocalDataOnClientCount;
446      }
447    }
448    idxLoop[0] += innerLoopSize;
449    idx += innerLoopSize;
450  }
451
452  // Now allocate these arrays
453  localDataIndex_.resize(indexLocalDataOnClientCount);
454  localMaskIndex_.resize(indexLocalDataOnClientCount);
455  localMaskedDataIndex_.resize(indexLocalDataOnClientCount);
456  globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor()));
457  globalLocalDataSendToServerMap_.rehash(std::ceil(indexLocalDataOnClientCount/globalLocalDataSendToServerMap_.max_load_factor()));
458
459  // We need to loop with data index
460  idxLoop.assign(numElement_,0);
461  idx = indexLocalDataOnClientCount = 0;
462  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
463  innerLoopSize = dataNIndex_[0];
464  int countLocalData = 0;
465  std::vector<int> correctIndexOfElement(numElement_,0);
466  bool isOuterIndexCorrect = true;
467  while (idx < ssize)
468  {
469    for (int i = 0; i < numElement_-1; ++i)
470    {
471      if (idxLoop[i] == dataNIndex_[i])
472      {
473        idxLoop[i] = 0;
474        correctIndexOfElement[i] = 0;
475        ++idxLoop[i+1];
476        if (isOuterIndexCorrect) ++correctIndexOfElement[i+1];
477      }
478    }
479
480    // Depending the inner-most element axis or domain,
481    // The outer loop index begins correspondingly at one (1) or zero (0)
482    bool isIndexElementDataCorrect = true;
483    for (int i = 1; i < numElement_; ++i)
484    {
485      if (elementIndexData_[i](idxLoop[i]))
486      {
487        currentIndex[i] = elementLocalIndex_[i](correctIndexOfElement[i]);
488        currentGlobalIndex[i] = elementGlobalIndex_[i](correctIndexOfElement[i]);
489        isIndexElementDataCorrect &= true;
490      }
491      else isIndexElementDataCorrect = false;
492    }
493
494    isOuterIndexCorrect = isIndexElementDataCorrect;
495
496    if (isOuterIndexCorrect)
497    {
498      // Inner most index
499      int correctIndexInnerElement = 0;
500      for (int i = 0; i < innerLoopSize; ++i)
501      {
502        bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
503        if (elementIndexData_[0](i))
504        {
505          currentIndex[0] = elementLocalIndex_[0](correctIndexInnerElement);
506          currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexInnerElement);
507          isCurrentIndexDataCorrect &= true;
508          ++correctIndexInnerElement;
509        }
510        else isCurrentIndexDataCorrect = false;
511
512        if (isCurrentIndexDataCorrect)
513        {
514          int gridMaskIndex = 0;
515          for (int k = 0; k < this->numElement_; ++k)
516          {
517            gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
518          }
519
520          if (gridMask_(gridMaskIndex))
521          {
522            size_t globalIndex = 0;
523            for (int k = 0; k < numElement_; ++k)
524            {
525              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
526            }
527            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
528            localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
529            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
530            localMaskIndex_[indexLocalDataOnClientCount] = gridMaskIndex;
531            localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
532            ++indexLocalDataOnClientCount;
533          }
534        }
535        ++countLocalData;
536        correctIndexOfElement[0] = correctIndexInnerElement;;
537      }
538    }
539    idxLoop[0] += innerLoopSize;
540    idx += innerLoopSize;
541  }
542}
543
544void CDistributionClient::createGlobalIndex()
545{
546}
547
548/*!
549  Retrieve index i and index j of a domain from its data index
550  Data contains not only true data, which are sent to servers, but also ghost data, which
551very often play a role of border of each local data, so does data index. Because data of a domain
552can be one dimension, or two dimensions, there is a need to convert data index to domain index
553  \param [in] dataIIndex index of i data
554  \param [in] dataJIndex index of j data
555  \param [in] dataIBegin index begin of i data
556  \param [in] dataJBegin index begin of j data
557  \param [in] dataDim dimension of data (1 or 2)
558  \param [in] ni local size ni of domain
559  \param [out] j j index of domain
560  \return i index of domain
561*/
562int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
563                                        const int& dataIBegin, const int& dataJBegin,
564                                        const int& dataDim, const int& ni, int& j)
565{
566  int tempI = dataIIndex + dataIBegin,
567      tempJ = (dataJIndex + dataJBegin);
568  if (ni == 0)
569  {
570    int i = 0;
571    j = 0;
572    return i;
573  }
574  int i = (dataDim == 1) ? (tempI) % ni
575                         : (tempI) ;
576  j = (dataDim == 1) ? (tempI) / ni
577                     : (tempJ) ;
578
579  return i;
580}
581
582/*!
583  Retrieve index of an axis from its data index
584  \param [in] dataIndex index of data
585  \param [in] dataBegin index begin of data
586  \param [in] ni local size of axis
587  \return index of domain
588*/
589int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
590{
591  if (ni == 0)
592  {
593    return -1;
594  }
595  int tempI = dataIndex + dataBegin;
596  if ((tempI < 0) || (tempI > ni))
597    return -1;
598  else
599    return tempI;
600}
601
602/*!
603  Return global local data mapping of client
604*/
605CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
606{
607  if (!isComputed_) createGlobalIndexSendToServer();
608  return globalLocalDataSendToServerMap_;
609}
610
611CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalDataIndexOnClient()
612{
613  if (!isComputed_) createGlobalIndexSendToServer();
614  return globalDataIndex_;
615}
616
617/*!
618  Return local data index of client
619*/
620const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
621{
622  if (!isComputed_) createGlobalIndexSendToServer();
623  return localDataIndex_;
624}
625
626/*!
627  Return local mask index of client
628*/
629const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
630{
631  if (!isComputed_) createGlobalIndexSendToServer();
632  return localMaskIndex_;
633}
634
635/*!
636  Return local mask index of client
637*/
638const std::vector<int>& CDistributionClient::getLocalMaskedDataIndexOnClient()
639{
640  if (!isComputed_) createGlobalIndexSendToServer();
641  return localMaskedDataIndex_;
642}
643
644} // namespace xios
Note: See TracBrowser for help on using the repository browser.