source: XIOS/trunk/src/server_distribution_description.cpp @ 568

Last change on this file since 568 was 568, checked in by mhnguyen, 9 years ago

Implementing discovering algorithm of server index

+) Implement the algorithm with only one level
+) Remove some redundant functions, corrects some interface

Test
+) On Curie
+) Test passed and results are correct

File size: 6.7 KB
Line 
1/*!
2   \file server_distribution_description.hpp
3   \author Ha NGUYEN
4   \since 04 Jan 2015
5   \date 09 Feb 2015
6
7   \brief Description of index distribution on server(s).
8 */
9
10#include "server_distribution_description.hpp"
11
12namespace xios
13{
14CServerDistributionDescription::CServerDistributionDescription(const std::vector<int>& globalDimensionSize)
15  : nGlobal_(globalDimensionSize), indexBegin_(), dimensionSizes_(), globalIndex_(), vecGlobalIndex_()
16{
17
18}
19
20CServerDistributionDescription::~CServerDistributionDescription()
21{
22//  if (0 != globalIndex_) delete globalIndex_;
23  if (!vecGlobalIndex_.empty())
24    for (int i = 0; i < vecGlobalIndex_.size(); ++i) delete vecGlobalIndex_[i];
25}
26
27/*!
28  Compute pre-defined global index distribution of server(s).
29  \param [in] nServer number of server
30  \param [in] doComputeGlobalIndex flag to compute global index on each server. By default, false
31  \param [in] serType type of server distribution. For now, we can distribute server by band or plan
32*/
33void CServerDistributionDescription::computeServerDistribution(int nServer,
34                                                               bool doComputeGlobalIndex,
35                                                               ServerDistributionType serType)
36{
37  switch (serType) {
38    case BAND_DISTRIBUTION:
39      computeBandDistribution(nServer);
40      break;
41    default:
42      break;
43  }
44
45  if (doComputeGlobalIndex)
46  {
47    vecGlobalIndex_.resize(nServer);
48    int dim = nGlobal_.size();
49    std::vector<int> currentIndex(dim);
50
51    for (int idxServer = 0; idxServer < nServer; ++idxServer)
52    {
53      size_t ssize = 1, idx = 0;
54      for (int j = 0; j < dim; ++j) ssize *= dimensionSizes_[idxServer][j];
55      vecGlobalIndex_[idxServer] = new CArray<size_t,1>(ssize);
56
57      std::vector<int> idxLoop(dim,0);
58
59      int innerLoopSize = dimensionSizes_[idxServer][0];
60
61      while (idx<ssize)
62      {
63        for (int idxDim = 0; idxDim < dim-1; ++idxDim)
64        {
65          if (idxLoop[idxDim] == dimensionSizes_[idxServer][idxDim])
66          {
67            idxLoop[idxDim] = 0;
68            ++idxLoop[idxDim+1];
69          }
70        }
71
72        for (int idxDim = 1; idxDim < dim; ++idxDim)  currentIndex[idxDim] = idxLoop[idxDim] + indexBegin_[idxServer][idxDim];
73
74        size_t mulDim, globalIndex;
75        for (int j = 0; j < innerLoopSize; ++j)
76        {
77          mulDim = 1;
78          globalIndex = j + indexBegin_[idxServer][0];
79
80          for (int k = 1; k < dim; ++k)
81          {
82            mulDim *= nGlobal_[k-1];
83            globalIndex += (currentIndex[k])*mulDim;
84          }
85          (*vecGlobalIndex_[idxServer])(idx) = globalIndex;
86          ++idx;
87        }
88        idxLoop[0] += innerLoopSize;
89      }
90    }
91  }
92}
93
94void CServerDistributionDescription::computeServerGlobalIndexInRange(int nServer,
95                                        const std::pair<size_t, size_t>& indexBeginEnd,
96                                        ServerDistributionType distributionType)
97{
98  switch (distributionType) {
99    case BAND_DISTRIBUTION:
100      computeBandDistribution(nServer);
101      break;
102    default:
103      break;
104  }
105
106  size_t indexBegin = indexBeginEnd.first;
107  size_t indexEnd   = indexBeginEnd.second;
108  if (indexBegin > indexEnd)
109     ERROR("CServerDistributionDescription::computeServerGlobalIndexInRange",
110           << "Index begin is larger than index end");
111
112  int dim = nGlobal_.size();
113  std::vector<int> currentIndex(dim);
114
115  for (int idxServer = 0; idxServer < nServer; ++idxServer)
116  {
117    size_t ssize = 1, idx = 0;
118    for (int j = 0; j < dim; ++j) ssize *= dimensionSizes_[idxServer][j];
119    vecGlobalIndex_[idxServer] = new CArray<size_t,1>(ssize);
120
121    std::vector<int> idxLoop(dim,0);
122
123    int innerLoopSize = dimensionSizes_[idxServer][0];
124
125    while (idx<ssize)
126    {
127      for (int idxDim = 0; idxDim < dim-1; ++idxDim)
128      {
129        if (idxLoop[idxDim] == dimensionSizes_[idxServer][idxDim])
130        {
131          idxLoop[idxDim] = 0;
132          ++idxLoop[idxDim+1];
133        }
134      }
135
136      for (int idxDim = 1; idxDim < dim; ++idxDim)  currentIndex[idxDim] = idxLoop[idxDim] + indexBegin_[idxServer][idxDim];
137
138      size_t mulDim, globalIndex;
139      for (int j = 0; j < innerLoopSize; ++j)
140      {
141        mulDim = 1;
142        globalIndex = j + indexBegin_[idxServer][0];
143
144        for (int k = 1; k < dim; ++k)
145        {
146          mulDim *= nGlobal_[k-1];
147          globalIndex += (currentIndex[k])*mulDim;
148        }
149        if ((indexBegin <= globalIndex) && (globalIndex <= indexEnd))
150          globalIndex_.insert(std::make_pair<size_t,int>(globalIndex, idxServer));
151        ++idx;
152      }
153      idxLoop[0] += innerLoopSize;
154    }
155  }
156
157}
158
159/*!
160  Compute global index of servers with band distribution
161  \param [in] nServer number of server
162*/
163void CServerDistributionDescription::computeBandDistribution(int nServer)
164{
165  int dim = nGlobal_.size();
166  indexBegin_.resize(nServer);
167  dimensionSizes_.resize(nServer);
168
169  for (int i = 0; i< nServer; ++i)
170  {
171    indexBegin_[i].resize(dim);
172    dimensionSizes_[i].resize(dim);
173  }
174
175  int njRangeSize;
176  int nGlobTemp = 0;
177  std::vector<int> njRangeBegin(nServer,0);
178  std::vector<int> njRangeEnd(nServer,0);
179
180  if (1<dim) nGlobTemp = nGlobal_[1];
181  else nGlobTemp = nGlobal_[0];
182
183  for (int i = 0; i < nServer; ++i)
184  {
185    if (0 < i) njRangeBegin[i] = njRangeEnd[i-1];
186    njRangeSize = nGlobTemp / nServer;
187    if (i < nGlobTemp%nServer) ++njRangeSize;
188    njRangeEnd[i] = njRangeSize + njRangeBegin[i];
189  }
190  njRangeEnd[nServer-1] = nGlobTemp;
191
192  for (int i = 0; i < nServer; ++i)
193  {
194    for (int j = 0; j < dim; ++j)
195    {
196      if (1 != j)
197      {
198        if (1 == dim)
199        {
200          indexBegin_[i][j] = njRangeBegin[i];
201          dimensionSizes_[i][j] = njRangeEnd[i] - njRangeBegin[i];
202        }
203        else
204        {
205          indexBegin_[i][j] = 0;
206          dimensionSizes_[i][j] = nGlobal_[j];
207        }
208      }
209      else
210      {
211        indexBegin_[i][j] = njRangeBegin[i];
212        dimensionSizes_[i][j] = njRangeEnd[i] - njRangeBegin[i];
213      }
214    }
215  }
216}
217
218/*!
219  Get size of each dimension on distributed server
220  \return size of dimensions on server(s)
221*/
222std::vector<std::vector<int> > CServerDistributionDescription::getServerDimensionSizes() const
223{
224  return dimensionSizes_;
225}
226
227/*!
228  Get index begin of each dimension on distributed server
229  \return index begin of dimensions on server(s)
230*/
231std::vector<std::vector<int> > CServerDistributionDescription::getServerIndexBegin() const
232{
233  return indexBegin_;
234}
235
236/*!
237  Get global index on distributed server
238  \return global index on server(s)
239*/
240const std::vector<CArray<size_t,1>* >& CServerDistributionDescription::getGlobalIndex() const
241{
242  return vecGlobalIndex_;
243}
244
245const boost::unordered_map<size_t,int>& CServerDistributionDescription::getGlobalIndexRange() const
246{
247  return globalIndex_;
248}
249} // namespace xios
Note: See TracBrowser for help on using the repository browser.