source: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp @ 862

Last change on this file since 862 was 862, checked in by mhnguyen, 8 years ago

Chaning the way to process transformation to improve the performance.
Instead of exchanging global index and weights on full GRID, each process only
sends and receives the global index and weights on each ELEMENT, which can reduce
the message size of DHT.

+) Domain and axis now have their own exchange function to transfer global index and weight
+) Generic transformation now plays the role of "synthesizer" for all elements
+) Grid transformation now plays the role of transformation mapping, e.x: exchange final global index and weight
among processes.

Test
+) On Curie
+) Pass on all basic tests
+) Dynamic interpolation on axis hasn't been tested (and it seems to need more change to make it rework)

File size: 8.6 KB
Line 
1/*!
2   \file axis_algorithm_transformation.hpp
3   \author Ha NGUYEN
4   \since 14 May 2015
5   \date 29 June 2015
6
7   \brief Interface for all axis transformation algorithms.
8 */
9
10#include "axis_algorithm_transformation.hpp"
11#include "axis_algorithm_inverse.hpp"
12#include "axis_algorithm_zoom.hpp"
13#include "context.hpp"
14#include "context_client.hpp"
15#include "client_client_dht_template.hpp"
16
17namespace xios {
18
19CAxisAlgorithmTransformation::CAxisAlgorithmTransformation(CAxis* axisDestination, CAxis* axisSource)
20 : CGenericAlgorithmTransformation(), axisDest_(axisDestination), axisSrc_(axisSource)
21{
22  axisDestGlobalSize_ = axisDestination->n_glo.getValue();
23  int niDest = axisDestination->n.getValue();
24  int ibeginDest = axisDestination->begin.getValue();
25
26  for (int idx = 0; idx < niDest; ++idx)
27    if ((axisDestination->mask)(idx)) axisDestGlobalIndex_.push_back(ibeginDest+idx);
28}
29
30CAxisAlgorithmTransformation::~CAxisAlgorithmTransformation()
31{
32}
33
34void CAxisAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex,
35                                                              boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc)
36{
37  CContext* context = CContext::getCurrent();
38  CContextClient* client=context->client;
39  int clientRank = client->clientRank;
40  int clientSize = client->clientSize;
41
42  size_t globalIndex;
43  int nIndexSize = axisSrc_->index.numElements();
44  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
45  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
46  for (int idx = 0; idx < nIndexSize; ++idx)
47  {
48    globalIndex = axisSrc_->index(idx);
49    globalIndex2ProcRank[globalIndex].push_back(clientRank);
50  }
51
52  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
53  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex);
54
55  std::vector<int> countIndex(clientSize,0);
56  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
57  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
58                                                               ite = computedGlobalIndexOnProc.end();
59  for (it = itb; it != ite; ++it)
60  {
61    const std::vector<int>& procList = it->second;
62    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
63  }
64
65  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor()));
66  for (int idx = 0; idx < clientSize; ++idx)
67  {
68    if (0 != countIndex[idx])
69    {
70      globalAxisIndexOnProc[idx].resize(countIndex[idx]);
71      countIndex[idx] = 0;
72    }
73  }
74
75  for (it = itb; it != ite; ++it)
76  {
77    const std::vector<int>& procList = it->second;
78    for (int idx = 0; idx < procList.size(); ++idx)
79    {
80      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
81      ++countIndex[procList[idx]];
82    }
83  }
84}
85
86void CAxisAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
87{
88}
89
90/*!
91  Compute an array of global index from a global index on a axis
92  \param[in] axisDestGlobalIndex global index on an axis of destination grid
93  \param[in] axisSrcGlobalIndex global index on an axis of source grid (which are needed by one index on axis destination)
94  \param[in] axisPositionInGrid position of the axis in the grid
95  \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the axis on which transformation is performed)
96  \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s), this array is already acsending sorted
97  \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
98  \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
99*/
100void CAxisAlgorithmTransformation::computeGlobalGridIndexFromGlobalIndexElement(int axisDestGlobalIndex,
101                                                                          const std::vector<int>& axisSrcGlobalIndex,
102                                                                          const std::vector<int>& destGlobalIndexPositionInGrid,
103                                                                          int axisPositionInGrid,
104                                                                          const std::vector<int>& gridDestGlobalDim,
105                                                                          const std::vector<int>& gridSrcGlobalDim,
106                                                                          const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
107                                                                          std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
108                                                                          std::vector<std::vector<size_t> >& globalIndexSrcGrid)
109{
110  bool hasDestGlobalIndexPos = !destGlobalIndexPositionInGrid.empty();
111  int globalDim = gridDestGlobalDim.size();
112
113  std::vector<size_t> currentIndex(globalDim);
114  std::vector<int> gridAxisGlobalDim(globalDim);
115  std::vector<int> idxLoop(globalDim, 0);
116
117  size_t ssize = 1, idx = 0, realGlobalIndexSize = 0;
118  for (int i = 0; i< globalDim; ++i)
119  {
120    if (axisPositionInGrid == i) gridAxisGlobalDim[i] = 1;
121    else
122    {
123      if (!hasDestGlobalIndexPos) gridAxisGlobalDim[i] = gridDestGlobalDim[i];
124      else gridAxisGlobalDim[i] = 1;
125    }
126    ssize *= gridAxisGlobalDim[i];
127  }
128
129  GlobalLocalMap::const_iterator iteArr = globalLocalIndexDestSendToServerMap.end(), it;
130
131  while (idx < ssize)
132  {
133    for (int i = 0; i < globalDim-1; ++i)
134    {
135      if (idxLoop[i] == gridAxisGlobalDim[i])
136      {
137        idxLoop[i] = 0;
138        ++idxLoop[i+1];
139      }
140    }
141
142    int j = 0;
143    for (int i = 0; i < globalDim; ++i)
144    {
145      if (!hasDestGlobalIndexPos) currentIndex[i] = idxLoop[i];
146      else
147      {
148        if (axisPositionInGrid == i) currentIndex[i] = axisDestGlobalIndex;
149        else
150        {
151          currentIndex[i] = destGlobalIndexPositionInGrid[j];
152          ++j;
153        }
154      }
155    }
156
157    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
158
159    size_t globIndex = currentIndex[0];
160    size_t mulDim = 1;
161    for (int k = 1; k < globalDim; ++k)
162    {
163      mulDim *= gridDestGlobalDim[k-1];
164      globIndex += (currentIndex[k])*mulDim;
165    }
166
167    if (iteArr != globalLocalIndexDestSendToServerMap.find(globIndex)) ++realGlobalIndexSize;
168    ++idxLoop[0];
169    ++idx;
170  }
171
172  if (globalLocalIndexDestMap.size() != realGlobalIndexSize)
173    globalLocalIndexDestMap.resize(realGlobalIndexSize);
174
175  if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
176  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
177    if (globalIndexSrcGrid[i].size() != axisSrcGlobalIndex.size())
178      globalIndexSrcGrid[i].resize(axisSrcGlobalIndex.size());
179
180  size_t realGlobalIndex = 0;
181  idx = 0;
182  idxLoop.assign(globalDim, 0);
183  while (idx < ssize)
184  {
185    for (int i = 0; i < globalDim-1; ++i)
186    {
187      if (idxLoop[i] == gridAxisGlobalDim[i])
188      {
189        idxLoop[i] = 0;
190        ++idxLoop[i+1];
191      }
192    }
193
194    int j = 0;
195    for (int i = 0; i < globalDim; ++i)
196    {
197      if (!hasDestGlobalIndexPos) currentIndex[i] = idxLoop[i];
198      else
199      {
200        if (axisPositionInGrid == i) currentIndex[i] = axisDestGlobalIndex;
201        else
202        {
203          currentIndex[i] = destGlobalIndexPositionInGrid[j];
204          ++j;
205        }
206      }
207    }
208    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
209
210    size_t globIndex = currentIndex[0];
211    size_t mulDim = 1;
212    for (int k = 1; k < globalDim; ++k)
213    {
214      mulDim *= gridDestGlobalDim[k-1];
215      globIndex += (currentIndex[k])*mulDim;
216    }
217
218    it = globalLocalIndexDestSendToServerMap.find(globIndex);
219    if (iteArr != it)
220    {
221      globalLocalIndexDestMap[realGlobalIndex] = (std::make_pair(it->first,it->second));
222      for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
223      {
224        currentIndex[axisPositionInGrid] = axisSrcGlobalIndex[i];
225        globIndex = currentIndex[0];
226        mulDim = 1;
227        for (int k = 1; k < globalDim; ++k)
228        {
229          mulDim *= gridDestGlobalDim[k-1];
230          globIndex += (currentIndex[k])*mulDim;
231        }
232        (globalIndexSrcGrid[realGlobalIndex])[i] = globIndex;
233      }
234      ++realGlobalIndex;
235    }
236
237    ++idxLoop[0];
238    ++idx;
239  }
240}
241}
Note: See TracBrowser for help on using the repository browser.