source: XIOS/dev/dev_cmip6_omp/src/distribution_server.cpp @ 1606

Last change on this file since 1606 was 1340, checked in by ymipsl, 6 years ago

Reduce the memory footprint on server level2.

YM

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