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

Last change on this file since 1021 was 1021, checked in by oabramkina, 7 years ago

Intermeadiate version for merging with new server functionalities.

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