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

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

Removing some unnecessary files and code lines

File size: 22.3 KB
Line 
1/*!
2   \file distribution_client.cpp
3   \author Ha NGUYEN
4   \since 13 Jan 2015
5   \date 09 Mars 2015
6
7   \brief Index distribution on client side.
8 */
9#include "distribution_client.hpp"
10
11namespace xios {
12
13CDistributionClient::CDistributionClient(int rank, int dims, 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> correctOuterIndex(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        correctOuterIndex[i] = 0;
453        ++idxLoop[i+1];
454        if (isOuterIndexCorrect) ++correctOuterIndex[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](correctOuterIndex[i]);
466        currentGlobalIndex[i] = elementGlobalIndex_[i](correctOuterIndex[i]);
467        isIndexElementDataCorrect &= true;
468      }
469      else isIndexElementDataCorrect = false;
470    }
471
472    isOuterIndexCorrect = isIndexElementDataCorrect;
473
474    // Inner most index
475    int correctIndexElement = 0;
476    for (int i = 0; i < innerLoopSize; ++i)
477    {
478      bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
479      if (elementIndexData_[0](i))
480      {
481        currentIndex[0] = elementLocalIndex_[0](correctIndexElement);
482        currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexElement);
483        isCurrentIndexDataCorrect &= true;
484        ++correctIndexElement;
485      }
486      else isCurrentIndexDataCorrect = false;
487
488      if (isCurrentIndexDataCorrect)
489      {
490        int gridMaskIndex = 0;
491        for (int k = 0; k < this->numElement_; ++k)
492        {
493          gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
494        }
495
496        if (gridMask_(gridMaskIndex))
497        {
498          localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
499          bool isIndexOnServer = true;
500          for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
501          {
502            isIndexOnServer = isIndexOnServer && elementZoomMask_[idxElement](idxLoop[idxElement]);
503          }
504
505          if (isIndexOnServer)
506          {
507            size_t globalIndex = 0;
508            for (int k = 0; k < numElement_; ++k)
509            {
510              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
511            }
512            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
513            localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
514            ++indexSend2ServerCount;
515          }
516          ++indexLocalDataOnClientCount;
517        }
518      }
519      ++countLocalData;
520    }
521    idxLoop[0] += innerLoopSize;
522    idx += innerLoopSize;
523  }
524}
525
526void CDistributionClient::createGlobalIndex()
527{
528  size_t ssize = 1, idx = 0;
529  for (int i = 0; i < this->dims_; ++i)
530  ssize *= nLocal_[i];
531
532  this->globalIndex_.resize(ssize);
533  std::vector<int> idxLoop(this->numElement_,0);
534  int innnerLoopSize = (*infoIndex_[0]).numElements();
535  while (idx < ssize)
536  {
537    for (int i = 0; i < this->numElement_; ++i)
538    {
539      if (idxLoop[i] == (*infoIndex_[indexMap_[i]]).numElements())
540      {
541        idxLoop[i] = 0;
542        ++idxLoop[i+1];
543      }
544    }
545
546    for (int i = 0; i < innnerLoopSize; ++i)
547    {
548      size_t globalIndex = (*infoIndex_[0])(idxLoop[0]);
549      size_t mulDim = 1;
550      for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
551      {
552        if (axisDomainOrder_(idxElement))
553        {
554          int jb = (0 == idxElement) ? 1 : 0;
555          for (int j = jb; j <= 1; ++j)
556          {
557            mulDim *= nGlob_[indexMap_[idxElement]+j-1];
558            globalIndex += ((*infoIndex_[indexMap_[idxElement]+j])(idxLoop[idxElement]))*mulDim;
559          }
560        }
561        else
562        {
563          if (0 != idxElement)
564          {
565            mulDim *= nGlob_[indexMap_[idxElement]-1];
566            globalIndex += ((*infoIndex_[indexMap_[idxElement]])(idxLoop[idxElement]))*mulDim;
567          }
568        }
569      }
570
571      this->globalIndex_(idx) = globalIndex;
572      ++idxLoop[0];
573      ++idx;
574    }
575  }
576
577}
578
579/*!
580  Retrieve index i and index j of a domain from its data index
581  Data contains not only true data, which are sent to servers, but also ghost data, which
582very often play a role of border of each local data, so does data index. Because data of a domain
583can be one dimension, or two dimensions, there is a need to convert data index to domain index
584  \param [in] dataIIndex index of i data
585  \param [in] dataJIndex index of j data
586  \param [in] dataIBegin index begin of i data
587  \param [in] dataJBegin index begin of j data
588  \param [in] dataDim dimension of data (1 or 2)
589  \param [in] ni local size ni of domain
590  \param [out] j j index of domain
591  \return i index of domain
592*/
593int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
594                                        const int& dataIBegin, const int& dataJBegin,
595                                        const int& dataDim, const int& ni, int& j)
596{
597  int tempI = dataIIndex + dataIBegin,
598      tempJ = (dataJIndex + dataJBegin);
599  int i = (dataDim == 1) ? (tempI) % ni
600                         : (tempI) ;
601  j = (dataDim == 1) ? (tempI) / ni
602                     : (tempJ) ;
603
604  return i;
605}
606
607/*!
608  Retrieve index of an axis from its data index
609  \param [in] dataIndex index of data
610  \param [in] dataBegin index begin of data
611  \param [in] ni local size of axis
612  \return index of domain
613*/
614int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
615{
616   int tempI = dataIndex + dataBegin;
617   return ((tempI)%ni);
618}
619
620/*!
621  Return global local data mapping of client
622*/
623CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
624{
625  if (!isComputed_) createGlobalIndexSendToServer();
626  return globalLocalDataSendToServerMap_;
627}
628
629/*!
630  Return local data index of client
631*/
632const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
633{
634  if (!isComputed_) createGlobalIndexSendToServer();
635  return localDataIndex_;
636}
637
638/*!
639  Return local mask index of client
640*/
641const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
642{
643  if (!isComputed_) createGlobalIndexSendToServer();
644  return localMaskIndex_;
645}
646
647} // namespace xios
Note: See TracBrowser for help on using the repository browser.