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

Last change on this file since 773 was 668, checked in by mhnguyen, 9 years ago

Implementing some code factoring

+) Replace some slow searching function by faster ones

Test
+) On Curie
+) test_client and test_complete are correct

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