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

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

Grid mask is now applied in the source filter of clients: unmasked values are replaced by NaN. It is not reconstructed any more by servers.

This needs to be tested more rigorously before commiting to trunk.

File size: 22.1 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  // We need to loop with data index
469  idxLoop.assign(numElement_,0);
470  idx = indexLocalDataOnClientCount = 0;
471  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
472  innerLoopSize = dataNIndex_[0];
473  int countLocalData = 0;
474  std::vector<int> correctIndexOfElement(numElement_,0);
475  bool isOuterIndexCorrect = true;
476  while (idx < ssize)
477  {
478    for (int i = 0; i < numElement_-1; ++i)
479    {
480      if (idxLoop[i] == dataNIndex_[i])
481      {
482        idxLoop[i] = 0;
483        correctIndexOfElement[i] = 0;
484        ++idxLoop[i+1];
485        if (isOuterIndexCorrect) ++correctIndexOfElement[i+1];
486      }
487    }
488
489    // Depending the inner-most element axis or domain,
490    // The outer loop index begins correspondingly at one (1) or zero (0)
491    bool isIndexElementDataCorrect = true;
492    for (int i = 1; i < numElement_; ++i)
493    {
494      if (elementIndexData_[i](idxLoop[i]))
495      {
496        currentIndex[i] = elementLocalIndex_[i](correctIndexOfElement[i]);
497        currentGlobalIndex[i] = elementGlobalIndex_[i](correctIndexOfElement[i]);
498        isIndexElementDataCorrect &= true;
499      }
500      else isIndexElementDataCorrect = false;
501    }
502
503    isOuterIndexCorrect = isIndexElementDataCorrect;
504
505    if (isOuterIndexCorrect)
506    {
507      // Inner most index
508      int correctIndexInnerElement = 0;
509      for (int i = 0; i < innerLoopSize; ++i)
510      {
511        bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
512        if (elementIndexData_[0](i))
513        {
514          currentIndex[0] = elementLocalIndex_[0](correctIndexInnerElement);
515          currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexInnerElement);
516          isCurrentIndexDataCorrect &= true;
517          ++correctIndexInnerElement;
518        }
519        else isCurrentIndexDataCorrect = false;
520
521        if (isCurrentIndexDataCorrect)
522        {
523          bool maskTmp = true;
524          bool maskGridTmp = true;
525
526          // Domain or axis mask: only unmasked values will be sent
527          int idxDomain = 0, idxAxis = 0;
528          for (int elem = 0; elem < numElement_; ++elem)
529          {
530            if (2 == axisDomainOrder_(elem))
531            {
532              maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]);
533              ++idxDomain;
534            }
535            else if (1 == axisDomainOrder_(elem))
536            {
537              maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]);
538              ++idxAxis;
539            }
540          }
541
542          // Grid mask: unmasked values will be replaces by NaN and then all values will be sent
543          if (!gridMask_.isEmpty())
544          {
545            int gridMaskIndex = 0;
546            for (int k = 0; k < this->numElement_; ++k)
547            {
548              gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
549            }
550            maskGridTmp =  gridMask_(gridMaskIndex);
551          }
552
553          if (maskTmp)
554          {
555            size_t globalIndex = 0;
556            for (int k = 0; k < numElement_; ++k)
557            {
558              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
559            }
560            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
561            localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
562            if (maskGridTmp)
563              localMaskIndex_[indexLocalDataOnClientCount] = true;
564            else
565              localMaskIndex_[indexLocalDataOnClientCount] = false;
566            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
567            localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
568            ++indexLocalDataOnClientCount;
569          }
570        }
571        ++countLocalData;
572        correctIndexOfElement[0] = correctIndexInnerElement;;
573      }
574    }
575    idxLoop[0] += innerLoopSize;
576    idx += innerLoopSize;
577  }
578}
579
580void CDistributionClient::createGlobalIndex()
581{
582}
583
584/*!
585  Retrieve index i and index j of a domain from its data index
586  Data contains not only true data, which are sent to servers, but also ghost data, which
587very often play a role of border of each local data, so does data index. Because data of a domain
588can be one dimension, or two dimensions, there is a need to convert data index to domain index
589  \param [in] dataIIndex index of i data
590  \param [in] dataJIndex index of j data
591  \param [in] dataIBegin index begin of i data
592  \param [in] dataJBegin index begin of j data
593  \param [in] dataDim dimension of data (1 or 2)
594  \param [in] ni local size ni of domain
595  \param [out] j j index of domain
596  \return i index of domain
597*/
598int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
599                                        const int& dataIBegin, const int& dataJBegin,
600                                        const int& dataDim, const int& ni, int& j)
601{
602  int tempI = dataIIndex + dataIBegin,
603      tempJ = (dataJIndex + dataJBegin);
604  if (ni == 0)
605  {
606    int i = 0;
607    j = 0;
608    return i;
609  }
610  int i = (dataDim == 1) ? (tempI) % ni
611                         : (tempI) ;
612  j = (dataDim == 1) ? (tempI) / ni
613                     : (tempJ) ;
614
615  return i;
616}
617
618/*!
619  Retrieve index of an axis from its data index
620  \param [in] dataIndex index of data
621  \param [in] dataBegin index begin of data
622  \param [in] ni local size of axis
623  \return index of domain
624*/
625int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
626{
627  if (ni == 0)
628  {
629    return -1;
630  }
631  int tempI = dataIndex; //+ dataBegin;
632  if ((tempI < 0) || (tempI > ni))
633    return -1;
634  else
635    return tempI;
636}
637
638/*!
639  Return global local data mapping of client
640*/
641CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
642{
643  if (!isComputed_) createGlobalIndexSendToServer();
644  return globalLocalDataSendToServerMap_;
645}
646
647CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalDataIndexOnClient()
648{
649  if (!isComputed_) createGlobalIndexSendToServer();
650  return globalDataIndex_;
651}
652
653/*!
654  Return local data index of client
655*/
656const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
657{
658  if (!isComputed_) createGlobalIndexSendToServer();
659  return localDataIndex_;
660}
661
662/*!
663  Return local mask index of client
664*/
665const std::vector<bool>& CDistributionClient::getLocalMaskIndexOnClient()
666{
667  if (!isComputed_) createGlobalIndexSendToServer();
668  return localMaskIndex_;
669}
670
671/*!
672  Return local mask index of client
673*/
674const std::vector<int>& CDistributionClient::getLocalMaskedDataIndexOnClient()
675{
676  if (!isComputed_) createGlobalIndexSendToServer();
677  return localMaskedDataIndex_;
678}
679
680} // namespace xios
681
Note: See TracBrowser for help on using the repository browser.