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

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

Fixing a bug on activating zoom on axis or domain

+) Correct index of zoom mask

Test
+) On Curie
+) All standard tests (test_client, test_complete) pass*
+) All other tests are correct.

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