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

Last change on this file since 666 was 666, checked in by mhnguyen, 6 years ago

Change name of several axis attributes and remove some redundant variable of domain

+) Change name of axis attributes to make them consistent with ones of domain
+) Remove zoom_client_* of domain

Test
+) On Curie
+) All tests pass and are correct

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