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

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

Adding new transformation for scalar: Reducing an axis to a scalar

+) Add new xml node for new transformation
+) Add new algorithms for axis reduction
+) Make change in some place to make sure everything work fine

Test
+) On Curie
+) Tests pass and are correct

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