source: XIOS/dev/dev_olga/src/transformation/generic_algorithm_transformation.cpp @ 1173

Last change on this file since 1173 was 1173, checked in by mhnguyen, 7 years ago

Fixing bug: Overlapped domains behave incorrectly

+) If local domains are overlapping on client, the re-constructed domain on server must take care of this overlapped region

Test
+) On Curie
+) test_client, test_complete work
+) Need to test with models

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