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

Last change on this file since 660 was 660, checked in by mhnguyen, 7 years ago

Adding interpolation test_remap

+) Add new test case for domain interpolation
+) Resolve circular dependence
+) Add function to read weigh file

Test
+) On Curie
+) test_remap can print out .nc

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