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

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

Minor correction for distribution client

+) Make sure the index of first element of grid initialized

Test
+) No test

File size: 35.8 KB
Line 
1/*!
2   \file distribution_client.cpp
3   \author Ha NGUYEN
4   \since 13 Jan 2015
5   \date 09 Mars 2015
6
7   \brief Index distribution on client side.
8 */
9#include "distribution_client.hpp"
10
11namespace xios {
12
13CDistributionClient::CDistributionClient(int rank, int dims, const CArray<size_t,1>& globalIndex)
14   : CDistribution(rank, dims, globalIndex)
15   , axisDomainOrder_()
16   , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_()
17   , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_()
18   , gridMask_(), indexMap_()
19   , isDataDistributed_(true), axisNum_(0), domainNum_(0)
20   , localDataIndex_(), localMaskIndex_()
21   , globalLocalDataSendToServerMap_()
22   , infoIndex_(), isComputed_(false)
23   , elementLocalIndex_(), elementGlobalIndex_(), elementIndexData_()
24   , elementZoomMask_(), elementNLocal_(), elementNGlobal_()
25{
26}
27
28CDistributionClient::CDistributionClient(int rank, CGrid* grid)
29   : CDistribution(rank, 0)
30   , axisDomainOrder_()
31   , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_()
32   , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_()
33   , gridMask_(), indexMap_()
34   , isDataDistributed_(true), axisNum_(0), domainNum_(0)
35   , localDataIndex_(), localMaskIndex_()
36   , globalLocalDataSendToServerMap_()
37   , infoIndex_(), isComputed_(false)
38   , elementLocalIndex_(), elementGlobalIndex_(), elementIndexData_()
39   , elementZoomMask_(), elementNLocal_(), elementNGlobal_()
40{
41  readDistributionInfo(grid);
42  createGlobalIndex();
43}
44
45CDistributionClient::~CDistributionClient()
46{ /* Nothing to do */ }
47
48/*!
49  Read information of a grid to generate distribution.
50  Every grid is composed of several axis or/and domain(s). Their information are processed
51stored and used to calculate index distribution between client and server
52  \param [in] grid Grid to read
53*/
54void CDistributionClient::readDistributionInfo(CGrid* grid)
55{
56  std::vector<CDomain*> domList = grid->getDomains();
57  std::vector<CAxis*> axisList = grid->getAxis();
58  CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
59
60  std::vector<CDomain*>::iterator itbDom, iteDom, itDom;
61  std::vector<CAxis*>::iterator itbAxis, iteAxis, itAxis;
62
63  itbDom  = itDom  = domList.begin();  iteDom  = domList.end();
64  itbAxis = itAxis = axisList.begin(); iteAxis = axisList.end();
65
66  readDistributionInfo(domList, axisList, axisDomainOrder);
67
68  // Then check mask of grid
69  int gridDim = domList.size() * 2 + axisList.size();
70  grid->checkMask();
71  switch (gridDim) {
72    case 1:
73      readGridMaskInfo(grid->mask_1d);
74      break;
75    case 2:
76      readGridMaskInfo(grid->mask_2d);
77      break;
78    case 3:
79      readGridMaskInfo(grid->mask_3d);
80      break;
81    default:
82      break;
83  }
84}
85
86/*!
87  Read information from domain(s) and axis to generate distribution.
88  All information related to domain, e.g ibegin, jbegin, ni, nj, ni_glo, nj_glo
89as well as related to axis, e.g dataNIndex, dataIndex will be stored to compute
90the distribution between clients and servers. Till now, every data structure of domain has been kept
91like before, e.g: data_n_index to make sure a compability, however, it should be changed?
92  \param [in] domList List of domains of grid
93  \param [in] axisList List of axis of grid
94  \param [in] axisDomainOrder order of axis and domain inside a grid. True if domain, false if axis
95//  \param [in] gridMask Mask of grid, for now, keep it 3 dimension, but it needs changing
96*/
97void CDistributionClient::readDistributionInfo(const std::vector<CDomain*>& domList,
98                                               const std::vector<CAxis*>& axisList,
99                                               const CArray<bool,1>& axisDomainOrder)
100{
101  domainNum_ = domList.size();
102  axisNum_   = axisList.size();
103  numElement_ = axisDomainOrder.numElements(); // Number of element, e.x: Axis, Domain
104
105  axisDomainOrder_.resize(numElement_);
106  axisDomainOrder_ = axisDomainOrder;
107
108  // Each domain or axis has its mask, of course
109  domainMasks_.resize(domainNum_);
110  for (int i = 0; i < domainNum_;++i)
111  {
112    domainMasks_[i].resize(domList[i]->mask_1d.numElements());
113    domainMasks_[i] = domList[i]->mask_1d;
114  }
115
116  axisMasks_.resize(axisNum_);
117  for (int i = 0; i < axisNum_; ++i)
118  {
119    axisMasks_[i].resize(axisList[i]->mask.numElements());
120    axisMasks_[i] = axisList[i]->mask;
121  }
122
123  // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
124  // their position should be specified. In axisDomainOrder, domain == true, axis == false
125  int idx = 0;
126  indexMap_.resize(numElement_);
127  this->dims_ = numElement_;
128  for (int i = 0; i < numElement_; ++i)
129  {
130    indexMap_[i] = idx;
131    if (true == axisDomainOrder(i))
132    {
133      ++(this->dims_);
134      idx += 2;
135    }
136    else ++idx;
137  }
138
139  // Size of each dimension (local and global)
140  nLocal_.resize(this->dims_);
141  nGlob_.resize(this->dims_);
142  nBeginLocal_.resize(this->dims_,0);
143  nBeginGlobal_.resize(this->dims_,0);
144  nZoomBegin_.resize(this->dims_);
145  nZoomEnd_.resize(this->dims_);
146
147  // Data_n_index of domain or axis (For now, axis uses its size as data_n_index
148  dataNIndex_.resize(numElement_);
149  dataDims_.resize(numElement_);
150  dataBegin_.resize(this->dims_);
151
152  // Data_*_index of each dimension
153  dataIndex_.resize(this->dims_);
154  infoIndex_.resize(this->dims_);
155
156  // A trick to determine position of each domain in domainList
157  int domIndex = 0, axisIndex = 0;
158  idx = 0;
159
160  elementLocalIndex_.resize(numElement_);
161  elementGlobalIndex_.resize(numElement_);
162  elementIndexData_.resize(numElement_);
163  elementZoomMask_.resize(numElement_);
164  elementNLocal_.resize(numElement_);
165  elementNGlobal_.resize(numElement_);
166  elementNLocal_[0] = 1;
167  elementNGlobal_[0] = 1;
168  size_t localSize = 1, globalSize = 1;
169
170  isDataDistributed_ = false;
171  // Update all the vectors above
172  for (idx = 0; idx < numElement_; ++idx)
173  {
174    bool isDomain = axisDomainOrder(idx);
175    elementNLocal_[idx] = localSize;
176    elementNGlobal_[idx] = globalSize;
177
178    // If this is a domain
179    if (isDomain)
180    {
181      // On the j axis
182      nLocal_.at(indexMap_[idx]+1) = domList[domIndex]->nj.getValue();
183      nGlob_.at(indexMap_[idx]+1)  = domList[domIndex]->nj_glo.getValue();
184      nBeginLocal_.at(indexMap_[idx]+1) = 0;
185      nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
186      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->global_zoom_jbegin;
187      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->global_zoom_jbegin + domList[domIndex]->global_zoom_nj-1;
188
189      dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue(); //(2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
190      dataIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->data_j_index);
191      infoIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->j_index);
192
193      // On the i axis
194      nLocal_.at(indexMap_[idx]) = domList[domIndex]->ni.getValue();
195      nGlob_.at(indexMap_[idx]) = domList[domIndex]->ni_glo.getValue();
196      nBeginLocal_.at(indexMap_[idx]) = 0;
197      nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
198      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->global_zoom_ibegin;
199      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->global_zoom_ibegin + domList[domIndex]->global_zoom_ni-1;
200
201      dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
202      dataIndex_.at(indexMap_[idx]) = &(domList[domIndex]->data_i_index);
203      infoIndex_.at(indexMap_[idx]) = &(domList[domIndex]->i_index);
204
205      dataNIndex_.at(idx) = domList[domIndex]->data_i_index.numElements();
206      dataDims_.at(idx) = domList[domIndex]->data_dim.getValue();
207
208      isDataDistributed_ |= domList[domIndex]->isDistributed();
209
210      localSize *= nLocal_.at(indexMap_[idx]+1)* nLocal_.at(indexMap_[idx]);
211      globalSize *= nGlob_.at(indexMap_[idx]+1)* nGlob_.at(indexMap_[idx]);
212      ++domIndex;
213    }
214    else // So it's an axis
215    {
216      nLocal_.at(indexMap_[idx]) = axisList[axisIndex]->n.getValue();
217      nGlob_.at(indexMap_[idx]) = axisList[axisIndex]->n_glo.getValue();
218      nBeginLocal_.at(indexMap_[idx]) = 0;
219      nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->begin.getValue();
220      nZoomBegin_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin;
221      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin + axisList[axisIndex]->global_zoom_n-1;
222
223      dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
224      dataIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->data_index);
225      infoIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->index);
226      dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
227      dataDims_.at(idx) = 1;
228
229      isDataDistributed_ |= axisList[axisIndex]->isDistributed();
230
231      localSize *= nLocal_.at(indexMap_[idx]);
232      globalSize *= nGlob_.at(indexMap_[idx]);
233
234      ++axisIndex;
235    }
236  }
237}
238
239/*!
240  Create local index of domain(s).
241  A domain can have data index which even contains the "ghost" points. Very often, these
242data surround the true data. In order to send correct data to server,
243a client need to know index of the true data.
244*/
245void CDistributionClient::createLocalDomainDataIndex()
246{
247  int idxDomain = 0;
248  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
249  {
250    if (axisDomainOrder_(i))
251    {
252      elementIndexData_[i].resize(dataNIndex_[i]);
253      elementIndexData_[i] = false;
254      int iIdx, jIdx = 0, count = 0, localIndex;
255      for (int j = 0; j < dataNIndex_[i]; ++j)
256      {
257        iIdx = getDomainIndex((*dataIndex_[indexMap_[i]])(j), (*dataIndex_[indexMap_[i]+1])(j),
258                              dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
259                              dataDims_[i], nLocal_[indexMap_[i]], jIdx);
260
261        if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
262           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
263           (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]])))
264        {
265          ++count;
266          elementIndexData_[i](j) = true;
267        }
268      }
269
270      elementLocalIndex_[i].resize(count);
271      elementGlobalIndex_[i].resize(count);
272      elementZoomMask_[i].resize(count);
273      elementZoomMask_[i] = false;
274      count = 0;
275      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
276      CArray<bool,1>& tmpZoomMaskElement = elementZoomMask_[i];
277      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
278      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
279      for (int j = 0; j < dataNIndex_[i]; ++j)
280      {
281        if (tmpIndexElementData(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          localIndex = tmpLocalElementIndex(count) = iIdx + jIdx * nLocal_[indexMap_[i]];
287          tmpGlobalElementIndex(count) = (*infoIndex_[indexMap_[i]])(localIndex) + ((*infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
288          if ((((*infoIndex_[indexMap_[i]])(localIndex)) <= nZoomEnd_[indexMap_[i]])
289             && (nZoomBegin_[indexMap_[i]] <= ((*infoIndex_[indexMap_[i]])(localIndex)))
290             && (((*infoIndex_[indexMap_[i]+1])(localIndex)) <= nZoomEnd_[indexMap_[i]+1])
291             && (nZoomBegin_[indexMap_[i]+1] <= ((*infoIndex_[indexMap_[i]+1])(localIndex))))
292          {
293            tmpZoomMaskElement(count) = true;
294          }
295          ++count;
296        }
297      }
298      ++idxDomain;
299    }
300  }
301}
302
303/*!
304  Create local index of axis.
305*/
306void CDistributionClient::createLocalAxisDataIndex()
307{
308  int idxAxis = 0;
309  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
310  {
311    if (!axisDomainOrder_(i))
312    {
313      elementIndexData_[i].resize(dataNIndex_[i]);
314      elementIndexData_[i] = false;
315      int iIdx = 0, count = 0, localIndex = 0;
316      for (int j = 0; j < dataNIndex_[i]; ++j)
317      {
318        iIdx = getAxisIndex((*dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
319        if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
320           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
321        {
322          ++count;
323          elementIndexData_[i](j) = true;
324        }
325      }
326
327      elementLocalIndex_[i].resize(count);
328      elementGlobalIndex_[i].resize(count);
329      elementZoomMask_[i].resize(count);
330      elementZoomMask_[i] = false;
331      count = 0;
332      CArray<bool,1>& tmpIndexElementData = elementIndexData_[i];
333      CArray<bool,1>& tmpZoomMaskElement = elementZoomMask_[i];
334      CArray<int,1>& tmpLocalElementIndex = elementLocalIndex_[i];
335      CArray<size_t,1>& tmpGlobalElementIndex = elementGlobalIndex_[i];
336      for (int j = 0; j < dataNIndex_[i]; ++j)
337      {
338        if (tmpIndexElementData(j))
339        {
340          iIdx = tmpLocalElementIndex(count) = getAxisIndex((*dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
341          tmpGlobalElementIndex(count) = (*infoIndex_[indexMap_[i]])(iIdx);
342          if ((((*infoIndex_[indexMap_[i]])(iIdx)) <= nZoomEnd_[indexMap_[i]])
343             && (nZoomBegin_[indexMap_[i]] <= ((*infoIndex_[indexMap_[i]])(iIdx))))
344          {
345            tmpZoomMaskElement(count) = true;
346          }
347          ++count;
348        }
349      }
350      ++idxAxis;
351    }
352  }
353}
354
355/*!
356   Create global index on client
357   In order to do the mapping between client-server, each client creates its own
358global index of sending data. This global index is then used to calculate to which server
359the client needs to send it data as well as which part of data belongs to the server.
360So as to make clients and server coherent in order of index, global index is calculated by
361take into account of C-convention, the rightmost dimension varies faster.
362*/
363void CDistributionClient::createGlobalIndexSendToServer()
364{
365  if (isComputed_) return;
366  isComputed_ = true;
367  createLocalDomainDataIndex();
368  createLocalAxisDataIndex();
369
370  int idxDomain = 0, idxAxis = 0;
371  std::vector<int> eachElementSize(numElement_);
372
373  // Precompute size of the loop
374  for (int i = 0; i < numElement_; ++i)
375  {
376    eachElementSize[i] = elementLocalIndex_[i].numElements();
377  }
378
379  //   Compute size of the global index on client
380  std::vector<StdSize> idxLoop(numElement_,0);
381  std::vector<StdSize> currentIndex(numElement_,0);
382  std::vector<StdSize> currentGlobalIndex(numElement_,0);
383  int innerLoopSize = eachElementSize[0];
384  size_t idx = 0, indexLocalDataOnClientCount = 0, indexSend2ServerCount = 0;
385  size_t ssize = 1;
386  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
387  while (idx < ssize)
388  {
389    for (int i = 0; i < numElement_-1; ++i)
390    {
391      if (idxLoop[i] == eachElementSize[i])
392      {
393        idxLoop[i] = 0;
394        ++idxLoop[i+1];
395      }
396    }
397
398    // Find out outer index
399    // Depending the inner-most element is axis or domain,
400    // The outer loop index begins correspondingly at one (1) or zero (0)
401    for (int i = 1; i < numElement_; ++i)
402    {
403      currentIndex[i] = elementLocalIndex_[i](idxLoop[i]);
404    }
405
406    // Inner most index
407    for (int i = 0; i < innerLoopSize; ++i)
408    {
409      int gridMaskIndex = 0;
410      currentIndex[0] = elementLocalIndex_[0](i);
411      for (int k = 0; k < this->numElement_; ++k)
412      {
413        gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
414      }
415
416      if (gridMask_(gridMaskIndex))
417      {
418        ++indexLocalDataOnClientCount;
419        bool isIndexOnServer = true;
420
421        for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
422        {
423          isIndexOnServer = isIndexOnServer && elementZoomMask_[idxElement](idxLoop[idxElement]);
424        }
425        if (isIndexOnServer) ++indexSend2ServerCount;
426      }
427    }
428    idxLoop[0] += innerLoopSize;
429    idx += innerLoopSize;
430  }
431
432  // Now allocate these arrays
433  localDataIndex_.resize(indexLocalDataOnClientCount);
434  localMaskIndex_.resize(indexSend2ServerCount);
435  globalLocalDataSendToServerMap_.rehash(std::ceil(indexSend2ServerCount/globalLocalDataSendToServerMap_.max_load_factor())); //globalLocalDataSendToServerMap_.reserve(indexSend2ServerCount);
436
437  // We need to loop with data index
438  idxLoop.assign(numElement_,0);
439  idx = indexLocalDataOnClientCount = indexSend2ServerCount = 0;
440  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
441  innerLoopSize = dataNIndex_[0];
442  int countLocalData = 0;
443  std::vector<int> correctOuterIndex(numElement_,0);
444  bool isOuterIndexCorrect = true;
445  while (idx < ssize)
446  {
447    for (int i = 0; i < numElement_-1; ++i)
448    {
449      if (idxLoop[i] == dataNIndex_[i])
450      {
451        idxLoop[i] = 0;
452        correctOuterIndex[i] = 0;
453        ++idxLoop[i+1];
454        if (isOuterIndexCorrect) ++correctOuterIndex[i+1];
455      }
456    }
457
458    // Depending the inner-most element axis or domain,
459    // The outer loop index begins correspondingly at one (1) or zero (0)
460    bool isIndexElementDataCorrect = true;
461    for (int i = 1; i < numElement_; ++i)
462    {
463      if (elementIndexData_[i](idxLoop[i]))
464      {
465        currentIndex[i] = elementLocalIndex_[i](correctOuterIndex[i]);
466        currentGlobalIndex[i] = elementGlobalIndex_[i](correctOuterIndex[i]);
467        isIndexElementDataCorrect &= true;
468      }
469      else isIndexElementDataCorrect = false;
470    }
471
472    isOuterIndexCorrect = isIndexElementDataCorrect;
473
474    // Inner most index
475    int correctIndexElement = 0;
476    for (int i = 0; i < innerLoopSize; ++i)
477    {
478      bool isCurrentIndexDataCorrect = isOuterIndexCorrect;
479      if (elementIndexData_[0](i))
480      {
481        currentIndex[0] = elementLocalIndex_[0](correctIndexElement);
482        currentGlobalIndex[0] = elementGlobalIndex_[0](correctIndexElement);
483        isCurrentIndexDataCorrect &= true;
484        ++correctIndexElement;
485      }
486      else isCurrentIndexDataCorrect = false;
487
488      if (isCurrentIndexDataCorrect)
489      {
490        int gridMaskIndex = 0; //currentIndex[0];
491        for (int k = 0; k < this->numElement_; ++k)
492        {
493          gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
494        }
495
496        if (gridMask_(gridMaskIndex))
497        {
498          localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
499          bool isIndexOnServer = true;
500          for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
501          {
502            isIndexOnServer = isIndexOnServer && elementZoomMask_[idxElement](idxLoop[idxElement]);
503          }
504
505          if (isIndexOnServer)
506          {
507            size_t globalIndex = 0; //currentGlobalIndex[0];
508            for (int k = 0; k < numElement_; ++k)
509            {
510              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
511            }
512            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
513            localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
514            ++indexSend2ServerCount;
515          }
516          ++indexLocalDataOnClientCount;
517        }
518      }
519      ++countLocalData;
520    }
521    idxLoop[0] += innerLoopSize;
522    idx += innerLoopSize;
523  }
524}
525
526///*!
527//  Create local index of domain(s).
528//  A domain can have data index which even contains the "ghost" points. Very often, these
529//data surround the true data. In order to send correct data to server,
530//a client need to know index of the true data.
531//*/
532//void CDistributionClient::createLocalDomainDataIndex()
533//{
534//  int numDomain = 0;
535//  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
536//    if (axisDomainOrder_(i)) ++numDomain;
537//
538//  localDomainIndex_.resize(numDomain*2);
539//  indexDomainData_.resize(numDomain);
540//
541//  int idxDomain = 0;
542//  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
543//  {
544//    if (axisDomainOrder_(i))
545//    {
546//      int iIdx, jIdx = 0, count = 0;
547//      indexDomainData_[idxDomain].resize(dataNIndex_[i], false);
548//      for (int j = 0; j < dataNIndex_[i]; ++j)
549//      {
550//        iIdx = getDomainIndex((*dataIndex_[indexMap_[i]])(j), (*dataIndex_[indexMap_[i]+1])(j),
551//                              dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
552//                              dataDims_[i], nLocal_[indexMap_[i]], jIdx);
553//
554//        if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
555//           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
556//           (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]])))
557//        {
558//          (localDomainIndex_[idxDomain]).push_back(iIdx);
559//          (localDomainIndex_[idxDomain*2+1]).push_back(jIdx);
560//          indexDomainData_[idxDomain][j] = true;
561//        }
562//      }
563//      ++idxDomain;
564//    }
565//  }
566//}
567
568///*!
569//  Create local index of axis.
570//*/
571//void CDistributionClient::createLocalAxisDataIndex()
572//{
573//  int numAxis = 0;
574//  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
575//    if (!axisDomainOrder_(i)) ++numAxis;
576//
577//  localAxisIndex_.resize(numAxis);
578//  indexAxisData_.resize(numAxis);
579//
580//  int idxAxis = 0;
581//  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
582//  {
583//    if (!axisDomainOrder_(i))
584//    {
585//      int iIdx = 0;
586//      indexAxisData_[idxAxis].resize(dataNIndex_[i], false);
587//      for (int j = 0; j < dataNIndex_[i]; ++j)
588//      {
589//        iIdx = getAxisIndex((*dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
590//        if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
591//           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
592//        {
593//          localAxisIndex_[idxAxis].push_back(iIdx);
594//          indexAxisData_[idxAxis][j] = true;
595//        }
596//      }
597//      ++idxAxis;
598//    }
599//  }
600//}
601
602void CDistributionClient::createGlobalIndex()
603{
604  size_t ssize = 1, idx = 0;
605  for (int i = 0; i < this->dims_; ++i)
606  ssize *= nLocal_[i];
607
608  this->globalIndex_.resize(ssize);
609  std::vector<int> idxLoop(this->numElement_,0);
610  int innnerLoopSize = (*infoIndex_[0]).numElements();
611  while (idx < ssize)
612  {
613    for (int i = 0; i < this->numElement_; ++i)
614    {
615      if (idxLoop[i] == (*infoIndex_[indexMap_[i]]).numElements())
616      {
617        idxLoop[i] = 0;
618        ++idxLoop[i+1];
619      }
620    }
621
622    for (int i = 0; i < innnerLoopSize; ++i)
623    {
624      size_t globalIndex = (*infoIndex_[0])(idxLoop[0]);
625      size_t mulDim = 1;
626      for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
627      {
628        if (axisDomainOrder_(idxElement))
629        {
630          int jb = (0 == idxElement) ? 1 : 0;
631          for (int j = jb; j <= 1; ++j)
632          {
633            mulDim *= nGlob_[indexMap_[idxElement]+j-1];
634            globalIndex += ((*infoIndex_[indexMap_[idxElement]+j])(idxLoop[idxElement]))*mulDim;
635          }
636        }
637        else
638        {
639          if (0 != idxElement)
640          {
641            mulDim *= nGlob_[indexMap_[idxElement]-1];
642            globalIndex += ((*infoIndex_[indexMap_[idxElement]])(idxLoop[idxElement]))*mulDim;
643          }
644        }
645      }
646
647      this->globalIndex_(idx) = globalIndex;
648      ++idxLoop[0];
649      ++idx;
650    }
651  }
652
653}
654
655
656///*!
657//   Create global index on client
658//   In order to do the mapping between client-server, each client creates its own
659//global index of sending data. This global index is then used to calculate to which server
660//the client needs to send it data as well as which part of data belongs to the server.
661//So as to make clients and server coherent in order of index, global index is calculated by
662//take into account of C-convention, the rightmost dimension varies faster.
663//*/
664//void CDistributionClient::createGlobalIndexSendToServer()
665//{
666//  if (isComputed_) return;
667//  isComputed_ = true;
668//  createLocalDomainDataIndex();
669//  createLocalAxisDataIndex();
670//
671//  int idxDomain = 0, idxAxis = 0;
672//  std::vector<int> eachElementSize(numElement_);
673//
674//  // Precompute size of the loop
675//  for (int i = 0; i < numElement_; ++i)
676//  {
677//    if(axisDomainOrder_(i))
678//    {
679//      eachElementSize[i] = localDomainIndex_[idxDomain].size();
680//      idxDomain += 2;
681//    }
682//    else
683//    {
684//      eachElementSize[i] = localAxisIndex_[idxAxis].size();
685//      ++idxAxis;
686//    }
687//  }
688//
689//  //   Compute size of the global index on client
690//  std::vector<StdSize> idxLoop(numElement_,0);
691//  std::vector<StdSize> currentIndex(this->dims_,0);
692//  int innerLoopSize = eachElementSize[0];
693//  size_t idx = 0, indexLocalDataOnClientCount = 0, indexSend2ServerCount = 0;
694//  size_t ssize = 1;
695//  for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
696//  while (idx < ssize)
697//  {
698//    for (int i = 0; i < numElement_-1; ++i)
699//    {
700//      if (idxLoop[i] == eachElementSize[i])
701//      {
702//        idxLoop[i] = 0;
703//        ++idxLoop[i+1];
704//      }
705//    }
706//
707//    // Find out outer index
708//    // Depending the inner-most element is axis or domain,
709//    // The outer loop index begins correspondingly at one (1) or zero (0)
710//    idxDomain = idxAxis = 0;
711//    if (axisDomainOrder_(0)) ++idxDomain;
712//    else ++idxAxis;
713//    for (int i = 1; i < numElement_; ++i)
714//    {
715//      if (axisDomainOrder_(i))
716//      {
717//        currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][idxLoop[i]];
718//        currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain+1][idxLoop[i]];
719//        idxDomain += 2;
720//      }
721//      else
722//      {
723//        currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][idxLoop[i]];
724//        ++idxAxis;
725//      }
726//    }
727//
728//    // Inner most index
729//    idxDomain = idxAxis = 0;
730//    for (int i = 0; i < innerLoopSize; ++i)
731//    {
732//      if (axisDomainOrder_(0))
733//      {
734//        currentIndex[0] = localDomainIndex_[idxDomain][i];
735//        currentIndex[1] = localDomainIndex_[idxDomain+1][i];
736//      }
737//      else currentIndex[0]   = localAxisIndex_[idxAxis][i];
738//
739//      StdSize gridMaskIndex = currentIndex[0];
740//      int mulDimMask = 1;
741//      for (int k = 1; k < this->dims_; ++k)
742//      {
743//        mulDimMask *= nLocal_[k-1];
744//        gridMaskIndex += (currentIndex[k])*mulDimMask;
745//      }
746//
747//      if (gridMask_(gridMaskIndex))
748//      {
749//        ++indexLocalDataOnClientCount;
750//        bool isIndexOnServer = true;
751//
752//        for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
753//        {
754//          int actualIdx = 0;
755//          if (axisDomainOrder_(idxElement))
756//          {
757//            actualIdx = currentIndex[indexMap_[idxElement]]+currentIndex[indexMap_[idxElement]+1]*nLocal_[indexMap_[idxElement]];
758//            isIndexOnServer = isIndexOnServer && (((*infoIndex_[indexMap_[idxElement]])(actualIdx)) <= nZoomEnd_[indexMap_[idxElement]])
759//                                              && (nZoomBegin_[indexMap_[idxElement]] <= ((*infoIndex_[indexMap_[idxElement]])(actualIdx)))
760//                                              && (((*infoIndex_[indexMap_[idxElement]+1])(actualIdx)) <= nZoomEnd_[indexMap_[idxElement]+1])
761//                                              && (nZoomBegin_[indexMap_[idxElement]+1] <= ((*infoIndex_[indexMap_[idxElement]+1])(actualIdx)));
762//          }
763//          else
764//          {
765//            isIndexOnServer = isIndexOnServer && (((*infoIndex_[indexMap_[idxElement]])(currentIndex[indexMap_[idxElement]])) <= nZoomEnd_[indexMap_[idxElement]])
766//                                              && (nZoomBegin_[indexMap_[idxElement]] <= ((*infoIndex_[indexMap_[idxElement]])(currentIndex[indexMap_[idxElement]])));
767//          }
768//        }
769//        if (isIndexOnServer) ++indexSend2ServerCount;
770//      }
771//
772//    }
773//    idxLoop[0] += innerLoopSize;
774//    idx += innerLoopSize;
775//  }
776//
777//  // Now allocate these arrays
778//  localDataIndex_.resize(indexLocalDataOnClientCount);
779//  localMaskIndex_.resize(indexSend2ServerCount);
780//  globalLocalDataSendToServerMap_.rehash(std::ceil(indexSend2ServerCount/globalLocalDataSendToServerMap_.max_load_factor())); //globalLocalDataSendToServerMap_.reserve(indexSend2ServerCount);
781//
782//  // We need to loop with data index
783//  idxLoop.assign(numElement_,0);
784//  idx = indexLocalDataOnClientCount = indexSend2ServerCount = 0;
785//  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
786//  innerLoopSize = dataNIndex_[0];
787//  int countLocalData = 0;
788//  std::vector<int> correctOuterIndex(numElement_,0);
789//  bool isOuterIndexCorrect = true;
790//  while (idx < ssize)
791//  {
792//    for (int i = 0; i < numElement_-1; ++i)
793//    {
794//      if (idxLoop[i] == dataNIndex_[i])
795//      {
796//        idxLoop[i] = 0;
797//        correctOuterIndex[i] = 0;
798//        ++idxLoop[i+1];
799//        if (isOuterIndexCorrect) ++correctOuterIndex[i+1];
800//      }
801//    }
802//
803//    // Depending the inner-most element axis or domain,
804//    // The outer loop index begins correspondingly at one (1) or zero (0)
805//    idxDomain = idxAxis = 0;
806//    if (axisDomainOrder_(0)) ++idxDomain;
807//    else ++idxAxis;
808//    bool isIndexDomainDataCorrect = true;
809//    bool isIndexAxisDataCorrect = true;
810//
811//    for (int i = 1; i < numElement_; ++i)
812//    {
813//      if (axisDomainOrder_(i))
814//      {
815//        if (indexDomainData_[idxDomain][idxLoop[i]])
816//        {
817//          currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][correctOuterIndex[i]];
818//          currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain*2+1][correctOuterIndex[i]];
819//          isIndexDomainDataCorrect &= true;
820//        }
821//        else isIndexDomainDataCorrect = false;
822//        ++idxDomain;
823//      }
824//      else
825//      {
826//        if (indexAxisData_[idxAxis][idxLoop[i]])
827//        {
828//          currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndex[i]];
829//          isIndexAxisDataCorrect &= true;
830//        }
831//        else isIndexAxisDataCorrect = false;
832//        ++idxAxis;
833//      }
834//    }
835//
836//    isOuterIndexCorrect = (isIndexAxisDataCorrect) && (isIndexDomainDataCorrect);
837//
838//    // Inner most index
839//    idxDomain = idxAxis = 0;
840//    int correctIndexDomain = 0, correctIndexAxis = 0;
841//    for (int i = 0; i < innerLoopSize; ++i)
842//    {
843//      bool isCurrentIndexDomainDataCorrect = isIndexDomainDataCorrect;
844//      bool isCurrentIndexAxisDataCorrect = isIndexAxisDataCorrect;
845//
846//      if (axisDomainOrder_(0))
847//      {
848//        if (indexDomainData_[idxDomain][i])
849//        {
850//          currentIndex[0] = localDomainIndex_[idxDomain][correctIndexDomain];
851//          currentIndex[1] = localDomainIndex_[idxDomain+1][correctIndexDomain];
852//          isCurrentIndexDomainDataCorrect &= true;
853//          ++correctIndexDomain;
854//        }
855//        else isCurrentIndexDomainDataCorrect = false;
856//      }
857//      else
858//      {
859//        if (indexAxisData_[idxAxis][i])
860//        {
861//          currentIndex[0] = localAxisIndex_[idxAxis][correctIndexAxis];
862//          isCurrentIndexAxisDataCorrect &= true;
863//          ++correctIndexAxis;
864//        }
865//        else isCurrentIndexAxisDataCorrect = false;
866//      }
867//
868//      int gridMaskIndex = currentIndex[0];
869//      int mulDimMask = 1;
870//      for (int k = 1; k < this->dims_; ++k)
871//      {
872//        mulDimMask *= nLocal_[k-1];
873//        gridMaskIndex += (currentIndex[k])*mulDimMask;
874//      }
875//
876//      if (isCurrentIndexDomainDataCorrect &&
877//          isCurrentIndexAxisDataCorrect &&
878//          gridMask_(gridMaskIndex))
879//      {
880//        localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
881//        bool isIndexOnServer = true;
882//        for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
883//        {
884//          int actualIdx = 0;
885//          if (axisDomainOrder_(idxElement))
886//          {
887//            actualIdx = currentIndex[indexMap_[idxElement]]+currentIndex[indexMap_[idxElement]+1]*nLocal_[indexMap_[idxElement]];
888//            isIndexOnServer = isIndexOnServer && (((*infoIndex_[indexMap_[idxElement]])(actualIdx)) <= nZoomEnd_[indexMap_[idxElement]])
889//                                              && (nZoomBegin_[indexMap_[idxElement]] <= ((*infoIndex_[indexMap_[idxElement]])(actualIdx)))
890//                                              && (((*infoIndex_[indexMap_[idxElement]+1])(actualIdx)) <= nZoomEnd_[indexMap_[idxElement]+1])
891//                                              && (nZoomBegin_[indexMap_[idxElement]+1] <= ((*infoIndex_[indexMap_[idxElement]+1])(actualIdx)));
892//          }
893//          else
894//          {
895//            isIndexOnServer = isIndexOnServer && (((*infoIndex_[indexMap_[idxElement]])(currentIndex[indexMap_[idxElement]])) <= nZoomEnd_[indexMap_[idxElement]])
896//                                              && (nZoomBegin_[indexMap_[idxElement]] <= ((*infoIndex_[indexMap_[idxElement]])(currentIndex[indexMap_[idxElement]])));
897//          }
898//        }
899//
900//        if (isIndexOnServer)
901//        {
902//          int actualIdx = (axisDomainOrder_(0)) ? currentIndex[0]+currentIndex[1]*nLocal_[0]
903//                                                : currentIndex[0];
904//          size_t globalIndex = (*infoIndex_[0])(actualIdx); //idxLoop[0] + nBeginGlobal_[0];
905//          size_t mulDim = 1;
906//          for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
907//          {
908//            if (axisDomainOrder_(idxElement))
909//            {
910//              actualIdx = currentIndex[indexMap_[idxElement]]+currentIndex[indexMap_[idxElement]+1]*nLocal_[indexMap_[idxElement]];
911//              int jb = (0 == idxElement) ? 1 : 0;
912//              for (int j = jb; j <= 1; ++j)
913//              {
914//                mulDim *= nGlob_[indexMap_[idxElement]+j-1];
915//                globalIndex += ((*infoIndex_[indexMap_[idxElement]+j])(actualIdx))*mulDim;
916//              }
917//            }
918//            else
919//            {
920//              if (0 != idxElement)
921//              {
922//                mulDim *= nGlob_[indexMap_[idxElement]-1];
923//                globalIndex += ((*infoIndex_[indexMap_[idxElement]])(currentIndex[indexMap_[idxElement]]))*mulDim;
924//              }
925//            }
926//          }
927//          globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
928//          localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
929//          ++indexSend2ServerCount;
930//        }
931//        ++indexLocalDataOnClientCount;
932//      }
933//      ++countLocalData;
934//    }
935//    idxLoop[0] += innerLoopSize;
936//    idx += innerLoopSize;
937//  }
938//}
939
940/*!
941  Retrieve index i and index j of a domain from its data index
942  Data contains not only true data, which are sent to servers, but also ghost data, which
943very often play a role of border of each local data, so does data index. Because data of a domain
944can be one dimension, or two dimensions, there is a need to convert data index to domain index
945  \param [in] dataIIndex index of i data
946  \param [in] dataJIndex index of j data
947  \param [in] dataIBegin index begin of i data
948  \param [in] dataJBegin index begin of j data
949  \param [in] dataDim dimension of data (1 or 2)
950  \param [in] ni local size ni of domain
951  \param [out] j j index of domain
952  \return i index of domain
953*/
954int CDistributionClient::getDomainIndex(const int& dataIIndex, const int& dataJIndex,
955                                        const int& dataIBegin, const int& dataJBegin,
956                                        const int& dataDim, const int& ni, int& j)
957{
958  int tempI = dataIIndex + dataIBegin,
959      tempJ = (dataJIndex + dataJBegin);
960  int i = (dataDim == 1) ? (tempI) % ni
961                         : (tempI) ;
962  j = (dataDim == 1) ? (tempI) / ni
963                     : (tempJ) ;
964
965  return i;
966}
967
968/*!
969  Retrieve index of an axis from its data index
970  \param [in] dataIndex index of data
971  \param [in] dataBegin index begin of data
972  \param [in] ni local size of axis
973  \return index of domain
974*/
975int CDistributionClient::getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni)
976{
977   int tempI = dataIndex + dataBegin;
978   return ((tempI)%ni);
979}
980
981/*!
982  Return global local data mapping of client
983*/
984CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalLocalDataSendToServer()
985{
986  if (!isComputed_) createGlobalIndexSendToServer();
987  return globalLocalDataSendToServerMap_;
988}
989
990/*!
991  Return local data index of client
992*/
993const std::vector<int>& CDistributionClient::getLocalDataIndexOnClient()
994{
995  if (!isComputed_) createGlobalIndexSendToServer();
996  return localDataIndex_;
997}
998
999/*!
1000  Return local mask index of client
1001*/
1002const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
1003{
1004  if (!isComputed_) createGlobalIndexSendToServer();
1005  return localMaskIndex_;
1006}
1007
1008} // namespace xios
Note: See TracBrowser for help on using the repository browser.