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

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

Making some minor changes in distribution client

+) Seperate global index computation and local index computation

Test
+) On Curie
+) OK

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