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

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

First rebond on the secondary server pool. XIOS finalizes correctly.

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