source: XIOS/dev/branch_yushan_merged/src/distribution_server.cpp @ 1205

Last change on this file since 1205 was 1205, checked in by yushan, 3 years ago

branch merged with trunk @1200

File size: 7.6 KB
Line 
1/*!
2   \file distribution_server.cpp
3   \author Ha NGUYEN
4   \since 13 Jan 2015
5   \date 10 Sep 2016
6
7   \brief Index distribution on server side.
8 */
9#include "distribution_server.hpp"
10#include "utils.hpp"
11
12namespace xios {
13
14CDistributionServer::CDistributionServer(int rank, int dims, const CArray<size_t,1>& globalIndex)
15  : CDistribution(rank, dims, globalIndex), nGlobal_(), nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_()
16{
17}
18
19CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
20                                         const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal)
21  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_()
22{
23  createGlobalIndex();
24}
25
26CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
27                                         const std::vector<int>& nZoomSize,
28                                         const std::vector<int>& nZoomBeginGlobal,
29                                         const std::vector<int>& nGlobal)
30  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
31    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_()
32{
33  createGlobalIndex();
34}
35
36CDistributionServer::CDistributionServer(int rank, 
37                                        const std::vector<CArray<int,1> >& globalIndexElements,
38                                        const CArray<int,1>& elementOrder,
39                                        const std::vector<int>& nZoomBeginServer,
40                                        const std::vector<int>& nZoomSizeServer,
41                                        const std::vector<int>& nZoomBeginGlobal,
42                                        const std::vector<int>& nGlobal)
43  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
44    nZoomSize_(nZoomSizeServer), nZoomBegin_(nZoomBeginServer), globalLocalIndexMap_()
45{
46  createGlobalIndex(globalIndexElements, elementOrder);
47}
48
49CDistributionServer::~CDistributionServer()
50{
51}
52
53/*!
54  Create global index on server side
55  Like the similar function on client side, this function serves on creating global index
56for data written by the server. The global index is used to calculating local index of data
57written on each server
58*/
59void CDistributionServer::createGlobalIndex()
60{
61  size_t idx = 0, ssize = 1;
62  for (int i = 0; i < nZoomSize_.size(); ++i) ssize *= nZoomSize_[i];
63
64  this->globalIndex_.resize(ssize);
65  std::vector<int> idxLoop(this->getDims(),0);
66  std::vector<int> currentIndex(this->getDims());
67  int innerLoopSize = nZoomSize_[0];
68
69  globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor()));
70  while (idx<ssize)
71  {
72    for (int i = 0; i < this->dims_-1; ++i)
73    {
74      if (idxLoop[i] == nZoomSize_[i])
75      {
76        idxLoop[i] = 0;
77        ++idxLoop[i+1];
78      }
79    }
80
81    for (int i = 1; i < this->dims_; ++i)  currentIndex[i] = idxLoop[i] + nZoomBegin_[i];
82
83    size_t mulDim, globalIndex;
84    for (int i = 0; i < innerLoopSize; ++i)
85    {
86      mulDim = 1;
87      globalIndex = i + nZoomBegin_[0];
88
89      for (int k = 1; k < this->dims_; ++k)
90      {
91        mulDim *= nGlobal_[k-1];
92        globalIndex += (currentIndex[k])*mulDim;
93      }
94      globalLocalIndexMap_[globalIndex] = idx;
95      this->globalIndex_(idx) = globalIndex;
96
97      ++idx;
98    }
99    idxLoop[0] += innerLoopSize;
100  }
101}
102
103/*!
104  Create global index on server side
105  Like the similar function on client side, this function serves on creating global index
106for data written by the server. The global index is used to calculating local index of data
107written on each server
108  \param[in] globalIndexElement global index on server side of each element of grid (scalar, axis, domain)
109  \param[in] elementOrder the order of elements of grid (e.x: domain->axis or domain->scalar)
110*/
111void CDistributionServer::createGlobalIndex(const std::vector<CArray<int,1> >& globalIndexElements,
112                                            const CArray<int,1>& elementOrder)
113{
114  int numElement = elementOrder.numElements(), elementIdx = 0; 
115  std::vector<int> indexMap(numElement);
116  for (int i = 0; i < numElement; ++i)
117  {
118    indexMap[i] = elementIdx;
119    if (2 == elementOrder(i))
120    {     
121      elementIdx += 2;
122    }
123    else
124      ++elementIdx;
125  }
126
127  std::vector<size_t> elementGlobalSize(numElement);
128  size_t globalSize = 1;
129  for (int i = 0; i < numElement; ++i)
130  {
131    int elementType = elementOrder(i);
132    elementGlobalSize[i] = globalSize;
133    if (2 == elementType) // domain
134    {
135      globalSize *= nGlobal_[indexMap[i]+1] * nGlobal_[indexMap[i]];
136    }
137    else // axis or scalar
138    {
139      globalSize *= nGlobal_[indexMap[i]];
140    }
141  } 
142
143  size_t ssize = 1;
144  for (int i = 0; i < globalIndexElements.size(); ++i) ssize *= globalIndexElements[i].numElements();
145  this->globalIndex_.resize(ssize);
146  globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor()));
147
148  std::vector<int> idxLoop(numElement,0);
149  std::vector<int> currentIndex(numElement);
150  int innerLoopSize = globalIndexElements[0].numElements();
151
152  size_t idx = 0;
153  while (idx<ssize)
154  {
155    for (int i = 0; i < numElement-1; ++i)
156    {
157      if (idxLoop[i] == globalIndexElements[i].numElements())
158      {
159        idxLoop[i] = 0;
160        ++idxLoop[i+1];
161      }
162    }
163
164    for (int i = 1; i < numElement; ++i)  currentIndex[i] = globalIndexElements[i](idxLoop[i]);
165
166    size_t mulDim, globalIndex;
167    for (int i = 0; i < innerLoopSize; ++i)
168    {     
169      globalIndex = 0;
170      currentIndex[0] = globalIndexElements[0](i);
171
172      for (int k = 0; k < numElement; ++k)
173      {     
174        globalIndex += (currentIndex[k])*elementGlobalSize[k];
175      }
176      globalLocalIndexMap_[globalIndex] = idx;
177      this->globalIndex_(idx) = globalIndex;
178      ++idx;
179    }
180    idxLoop[0] += innerLoopSize;
181  }
182}
183
184/*!
185  Compute local index for writing data on server
186  \param [in] globalIndex global index received from client
187  \return local index of written data
188*/
189CArray<size_t,1> CDistributionServer::computeLocalIndex(const CArray<size_t,1>& globalIndex)
190{
191  int ssize = globalIndex.numElements();
192  CArray<size_t,1> localIndex(ssize);
193  GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it;
194  for (int idx = 0; idx < ssize; ++idx)
195  {
196    it = globalLocalIndexMap_.find(globalIndex(idx));
197    if (ite != it)
198      localIndex(idx) = it->second;
199  }
200
201  return localIndex;
202}
203
204/*!
205  Compute local index for writing data on server
206  \param [in] globalIndex Global index received from client
207*/
208void CDistributionServer::computeLocalIndex(CArray<size_t,1>& globalIndex)
209{
210  int ssize = globalIndex.numElements();
211  CArray<size_t,1> localIndex(ssize);
212  GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it;
213  for (int idx = 0; idx < ssize; ++idx)
214  {
215    it = globalLocalIndexMap_.find(globalIndex(idx));
216    if (ite != it)
217      localIndex(idx) = it->second;
218  }
219
220  globalIndex.reference(localIndex);
221}
222
223/*!
224  Transforms local indexes owned by the server into global indexes
225  \param [in/out] indexes on input, local indexes of the server,
226                          on output, the corresponding global indexes
227*/
228void CDistributionServer::computeGlobalIndex(CArray<int,1>& indexes) const
229{
230  for (int i = 0; i < indexes.numElements(); ++i)
231  {
232    indexes(i) = globalIndex_(indexes(i));
233  }
234}
235
236
237const std::vector<int>& CDistributionServer::getZoomBeginGlobal() const
238{
239  return nZoomBeginGlobal_;
240}
241
242const std::vector<int>& CDistributionServer::getZoomBeginServer() const
243{
244  return nZoomBegin_;
245}
246
247const std::vector<int>& CDistributionServer::getZoomSizeServer() const
248{
249  return nZoomSize_;
250}
251} // namespace xios
Note: See TracBrowser for help on using the repository browser.