source: XIOS/trunk/src/distribution_server.cpp @ 895

Last change on this file since 895 was 676, checked in by rlacroix, 9 years ago

Add support for indexed output.

If the new field attribute "indexed_output" is set to true and a mask is defined (either at grid, domain or axis level), the indexed data will be outputed instead of the full data with missing values.

See http://cfconventions.org/Data/cf-conventions/cf-conventions-1.5/build/cf-conventions.html#compression-by-gathering for more information.

File size: 5.0 KB
Line 
1/*!
2   \file distribution_server.cpp
3   \author Ha NGUYEN
4   \since 13 Jan 2015
5   \date 04 Feb 2015
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, int dims, const CArray<size_t,1>& globalIndex)
15  : CDistribution(rank, dims, globalIndex), nGlobal_(), nZoomSize_(), nZoomBegin_()
16{
17}
18
19CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
20                                         const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal)
21  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin)
22{
23  createGlobalIndex();
24}
25
26CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
27                                         const std::vector<int>& nZoomSize,
28                                         const std::vector<int>& nZoomBeginGlobal,
29                                         const std::vector<int>& nGlobal)
30  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
31    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin)
32{
33  createGlobalIndex();
34}
35
36CDistributionServer::~CDistributionServer()
37{
38}
39
40/*!
41  Create global index on server side
42  Like the similar function on client side, this function serves on creating global index
43for data written by the server. The global index is used to calculating local index of data
44written on each server
45*/
46void CDistributionServer::createGlobalIndex()
47{
48  size_t idx = 0, ssize = 1;
49  for (int i = 0; i < nZoomSize_.size(); ++i) ssize *= nZoomSize_[i];
50
51  this->globalIndex_.resize(ssize);
52  std::vector<int> idxLoop(this->getDims(),0);
53  std::vector<int> currentIndex(this->getDims());
54  int innerLoopSize = nZoomSize_[0];
55
56  while (idx<ssize)
57  {
58    for (int i = 0; i < this->dims_-1; ++i)
59    {
60      if (idxLoop[i] == nZoomSize_[i])
61      {
62        idxLoop[i] = 0;
63        ++idxLoop[i+1];
64      }
65    }
66
67    for (int i = 1; i < this->dims_; ++i)  currentIndex[i] = idxLoop[i] + nZoomBegin_[i];
68
69    size_t mulDim, globalIndex;
70    for (int i = 0; i < innerLoopSize; ++i)
71    {
72      mulDim = 1;
73      globalIndex = i + nZoomBegin_[0];
74
75      for (int k = 1; k < this->dims_; ++k)
76      {
77        mulDim *= nGlobal_[k-1];
78        globalIndex += (currentIndex[k])*mulDim;
79      }
80      this->globalIndex_(idx) = globalIndex;
81      ++idx;
82    }
83    idxLoop[0] += innerLoopSize;
84  }
85}
86
87/*!
88  Compute local index for writing data on server
89  \param [in] globalIndex global index received from client
90  \return local index of written data
91*/
92CArray<size_t,1> CDistributionServer::computeLocalIndex(const CArray<size_t,1>& globalIndex)
93{
94  int ssize = globalIndex.numElements();
95  int nbGlobalIndex = this->globalIndex_.numElements();
96
97  std::vector<int>::iterator it;
98  std::vector<int> permutIndex(nbGlobalIndex);
99  XIOSAlgorithms::fillInIndex(nbGlobalIndex, permutIndex);
100  XIOSAlgorithms::sortWithIndex<size_t, CArrayStorage>(this->globalIndex_, permutIndex);
101  typedef XIOSBinarySearchWithIndex<size_t, CArrayStorage> BinarySearch;
102  BinarySearch binarySearch(this->globalIndex_);
103
104  CArray<size_t,1> localIndex(ssize);
105  int idx = 0;
106  for (int i = 0; i < ssize; ++i)
107  {
108    if (binarySearch.search(permutIndex.begin(), permutIndex.end(), globalIndex(i), it))
109    {
110      localIndex(idx) = *it;
111      ++idx;
112    }
113  }
114
115  return localIndex;
116}
117
118/*!
119  Compute local index for writing data on server
120  \param [in] globalIndex Global index received from client
121*/
122void CDistributionServer::computeLocalIndex(CArray<size_t,1>& globalIndex)
123{
124  int ssize = globalIndex.numElements();
125  int nbGlobalIndex = this->globalIndex_.numElements();
126
127  std::vector<int>::iterator it;
128  std::vector<int> permutIndex(nbGlobalIndex);
129  XIOSAlgorithms::fillInIndex(nbGlobalIndex, permutIndex);
130  XIOSAlgorithms::sortWithIndex<size_t, CArrayStorage>(this->globalIndex_, permutIndex);
131  typedef XIOSBinarySearchWithIndex<size_t, CArrayStorage> BinarySearch;
132  BinarySearch binarySearch(this->globalIndex_);
133
134  CArray<size_t,1> localIndex(ssize);
135  int idx = 0;
136  for (int i = 0; i < ssize; ++i)
137  {
138    if (binarySearch.search(permutIndex.begin(), permutIndex.end(), globalIndex(i), it))
139    {
140      localIndex(idx) = *it;
141      ++idx;
142    }
143  }
144
145  globalIndex = localIndex;
146}
147
148/*!
149  Transforms local indexes owned by the server into global indexes
150  \param [in/out] indexes on input, local indexes of the server,
151                          on output, the corresponding global indexes
152*/
153void CDistributionServer::computeGlobalIndex(CArray<int,1>& indexes) const
154{
155  for (int i = 0; i < indexes.numElements(); ++i)
156  {
157    indexes(i) = globalIndex_(indexes(i));
158  }
159}
160
161
162const std::vector<int>& CDistributionServer::getZoomBeginGlobal() const
163{
164  return nZoomBeginGlobal_;
165}
166
167const std::vector<int>& CDistributionServer::getZoomBeginServer() const
168{
169  return nZoomBegin_;
170}
171
172const std::vector<int>& CDistributionServer::getZoomSizeServer() const
173{
174  return nZoomSize_;
175}
176} // namespace xios
Note: See TracBrowser for help on using the repository browser.