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

Last change on this file since 833 was 833, checked in by mhnguyen, 8 years ago

Improvements for dht

+) Implement adaptive hierarchy for dht, level of hierarchy depends on number of processes
+) Remove some redundant codes

Test
+) On Curie
+) All tests are correct

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