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