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

Last change on this file since 821 was 821, checked in by mhnguyen, 5 years ago

Making some improvements of transformation algorithm

+) Correct the way to enlisting transformations in an element (domain, axis)
+) Optimize generic transformation to make sure temporary grid to be created on demand
+) Update some mpi tag to prevent conflict
+) Correct some minor stuffs
+) Update documents

Test
+) On Curie
+) all test pass

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