source: XIOS3/trunk/src/distribution/distribution_server.cpp @ 2401

Last change on this file since 2401 was 1918, checked in by ymipsl, 4 years ago

Big update on on going work related to data distribution and transfer between clients and servers.

  • move all related file into distribution directorie
  • implement the concept of data "View"
  • implement the concept of "connector" which make the data transfer between 2 differents "Views"

YM

  • Property svn:eol-style set to native
File size: 6.5 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>& nBegin,
15                                         const std::vector<int>& nSize,
16                                         const std::vector<int>& nBeginGlobal,
17                                         const std::vector<int>& nGlobal)
18  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nBeginGlobal_(nBeginGlobal),
19    nSize_(nSize), nBegin_(nBegin), 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>& nBegin,
28                                        const std::vector<int>& nSize,
29                                        const std::vector<int>& nBeginGlobal,
30                                        const std::vector<int>& nGlobal)
31  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nBeginGlobal_(nBeginGlobal),
32    nSize_(nSize), nBegin_(nBegin), 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 < nSize_.size(); ++i) ssize *= nSize_[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 = nSize_[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] == nSize_[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] + nBegin_[i];
70
71    size_t mulDim, globalIndex;
72    for (int i = 0; i < innerLoopSize; ++i)
73    {
74      mulDim = 1;
75      globalIndex = i + nBegin_[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
217void CDistributionServer::partialClear(void)
218{
219  GlobalLocalMap void1 ;
220  globalLocalIndexMap_.swap(void1) ;
221}
222 
223} // namespace xios
Note: See TracBrowser for help on using the repository browser.