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

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

Cleaning up some redundant coeds and making some improvements

+) Remove some XIOS Search to make code run faster
+) Remove some commented codes

Test
+) On Curie
+) All tests pass

File size: 25.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   , localDataIndex_(), localMaskIndex_()//, globalDataSendToServer_(), localDataIndexSendToServer_()
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_()//, globalDataSendToServer_(), localDataIndexSendToServer_()
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//  globalDataSendToServer_.resize(indexSend2ServerCount);
510//  localDataIndexSendToServer_.resize(indexSend2ServerCount);
511  localDataIndex_.resize(indexLocalDataOnClientCount);
512
513  localMaskIndex_.resize(indexSend2ServerCount);
514
515  // We need to loop with data index
516  idxLoop.assign(numElement_,0);
517  idx = indexLocalDataOnClientCount = indexSend2ServerCount = 0;
518  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
519  innerLoopSize = dataNIndex_[0];
520  int countLocalData = 0;
521  std::vector<int> correctOuterIndex(numElement_,0);
522  bool isOuterIndexCorrect = true;
523  while (idx < ssize)
524  {
525    for (int i = 0; i < numElement_-1; ++i)
526    {
527      if (idxLoop[i] == dataNIndex_[i])
528      {
529        idxLoop[i] = 0;
530        correctOuterIndex[i] = 0;
531        ++idxLoop[i+1];
532        if (isOuterIndexCorrect) ++correctOuterIndex[i+1];
533      }
534    }
535
536    // Depending the inner-most element axis or domain,
537    // The outer loop index begins correspondingly at one (1) or zero (0)
538    idxDomain = idxAxis = 0;
539    if (axisDomainOrder_(0)) ++idxDomain;
540    else ++idxAxis;
541    bool isIndexDomainDataCorrect = true;
542    bool isIndexAxisDataCorrect = true;
543
544    for (int i = 1; i < numElement_; ++i)
545    {
546      if (axisDomainOrder_(i))
547      {
548        if (indexDomainData_[idxDomain][idxLoop[i]])
549        {
550          currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][correctOuterIndex[i]];
551          currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain*2+1][correctOuterIndex[i]];
552          isIndexDomainDataCorrect &= true;
553        }
554        else isIndexDomainDataCorrect = false;
555        ++idxDomain;
556      }
557      else
558      {
559        if (indexAxisData_[idxAxis][idxLoop[i]])
560        {
561          currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndex[i]];
562          isIndexAxisDataCorrect &= true;
563        }
564        else isIndexAxisDataCorrect = false;
565        ++idxAxis;
566      }
567    }
568
569    isOuterIndexCorrect = (isIndexAxisDataCorrect) && (isIndexDomainDataCorrect);
570
571    // Inner most index
572    idxDomain = idxAxis = 0;
573    int correctIndexDomain = 0, correctIndexAxis = 0;
574    for (int i = 0; i < innerLoopSize; ++i)
575    {
576      bool isCurrentIndexDomainDataCorrect = isIndexDomainDataCorrect;
577      bool isCurrentIndexAxisDataCorrect = isIndexAxisDataCorrect;
578
579      if (axisDomainOrder_(0))
580      {
581        if (indexDomainData_[idxDomain][i])
582        {
583          currentIndex[0] = localDomainIndex_[idxDomain][correctIndexDomain];
584          currentIndex[1] = localDomainIndex_[idxDomain+1][correctIndexDomain];
585          isCurrentIndexDomainDataCorrect &= true;
586          ++correctIndexDomain;
587        }
588        else isCurrentIndexDomainDataCorrect = false;
589      }
590      else
591      {
592        if (indexAxisData_[idxAxis][i])
593        {
594          currentIndex[0] = localAxisIndex_[idxAxis][correctIndexAxis];
595          isCurrentIndexAxisDataCorrect &= true;
596          ++correctIndexAxis;
597        }
598        else isCurrentIndexAxisDataCorrect = false;
599      }
600
601      int gridMaskIndex = currentIndex[0];
602      int mulDimMask = 1;
603      for (int k = 1; k < this->dims_; ++k)
604      {
605        mulDimMask *= nLocal_[k-1];
606        gridMaskIndex += (currentIndex[k])*mulDimMask;
607      }
608
609      if (isCurrentIndexDomainDataCorrect &&
610          isCurrentIndexAxisDataCorrect &&
611          gridMask_(gridMaskIndex))
612      {
613        localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
614        bool isIndexOnServer = true;
615        for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
616        {
617          int actualIdx = 0;
618          if (axisDomainOrder_(idxElement))
619          {
620            actualIdx = currentIndex[indexMap_[idxElement]]+currentIndex[indexMap_[idxElement]+1]*nLocal_[indexMap_[idxElement]];
621            isIndexOnServer = isIndexOnServer && ((infoIndex_[indexMap_[idxElement]](actualIdx)) <= nZoomEnd_[indexMap_[idxElement]])
622                                              && (nZoomBegin_[indexMap_[idxElement]] <= (infoIndex_[indexMap_[idxElement]](actualIdx)))
623                                              && ((infoIndex_[indexMap_[idxElement]+1](actualIdx)) <= nZoomEnd_[indexMap_[idxElement]+1])
624                                              && (nZoomBegin_[indexMap_[idxElement]+1] <= (infoIndex_[indexMap_[idxElement]+1](actualIdx)));
625          }
626          else
627          {
628            isIndexOnServer = isIndexOnServer && ((infoIndex_[indexMap_[idxElement]](currentIndex[indexMap_[idxElement]])) <= nZoomEnd_[indexMap_[idxElement]])
629                                              && (nZoomBegin_[indexMap_[idxElement]] <= (infoIndex_[indexMap_[idxElement]](currentIndex[indexMap_[idxElement]])));
630          }
631        }
632
633        if (isIndexOnServer)
634        {
635          int actualIdx = (axisDomainOrder_(0)) ? currentIndex[0]+currentIndex[1]*nLocal_[0]
636                                                : currentIndex[0];
637          size_t globalIndex = infoIndex_[0](actualIdx); //idxLoop[0] + nBeginGlobal_[0];
638          size_t mulDim = 1;
639          for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
640          {
641            if (axisDomainOrder_(idxElement))
642            {
643              actualIdx = currentIndex[indexMap_[idxElement]]+currentIndex[indexMap_[idxElement]+1]*nLocal_[indexMap_[idxElement]];
644              int jb = (0 == idxElement) ? 1 : 0;
645              for (int j = jb; j <= 1; ++j)
646              {
647                mulDim *= nGlob_[indexMap_[idxElement]+j-1];
648                globalIndex += (infoIndex_[indexMap_[idxElement]+j](actualIdx))*mulDim;
649              }
650            }
651            else
652            {
653              if (0 != idxElement)
654              {
655                mulDim *= nGlob_[indexMap_[idxElement]-1];
656                globalIndex += (infoIndex_[indexMap_[idxElement]](currentIndex[indexMap_[idxElement]]))*mulDim;
657              }
658            }
659          }
660//          globalDataSendToServer_[indexSend2ServerCount] = globalIndex;
661//          localDataIndexSendToServer_[indexSend2ServerCount] = indexLocalDataOnClientCount;
662          globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
663          localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
664          ++indexSend2ServerCount;
665        }
666        ++indexLocalDataOnClientCount;
667      }
668      ++countLocalData;
669    }
670    idxLoop[0] += innerLoopSize;
671    idx += innerLoopSize;
672  }
673}
674
675/*!
676  Retrieve index i and index j of a domain from its data index
677  Data contains not only true data, which are sent to servers, but also ghost data, which
678very often play a role of border of each local data, so does data index. Because data of a domain
679can be one dimension, or two dimensions, there is a need to convert data index to domain index
680  \param [in] dataIIndex index of i data
681  \param [in] dataJIndex index of j data
682  \param [in] dataIBegin index begin of i data
683  \param [in] dataJBegin index begin of j data
684  \param [in] dataDim dimension of data (1 or 2)
685  \param [in] ni local size ni of domain
686  \param [out] j j index of domain
687  \return i index of domain
688*/
689int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
690                                        const int& dataIBegin, const int& dataJBegin,
691                                        const int& dataDim, const int& ni, int& j)
692{
693  int tempI = dataIIndex + dataIBegin,
694      tempJ = (dataJIndex + dataJBegin);
695  int i = (dataDim == 1) ? (tempI) % ni
696                         : (tempI) ;
697  j = (dataDim == 1) ? (tempI) / ni
698                     : (tempJ) ;
699
700  return i;
701}
702
703/*!
704  Retrieve index of an axis from its data index
705  \param [in] dataIndex index of data
706  \param [in] dataBegin index begin of data
707  \param [in] ni local size of axis
708  \return index of domain
709*/
710int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
711{
712   int tempI = dataIndex + dataBegin;
713   return ((tempI)%ni);
714}
715
716/*!
717  Return global local data mapping of client
718*/
719const CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer() const
720{
721  return globalLocalDataSendToServerMap_;
722}
723
724/*!
725  Return local data index of client
726*/
727const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient() const
728{
729  return localDataIndex_;
730}
731
732/*!
733  Return local mask index of client
734*/
735const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient() const
736{
737  return localMaskIndex_;
738}
739
740} // namespace xios
Note: See TracBrowser for help on using the repository browser.