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

Last change on this file since 1620 was 1593, checked in by ymipsl, 5 years ago

Bug fix in client distribution index computation.
storeIndex_client was badly computed when grid elements (domain or axis) was indexed, except for the first element.
It seems to be a correct fix but the class must probably be rewritten in future.

YM

File size: 22.4 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      if (!grid->mask_1d.isEmpty()) readGridMaskInfo(grid->mask_1d);
71      break;
72    case 2:
73      if (!grid->mask_2d.isEmpty()) readGridMaskInfo(grid->mask_2d);
74      break;
75    case 3:
76      if (!grid->mask_3d.isEmpty()) readGridMaskInfo(grid->mask_3d);
77      break;
78    case 4:
79      if (!grid->mask_4d.isEmpty()) readGridMaskInfo(grid->mask_4d);
80      break;
81    case 5:
82      if (!grid->mask_5d.isEmpty()) readGridMaskInfo(grid->mask_5d);
83      break;
84    case 6:
85      if (!grid->mask_6d.isEmpty()) readGridMaskInfo(grid->mask_6d);
86      break;
87    case 7:
88      if (!grid->mask_7d.isEmpty()) 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
414  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
415  while (idx < ssize)
416  {
417    for (int i = 0; i < numElement_-1; ++i)
418    {
419      if (idxLoop[i] == eachElementSize[i])
420      {
421        idxLoop[i] = 0;
422        ++idxLoop[i+1];
423      }
424    }
425
426    // Find out outer index
427    // Depending the inner-most element is axis or domain,
428    // The outer loop index begins correspondingly at one (1) or zero (0)
429    for (int i = 1; i < numElement_; ++i)
430    {
431      currentIndex[i] = elementLocalIndex_[i](idxLoop[i]);
432    }
433
434    // Inner most index
435    for (int i = 0; i < innerLoopSize; ++i)
436    {
437      int gridMaskIndex = 0;
438      currentIndex[0] = elementLocalIndex_[0](i);
439
440      // If defined, iterate on grid mask
441      if (!gridMask_.isEmpty())
442      {
443        for (int k = 0; k < this->numElement_; ++k)
444        {
445          gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
446        }
447        if (gridMask_(gridMaskIndex)) ++indexLocalDataOnClientCount;
448      }
449      // If grid mask is not defined, iterate on elements' mask
450      else
451      {
452        bool maskTmp = true;
453        int idxDomain = 0, idxAxis = 0;
454        for (int elem = 0; elem < numElement_; ++elem)
455        {
456          if (2 == axisDomainOrder_(elem))
457          {
458            maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]);
459            ++idxDomain;
460          }
461          else if (1 == axisDomainOrder_(elem))
462          {
463            maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]);
464            ++idxAxis;
465          }
466        }
467        if (maskTmp) ++indexLocalDataOnClientCount;
468      }
469
470    }
471    idxLoop[0] += innerLoopSize;
472    idx += innerLoopSize;
473  }
474
475  // Now allocate these arrays
476  localDataIndex_.resize(indexLocalDataOnClientCount);
477  localMaskIndex_.resize(indexLocalDataOnClientCount);
478  localMaskedDataIndex_.resize(indexLocalDataOnClientCount);
479  globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor()));
480  globalLocalDataSendToServerMap_.rehash(std::ceil(indexLocalDataOnClientCount/globalLocalDataSendToServerMap_.max_load_factor()));
481
482  // We need to loop with data index
483  idxLoop.assign(numElement_,0);
484  idx = indexLocalDataOnClientCount = 0;
485  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
486  innerLoopSize = dataNIndex_[0];
487  int countLocalData = 0;
488  std::vector<int> correctIndexOfElement(numElement_,0);
489  bool isOuterIndexCorrect = true;
490  while (idx < ssize)
491  {
492    for (int i = 0; i < numElement_-1; ++i)
493    {
494      if (idxLoop[i] == dataNIndex_[i])
495      {
496        idxLoop[i] = 0;
497        correctIndexOfElement[i] = 0;
498        ++idxLoop[i+1];
499        if (isOuterIndexCorrect) ++correctIndexOfElement[i+1];
500      }
501    }
502
503    // Depending the inner-most element axis or domain,
504    // The outer loop index begins correspondingly at one (1) or zero (0)
505    bool isIndexElementDataCorrect = true;
506    for (int i = 1; i < numElement_; ++i)
507    {
508      if (elementIndexData_[i](idxLoop[i]))
509      {
510        currentIndex[i] = elementLocalIndex_[i](correctIndexOfElement[i]);
511        currentGlobalIndex[i] = elementGlobalIndex_[i](correctIndexOfElement[i]);
512        isIndexElementDataCorrect &= true;
513      }
514      else isIndexElementDataCorrect = false;
515    }
516
517    isOuterIndexCorrect = isIndexElementDataCorrect;
518
519    if (isOuterIndexCorrect)
520    {
521      // Inner most index
522      int correctIndexInnerElement = 0;
523      for (int i = 0; i < innerLoopSize; ++i)
524      {
525        bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
526        if (elementIndexData_[0](i))
527        {
528          currentIndex[0] = elementLocalIndex_[0](correctIndexInnerElement);
529          currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexInnerElement);
530          isCurrentIndexDataCorrect &= true;
531          ++correctIndexInnerElement;
532        }
533        else isCurrentIndexDataCorrect = false;
534
535        if (isCurrentIndexDataCorrect)
536        {
537          int gridMaskIndex = 0;
538          for (int k = 0; k < this->numElement_; ++k)
539          {
540            gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
541          }
542
543          bool maskTmp = true;
544          // If defined, apply grid mask
545         if (!gridMask_.isEmpty())
546          {
547            maskTmp =  gridMask_(gridMaskIndex);
548          }
549          // If grid mask is not defined, apply elements' mask
550          else
551          {
552            int idxDomain = 0, idxAxis = 0;
553            for (int elem = 0; elem < numElement_; ++elem)
554            {
555              if (2 == axisDomainOrder_(elem))
556              {
557                maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]);
558                ++idxDomain;
559              }
560              else if (1 == axisDomainOrder_(elem))
561              {
562                maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]);
563                ++idxAxis;
564              }
565            }
566          }
567
568          if (maskTmp)
569          {
570            size_t globalIndex = 0;
571            for (int k = 0; k < numElement_; ++k)
572            {
573              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
574            }
575            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
576            localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
577            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
578            localMaskIndex_[indexLocalDataOnClientCount] = gridMaskIndex;
579            localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
580            ++indexLocalDataOnClientCount;
581          }
582        }
583        ++countLocalData;
584        correctIndexOfElement[0] = correctIndexInnerElement;;
585      }
586    }
587    else countLocalData+=innerLoopSize ;
588   
589    idxLoop[0] += innerLoopSize;
590    idx += innerLoopSize;
591  }
592}
593
594void CDistributionClient::createGlobalIndex()
595{
596}
597
598/*!
599  Retrieve index i and index j of a domain from its data index
600  Data contains not only true data, which are sent to servers, but also ghost data, which
601very often play a role of border of each local data, so does data index. Because data of a domain
602can be one dimension, or two dimensions, there is a need to convert data index to domain index
603  \param [in] dataIIndex index of i data
604  \param [in] dataJIndex index of j data
605  \param [in] dataIBegin index begin of i data
606  \param [in] dataJBegin index begin of j data
607  \param [in] dataDim dimension of data (1 or 2)
608  \param [in] ni local size ni of domain
609  \param [out] j j index of domain
610  \return i index of domain
611*/
612int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
613                                        const int& dataIBegin, const int& dataJBegin,
614                                        const int& dataDim, const int& ni, int& j)
615{
616  int tempI = dataIIndex + dataIBegin,
617      tempJ = (dataJIndex + dataJBegin);
618  if (ni == 0)
619  {
620    int i = 0;
621    j = 0;
622    return i;
623  }
624  int i = (dataDim == 1) ? (tempI) % ni
625                         : (tempI) ;
626  j = (dataDim == 1) ? (tempI) / ni
627                     : (tempJ) ;
628
629  return i;
630}
631
632/*!
633  Retrieve index of an axis from its data index
634  \param [in] dataIndex index of data
635  \param [in] dataBegin index begin of data
636  \param [in] ni local size of axis
637  \return index of domain
638*/
639int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
640{
641  if (ni == 0)
642  {
643    return -1;
644  }
645  int tempI = dataIndex + dataBegin;
646  if ((tempI < 0) || (tempI > ni))
647    return -1;
648  else
649    return tempI;
650}
651
652/*!
653  Return global local data mapping of client
654*/
655CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
656{
657  if (!isComputed_) createGlobalIndexSendToServer();
658  return globalLocalDataSendToServerMap_;
659}
660
661CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalDataIndexOnClient()
662{
663  if (!isComputed_) createGlobalIndexSendToServer();
664  return globalDataIndex_;
665}
666
667/*!
668  Return local data index of client
669*/
670const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
671{
672  if (!isComputed_) createGlobalIndexSendToServer();
673  return localDataIndex_;
674}
675
676/*!
677  Return local mask index of client
678*/
679const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
680{
681  if (!isComputed_) createGlobalIndexSendToServer();
682  return localMaskIndex_;
683}
684
685/*!
686  Return local mask index of client
687*/
688const std::vector<int>& CDistributionClient::getLocalMaskedDataIndexOnClient()
689{
690  if (!isComputed_) createGlobalIndexSendToServer();
691  return localMaskedDataIndex_;
692}
693
694} // namespace xios
Note: See TracBrowser for help on using the repository browser.