source: XIOS/dev/XIOS_DEV_CMIP6/src/distribution_client.cpp @ 1269

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

Fixing bug on mask grid

+) Add mask_0d for scalar grid
+) Transmit grid's attributes (mask) from client and reconstruct them correctly on server
+) Rebuild data in the input of data flow on the server side

Test
+) On Curie
+) Simple test

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