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

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

Seperating global index computation on client and server side

+) Create a class which do mapping in general manner, between client and server index global
+) Remove some redundant functions and variables
+) Add some comments to code

Test
+) On Curie. Only test_new_features.f90
+) Test passes and results are correct.
+) Need to change index from 1 to 0

File size: 4.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_(0), 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
94/*!
95  Compute global index of servers with band distribution
96  \param [in] nServer number of server
97*/
98void CServerDistributionDescription::computeBandDistribution(int nServer)
99{
100  int dim = nGlobal_.size();
101  indexBegin_.resize(dim);
102  dimensionSizes_.resize(dim);
103
104  for (int i = 0; i< nServer; ++i)
105  {
106    indexBegin_[i].resize(nServer);
107    dimensionSizes_[i].resize(nServer);
108  }
109
110  int njRangeSize;
111  int nGlobTemp = 0;
112  std::vector<int> njRangeBegin(nServer,0);
113  std::vector<int> njRangeEnd(nServer,0);
114
115  if (1<dim) nGlobTemp = nGlobal_[1];
116  else nGlobTemp = nGlobal_[0];
117
118  for (int i = 0; i < nServer; ++i)
119  {
120    if (0 < i) njRangeBegin[i] = njRangeEnd[i-1];
121    njRangeSize = nGlobTemp / nServer;
122    if (i < nGlobTemp%nServer) ++njRangeSize;
123    njRangeEnd[i] = njRangeSize + njRangeBegin[i];
124  }
125  njRangeEnd[nServer-1] = nGlobTemp;
126
127  for (int i = 0; i < nServer; ++i)
128  {
129    for (int j = 0; j < dim; ++j)
130    {
131      if (1 != j)
132      {
133        if (1 == dim)
134        {
135          indexBegin_[i][j] = njRangeBegin[i];
136          dimensionSizes_[i][j] = njRangeEnd[i] - njRangeBegin[i];
137        }
138        else
139        {
140          indexBegin_[i][j] = 0;
141          dimensionSizes_[i][j] = nGlobal_[j];
142        }
143      }
144      else
145      {
146        indexBegin_[i][j] = njRangeBegin[i];
147        dimensionSizes_[i][j] = njRangeEnd[i] - njRangeBegin[i];
148      }
149    }
150  }
151}
152
153/*!
154  Get size of each dimension on distributed server
155  \return size of dimensions on server(s)
156*/
157std::vector<std::vector<int> > CServerDistributionDescription::getServerDimensionSizes() const
158{
159  return dimensionSizes_;
160}
161
162/*!
163  Get index begin of each dimension on distributed server
164  \return index begin of dimensions on server(s)
165*/
166std::vector<std::vector<int> > CServerDistributionDescription::getServerIndexBegin() const
167{
168  return indexBegin_;
169}
170
171/*!
172  Get global index on distributed server
173  \return global index on server(s)
174*/
175const std::vector<CArray<size_t,1>* >& CServerDistributionDescription::getGlobalIndex() const
176{
177  return vecGlobalIndex_;
178}
179
180} // namespace xios
Note: See TracBrowser for help on using the repository browser.