Ignore:
Timestamp:
06/09/16 11:32:27 (8 years ago)
Author:
mhnguyen
Message:

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:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp

    r843 r862  
    88 */ 
    99#include "generic_algorithm_transformation.hpp" 
     10#include "context.hpp" 
     11#include "context_client.hpp" 
     12#include "client_client_dht_template.hpp" 
    1013 
    1114namespace xios { 
     
    2629             and the weighted value as well as global index from grid index source 
    2730*/ 
     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*/ 
    28110void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid, 
    29                                                                const std::vector<int>& gridDestGlobalDim, 
    30                                                                const std::vector<int>& gridSrcGlobalDim, 
    31                                                                const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 
    32                                                                DestinationIndexMap& globaIndexWeightFromDestToSource) 
    33 { 
     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; 
    34120  bool isTransPosEmpty = transformationPosition_.empty(); 
    35121  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
    36122  { 
    37123    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 
    38                                                      iteTransMap = transformationMapping_[idxTrans].end(); 
    39     TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[idxTrans].begin(); 
    40  
    41     // If transformation position exists 
    42     TransformationIndexMap::const_iterator itTransPos, iteTransPos; 
     124                                           iteTransMap = transformationMapping_[idxTrans].end(); 
     125    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 
     126    SrcToDstMap src2DstMap; 
     127    src2DstMap.rehash(std::ceil(transformationMapping_[idxTrans].size()/src2DstMap.max_load_factor())); 
     128 
     129    int indexSrcSize = 0; 
     130    itTransWeight = itbTransWeight; 
     131    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
     132    { 
     133       indexSrcSize += (itTransMap->second).size(); 
     134    } 
     135 
     136    CArray<size_t,1> indexSrc(indexSrcSize); 
     137    int indexSrcIndex = 0; 
     138    // Build mapping between global source element index and global destination element index. 
     139    itTransWeight = itbTransWeight; 
     140    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
     141    { 
     142      const std::vector<int>& srcIndex = itTransMap->second; 
     143      const std::vector<double>& weight = itTransWeight->second; 
     144      for (int idx = 0; idx < srcIndex.size(); ++idx) 
     145      { 
     146        src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx])); 
     147        indexSrc(indexSrcIndex) = srcIndex[idx]; 
     148        ++indexSrcIndex; 
     149      } 
     150    } 
     151 
     152    std::vector<CAxis*> axisListDestP = gridDst->getAxis(); 
     153    std::vector<CDomain*> domainListDestP = gridDst->getDomains(); 
     154    CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order; 
     155    std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     156    std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     157    CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order; 
     158 
     159    CArray<size_t,1> transPos; 
    43160    if (!isTransPosEmpty) 
    44161    { 
    45       itTransPos  = transformationPosition_[idxTrans].begin(), 
    46       iteTransPos = transformationPosition_[idxTrans].end(); 
    47     } 
    48     std::vector<int> emptyTransPos; 
    49  
    50     std::vector<std::vector<size_t> > globalIndexSrcGrid; 
    51     std::vector<std::pair<size_t,int> > globalLocalIndexDest; 
    52     for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
    53     { 
    54       if (!isTransPosEmpty) 
     162      transPos.resize(transformationPosition_[idxTrans].size()); 
     163      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(), 
     164                                               itePosMap = transformationPosition_[idxTrans].end(); 
     165      for (int idx = 0; itPosMap != itePosMap; ++itPosMap, ++idx) 
     166        transPos(idx) = itPosMap->second[0]; 
     167    } 
     168    // Find out global index source of transformed element on corresponding process. 
     169    std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements()); 
     170    int axisIndex = 0, domainIndex = 0; 
     171    for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     172    { 
     173      if (idx == elementPositionInGrid) 
     174        computeExchangeGlobalIndex(indexSrc, globalElementIndexOnProc[idx]); 
     175      if (axisDomainDstOrder(idx)) // It's domain 
    55176      { 
    56         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 
    57                                                            itTransMap->second, 
    58                                                            itTransPos->second, 
    59                                                            elementPositionInGrid, 
    60                                                            gridDestGlobalDim, 
    61                                                            gridSrcGlobalDim, 
    62                                                            globalLocalIndexGridDestSendToServer, 
    63                                                            globalLocalIndexDest, 
    64                                                            globalIndexSrcGrid); 
    65         ++itTransPos; 
     177        if (idx != elementPositionInGrid) 
     178          computeExchangeDomainIndex(domainListDestP[domainIndex], 
     179                                     domainListSrcP[domainIndex], 
     180                                     transPos, 
     181                                     globalElementIndexOnProc[idx]); 
     182        ++domainIndex; 
     183 
    66184      } 
    67       else 
     185      else //it's an axis 
    68186      { 
    69         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 
    70                                                            itTransMap->second, 
    71                                                            emptyTransPos, 
    72                                                            elementPositionInGrid, 
    73                                                            gridDestGlobalDim, 
    74                                                            gridSrcGlobalDim, 
    75                                                            globalLocalIndexGridDestSendToServer, 
    76                                                            globalLocalIndexDest, 
    77                                                            globalIndexSrcGrid); 
     187        if (idx != elementPositionInGrid) 
     188          computeExchangeAxisIndex(axisListDestP[axisIndex], 
     189                                   axisListSrcP[axisIndex], 
     190                                   transPos, 
     191                                   globalElementIndexOnProc[idx]); 
     192        ++axisIndex; 
     193 
    78194      } 
    79       std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end(); 
    80       const std::vector<double>& currentVecWeight = itTransWeight->second; 
    81  
    82       for (size_t idx = 0; it != ite; ++it, ++idx) 
     195    } 
     196 
     197    std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false)); 
     198 
     199    boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite; 
     200    for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 
     201    { 
     202      itb = globalElementIndexOnProc[idx].begin(); 
     203      ite = globalElementIndexOnProc[idx].end(); 
     204      for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true; 
     205    } 
     206 
     207    // Determine procs which contain global source index 
     208    std::vector<bool> intersectedProc(nbClient, true); 
     209    for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     210    { 
     211      std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(), 
     212                     intersectedProc.begin(), intersectedProc.begin(), 
     213                     std::logical_and<bool>()); 
     214    } 
     215 
     216    std::vector<int> srcRank; 
     217    for (int idx = 0; idx < nbClient; ++idx) 
     218    { 
     219      if (intersectedProc[idx]) srcRank.push_back(idx); 
     220    } 
     221 
     222    // Ok, now compute global index of grid source and ones of grid destination 
     223    computeGlobalGridIndexMapping(elementPositionInGrid, 
     224                                  srcRank, 
     225                                  src2DstMap, 
     226                                  gridDst, 
     227                                  gridSrc, 
     228                                  globalElementIndexOnProc, 
     229                                  globaIndexWeightFromSrcToDst); 
     230  } 
     231 } 
     232 
     233/*! 
     234  Compute mapping of global index of grid source and grid destination 
     235  \param [in] elementPositionInGrid position of element in grid. E.x: grid composed of domain and axis, domain has position 0 and axis 1. 
     236  \param [in] srcRank rank of client from which we demand global index of element source 
     237  \param [in] src2DstMap mapping of global index of element source and global index of element destination 
     238  \param[in] gridSrc Grid source 
     239  \param[in] gridDst Grid destination 
     240  \param[in] globalElementIndexOnProc Global index of element source on different client rank 
     241  \param[out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination 
     242*/ 
     243void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid, 
     244                                                                   const std::vector<int>& srcRank, 
     245                                                                   boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap, 
     246                                                                   CGrid* gridSrc, 
     247                                                                   CGrid* gridDst, 
     248                                                                   std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc, 
     249                                                                   SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 
     250{ 
     251  std::vector<CAxis*> axisListDestP = gridDst->getAxis(); 
     252  std::vector<CDomain*> domainListDestP = gridDst->getDomains(); 
     253  CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order; 
     254  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     255  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     256  CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order; 
     257  size_t nbElement = axisDomainSrcOrder.numElements(); 
     258  std::vector<size_t> nGlobSrc(nbElement), nGlobDst(nbElement); 
     259  size_t globalSrcSize = 1, globalDstSize = 1; 
     260  int domainIndex = 0; 
     261  int axisIndex = 0; 
     262  for (int idx = 0; idx < nbElement; ++idx) 
     263  { 
     264    nGlobSrc[idx] = globalSrcSize; 
     265    nGlobDst[idx] = globalDstSize; 
     266    bool isDomain = axisDomainSrcOrder(idx); 
     267 
     268    // If this is a domain 
     269    if (isDomain) 
     270    { 
     271      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue(); 
     272      globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue(); 
     273      ++domainIndex; 
     274    } 
     275    else // So it's an axis 
     276    { 
     277      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue(); 
     278      globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue(); 
     279      ++axisIndex; 
     280    } 
     281  } 
     282 
     283  for (int i = 0; i < srcRank.size(); ++i) 
     284  { 
     285    size_t ssize = 1; 
     286    int rankSrc = srcRank[i]; 
     287    for (int idx = 0; idx < nbElement; ++idx) 
     288    { 
     289      ssize *= (globalElementIndexOnProc[idx][rankSrc]).size(); 
     290    } 
     291 
     292    std::vector<int> idxLoop(nbElement,0); 
     293    std::vector<int> currentIndexSrc(nbElement, 0); 
     294    std::vector<int> currentIndexDst(nbElement, 0); 
     295    int innnerLoopSize = (globalElementIndexOnProc[0])[rankSrc].size(); 
     296    size_t idx = 0; 
     297    while (idx < ssize) 
     298    { 
     299      for (int ind = 0; ind < nbElement; ++ind) 
    83300      { 
    84         size_t srcGridSize = globalIndexSrcGrid[idx].size(); 
    85 //        globaIndexWeightFromDestToSource[(it->first)].resize(srcGridSize); 
    86         DestinationGlobalIndex& tmp = globaIndexWeightFromDestToSource[(it->first)]; 
    87         tmp.resize(srcGridSize); 
    88         for (int i = 0; i < srcGridSize; ++i) 
     301        if (idxLoop[ind] == (globalElementIndexOnProc[ind])[rankSrc].size()) 
    89302        { 
    90           tmp[i].first = it->second; 
    91           tmp[i].second = make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]); 
    92 //          globaIndexWeightFromDestToSource[(it->first)][i] = (make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]))); 
     303          idxLoop[ind] = 0; 
     304          ++idxLoop[ind+1]; 
    93305        } 
     306 
     307        currentIndexDst[ind] = currentIndexSrc[ind] = (globalElementIndexOnProc[ind])[rankSrc][idxLoop[ind]]; 
    94308      } 
    95     } 
    96   } 
    97 } 
    98  
     309 
     310      for (int ind = 0; ind < innnerLoopSize; ++ind) 
     311      { 
     312        currentIndexSrc[0] = (globalElementIndexOnProc[0])[rankSrc][ind]; 
     313        int globalElementDstIndexSize = 0; 
     314        if (1 == src2DstMap.count(currentIndexSrc[elementPositionInGrid])) 
     315        { 
     316          globalElementDstIndexSize = src2DstMap[currentIndexSrc[elementPositionInGrid]].size(); 
     317        } 
     318        std::vector<size_t> globalDstVecIndex(globalElementDstIndexSize,0); 
     319        size_t globalSrcIndex = 0; 
     320        for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
     321        { 
     322          if (idxElement == elementPositionInGrid) 
     323          { 
     324            for (int k = 0; k < globalElementDstIndexSize; ++k) 
     325            { 
     326              globalDstVecIndex[k] += src2DstMap[currentIndexSrc[elementPositionInGrid]][k].first * nGlobDst[idxElement]; 
     327            } 
     328          } 
     329          else 
     330          { 
     331            for (int k = 0; k < globalElementDstIndexSize; ++k) 
     332            { 
     333              globalDstVecIndex[k] += currentIndexDst[idxElement] * nGlobDst[idxElement]; 
     334            } 
     335          } 
     336          globalSrcIndex += currentIndexSrc[idxElement] * nGlobSrc[idxElement]; 
     337        } 
     338 
     339        for (int k = 0; k < globalElementDstIndexSize; ++k) 
     340        { 
     341          globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 
     342        } 
     343        ++idxLoop[0]; 
     344      } 
     345      idx += innnerLoopSize; 
     346    } 
     347  } 
     348} 
     349 
     350/*! 
     351  Find out proc and global index of axis source which axis destination is on demande 
     352  \param[in] axisDst Axis destination 
     353  \param[in] axisSrc Axis source 
     354  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid. 
     355  \param[out] globalAxisIndexOnProc Global index of axis source on different procs 
     356*/ 
     357void CGenericAlgorithmTransformation::computeExchangeAxisIndex(CAxis* axisDst, 
     358                                                               CAxis* axisSrc, 
     359                                                               CArray<size_t,1>& destGlobalIndexPositionInGrid, 
     360                                                               boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc) 
     361{ 
     362  CContext* context = CContext::getCurrent(); 
     363  CContextClient* client=context->client; 
     364  int clientRank = client->clientRank; 
     365  int clientSize = client->clientSize; 
     366 
     367  size_t globalIndex; 
     368  int nIndexSize = axisSrc->index.numElements(); 
     369  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 
     370  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 
     371  for (int idx = 0; idx < nIndexSize; ++idx) 
     372  { 
     373    globalIndex = axisSrc->index(idx); 
     374    globalIndex2ProcRank[globalIndex].push_back(clientRank); 
     375  } 
     376 
     377  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 
     378  CArray<size_t,1> globalAxisIndex(axisDst->index.numElements()); 
     379  for (int idx = 0; idx < globalAxisIndex.numElements(); ++idx) 
     380  { 
     381    globalAxisIndex(idx) = axisDst->index(idx); 
     382  } 
     383  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex); 
     384 
     385  std::vector<int> countIndex(clientSize,0); 
     386  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 
     387  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 
     388                                                               ite = computedGlobalIndexOnProc.end(); 
     389  for (it = itb; it != ite; ++it) 
     390  { 
     391    const std::vector<int>& procList = it->second; 
     392    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 
     393  } 
     394 
     395  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor())); 
     396  for (int idx = 0; idx < clientSize; ++idx) 
     397  { 
     398    if (0 != countIndex[idx]) 
     399    { 
     400      globalAxisIndexOnProc[idx].resize(countIndex[idx]); 
     401      countIndex[idx] = 0; 
     402    } 
     403  } 
     404 
     405  for (it = itb; it != ite; ++it) 
     406  { 
     407    const std::vector<int>& procList = it->second; 
     408    for (int idx = 0; idx < procList.size(); ++idx) 
     409    { 
     410      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 
     411      ++countIndex[procList[idx]]; 
     412    } 
     413  } 
     414} 
     415 
     416/*! 
     417  Find out proc and global index of domain source which domain destination is on demande 
     418  \param[in] domainDst Domain destination 
     419  \param[in] domainSrc Domain source 
     420  \param[in] destGlobalIndexPositionInGrid Relative position of domain corresponds to other element of grid. 
     421  \param[out] globalDomainIndexOnProc Global index of domain source on different procs 
     422*/ 
     423void CGenericAlgorithmTransformation::computeExchangeDomainIndex(CDomain* domainDst, 
     424                                                                 CDomain* domainSrc, 
     425                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid, 
     426                                                                 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc) 
     427{ 
     428  CContext* context = CContext::getCurrent(); 
     429  CContextClient* client=context->client; 
     430  int clientRank = client->clientRank; 
     431  int clientSize = client->clientSize; 
     432 
     433  int niGlob = domainSrc->ni_glo.getValue(); 
     434  int njGlob = domainSrc->nj_glo.getValue(); 
     435  size_t globalIndex; 
     436  int nIndexSize = domainSrc->i_index.numElements(), i_ind, j_ind; 
     437  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 
     438  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 
     439  for (int idx = 0; idx < nIndexSize; ++idx) 
     440  { 
     441    i_ind=domainSrc->i_index(idx) ; 
     442    j_ind=domainSrc->j_index(idx) ; 
     443 
     444    globalIndex = i_ind + j_ind * niGlob; 
     445    globalIndex2ProcRank[globalIndex].push_back(clientRank); 
     446  } 
     447 
     448  CArray<size_t,1> globalDomainIndex; 
     449  if (destGlobalIndexPositionInGrid.isEmpty()) 
     450  { 
     451    globalDomainIndex.resize(domainDst->i_index.numElements()); 
     452    nIndexSize = domainDst->i_index.numElements(); 
     453 
     454    for (int idx = 0; idx < nIndexSize; ++idx) 
     455    { 
     456      i_ind=domainDst->i_index(idx) ; 
     457      j_ind=domainDst->j_index(idx) ; 
     458 
     459      globalDomainIndex(idx) = i_ind + j_ind * niGlob; 
     460    } 
     461  } 
     462  else 
     463  { 
     464    globalDomainIndex  = destGlobalIndexPositionInGrid; 
     465//    for (int idx = 0; idx < destGlobalIndexPositionInGrid.size(); ++idx) 
     466//    { 
     467//      globalDomainIndex(idx) = destGlobalIndexPositionInGrid[idx]; 
     468//    } 
     469  } 
     470 
     471  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 
     472  dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex); 
     473 
     474  std::vector<int> countIndex(clientSize,0); 
     475  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 
     476  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 
     477                                                               ite = computedGlobalIndexOnProc.end(); 
     478  for (it = itb; it != ite; ++it) 
     479  { 
     480    const std::vector<int>& procList = it->second; 
     481    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 
     482  } 
     483 
     484  globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor())); 
     485  for (int idx = 0; idx < clientSize; ++idx) 
     486  { 
     487    if (0 != countIndex[idx]) 
     488    { 
     489      globalDomainIndexOnProc[idx].resize(countIndex[idx]); 
     490      countIndex[idx] = 0; 
     491    } 
     492  } 
     493 
     494  for (it = itb; it != ite; ++it) 
     495  { 
     496    const std::vector<int>& procList = it->second; 
     497    for (int idx = 0; idx < procList.size(); ++idx) 
     498    { 
     499      globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 
     500      ++countIndex[procList[idx]]; 
     501    } 
     502  } 
     503} 
     504 
     505/*! 
     506  Compute index mapping between element source and element destination with an auxiliary inputs which determine 
     507position of each mapped index in global index of grid destination. 
     508  \param [in] dataAuxInputs auxiliary inputs 
     509*/ 
    99510void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs) 
    100511{ 
Note: See TracChangeset for help on using the changeset viewer.