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

Last change on this file since 623 was 623, checked in by mhnguyen, 9 years ago

Implementing transformation algorithm: zoom axis (local commit)

+) Implement zoom axis: zoomed points are points not masked
+) Correct some minor bugs

Test
+) Ok with normal cases: zoom in the last of transformation list
+) There is still a bug in case of zoom then inverse

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