source: XIOS/dev/dev_olga/src/distribution_server.cpp @ 1099

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

Updating 2-level server

+) Make some changes in the way data rebuilt on each level of server
+) Make some changes in the order of functions call during close context to make sure that each server receives the global indexes before calculating index to send to next level
+) Modify some functions to make sure data sent to the correct server pool

Test
+) On Curie
+) Only test_client

File size: 6.7 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  globalIndexEachDimension_()
17{
18}
19
20CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
21                                         const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal)
22  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_(),
23  globalIndexEachDimension_()
24{
25  createGlobalIndex();
26}
27
28CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
29                                         const std::vector<int>& nZoomSize,
30                                         const std::vector<int>& nZoomBeginGlobal,
31                                         const std::vector<int>& nGlobal)
32  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
33    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_(),
34    globalIndexEachDimension_()
35{
36  createGlobalIndex();
37}
38
39CDistributionServer::CDistributionServer(int rank, 
40                                         const std::vector<CArray<int,1> >& globalIndexEachDimension,
41                                         const std::vector<int>& nGlobal)
42  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(),
43    nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_(), 
44    globalIndexEachDimension_(globalIndexEachDimension)
45{
46  createGlobalIndexFromIndex(globalIndexEachDimension, nGlobal);
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
103void CDistributionServer::createGlobalIndexFromIndex(const std::vector<CArray<int,1> >& globalIndexOnEachDimension,
104                                                     const std::vector<int>& nbGlobal)
105{
106  size_t idx = 0, ssize = 1;
107  for (int i = 0; i < globalIndexOnEachDimension.size(); ++i) ssize *= globalIndexOnEachDimension[i].numElements();
108
109  this->globalIndex_.resize(ssize);
110  size_t nbDim = nbGlobal.size();
111  std::vector<int> idxLoop(nbDim,0);
112  std::vector<int> currentIndex(nbDim);
113  int innerLoopSize = globalIndexOnEachDimension[0].numElements();
114
115  globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor()));
116  while (idx<ssize)
117  {
118    for (int i = 0; i < nbDim-1; ++i)
119    {
120      if (idxLoop[i] == globalIndexOnEachDimension[i].numElements())
121      {
122        idxLoop[i] = 0;
123        ++idxLoop[i+1];
124      }
125    }
126
127    for (int i = 1; i < nbDim; ++i)
128      currentIndex[i] = globalIndexOnEachDimension[i](idxLoop[i]);
129
130    size_t mulDim, globalIndex;
131    for (int i = 0; i < innerLoopSize; ++i)
132    {
133      mulDim = 1;
134      globalIndex = globalIndexOnEachDimension[0](i);
135
136      for (int k = 0; k < nbDim; ++k)
137      {
138        mulDim *= nbGlobal[k];
139        globalIndex += (currentIndex[k])*mulDim;
140      }
141      globalLocalIndexMap_[globalIndex] = idx;
142      this->globalIndex_(idx) = globalIndex;
143
144      ++idx;
145    }
146    idxLoop[0] += innerLoopSize;
147  }
148
149}
150
151/*!
152  Compute local index for writing data on server
153  \param [in] globalIndex global index received from client
154  \return local index of written data
155*/
156CArray<size_t,1> CDistributionServer::computeLocalIndex(const CArray<size_t,1>& globalIndex)
157{
158  int ssize = globalIndex.numElements();
159  CArray<size_t,1> localIndex(ssize);
160  GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it;
161  for (int idx = 0; idx < ssize; ++idx)
162  {
163    it = globalLocalIndexMap_.find(globalIndex(idx));
164    if (ite != it)
165      localIndex(idx) = it->second;
166  }
167
168  return localIndex;
169}
170
171/*!
172  Compute local index for writing data on server
173  \param [in] globalIndex Global index received from client
174*/
175void CDistributionServer::computeLocalIndex(CArray<size_t,1>& globalIndex)
176{
177  size_t ssize = globalIndex.numElements();
178  size_t localIndexSize = std::min(globalIndex_.numElements(), ssize);
179  CArray<size_t,1> localIndex(localIndexSize);
180  GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it;
181  int i = 0;
182  for (size_t idx = 0; idx < ssize; ++idx)
183  {
184    it = globalLocalIndexMap_.find(globalIndex(idx));
185    if (ite != it)
186    {
187      localIndex(i) = it->second;
188      ++i;
189    }
190  }
191
192  globalIndex.reference(localIndex);
193}
194
195/*!
196  Transforms local indexes owned by the server into global indexes
197  \param [in/out] indexes on input, local indexes of the server,
198                          on output, the corresponding global indexes
199*/
200void CDistributionServer::computeGlobalIndex(CArray<int,1>& indexes) const
201{
202  for (int i = 0; i < indexes.numElements(); ++i)
203  {
204    indexes(i) = globalIndex_(indexes(i));
205  }
206}
207
208/*!
209  Get the size of grid index in server (e.x: sizeGrid *= size of each dimensiion)
210*/
211int CDistributionServer::getGridSize() const
212{
213   return globalLocalIndexMap_.size();
214}
215
216const std::vector<int>& CDistributionServer::getZoomBeginGlobal() const
217{
218  return nZoomBeginGlobal_;
219}
220
221const std::vector<int>& CDistributionServer::getZoomBeginServer() const
222{
223  return nZoomBegin_;
224}
225
226const std::vector<int>& CDistributionServer::getZoomSizeServer() const
227{
228  return nZoomSize_;
229}
230} // namespace xios
Note: See TracBrowser for help on using the repository browser.