Changeset 862


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)

Location:
XIOS/trunk/src/transformation
Files:
9 edited

Legend:

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

    r833 r862  
    265265    CDomain* dom = domListP[0]; 
    266266    size_t vecAxisValueSize = dom->i_index.numElements(); 
     267    int niGlobDom = dom->ni_glo.getValue(); 
    267268    vecAxisValue.resize(vecAxisValueSize); 
    268269    if (transPosition_.empty()) 
     
    271272      for (size_t idx = 0; idx < vecAxisValueSize; ++idx) 
    272273      { 
    273         transPosition_[idx].resize(2); 
    274         transPosition_[idx][0] = (dom->i_index)(idx); 
    275         transPosition_[idx][1] = (dom->j_index)(idx); 
     274        transPosition_[idx].resize(1); 
     275        transPosition_[idx][0] = (dom->i_index)(idx) + niGlobDom * (dom->j_index)(idx); 
     276//        transPosition_[idx][0] = (dom->i_index)(idx); 
     277//        transPosition_[idx][1] = (dom->j_index)(idx); 
    276278      } 
    277279    } 
  • XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp

    r829 r862  
    1111#include "axis_algorithm_inverse.hpp" 
    1212#include "axis_algorithm_zoom.hpp" 
     13#include "context.hpp" 
     14#include "context_client.hpp" 
     15#include "client_client_dht_template.hpp" 
    1316 
    1417namespace xios { 
     
    2730CAxisAlgorithmTransformation::~CAxisAlgorithmTransformation() 
    2831{ 
     32} 
     33 
     34void CAxisAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex, 
     35                                                              boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc) 
     36{ 
     37  CContext* context = CContext::getCurrent(); 
     38  CContextClient* client=context->client; 
     39  int clientRank = client->clientRank; 
     40  int clientSize = client->clientSize; 
     41 
     42  size_t globalIndex; 
     43  int nIndexSize = axisSrc_->index.numElements(); 
     44  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 
     45  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 
     46  for (int idx = 0; idx < nIndexSize; ++idx) 
     47  { 
     48    globalIndex = axisSrc_->index(idx); 
     49    globalIndex2ProcRank[globalIndex].push_back(clientRank); 
     50  } 
     51 
     52  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 
     53  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex); 
     54 
     55  std::vector<int> countIndex(clientSize,0); 
     56  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 
     57  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 
     58                                                               ite = computedGlobalIndexOnProc.end(); 
     59  for (it = itb; it != ite; ++it) 
     60  { 
     61    const std::vector<int>& procList = it->second; 
     62    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 
     63  } 
     64 
     65  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor())); 
     66  for (int idx = 0; idx < clientSize; ++idx) 
     67  { 
     68    if (0 != countIndex[idx]) 
     69    { 
     70      globalAxisIndexOnProc[idx].resize(countIndex[idx]); 
     71      countIndex[idx] = 0; 
     72    } 
     73  } 
     74 
     75  for (it = itb; it != ite; ++it) 
     76  { 
     77    const std::vector<int>& procList = it->second; 
     78    for (int idx = 0; idx < procList.size(); ++idx) 
     79    { 
     80      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 
     81      ++countIndex[procList[idx]]; 
     82    } 
     83  } 
    2984} 
    3085 
  • XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp

    r829 r862  
    3939  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs); 
    4040 
     41  void computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex, 
     42                                  boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 
     43 
    4144protected: 
    4245  //! Global index of an axis on grid destination 
  • XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp

    r829 r862  
    99 
    1010#include "domain_algorithm_transformation.hpp" 
     11#include "context.hpp" 
     12#include "context_client.hpp" 
     13#include "client_client_dht_template.hpp" 
    1114 
    1215namespace xios { 
     
    2326void CDomainAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs) 
    2427{ 
     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  } 
    2585} 
    2686 
  • XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp

    r829 r862  
    3939  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&); 
    4040 
     41  void computeExchangeGlobalIndex(const CArray<size_t,1>& globalDomainIndex, 
     42                                  boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 
    4143protected: 
    4244  inline void domainGlobalIndex(const int& index, const int& niGlob, const int& njGlob, 
  • 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{ 
  • XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp

    r843 r862  
    1515 
    1616namespace xios { 
     17  class CGrid; 
     18  class CDomain; 
     19  class CAxis; 
     20 
    1721  /*! 
    1822  \class CGenericAlgorithmTransformation 
     
    2731  // Mapping between global index map of DESTINATION and its local index with pair of global index of SOURCE and weights 
    2832  typedef boost::unordered_map<size_t, DestinationGlobalIndex> DestinationIndexMap; 
     33  // 
     34  typedef boost::unordered_map<int, boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > > > SourceDestinationIndexMap; 
    2935 
    3036protected: 
    3137  typedef boost::unordered_map<size_t,int> GlobalLocalMap; 
     38protected: 
     39  typedef boost::unordered_map<int, std::vector<int> > TransformationIndexMap; 
     40  typedef boost::unordered_map<int, std::vector<double> > TransformationWeightMap; 
     41  typedef boost::unordered_map<int, std::vector<int> > TransformationPositionMap; 
    3242 
    3343public: 
     
    3646  virtual ~CGenericAlgorithmTransformation() {} 
    3747 
     48//  void computeGlobalSourceIndex(int elementPositionInGrid, 
     49//                                const std::vector<int>& gridDestGlobalDim, 
     50//                                const std::vector<int>& gridSrcGlobalDim, 
     51//                                const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 
     52//                                DestinationIndexMap& globaIndexWeightFromDestToSource); 
     53 
    3854  void computeGlobalSourceIndex(int elementPositionInGrid, 
    39                                 const std::vector<int>& gridDestGlobalDim, 
    40                                 const std::vector<int>& gridSrcGlobalDim, 
    41                                 const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 
    42                                 DestinationIndexMap& globaIndexWeightFromDestToSource); 
     55                               CGrid* gridSrc, 
     56                               CGrid* gridDst, 
     57                               SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); 
    4358 
    4459  std::vector<StdString> getIdAuxInputs(); 
     
    7287  virtual void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&) = 0; 
    7388 
     89  virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalElementIndex, 
     90                                          boost::unordered_map<int,std::vector<size_t> >& globalElementIndexOnProc) = 0; 
     91 
     92  void computeGlobalGridIndexMapping(int elementPositionInGrid, 
     93                                     const std::vector<int>& srcRank, 
     94                                     boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap, 
     95                                     CGrid* gridDst, 
     96                                     CGrid* gridSrc, 
     97                                     std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc, 
     98                                     SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); 
     99 
     100  void computeExchangeDomainIndex(CDomain* domainDst, 
     101                                  CDomain* domainSrc, 
     102                                  CArray<size_t,1>& destGlobalIndexPositionInGrid, 
     103                                  boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 
     104 
     105  void computeExchangeAxisIndex(CAxis* axisDst, 
     106                                CAxis* axisSrc, 
     107                                CArray<size_t,1>& destGlobalIndexPositionInGrid, 
     108                                boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc); 
     109 
    74110protected: 
    75   typedef boost::unordered_map<int, std::vector<int> > TransformationIndexMap; 
    76   typedef boost::unordered_map<int, std::vector<double> > TransformationWeightMap; 
    77   typedef boost::unordered_map<int, std::vector<int> > TransformationPositionMap; 
    78  
    79111  //! Map between global index of destination element and source element 
    80112  std::vector<TransformationIndexMap> transformationMapping_; 
  • XIOS/trunk/src/transformation/grid_transformation.cpp

    r858 r862  
    9494    if (false == (gridDestination_->axis_domain_order)(i)) 
    9595    { 
    96       axisPositionInGrid.push_back(idx); 
    97       ++idx; 
     96      axisPositionInGrid.push_back(i); 
     97//      axisPositionInGrid.push_back(idx); 
     98//      ++idx; 
    9899    } 
    99100    else 
    100101    { 
    101       ++idx; 
    102       domPositionInGrid.push_back(idx); 
    103       ++idx; 
     102      domPositionInGrid.push_back(i); 
     103//      ++idx; 
     104//      domPositionInGrid.push_back(idx); 
     105//      ++idx; 
    104106    } 
    105107  } 
     
    120122    if (false == (gridDestination_->axis_domain_order)(i)) 
    121123    { 
    122       initializeAxisAlgorithms(idx); 
    123       ++idx; 
     124      initializeAxisAlgorithms(i); 
     125//      initializeAxisAlgorithms(idx); 
     126//      ++idx; 
    124127    } 
    125128    else 
    126129    { 
    127       ++idx; 
    128       initializeDomainAlgorithms(idx); 
    129       ++idx; 
     130      initializeDomainAlgorithms(i); 
     131//      ++idx; 
     132//      initializeDomainAlgorithms(idx); 
     133//      ++idx; 
    130134    } 
    131135  } 
     
    356360  -) Make current grid destination become grid source in the next transformation 
    357361*/ 
     362//void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs, Time timeStamp) 
     363//{ 
     364//  if (nbAlgos_ < 1) return; 
     365//  if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; } 
     366//  if (dynamicalTransformation_) 
     367//  { 
     368//    if (timeStamp_.insert(timeStamp).second) 
     369//      DestinationIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map 
     370//    else 
     371//      return; 
     372//  } 
     373// 
     374//  CContext* context = CContext::getCurrent(); 
     375//  CContextClient* client = context->client; 
     376// 
     377//  ListAlgoType::const_iterator itb = listAlgos_.begin(), 
     378//                               ite = listAlgos_.end(), it; 
     379// 
     380//  CGenericAlgorithmTransformation* algo = 0; 
     381//  int nbAgloTransformation = 0; // Only count for executed transformation. Generate domain is a special one, not executed in the list 
     382//  for (it = itb; it != ite; ++it) 
     383//  { 
     384//    int elementPositionInGrid = it->first; 
     385//    ETranformationType transType = (it->second).first; 
     386//    int transformationOrder = (it->second).second; 
     387//    DestinationIndexMap globaIndexWeightFromDestToSource; 
     388// 
     389//    // First of all, select an algorithm 
     390//    if (!dynamicalTransformation_ || (algoTransformation_.size() < listAlgos_.size())) 
     391//    { 
     392//      selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]); 
     393//      algo = algoTransformation_.back(); 
     394//    } 
     395//    else 
     396//      algo = algoTransformation_[std::distance(itb, it)]; 
     397// 
     398//    if (0 != algo) // Only registered transformation can be executed 
     399//    { 
     400//      algo->computeIndexSourceMapping(dataAuxInputs); 
     401// 
     402//      // Recalculate the distribution of grid destination 
     403//      CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 
     404//      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer(); 
     405// 
     406//      // ComputeTransformation of global index of each element 
     407//      std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension(); 
     408//      std::vector<int> gridSrcDimensionSize = gridSource_->getGlobalDimension(); 
     409//      int elementPosition = it->first; 
     410//      algo->computeGlobalSourceIndex(elementPosition, 
     411//                                     gridDestinationDimensionSize, 
     412//                                     gridSrcDimensionSize, 
     413//                                     globalLocalIndexGridDestSendToServer, 
     414//                                     globaIndexWeightFromDestToSource); 
     415// 
     416//      // Compute transformation of global indexes among grids 
     417//      computeTransformationMapping(globaIndexWeightFromDestToSource); 
     418// 
     419//      // Update number of local index on each transformation 
     420//      nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 
     421// 
     422//      if (1 < nbAlgos_) 
     423//      { 
     424//        // Now grid destination becomes grid source in a new transformation 
     425//        if (nbAgloTransformation != (nbAlgos_-1)) setUpGrid(elementPositionInGrid, transType, nbAgloTransformation); 
     426//      } 
     427//      ++nbAgloTransformation; 
     428//    } 
     429//  } 
     430//} 
     431 
    358432void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs, Time timeStamp) 
    359433{ 
     
    386460    ETranformationType transType = (it->second).first; 
    387461    int transformationOrder = (it->second).second; 
    388     DestinationIndexMap globaIndexWeightFromDestToSource; 
     462    SourceDestinationIndexMap globaIndexWeightFromSrcToDst; 
    389463 
    390464    // First of all, select an algorithm 
     
    401475      algo->computeIndexSourceMapping(dataAuxInputs); 
    402476 
    403       // Recalculate the distribution of grid destination 
    404       CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 
    405       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer(); 
    406  
    407477      // ComputeTransformation of global index of each element 
    408       std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension(); 
    409       std::vector<int> gridSrcDimensionSize = gridSource_->getGlobalDimension(); 
    410478      int elementPosition = it->first; 
    411479      algo->computeGlobalSourceIndex(elementPosition, 
    412                                      gridDestinationDimensionSize, 
    413                                      gridSrcDimensionSize, 
    414                                      globalLocalIndexGridDestSendToServer, 
    415                                      globaIndexWeightFromDestToSource); 
     480                                     gridSource_, 
     481                                     gridDestination_, 
     482                                     globaIndexWeightFromSrcToDst); 
    416483 
    417484      // Compute transformation of global indexes among grids 
    418       computeTransformationMapping(globaIndexWeightFromDestToSource); 
    419  
    420       // Update number of local index on each transformation 
    421       nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 
     485      computeTransformationMapping(globaIndexWeightFromSrcToDst); 
    422486 
    423487      if (1 < nbAlgos_) 
     
    435499  \param [in] globalIndexWeightFromDestToSource global index mapping between grid destination and grid source 
    436500*/ 
    437 void CGridTransformation::computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource) 
     501void CGridTransformation::computeTransformationMapping(const SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 
    438502{ 
    439503  CContext* context = CContext::getCurrent(); 
    440504  CContextClient* client = context->client; 
    441  
    442   CTransformationMapping transformationMap(gridDestination_, gridSource_); 
    443  
    444   transformationMap.computeTransformationMapping(globalIndexWeightFromDestToSource); 
    445  
    446   const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 
    447   CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv; 
    448   itbMapRecv = globalIndexToReceive.begin(); 
    449   iteMapRecv = globalIndexToReceive.end(); 
     505  int nbClient = client->clientSize; 
     506  int clientRank = client->clientRank; 
     507 
     508  // Recalculate the distribution of grid destination 
     509  CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 
     510  CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer(); 
     511  // Update number of local index on each transformation 
     512  nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 
     513 
     514  // Find out number of index sent from grid source and number of index received on grid destination 
     515  SourceDestinationIndexMap::const_iterator itbIndex = globaIndexWeightFromSrcToDst.begin(), 
     516                                            iteIndex = globaIndexWeightFromSrcToDst.end(), itIndex; 
     517  typedef boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > > SendIndexMap; 
     518  std::map<int,int> sendRankSizeMap,recvRankSizeMap; 
     519  int connectedClient = globaIndexWeightFromSrcToDst.size(); 
     520  int* recvCount=new int[nbClient]; 
     521  int* displ=new int[nbClient]; 
     522  int* sendRankBuff=new int[connectedClient]; 
     523  int* sendSizeBuff=new int[connectedClient]; 
     524  int n = 0; 
     525  for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex, ++n) 
     526  { 
     527    sendRankBuff[n] = itIndex->first; 
     528    const SendIndexMap& sendIndexMap = itIndex->second; 
     529    SendIndexMap::const_iterator itbSend = sendIndexMap.begin(), iteSend = sendIndexMap.end(), itSend; 
     530    int sendSize = 0; 
     531    for (itSend = itbSend; itSend != iteSend; ++itSend) 
     532    { 
     533      sendSize += itSend->second.size(); 
     534    } 
     535    sendSizeBuff[n] = sendSize; 
     536    sendRankSizeMap[itIndex->first] = sendSize; 
     537  } 
     538  MPI_Allgather(&connectedClient,1,MPI_INT,recvCount,1,MPI_INT,client->intraComm); 
     539 
     540  displ[0]=0 ; 
     541  for(int n=1;n<nbClient;n++) displ[n]=displ[n-1]+recvCount[n-1]; 
     542  int recvSize=displ[nbClient-1]+recvCount[nbClient-1]; 
     543  int* recvRankBuff=new int[recvSize]; 
     544  int* recvSizeBuff=new int[recvSize]; 
     545  MPI_Allgatherv(sendRankBuff,connectedClient,MPI_INT,recvRankBuff,recvCount,displ,MPI_INT,client->intraComm); 
     546  MPI_Allgatherv(sendSizeBuff,connectedClient,MPI_INT,recvSizeBuff,recvCount,displ,MPI_INT,client->intraComm); 
     547  for (int i = 0; i < nbClient; ++i) 
     548  { 
     549    int currentPos = displ[i]; 
     550    for (int j = 0; j < recvCount[i]; ++j) 
     551      if (recvRankBuff[currentPos+j] == clientRank) 
     552      { 
     553        recvRankSizeMap[i] = recvSizeBuff[currentPos+j]; 
     554      } 
     555  } 
     556 
     557 
     558 
     559  // Sending global index of grid source to corresponding process as well as the corresponding mask 
     560  std::vector<MPI_Request> requests; 
     561  std::vector<MPI_Status> status; 
     562  boost::unordered_map<int, unsigned char* > recvMaskDst; 
     563  boost::unordered_map<int, unsigned long* > recvGlobalIndexSrc; 
     564  for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 
     565  { 
     566    int recvRank = itRecv->first; 
     567    int recvSize = itRecv->second; 
     568    recvMaskDst[recvRank] = new unsigned char [recvSize]; 
     569    recvGlobalIndexSrc[recvRank] = new unsigned long [recvSize]; 
     570 
     571    requests.push_back(MPI_Request()); 
     572    MPI_Irecv(recvGlobalIndexSrc[recvRank], recvSize, MPI_UNSIGNED_LONG, recvRank, 46, client->intraComm, &requests.back()); 
     573    requests.push_back(MPI_Request()); 
     574    MPI_Irecv(recvMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 47, client->intraComm, &requests.back()); 
     575  } 
     576 
     577  boost::unordered_map<int, CArray<size_t,1> > globalIndexDst; 
     578  boost::unordered_map<int, CArray<double,1> > weightDst; 
     579  boost::unordered_map<int, unsigned char* > sendMaskDst; 
     580  boost::unordered_map<int, unsigned long* > sendGlobalIndexSrc; 
     581  for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex) 
     582  { 
     583    int sendRank = itIndex->first; 
     584    int sendSize = sendRankSizeMap[sendRank]; 
     585    const SendIndexMap& sendIndexMap = itIndex->second; 
     586    SendIndexMap::const_iterator itbSend = sendIndexMap.begin(), iteSend = sendIndexMap.end(), itSend; 
     587    globalIndexDst[sendRank].resize(sendSize); 
     588    weightDst[sendRank].resize(sendSize); 
     589    sendMaskDst[sendRank] = new unsigned char [sendSize]; 
     590    sendGlobalIndexSrc[sendRank] = new unsigned long [sendSize]; 
     591    int countIndex = 0; 
     592    for (itSend = itbSend; itSend != iteSend; ++itSend) 
     593    { 
     594      const std::vector<std::pair<size_t,double> >& dstWeight = itSend->second; 
     595      for (int idx = 0; idx < dstWeight.size(); ++idx) 
     596      { 
     597        globalIndexDst[sendRank](countIndex) = dstWeight[idx].first; 
     598        weightDst[sendRank](countIndex) = dstWeight[idx].second; 
     599        if (0 < globalLocalIndexGridDestSendToServer.count(dstWeight[idx].first)) 
     600          sendMaskDst[sendRank][countIndex] = 1; 
     601        else 
     602          sendMaskDst[sendRank][countIndex] = 0; 
     603        sendGlobalIndexSrc[sendRank][countIndex] = itSend->first; 
     604        ++countIndex; 
     605      } 
     606    } 
     607 
     608    // Send global index source and mask 
     609    requests.push_back(MPI_Request()); 
     610    MPI_Isend(sendGlobalIndexSrc[sendRank], sendSize, MPI_UNSIGNED_LONG, sendRank, 46, client->intraComm, &requests.back()); 
     611    requests.push_back(MPI_Request()); 
     612    MPI_Isend(sendMaskDst[sendRank], sendSize, MPI_UNSIGNED_CHAR, sendRank, 47, client->intraComm, &requests.back()); 
     613  } 
     614 
     615  status.resize(requests.size()); 
     616  MPI_Waitall(requests.size(), &requests[0], &status[0]); 
     617 
     618  // Okie, now use the mask to identify which index source we need to send, then also signal the destination which masked index we will return 
     619  std::vector<MPI_Request>().swap(requests); 
     620  std::vector<MPI_Status>().swap(status); 
     621  // Okie, on destination side, we will wait for information of masked index of source 
     622  for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 
     623  { 
     624    int recvRank = itSend->first; 
     625    int recvSize = itSend->second; 
     626 
     627    requests.push_back(MPI_Request()); 
     628    MPI_Irecv(sendMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 48, client->intraComm, &requests.back()); 
     629  } 
     630 
     631  // Ok, now we fill in local index of grid source (we even count for masked index) 
     632  CDistributionClient distributionClientSrc(client->clientRank, gridSource_); 
     633  CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridSrcSendToServer = distributionClientSrc.getGlobalLocalDataSendToServer(); 
     634  localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 
     635  SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 
     636  for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 
     637  { 
     638    int recvRank = itRecv->first; 
     639    int recvSize = itRecv->second; 
     640    unsigned char* recvMask = recvMaskDst[recvRank]; 
     641    unsigned long* recvIndexSrc = recvGlobalIndexSrc[recvRank]; 
     642    int realSendSize = 0; 
     643    for (int idx = 0; idx < recvSize; ++idx) 
     644    { 
     645      if (0 != (*(recvMask+idx))) // OKie, now we have a demand from non-masked index destination 
     646        if (0 < globalLocalIndexGridSrcSendToServer.count(*(recvIndexSrc+idx))) // check whether index source is masked 
     647         ++realSendSize; 
     648        else // inform the destination that this index is masked 
     649         *(recvMask+idx) = 0; 
     650    } 
     651 
     652    tmpSend[recvRank].resize(realSendSize); 
     653    realSendSize = 0; 
     654    for (int idx = 0; idx < recvSize; ++idx) 
     655    { 
     656      if (0 != (*(recvMask+idx))) // OKie, now we have a demand from non-masked index destination 
     657      { 
     658        tmpSend[recvRank](realSendSize) = globalLocalIndexGridSrcSendToServer[*(recvIndexSrc+idx)]; 
     659         ++realSendSize; 
     660      } 
     661    } 
     662 
     663    // Okie, now inform the destination which source index are masked 
     664    requests.push_back(MPI_Request()); 
     665    MPI_Isend(recvMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 48, client->intraComm, &requests.back()); 
     666  } 
     667  status.resize(requests.size()); 
     668  MPI_Waitall(requests.size(), &requests[0], &status[0]); 
     669 
     670  // Cool, now we can fill in local index of grid destination (counted for masked index) 
    450671  localIndexToReceiveOnGridDest_.push_back(RecvIndexGridDestinationMap()); 
    451672  RecvIndexGridDestinationMap& recvTmp = localIndexToReceiveOnGridDest_.back(); 
    452   for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv) 
    453   { 
    454     int sourceRank = itMapRecv->first; 
    455     int numGlobalIndex = (itMapRecv->second).size(); 
    456     recvTmp[sourceRank].resize(numGlobalIndex); 
    457     for (int i = 0; i < numGlobalIndex; ++i) 
    458     { 
    459       recvTmp[sourceRank][i] = make_pair((itMapRecv->second)[i].localIndex,(itMapRecv->second)[i].weight); 
    460     } 
    461   } 
    462  
    463   // Find out local index on grid source (to send) 
    464   const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping(); 
    465   CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap; 
    466   itbMap = globalIndexToSend.begin(); 
    467   iteMap = globalIndexToSend.end(); 
    468   localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 
    469   SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 
    470   for (itMap = itbMap; itMap != iteMap; ++itMap) 
    471   { 
    472     int destRank = itMap->first; 
    473     int vecSize = itMap->second.size(); 
    474     tmpSend[destRank].resize(vecSize); 
    475     for (int idx = 0; idx < vecSize; ++idx) 
    476     { 
    477       tmpSend[destRank](idx) = itMap->second[idx].first; 
    478     } 
    479   } 
    480 } 
     673  for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 
     674  { 
     675    int recvRank = itSend->first; 
     676    int recvSize = itSend->second; 
     677    unsigned char* recvMask = sendMaskDst[recvRank]; 
     678 
     679    CArray<size_t,1>& recvIndexDst = globalIndexDst[recvRank]; 
     680    CArray<double,1>& recvWeightDst = weightDst[recvRank]; 
     681    int realRecvSize = 0; 
     682    for (int idx = 0; idx < recvSize; ++idx) 
     683    { 
     684      if (0 != *(recvMask+idx)) // OKie, now we have a non-masked index destination 
     685         ++realRecvSize; 
     686    } 
     687 
     688    int localIndexDst; 
     689    recvTmp[recvRank].resize(realRecvSize); 
     690    realRecvSize = 0; 
     691    for (int idx = 0; idx < recvSize; ++idx) 
     692    { 
     693      if (0 != *(recvMask+idx)) // OKie, now we have a demand from non-masked index destination 
     694      { 
     695        recvTmp[recvRank][realRecvSize].first = globalLocalIndexGridDestSendToServer[recvIndexDst(idx)]; 
     696        recvTmp[recvRank][realRecvSize].second = recvWeightDst(idx); 
     697         ++realRecvSize; 
     698      } 
     699    } 
     700  } 
     701 
     702  delete [] recvCount; 
     703  delete [] displ; 
     704  delete [] sendRankBuff; 
     705  delete [] recvRankBuff; 
     706  delete [] sendSizeBuff; 
     707  delete [] recvSizeBuff; 
     708 
     709  boost::unordered_map<int, unsigned char* >::const_iterator itChar; 
     710  for (itChar = sendMaskDst.begin(); itChar != sendMaskDst.end(); ++itChar) 
     711    delete [] itChar->second; 
     712  for (itChar = recvMaskDst.begin(); itChar != recvMaskDst.end(); ++itChar) 
     713    delete [] itChar->second; 
     714  boost::unordered_map<int, unsigned long* >::const_iterator itLong; 
     715  for (itLong = sendGlobalIndexSrc.begin(); itLong != sendGlobalIndexSrc.end(); ++itLong) 
     716    delete [] itLong->second; 
     717  for (itLong = recvGlobalIndexSrc.begin(); itLong != recvGlobalIndexSrc.end(); ++itLong) 
     718    delete [] itLong->second; 
     719 
     720} 
     721 
     722///*! 
     723//  Compute exchange index between grid source and grid destination 
     724//  \param [in] globalIndexWeightFromDestToSource global index mapping between grid destination and grid source 
     725//*/ 
     726//void CGridTransformation::computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource) 
     727//{ 
     728//  CContext* context = CContext::getCurrent(); 
     729//  CContextClient* client = context->client; 
     730// 
     731//  CTransformationMapping transformationMap(gridDestination_, gridSource_); 
     732// 
     733//  transformationMap.computeTransformationMapping(globalIndexWeightFromDestToSource); 
     734// 
     735//  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 
     736//  CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv; 
     737//  itbMapRecv = globalIndexToReceive.begin(); 
     738//  iteMapRecv = globalIndexToReceive.end(); 
     739//  localIndexToReceiveOnGridDest_.push_back(RecvIndexGridDestinationMap()); 
     740//  RecvIndexGridDestinationMap& recvTmp = localIndexToReceiveOnGridDest_.back(); 
     741//  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv) 
     742//  { 
     743//    int sourceRank = itMapRecv->first; 
     744//    int numGlobalIndex = (itMapRecv->second).size(); 
     745//    recvTmp[sourceRank].resize(numGlobalIndex); 
     746//    for (int i = 0; i < numGlobalIndex; ++i) 
     747//    { 
     748//      recvTmp[sourceRank][i] = make_pair((itMapRecv->second)[i].localIndex,(itMapRecv->second)[i].weight); 
     749//    } 
     750//  } 
     751// 
     752//  // Find out local index on grid source (to send) 
     753//  const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping(); 
     754//  CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap; 
     755//  itbMap = globalIndexToSend.begin(); 
     756//  iteMap = globalIndexToSend.end(); 
     757//  localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 
     758//  SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 
     759//  for (itMap = itbMap; itMap != iteMap; ++itMap) 
     760//  { 
     761//    int destRank = itMap->first; 
     762//    int vecSize = itMap->second.size(); 
     763//    tmpSend[destRank].resize(vecSize); 
     764//    for (int idx = 0; idx < vecSize; ++idx) 
     765//    { 
     766//      tmpSend[destRank](idx) = itMap->second[idx].first; 
     767//    } 
     768//  } 
     769//} 
    481770 
    482771bool CGridTransformation::isSpecialTransformation(ETranformationType transType) 
  • XIOS/trunk/src/transformation/grid_transformation.hpp

    r842 r862  
    3939  typedef std::map<int, CArray<int,1> > SendingIndexGridSourceMap; 
    4040  typedef std::map<int,std::vector<std::pair<int,double> > > RecvIndexGridDestinationMap; 
    41 //  typedef std::map<int,std::vector<std::vector<std::pair<int,double> > > > RecvIndexGridDestinationMap; 
     41  typedef CGenericAlgorithmTransformation::SourceDestinationIndexMap SourceDestinationIndexMap; 
    4242 
    4343public: 
     
    7171//  void computeFinalTransformationMapping(); 
    7272//  void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource); 
    73   void computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource); 
     73  void computeTransformationMapping(const SourceDestinationIndexMap& globalIndexWeightFromSrcToDest); 
    7474//  void updateFinalGridDestination(); 
    7575  bool isSpecialTransformation(ETranformationType transType); 
Note: See TracChangeset for help on using the changeset viewer.