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

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

My branch

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