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

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

Adding a new type of element into grid: Scalar

+) Add a new node Scalar for xml
+) Make some change on writing scalar value
+) Reorganize some codes
+) Remove some redundant codes

Test
+) On Curie
+) All tests pass

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