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

Last change on this file since 1557 was 1557, checked in by oabramkina, 6 years ago

Bugfix for distributed axis with ghost points.

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