source: XIOS/dev/dev_olga/src/distribution_client.cpp @ 1148

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

Cleaning up some redundant codes

File size: 22.6 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  elementLocalIndex_.resize(numElement_);
155  elementGlobalIndex_.resize(numElement_);
156  elementIndexData_.resize(numElement_);
157  elementZoomMask_.resize(numElement_);
158  elementNLocal_.resize(numElement_);
159  elementNGlobal_.resize(numElement_);
160
161  elementNLocal_[0] = 1;
162  elementNGlobal_[0] = 1;
163  isDataDistributed_ = false;
164
165  size_t localSize = 1, globalSize = 1;
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 
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)) = 0; //domList[domIndex]->global_zoom_jbegin;
188      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->nj_glo.getValue()- 1; //domList[domIndex]->global_zoom_jbegin + domList[domIndex]->global_zoom_nj-1;
189
190      dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue();
191      dataIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->data_j_index);
192      infoIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->j_index);
193
194      // On the i axis
195      nLocal_.at(indexMap_[idx]) = domList[domIndex]->ni.getValue();
196      nGlob_.at(indexMap_[idx]) = domList[domIndex]->ni_glo.getValue();
197      nBeginLocal_.at(indexMap_[idx]) = 0;
198      nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
199      nZoomBegin_.at((indexMap_[idx])) = 0; // domList[domIndex]->global_zoom_ibegin;
200      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->ni_glo.getValue() -1; //domList[domIndex]->global_zoom_ibegin + domList[domIndex]->global_zoom_ni-1;
201
202      dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
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])) = 0; //axisList[axisIndex]->global_zoom_begin;
222      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->n_glo.getValue() - 1; //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]).reference(axisList[axisIndex]->data_index);
226      infoIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->index);
227      dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
228      dataDims_.at(idx) = 1;
229
230      isDataDistributed_ |= axisList[axisIndex]->isDistributed();
231
232      localSize *= nLocal_.at(indexMap_[idx]);
233      globalSize *= nGlob_.at(indexMap_[idx]);
234
235      ++axisIndex;
236    }
237    else // scalar
238    {
239      nLocal_.at(indexMap_[idx]) = 1;
240      nGlob_.at(indexMap_[idx]) = 1;
241      nBeginLocal_.at(indexMap_[idx]) = 0;
242      nBeginGlobal_.at(indexMap_[idx]) = 1;
243      nZoomBegin_.at((indexMap_[idx])) = 0;
244      nZoomEnd_.at((indexMap_[idx])) = 0;
245
246      dataBegin_.at(indexMap_[idx]) = 0;
247      dataIndex_.at(indexMap_[idx]).resize(1); dataIndex_.at(indexMap_[idx])(0) = 0;
248      infoIndex_.at(indexMap_[idx]).resize(1); infoIndex_.at(indexMap_[idx])(0) = 0;
249      dataNIndex_.at(idx) = 1;
250      dataDims_.at(idx) = 1;
251
252      isDataDistributed_ |= false;
253
254      localSize *= nLocal_.at(indexMap_[idx]);
255      globalSize *= nGlob_.at(indexMap_[idx]);
256
257      ++scalarIndex;
258    }
259  }
260}
261
262/*!
263  Create local index of domain(s).
264  A domain can have data index which even contains the "ghost" points. Very often, these
265data surround the true data. In order to send correct data to server,
266a client need to know index of the true data.
267*/
268void CDistributionClient::createLocalDomainDataIndex()
269{
270  int idxDomain = 0;
271  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
272  {
273    if (2 == axisDomainOrder_(i))
274    {
275      elementIndexData_[i].resize(dataNIndex_[i]);
276      elementIndexData_[i] = false;
277      int iIdx, jIdx = 0, count = 0, localIndex;
278      for (int j = 0; j < dataNIndex_[i]; ++j)
279      {
280        iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
281                              dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
282                              dataDims_[i], nLocal_[indexMap_[i]], jIdx);
283
284        if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
285           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
286           (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]])))
287        {
288          ++count;
289          elementIndexData_[i](j) = true;
290        }
291      }
292
293      elementLocalIndex_[i].resize(count);
294      elementGlobalIndex_[i].resize(count);
295      elementZoomMask_[i].resize(count);
296      elementZoomMask_[i] = false;
297      count = 0;
298      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
299      CArray<bool,1>& tmpZoomMaskElement = elementZoomMask_[i];
300      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
301      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
302      for (int j = 0; j < dataNIndex_[i]; ++j)
303      {
304        if (tmpIndexElementData(j))
305        {
306          iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
307                                dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
308                                dataDims_[i], nLocal_[indexMap_[i]], jIdx);
309          localIndex = tmpLocalElementIndex(count) = iIdx + jIdx * nLocal_[indexMap_[i]];
310          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(localIndex) + ((infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
311          if ((((infoIndex_[indexMap_[i]])(localIndex)) <= nZoomEnd_[indexMap_[i]])
312             && (nZoomBegin_[indexMap_[i]] <= ((infoIndex_[indexMap_[i]])(localIndex)))
313             && (((infoIndex_[indexMap_[i]+1])(localIndex)) <= nZoomEnd_[indexMap_[i]+1])
314             && (nZoomBegin_[indexMap_[i]+1] <= ((infoIndex_[indexMap_[i]+1])(localIndex))))
315          {
316            tmpZoomMaskElement(count) = true;
317          }
318          ++count;
319        }
320      }
321      ++idxDomain;
322    }
323  }
324}
325
326/*!
327  Create local index of axis.
328*/
329void CDistributionClient::createLocalAxisDataIndex()
330{
331  int idxAxis = 0;
332  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
333  {
334    if (1 == axisDomainOrder_(i))
335    {
336      elementIndexData_[i].resize(dataNIndex_[i]);
337      elementIndexData_[i] = false;
338      int iIdx = 0, count = 0, localIndex = 0;
339      for (int j = 0; j < dataNIndex_[i]; ++j)
340      {
341        iIdx = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
342        if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
343           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
344        {
345          ++count;
346          elementIndexData_[i](j) = true;
347        }
348      }
349
350      elementLocalIndex_[i].resize(count);
351      elementGlobalIndex_[i].resize(count);
352      elementZoomMask_[i].resize(count);
353      elementZoomMask_[i] = false;
354      count = 0;
355      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
356      CArray<bool,1>& tmpZoomMaskElement = elementZoomMask_[i];
357      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
358      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
359      for (int j = 0; j < dataNIndex_[i]; ++j)
360      {
361        if (tmpIndexElementData(j))
362        {
363          iIdx = tmpLocalElementIndex(count) = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
364          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(iIdx);
365          if ((((infoIndex_[indexMap_[i]])(iIdx)) <= nZoomEnd_[indexMap_[i]])
366             && (nZoomBegin_[indexMap_[i]] <= ((infoIndex_[indexMap_[i]])(iIdx))))
367          {
368            tmpZoomMaskElement(count) = true;
369          }
370          ++count;
371        }
372      }
373      ++idxAxis;
374    }
375  }
376}
377
378/*!
379  Create local index of scalar.
380*/
381void CDistributionClient::createLocalScalarDataIndex()
382{
383  int idxAxis = 0;
384  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
385  {
386    if (0 == axisDomainOrder_(i))
387    {
388      elementIndexData_[i].resize(dataNIndex_[i]);
389      elementIndexData_[i] = true;
390      int count = 1;
391
392      elementLocalIndex_[i].resize(count);
393      elementLocalIndex_[i] = 0;
394      elementGlobalIndex_[i].resize(count);
395      elementGlobalIndex_[i] = 0;
396      elementZoomMask_[i].resize(count);
397      elementZoomMask_[i] = true;
398    }
399  }
400}
401
402/*!
403   Create global index on client
404   In order to do the mapping between client-server, each client creates its own
405global index of sending data. This global index is then used to calculate to which server
406the client needs to send it data as well as which part of data belongs to the server.
407So as to make clients and server coherent in order of index, global index is calculated by
408take into account of C-convention, the rightmost dimension varies faster.
409*/
410void CDistributionClient::createGlobalIndexSendToServer()
411{
412  if (isComputed_) return;
413  isComputed_ = true;
414  createLocalDomainDataIndex();
415  createLocalAxisDataIndex();
416  createLocalScalarDataIndex();
417
418  int idxDomain = 0, idxAxis = 0;
419  std::vector<int> eachElementSize(numElement_);
420
421  // Precompute size of the loop
422  for (int i = 0; i < numElement_; ++i)
423  {
424    eachElementSize[i] = elementLocalIndex_[i].numElements();
425  }
426
427  //   Compute size of the global index on client
428  std::vector<StdSize> idxLoop(numElement_,0);
429  std::vector<StdSize> currentIndex(numElement_,0);
430  std::vector<StdSize> currentGlobalIndex(numElement_,0);
431  int innerLoopSize = eachElementSize[0];
432  size_t idx = 0, indexLocalDataOnClientCount = 0, indexSend2ServerCount = 0;
433  size_t ssize = 1;
434  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
435  while (idx < ssize)
436  {
437    for (int i = 0; i < numElement_-1; ++i)
438    {
439      if (idxLoop[i] == eachElementSize[i])
440      {
441        idxLoop[i] = 0;
442        ++idxLoop[i+1];
443      }
444    }
445
446    // Find out outer index
447    // Depending the inner-most element is axis or domain,
448    // The outer loop index begins correspondingly at one (1) or zero (0)
449    for (int i = 1; i < numElement_; ++i)
450    {
451      currentIndex[i] = elementLocalIndex_[i](idxLoop[i]);
452    }
453
454    // Inner most index
455    for (int i = 0; i < innerLoopSize; ++i)
456    {
457      int gridMaskIndex = 0;
458      currentIndex[0] = elementLocalIndex_[0](i);
459      for (int k = 0; k < this->numElement_; ++k)
460      {
461        gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
462      }
463
464      if (gridMask_(gridMaskIndex))
465      {
466        ++indexLocalDataOnClientCount;
467        bool isIndexOnServer = true;
468
469        for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
470        {
471          isIndexOnServer = isIndexOnServer && elementZoomMask_[idxElement](idxLoop[idxElement]);
472        }
473        if (isIndexOnServer) ++indexSend2ServerCount;
474      }
475    }
476    idxLoop[0] += innerLoopSize;
477    idx += innerLoopSize;
478  }
479
480  // Now allocate these arrays
481  localDataIndex_.resize(indexLocalDataOnClientCount);
482  localMaskIndex_.resize(indexSend2ServerCount);
483  globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor())); //globalLocalDataSendToServerMap_.reserve(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            size_t globalIndex = 0;
550            for (int k = 0; k < numElement_; ++k)
551            {
552              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
553            }
554            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
555            localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
556            bool isIndexOnServer = true;
557            for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
558            {
559              isIndexOnServer = isIndexOnServer && elementZoomMask_[idxElement](correctIndexOfElement[idxElement]);
560            }
561
562            if (isIndexOnServer)
563            {
564              globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
565              localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
566              ++indexSend2ServerCount;
567            }
568            ++indexLocalDataOnClientCount;
569          }
570        }
571        ++countLocalData;
572        correctIndexOfElement[0] = correctIndexInnerElement;;
573      }
574    }
575    idxLoop[0] += innerLoopSize;
576    idx += innerLoopSize;
577  }
578}
579
580void CDistributionClient::createGlobalIndex()
581{
582}
583
584/*!
585  Retrieve index i and index j of a domain from its data index
586  Data contains not only true data, which are sent to servers, but also ghost data, which
587very often play a role of border of each local data, so does data index. Because data of a domain
588can be one dimension, or two dimensions, there is a need to convert data index to domain index
589  \param [in] dataIIndex index of i data
590  \param [in] dataJIndex index of j data
591  \param [in] dataIBegin index begin of i data
592  \param [in] dataJBegin index begin of j data
593  \param [in] dataDim dimension of data (1 or 2)
594  \param [in] ni local size ni of domain
595  \param [out] j j index of domain
596  \return i index of domain
597*/
598int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
599                                        const int& dataIBegin, const int& dataJBegin,
600                                        const int& dataDim, const int& ni, int& j)
601{
602  int tempI = dataIIndex + dataIBegin,
603      tempJ = (dataJIndex + dataJBegin);
604  int i = (dataDim == 1) ? (tempI) % ni
605                         : (tempI) ;
606  j = (dataDim == 1) ? (tempI) / ni
607                     : (tempJ) ;
608
609  return i;
610}
611
612/*!
613  Retrieve index of an axis from its data index
614  \param [in] dataIndex index of data
615  \param [in] dataBegin index begin of data
616  \param [in] ni local size of axis
617  \return index of domain
618*/
619int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
620{
621   int tempI = dataIndex + dataBegin;
622   return ((tempI)%ni);
623}
624
625/*!
626  Return global local data mapping of client
627*/
628CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
629{
630  if (!isComputed_) createGlobalIndexSendToServer();
631  return globalLocalDataSendToServerMap_;
632}
633
634CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalDataIndexOnClient()
635{
636  if (!isComputed_) createGlobalIndexSendToServer();
637  return globalDataIndex_;
638}
639
640/*!
641  Return local data index of client
642*/
643const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
644{
645  if (!isComputed_) createGlobalIndexSendToServer();
646  return localDataIndex_;
647}
648
649/*!
650  Return local mask index of client
651*/
652const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
653{
654  if (!isComputed_) createGlobalIndexSendToServer();
655  return localMaskIndex_;
656}
657
658} // namespace xios
Note: See TracBrowser for help on using the repository browser.