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

Last change on this file since 932 was 932, checked in by mhnguyen, 4 years ago

Adding Fortran interface for high-dimension grid (up to 7)

+) Add check mask for high-dimension grid
+) Add Fortran interface for send_field, recv_field

Test
+) On Curie
+) Work

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