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

Last change on this file since 585 was 584, checked in by mhnguyen, 9 years ago

Implementing new hash algorithm and fixing bug related to zoom

+) Replace boost hash with hash algorithm of Jenkins
+) Domain, if an attribute is non-empty for one client, it should also be non-empty for others inspite of zoom
+) Replace the way to find the number of client connecting to a server to make sure every server receive a message

Test
+) On Curie
+) test_client: passed and results are same like before
+) test_complete: passed, results are partially the same, the different part comes from added working operation

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  // Update all the vectors above
186  while (idx < numElement_)
187  {
188    bool isDomain = axisDomainOrder(idx);
189
190    // If this is a domain
191    if (isDomain)
192    {
193      // On the j axis
194      nLocal_.at(indexMap_[idx]+1) = domList[domIndex]->nj.getValue();
195      nGlob_.at(indexMap_[idx]+1)  = domList[domIndex]->nj_glo.getValue();
196      nBeginLocal_.at(indexMap_[idx]+1) = 0;
197      nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
198      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->zoom_jbegin;
199      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->zoom_jbegin + domList[domIndex]->zoom_nj-1;
200
201      dataBegin_.at(indexMap_[idx]+1) = (2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
202      dataIndex_.at(indexMap_[idx]+1).resize(domList[domIndex]->data_j_index.numElements());
203      dataIndex_.at(indexMap_[idx]+1) = domList[domIndex]->data_j_index;
204
205      // On the i axis
206      nLocal_.at(indexMap_[idx]) = domList[domIndex]->ni.getValue();
207      nGlob_.at(indexMap_[idx]) = domList[domIndex]->ni_glo.getValue();
208      nBeginLocal_.at(indexMap_[idx]) = 0;
209      nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
210      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->zoom_ibegin;
211      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->zoom_ibegin + domList[domIndex]->zoom_ni-1;
212
213      dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
214      dataIndex_.at(indexMap_[idx]).resize(domList[domIndex]->data_i_index.numElements());
215      dataIndex_.at(indexMap_[idx]) = domList[domIndex]->data_i_index;
216
217      dataNIndex_.at(idx) = domList[domIndex]->data_n_index.getValue();
218      dataDims_.at(idx) = domList[domIndex]->data_dim.getValue();
219      ++domIndex;
220    }
221    else // So it's an axis
222    {
223      nLocal_.at(indexMap_[idx]) = axisList[axisIndex]->ni.getValue();
224      nGlob_.at(indexMap_[idx]) = axisList[axisIndex]->size.getValue();
225      nBeginLocal_.at(indexMap_[idx]) = 0;
226      nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->ibegin.getValue();
227      nZoomBegin_.at((indexMap_[idx])) = axisList[axisIndex]->zoom_begin;
228      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->zoom_begin + axisList[axisIndex]->zoom_size-1;
229
230      dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
231      dataIndex_.at(indexMap_[idx]).resize(axisList[axisIndex]->data_index.numElements());
232      dataIndex_.at(indexMap_[idx]) = axisList[axisIndex]->data_index;
233      dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
234      dataDims_.at(idx) = 1;
235      ++axisIndex;
236    }
237    ++idx;
238  }
239  readDomainIndex(domList);
240  readAxisIndex(axisList);
241
242  // Grid has only one axis and it is not distributed
243  bool isDataNotDistributed = true;
244  for (int i = 0; i < this->dims_; ++i)
245    isDataNotDistributed &= (nLocal_[i] == nGlob_[i]);
246  isDataDistributed_ = !isDataNotDistributed;
247}
248
249/*!
250  Create local index of domain(s).
251  A domain can have data index which even contains the "ghost" points. Very often, these
252data surround the true data. In order to send correct data to server,
253a client need to know index of the true data.
254*/
255void CDistributionClient::createLocalDomainDataIndex()
256{
257  int numDomain = 0;
258  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
259    if (axisDomainOrder_(i)) ++numDomain;
260
261  localDomainIndex_.resize(numDomain*2);
262  indexDomainData_.resize(numDomain);
263
264  int idxDomain = 0;
265  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
266  {
267    if (axisDomainOrder_(i))
268    {
269      int iIdx, jIdx = 0, count = 0;
270      indexDomainData_[idxDomain].resize(dataNIndex_[i], false);
271      for (int j = 0; j < dataNIndex_[i]; ++j)
272      {
273        iIdx = getDomainIndex(dataIndex_[indexMap_[i]](j), dataIndex_[indexMap_[i]+1](j),
274                              dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
275                              dataDims_[i], nLocal_[indexMap_[i]], jIdx);
276
277        if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
278           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
279           (domainMasks_[idxDomain](iIdx, jIdx)))
280        {
281          (localDomainIndex_[idxDomain]).push_back(iIdx);
282          (localDomainIndex_[idxDomain*2+1]).push_back(jIdx);
283          indexDomainData_[idxDomain][j] = true;
284        }
285      }
286      ++idxDomain;
287    }
288  }
289}
290
291/*!
292  Create local index of axis.
293*/
294void CDistributionClient::createLocalAxisDataIndex()
295{
296  int numAxis = 0;
297  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
298    if (!axisDomainOrder_(i)) ++numAxis;
299
300  localAxisIndex_.resize(numAxis);
301  indexAxisData_.resize(numAxis);
302
303  int idxAxis = 0;
304  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
305  {
306    if (!axisDomainOrder_(i))
307    {
308      int iIdx = 0;
309      indexAxisData_[idxAxis].resize(dataNIndex_[i], false);
310      for (int j = 0; j < dataNIndex_[i]; ++j)
311      {
312        iIdx = getAxisIndex(dataIndex_[indexMap_[i]](j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
313        if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
314           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
315        {
316          localAxisIndex_[idxAxis].push_back(iIdx);
317          indexAxisData_[idxAxis][j] = true;
318        }
319      }
320      ++idxAxis;
321    }
322  }
323}
324
325void CDistributionClient::createGlobalIndex()
326{
327  size_t ssize = 1, idx = 0;
328  for (int i = 0; i < this->dims_; ++i)
329    ssize *= nLocal_[i];
330
331  this->globalIndex_ = new CArray<size_t,1>(ssize);
332  std::vector<int> idxLoop(this->dims_,0);
333  int innnerLoopSize = nLocal_[0];
334  while (idx < ssize)
335  {
336    for (int i = 0; i < this->dims_; ++i)
337    {
338      if (idxLoop[i] == nLocal_[i])
339      {
340        idxLoop[i] = 0;
341        ++idxLoop[i+1];
342      }
343    }
344
345    for (int i = 0; i < innnerLoopSize; ++i)
346    {
347      size_t globalIndex = idxLoop[0] + nBeginGlobal_[0];
348      size_t mulDim = 1;
349      for (int k = 1; k < this->dims_; ++k)
350      {
351        mulDim *= nGlob_[k-1];
352        globalIndex += (idxLoop[k] + nBeginGlobal_[k])*mulDim;
353      }
354      (*this->globalIndex_)(idx) = globalIndex;
355      ++idxLoop[0];
356      ++idx;
357    }
358  }
359}
360
361
362/*!
363   Create global index on client
364   In order to do the mapping between client-server, each client creates its own
365global index of sending data. This global index is then used to calculate to which server
366the client needs to send it data as well as which part of data belongs to the server.
367So as to make clients and server coherent in order of index, global index is calculated by
368take into account of C-convention, the rightmost dimension varies faster.
369*/
370void CDistributionClient::createGlobalIndexSendToServer()
371{
372  createLocalDomainDataIndex();
373  createLocalAxisDataIndex();
374
375  int idxDomain = 0, idxAxis = 0;
376  std::vector<int> eachElementSize(numElement_);
377
378  // Precompute size of the loop
379  for (int i = 0; i < numElement_; ++i)
380  {
381    if(axisDomainOrder_(i))
382    {
383      eachElementSize[i] = localDomainIndex_[idxDomain].size();
384      idxDomain += 2;
385    }
386    else
387    {
388      eachElementSize[i] = localAxisIndex_[idxAxis].size();
389      ++idxAxis;
390    }
391  }
392
393  //   Compute size of the global index on client
394  std::vector<int> idxLoop(numElement_,0);
395  std::vector<int> currentIndex(this->dims_);
396  int innerLoopSize = eachElementSize[0];
397  size_t idx = 0, indexLocalDataOnClientCount = 0, indexSend2ServerCount = 0;
398  size_t ssize = 1;
399  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
400  while (idx < ssize)
401  {
402    for (int i = 0; i < numElement_-1; ++i)
403    {
404      if (idxLoop[i] == eachElementSize[i])
405      {
406        idxLoop[i] = 0;
407        ++idxLoop[i+1];
408      }
409    }
410
411    // Find out outer index
412    // Depending the inner-most element is axis or domain,
413    // The outer loop index begins correspondingly at one (1) or zero (0)
414    idxDomain = idxAxis = 0;
415    if (axisDomainOrder_(0)) ++idxDomain;
416    else ++idxAxis;
417    for (int i = 1; i < numElement_; ++i)
418    {
419      if (axisDomainOrder_(i))
420      {
421        currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][idxLoop[i]];
422        currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain+1][idxLoop[i]];
423        idxDomain += 2;
424      }
425      else
426      {
427        currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][idxLoop[i]];
428        ++idxAxis;
429      }
430    }
431
432    int maskIndex = currentIndex[0];
433    for (int j = 0; j < this->dims_; ++j)
434
435    // Inner most index
436    idxDomain = idxAxis = 0;
437    for (int i = 0; i < innerLoopSize; ++i)
438    {
439      if (axisDomainOrder_(0))
440      {
441        currentIndex[0] = localDomainIndex_[idxDomain][i];
442        currentIndex[1] = localDomainIndex_[idxDomain+1][i];
443      }
444      else currentIndex[0]   = localAxisIndex_[idxAxis][i];
445
446      int gridMaskIndex = currentIndex[0];
447      int mulDimMask = 1;
448      for (int k = 1; k < this->dims_; ++k)
449      {
450        mulDimMask *= nLocal_[k-1];
451        gridMaskIndex += (currentIndex[k])*mulDimMask;
452      }
453
454      if (gridMask_(gridMaskIndex)) //(gridMask_(currentIndex[0], currentIndex[1], currentIndex[2]))
455      {
456        ++indexLocalDataOnClientCount;
457        bool isIndexOnServer = true;
458        for (int j = 0; j < this->dims_; ++j)
459          isIndexOnServer = isIndexOnServer && ((currentIndex[j]+nBeginGlobal_[j]) <= nZoomEnd_[j])
460                                            && (nZoomBegin_[j] <= (currentIndex[j]+nBeginGlobal_[j]));
461        if (isIndexOnServer) ++indexSend2ServerCount;
462      }
463
464    }
465    idxLoop[0] += innerLoopSize;
466    idx += innerLoopSize;
467  }
468
469
470  // Now allocate these arrays
471  this->globalDataSendToServer_ = new CArray<size_t,1>(indexSend2ServerCount);
472  localDataIndex_ = new CArray<int,1>(indexLocalDataOnClientCount);
473  localDataIndexSendToServer_ = new CArray<int,1>(indexSend2ServerCount);
474
475  // We need to loop with data index
476  idxLoop.assign(numElement_,0);
477  idx = indexLocalDataOnClientCount = indexSend2ServerCount = 0;
478  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
479  innerLoopSize = dataNIndex_[0];
480  int countLocalData = 0;
481  std::vector<int> correctOuterIndex(numElement_,0);
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        ++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        }
512        else isIndexDomainDataCorrect = false;
513        ++idxDomain;
514      }
515      else
516      {
517        if (indexAxisData_[idxAxis][idxLoop[i]])
518        {
519          currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndex[i]];
520        }
521        else isIndexAxisDataCorrect = false;
522        ++idxAxis;
523      }
524    }
525
526    // Inner most index
527    idxDomain = idxAxis = 0;
528    int correctIndexDomain = 0, correctIndexAxis = 0;
529    for (int i = 0; i < innerLoopSize; ++i)
530    {
531      if (axisDomainOrder_(0))
532      {
533        if (indexDomainData_[idxDomain][i])
534        {
535          currentIndex[0] = localDomainIndex_[idxDomain][correctIndexDomain];
536          currentIndex[1] = localDomainIndex_[idxDomain+1][correctIndexDomain];
537          isIndexDomainDataCorrect = true;
538          ++correctIndexDomain;
539        }
540        else isIndexDomainDataCorrect = false;
541      }
542      else
543      {
544        if (indexAxisData_[idxAxis][i])
545        {
546          currentIndex[0] = localAxisIndex_[idxAxis][correctIndexAxis];
547          isIndexAxisDataCorrect = true;
548          ++correctIndexAxis;
549        }
550        else isIndexAxisDataCorrect = false;
551      }
552
553      int gridMaskIndex = currentIndex[0];
554      int mulDimMask = 1;
555      for (int k = 1; k < this->dims_; ++k)
556      {
557        mulDimMask *= nLocal_[k-1];
558        gridMaskIndex += (currentIndex[k])*mulDimMask;
559      }
560
561      if (isIndexDomainDataCorrect &&
562          isIndexAxisDataCorrect &&
563          gridMask_(gridMaskIndex))
564      {
565        (*localDataIndex_)(indexLocalDataOnClientCount) = countLocalData;
566
567        bool isIndexOnServer = true;
568        for (int j = 0; j < this->dims_; ++j)
569          isIndexOnServer = isIndexOnServer &&
570                            ((currentIndex[j]+nBeginGlobal_[j]) <= nZoomEnd_[j]) &&
571                            (nZoomBegin_[j] <= (currentIndex[j]+nBeginGlobal_[j]));
572        if (isIndexOnServer)
573        {
574          size_t globalIndex = currentIndex[0] + nBeginGlobal_[0];
575          size_t mulDim = 1;
576          for (int k = 1; k < this->dims_; ++k)
577          {
578            mulDim *= nGlob_[k-1];
579            globalIndex += (currentIndex[k] + nBeginGlobal_[k])*mulDim;
580          }
581          (*this->globalDataSendToServer_)(indexSend2ServerCount) = globalIndex;
582          (*localDataIndexSendToServer_)(indexSend2ServerCount) = indexLocalDataOnClientCount;
583          ++indexSend2ServerCount;
584        }
585        ++indexLocalDataOnClientCount;
586      }
587      ++countLocalData;
588    }
589    idxLoop[0] += innerLoopSize;
590    idx += innerLoopSize;
591  }
592}
593
594/*!
595  Retrieve index i and index j of a domain from its data index
596  Data contains not only true data, which are sent to servers, but also ghost data, which
597very often play a role of border of each local data, so does data index. Because data of a domain
598can be one dimension, or two dimensions, there is a need to convert data index to domain index
599  \param [in] dataIIndex index of i data
600  \param [in] dataJIndex index of j data
601  \param [in] dataIBegin index begin of i data
602  \param [in] dataJBegin index begin of j data
603  \param [in] dataDim dimension of data (1 or 2)
604  \param [in] ni local size ni of domain
605  \param [out] j j index of domain
606  \return i index of domain
607*/
608int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
609                                        const int& dataIBegin, const int& dataJBegin,
610                                        const int& dataDim, const int& ni, int& j)
611{
612  int tempI = dataIIndex + dataIBegin,
613      tempJ = (1 == dataDim) ? -1
614                             : (dataJIndex + dataJBegin);
615  int i = (dataDim == 1) ? (tempI - 1) % ni
616                     : (tempI - 1) ;
617  j = (dataDim == 1) ? (tempI - 1) / ni
618                     : (tempJ - 1) ;
619
620  return i;
621}
622
623/*!
624  Retrieve index of an axis from its data index
625  \param [in] dataIndex index of data
626  \param [in] dataBegin index begin of data
627  \param [in] ni local size of axis
628  \return index of domain
629*/
630int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
631{
632   int tempI = dataIndex + dataBegin;
633   return ((tempI-1)%ni);
634}
635
636const CArray<size_t,1>& CDistributionClient::getGlobalDataIndexSendToServer() const
637{
638  return (*globalDataSendToServer_);
639}
640
641/*!
642  Return local data index of client
643*/
644const CArray<int,1>& CDistributionClient::getLocalDataIndexOnClient() const
645{
646  return (*localDataIndex_);
647}
648
649/*!
650  Return local data index on client which are sent to servers
651*/
652const CArray<int,1>& CDistributionClient::getLocalDataIndexSendToServer() const
653{
654  return (*localDataIndexSendToServer_);
655}
656
657} // namespace xios
Note: See TracBrowser for help on using the repository browser.