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

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

Making changes in domain to make sure unstructed grid work with new method of index distribution

+) Change the way define i_index and j_index of a domain
+) Remove some redundant attributes of domain
+) Adjust the way to calculate index distribution on server side

Test
+) Make some minor change to test_unstruct_complete to work with new XIOS
+) On Curie
+) All test pass and correct

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