source: XIOS/trunk/src/node/distribution_client.cpp @ 594

Last change on this file since 594 was 594, checked in by rlacroix, 9 years ago

Change the definition of non distributed axis and domain.

Axis and domain were considered non distributed if the local domain matched the full domain. Instead allow the local domain definition to be ommited and consider the axis or domain to be non distributed in this case.

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