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

Last change on this file since 843 was 843, checked in by mhnguyen, 8 years ago

Several improvements

+) Replace some time-consuming operations by simpler ones

Test
+) On Curie
+) All tests pass

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