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

Last change on this file since 1570 was 1570, checked in by oabramkina, 3 years ago

Further simplifications on sending data/grid indexes.

(1) Domain/axis mask is not sent anymore. It has been incorporated into data index.

(2) Creating a map that holds grid mask only in case if grid mask is defined.

Still to fix: a hole in a domain or axis.

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