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

Last change on this file since 1077 was 1025, checked in by mhnguyen, 7 years ago

Merging working version of coupler

+) Add some changes of domain and axis: Retransfer the atttributes in a generic ways for each level of client (or server)
+) Remove some spoiled files from the previous commits

Test
+) No test

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