source: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp @ 866

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

Reorganizing codes

+) Reorganize some structures to make them more performant

Test:
+) On Curie
+) All tests pass

File size: 25.6 KB
Line 
1/*!
2   \file generic_algorithm_transformation.hpp
3   \author Ha NGUYEN
4   \since 14 May 2015
5   \date 21 Mars 2016
6
7   \brief Interface for all transformation algorithms.
8 */
9#include "generic_algorithm_transformation.hpp"
10#include "context.hpp"
11#include "context_client.hpp"
12#include "client_client_dht_template.hpp"
13
14namespace xios {
15
16CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
17 : transformationMapping_(), transformationWeight_(), transformationPosition_(), idAuxInputs_()
18{
19}
20
21/*!
22  This function computes the global indexes of grid source, which the grid destination is in demand.
23  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
24                then position of axis in grid is 2 (since a domain is considered to contain 2 elements (axis)
25  \param[in] gridDestGlobalDim global size of each dimension of grid source (all dimension must have the same size except of the one on which transformation is performed)
26  \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)
27  \param[in] globalLocalIndexGridDestSendToServer global and local index mapping of grid destination on the current client to send to server
28  \param[in/out] globaIndexWeightFromDestToSource mapping between transformed global index of grid destination
29             and the weighted value as well as global index from grid index source
30*/
31//void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
32//                                                               const std::vector<int>& gridDestGlobalDim,
33//                                                               const std::vector<int>& gridSrcGlobalDim,
34//                                                               const GlobalLocalMap& globalLocalIndexGridDestSendToServer,
35//                                                               DestinationIndexMap& globaIndexWeightFromDestToSource)
36//{
37//  bool isTransPosEmpty = transformationPosition_.empty();
38//  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
39//  {
40//    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
41//                                                     iteTransMap = transformationMapping_[idxTrans].end();
42//    TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[idxTrans].begin();
43//
44//    // If transformation position exists
45//    TransformationIndexMap::const_iterator itTransPos, iteTransPos;
46//    if (!isTransPosEmpty)
47//    {
48//      itTransPos  = transformationPosition_[idxTrans].begin(),
49//      iteTransPos = transformationPosition_[idxTrans].end();
50//    }
51//    std::vector<int> emptyTransPos;
52//
53//    std::vector<std::vector<size_t> > globalIndexSrcGrid;
54//    std::vector<std::pair<size_t,int> > globalLocalIndexDest;
55//    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
56//    {
57//      if (!isTransPosEmpty)
58//      {
59//        this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
60//                                                           itTransMap->second,
61//                                                           itTransPos->second,
62//                                                           elementPositionInGrid,
63//                                                           gridDestGlobalDim,
64//                                                           gridSrcGlobalDim,
65//                                                           globalLocalIndexGridDestSendToServer,
66//                                                           globalLocalIndexDest,
67//                                                           globalIndexSrcGrid);
68//        ++itTransPos;
69//      }
70//      else
71//      {
72//        this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
73//                                                           itTransMap->second,
74//                                                           emptyTransPos,
75//                                                           elementPositionInGrid,
76//                                                           gridDestGlobalDim,
77//                                                           gridSrcGlobalDim,
78//                                                           globalLocalIndexGridDestSendToServer,
79//                                                           globalLocalIndexDest,
80//                                                           globalIndexSrcGrid);
81//      }
82//      std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end();
83//      const std::vector<double>& currentVecWeight = itTransWeight->second;
84//
85//      for (size_t idx = 0; it != ite; ++it, ++idx)
86//      {
87//        size_t srcGridSize = globalIndexSrcGrid[idx].size();
88////        globaIndexWeightFromDestToSource[(it->first)].resize(srcGridSize);
89//        DestinationGlobalIndex& tmp = globaIndexWeightFromDestToSource[(it->first)];
90//        tmp.resize(srcGridSize);
91//        for (int i = 0; i < srcGridSize; ++i)
92//        {
93//          tmp[i].first = it->second;
94//          tmp[i].second = make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]);
95////          globaIndexWeightFromDestToSource[(it->first)][i] = (make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i])));
96//        }
97//      }
98//    }
99//  }
100//}
101
102/*!
103  This function computes the global indexes of grid source, which the grid destination is in demand.
104  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
105                then position of axis in grid is 1 and domain is positioned at 0.
106  \param[in] gridSrc Grid source
107  \param[in] gridDst Grid destination
108  \param[in] globaIndexWeightFromSrcToDst mapping of each global index source and weight to index destination
109*/
110void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
111                                                               CGrid* gridSrc,
112                                                               CGrid* gridDst,
113                                                               SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
114 {
115  CContext* context = CContext::getCurrent();
116  CContextClient* client = context->client;
117  int nbClient = client->clientSize;
118
119  typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap;
120
121  size_t indexSrcSize = 0;
122  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
123  {
124    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
125                                           iteTransMap = transformationMapping_[idxTrans].end();
126    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
127
128    itTransWeight = itbTransWeight;
129    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
130    {
131       indexSrcSize += (itTransMap->second).size();
132    }
133  }
134
135  bool isTransPosEmpty = transformationPosition_.empty();
136  CArray<size_t,1> transPos;
137  if (!isTransPosEmpty) transPos.resize(transformationMapping_.size());
138  CArray<size_t,1> indexSrc(indexSrcSize);
139  indexSrcSize = 0;
140  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
141  {
142    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
143                                           iteTransMap = transformationMapping_[idxTrans].end();
144    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
145
146    // Build mapping between global source element index and global destination element index.
147    itTransWeight = itbTransWeight;
148    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
149    {
150      const std::vector<int>& srcIndex = itTransMap->second;
151      for (int idx = 0; idx < srcIndex.size(); ++idx)
152      {
153        indexSrc(indexSrcSize) = srcIndex[idx];
154        ++indexSrcSize;
155      }
156    }
157
158    if (!isTransPosEmpty)
159    {
160      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin();
161      transPos(idxTrans) = itPosMap->second[0];
162    }
163  }
164
165  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
166  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
167  CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order;
168  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
169  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
170
171  // Find out global index source of transformed element on corresponding process.
172  std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements());
173  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc;
174  int axisIndex = 0, domainIndex = 0;
175  for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
176  {
177    if (idx == elementPositionInGrid)
178      computeExchangeGlobalIndex(indexSrc, globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]);
179    if (axisDomainDstOrder(idx)) // It's domain
180    {
181      if (idx != elementPositionInGrid)
182        computeExchangeDomainIndex(domainListDestP[domainIndex],
183                                   domainListSrcP[domainIndex],
184                                   transPos,
185                                   globalElementIndexOnProc[idx]);
186      ++domainIndex;
187
188    }
189    else //it's an axis
190    {
191      if (idx != elementPositionInGrid)
192        computeExchangeAxisIndex(axisListDestP[axisIndex],
193                                 axisListSrcP[axisIndex],
194                                 transPos,
195                                 globalElementIndexOnProc[idx]);
196      ++axisIndex;
197
198    }
199  }
200
201  if (!isTransPosEmpty)
202  {
203    for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
204    {
205      if (idx != elementPositionInGrid)
206      {
207        boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it,
208                                                                 ite = globalElementIndexOnProc[idx].end();
209        for (it = itb; it != ite; ++it) it->second.resize(1);
210      }
211    }
212  }
213
214  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
215  {
216    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
217                                           iteTransMap = transformationMapping_[idxTrans].end();
218    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
219    SrcToDstMap src2DstMap;
220    src2DstMap.rehash(std::ceil(transformationMapping_[idxTrans].size()/src2DstMap.max_load_factor()));
221
222    // Build mapping between global source element index and global destination element index.
223    boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc[elementPositionInGrid]);
224    boost::unordered_map<int,int> tmpCounter;
225    itTransWeight = itbTransWeight;
226    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
227    {
228      const std::vector<int>& srcIndex = itTransMap->second;
229      const std::vector<double>& weight = itTransWeight->second;
230      for (int idx = 0; idx < srcIndex.size(); ++idx)
231      {
232        src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx]));
233        if (1 == globalIndexOfTransformedElementOnProc.count(srcIndex[idx]) && (0 == tmpCounter.count(srcIndex[idx])))
234        {
235          tmpCounter[srcIndex[idx]] = 1;
236          std::vector<int>& srcProc = globalIndexOfTransformedElementOnProc[srcIndex[idx]];
237          for (int j = 0; j < srcProc.size(); ++j)
238            globalElementIndexOnProc[elementPositionInGrid][srcProc[j]].push_back(srcIndex[idx]);
239        }
240      }
241    }
242
243    if (!isTransPosEmpty)
244    {
245      for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
246      {
247        if (idx != elementPositionInGrid)
248        {
249          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it,
250                                                                   ite = globalElementIndexOnProc[idx].end();
251          for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans);
252        }
253      }
254    }
255
256    std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false));
257    boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite;
258    for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
259    {
260      itb = globalElementIndexOnProc[idx].begin();
261      ite = globalElementIndexOnProc[idx].end();
262      for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true;
263    }
264
265    // Determine procs which contain global source index
266    std::vector<bool> intersectedProc(nbClient, true);
267    for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
268    {
269      std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(),
270                     intersectedProc.begin(), intersectedProc.begin(),
271                     std::logical_and<bool>());
272    }
273
274    std::vector<int> srcRank;
275    for (int idx = 0; idx < nbClient; ++idx)
276    {
277      if (intersectedProc[idx]) srcRank.push_back(idx);
278    }
279
280    // Ok, now compute global index of grid source and ones of grid destination
281    computeGlobalGridIndexMapping(elementPositionInGrid,
282                                  srcRank,
283                                  src2DstMap,
284                                  gridDst,
285                                  gridSrc,
286                                  globalElementIndexOnProc,
287                                  globaIndexWeightFromSrcToDst);
288  }
289 }
290
291/*!
292  Compute mapping of global index of grid source and grid destination
293  \param [in] elementPositionInGrid position of element in grid. E.x: grid composed of domain and axis, domain has position 0 and axis 1.
294  \param [in] srcRank rank of client from which we demand global index of element source
295  \param [in] src2DstMap mapping of global index of element source and global index of element destination
296  \param[in] gridSrc Grid source
297  \param[in] gridDst Grid destination
298  \param[in] globalElementIndexOnProc Global index of element source on different client rank
299  \param[out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination
300*/
301void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid,
302                                                                   const std::vector<int>& srcRank,
303                                                                   boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap,
304                                                                   CGrid* gridSrc,
305                                                                   CGrid* gridDst,
306                                                                   std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc,
307                                                                   SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
308{
309  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
310  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
311  CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order;
312  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
313  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
314  CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order;
315  size_t nbElement = axisDomainSrcOrder.numElements();
316  std::vector<size_t> nGlobSrc(nbElement), nGlobDst(nbElement);
317  size_t globalSrcSize = 1, globalDstSize = 1;
318  int domainIndex = 0;
319  int axisIndex = 0;
320  for (int idx = 0; idx < nbElement; ++idx)
321  {
322    nGlobSrc[idx] = globalSrcSize;
323    nGlobDst[idx] = globalDstSize;
324    bool isDomain = axisDomainSrcOrder(idx);
325
326    // If this is a domain
327    if (isDomain)
328    {
329      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue();
330      globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue();
331      ++domainIndex;
332    }
333    else // So it's an axis
334    {
335      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue();
336      globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue();
337      ++axisIndex;
338    }
339  }
340
341  for (int i = 0; i < srcRank.size(); ++i)
342  {
343    size_t ssize = 1;
344    int rankSrc = srcRank[i];
345    for (int idx = 0; idx < nbElement; ++idx)
346    {
347      ssize *= (globalElementIndexOnProc[idx][rankSrc]).size();
348    }
349
350    std::vector<int> idxLoop(nbElement,0);
351    std::vector<int> currentIndexSrc(nbElement, 0);
352    std::vector<int> currentIndexDst(nbElement, 0);
353    int innnerLoopSize = (globalElementIndexOnProc[0])[rankSrc].size();
354    size_t idx = 0;
355    while (idx < ssize)
356    {
357      for (int ind = 0; ind < nbElement; ++ind)
358      {
359        if (idxLoop[ind] == (globalElementIndexOnProc[ind])[rankSrc].size())
360        {
361          idxLoop[ind] = 0;
362          ++idxLoop[ind+1];
363        }
364
365        currentIndexDst[ind] = currentIndexSrc[ind] = (globalElementIndexOnProc[ind])[rankSrc][idxLoop[ind]];
366      }
367
368      for (int ind = 0; ind < innnerLoopSize; ++ind)
369      {
370        currentIndexSrc[0] = (globalElementIndexOnProc[0])[rankSrc][ind];
371        int globalElementDstIndexSize = 0;
372        if (1 == src2DstMap.count(currentIndexSrc[elementPositionInGrid]))
373        {
374          globalElementDstIndexSize = src2DstMap[currentIndexSrc[elementPositionInGrid]].size();
375        }
376        std::vector<size_t> globalDstVecIndex(globalElementDstIndexSize,0);
377        size_t globalSrcIndex = 0;
378        for (int idxElement = 0; idxElement < nbElement; ++idxElement)
379        {
380          if (idxElement == elementPositionInGrid)
381          {
382            for (int k = 0; k < globalElementDstIndexSize; ++k)
383            {
384              globalDstVecIndex[k] += src2DstMap[currentIndexSrc[elementPositionInGrid]][k].first * nGlobDst[idxElement];
385            }
386          }
387          else
388          {
389            for (int k = 0; k < globalElementDstIndexSize; ++k)
390            {
391              globalDstVecIndex[k] += currentIndexDst[idxElement] * nGlobDst[idxElement];
392            }
393          }
394          globalSrcIndex += currentIndexSrc[idxElement] * nGlobSrc[idxElement];
395        }
396
397        for (int k = 0; k < globalElementDstIndexSize; ++k)
398        {
399          globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second ));
400        }
401        ++idxLoop[0];
402      }
403      idx += innnerLoopSize;
404    }
405  }
406}
407
408/*!
409  Find out proc and global index of axis source which axis destination is on demande
410  \param[in] axisDst Axis destination
411  \param[in] axisSrc Axis source
412  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
413  \param[out] globalAxisIndexOnProc Global index of axis source on different procs
414*/
415void CGenericAlgorithmTransformation::computeExchangeAxisIndex(CAxis* axisDst,
416                                                               CAxis* axisSrc,
417                                                               CArray<size_t,1>& destGlobalIndexPositionInGrid,
418                                                               boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc)
419{
420  CContext* context = CContext::getCurrent();
421  CContextClient* client=context->client;
422  int clientRank = client->clientRank;
423  int clientSize = client->clientSize;
424
425  size_t globalIndex;
426  int nIndexSize = axisSrc->index.numElements();
427  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
428  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
429  for (int idx = 0; idx < nIndexSize; ++idx)
430  {
431    globalIndex = axisSrc->index(idx);
432    globalIndex2ProcRank[globalIndex].push_back(clientRank);
433  }
434
435  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
436  CArray<size_t,1> globalAxisIndex(axisDst->index.numElements());
437  for (int idx = 0; idx < globalAxisIndex.numElements(); ++idx)
438  {
439    globalAxisIndex(idx) = axisDst->index(idx);
440  }
441  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex);
442
443  std::vector<int> countIndex(clientSize,0);
444  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
445  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
446                                                               ite = computedGlobalIndexOnProc.end();
447  for (it = itb; it != ite; ++it)
448  {
449    const std::vector<int>& procList = it->second;
450    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
451  }
452
453  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor()));
454  for (int idx = 0; idx < clientSize; ++idx)
455  {
456    if (0 != countIndex[idx])
457    {
458      globalAxisIndexOnProc[idx].resize(countIndex[idx]);
459      countIndex[idx] = 0;
460    }
461  }
462
463  for (it = itb; it != ite; ++it)
464  {
465    const std::vector<int>& procList = it->second;
466    for (int idx = 0; idx < procList.size(); ++idx)
467    {
468      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
469      ++countIndex[procList[idx]];
470    }
471  }
472}
473
474/*!
475  Find out proc and global index of domain source which domain destination is on demande
476  \param[in] domainDst Domain destination
477  \param[in] domainSrc Domain source
478  \param[in] destGlobalIndexPositionInGrid Relative position of domain corresponds to other element of grid.
479  \param[out] globalDomainIndexOnProc Global index of domain source on different procs
480*/
481void CGenericAlgorithmTransformation::computeExchangeDomainIndex(CDomain* domainDst,
482                                                                 CDomain* domainSrc,
483                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
484                                                                 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc)
485{
486  CContext* context = CContext::getCurrent();
487  CContextClient* client=context->client;
488  int clientRank = client->clientRank;
489  int clientSize = client->clientSize;
490
491  int niGlobSrc = domainSrc->ni_glo.getValue();
492  size_t globalIndex;
493  int i_ind, j_ind;
494  int nIndexSize = (destGlobalIndexPositionInGrid.isEmpty()) ? domainSrc->i_index.numElements()
495                                                             : destGlobalIndexPositionInGrid.numElements();
496  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
497  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
498  if (destGlobalIndexPositionInGrid.isEmpty())
499  {
500    for (int idx = 0; idx < nIndexSize; ++idx)
501    {
502      i_ind=domainSrc->i_index(idx) ;
503      j_ind=domainSrc->j_index(idx) ;
504
505      globalIndex = i_ind + j_ind * niGlobSrc;
506      globalIndex2ProcRank[globalIndex].resize(1);
507      globalIndex2ProcRank[globalIndex][0] = clientRank;
508    }
509  }
510  else
511  {
512    for (int idx = 0; idx < nIndexSize; ++idx)
513    {
514      globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank);
515    }
516  }
517
518  CArray<size_t,1> globalDomainIndex;
519  if (destGlobalIndexPositionInGrid.isEmpty())
520  {
521    int niGlobDst = domainDst->ni_glo.getValue();
522    globalDomainIndex.resize(domainDst->i_index.numElements());
523    nIndexSize = domainDst->i_index.numElements();
524
525    for (int idx = 0; idx < nIndexSize; ++idx)
526    {
527      i_ind=domainDst->i_index(idx) ;
528      j_ind=domainDst->j_index(idx) ;
529
530      globalDomainIndex(idx) = i_ind + j_ind * niGlobDst;
531    }
532  }
533  else
534  {
535    globalDomainIndex.reference(destGlobalIndexPositionInGrid);
536  }
537
538  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
539  dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex);
540
541  std::vector<int> countIndex(clientSize,0);
542  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
543  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
544                                                               ite = computedGlobalIndexOnProc.end();
545  for (it = itb; it != ite; ++it)
546  {
547    const std::vector<int>& procList = it->second;
548    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
549  }
550
551  globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor()));
552  for (int idx = 0; idx < clientSize; ++idx)
553  {
554    if (0 != countIndex[idx])
555    {
556      globalDomainIndexOnProc[idx].resize(countIndex[idx]);
557      countIndex[idx] = 0;
558    }
559  }
560
561  for (it = itb; it != ite; ++it)
562  {
563    const std::vector<int>& procList = it->second;
564    for (int idx = 0; idx < procList.size(); ++idx)
565    {
566      globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
567      ++countIndex[procList[idx]];
568    }
569  }
570}
571
572/*!
573  Compute index mapping between element source and element destination with an auxiliary inputs which determine
574position of each mapped index in global index of grid destination.
575  \param [in] dataAuxInputs auxiliary inputs
576*/
577void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs)
578{
579  computeIndexSourceMapping_(dataAuxInputs);
580}
581
582std::vector<StdString> CGenericAlgorithmTransformation::getIdAuxInputs()
583{
584  return idAuxInputs_;
585}
586
587}
Note: See TracBrowser for help on using the repository browser.