Ignore:
Timestamp:
03/22/18 10:43:20 (6 years ago)
Author:
yushan
Message:

branch_openmp merged with XIOS_DEV_CMIP6@1459

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/branch_openmp/src/transformation/generic_algorithm_transformation.cpp

    r1328 r1460  
    1212#include "client_client_dht_template.hpp" 
    1313#include "utils.hpp" 
     14#include "timer.hpp" 
     15#include "mpi.hpp" 
    1416 
    1517namespace xios { 
     
    1719CGenericAlgorithmTransformation::CGenericAlgorithmTransformation() 
    1820 : transformationMapping_(), transformationWeight_(), transformationPosition_(), 
    19    idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA) 
     21   idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(), 
     22   computedProcSrcNonTransformedElement_(false), eliminateRedondantSrc_(true), isDistributedComputed_(false) 
    2023{ 
    2124} 
     
    112115} 
    113116 
     117bool CGenericAlgorithmTransformation::isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst) 
     118{ 
     119 
     120  if (!isDistributedComputed_) 
     121  { 
     122    isDistributedComputed_=true ; 
     123    if (!eliminateRedondantSrc_) isDistributed_=true ; 
     124    else 
     125    { 
     126      CContext* context = CContext::getCurrent(); 
     127      CContextClient* client = context->client; 
     128   
     129      computePositionElements(gridSrc, gridDst); 
     130      std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars(); 
     131      std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     132      std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     133      int distributed, distributed_glo ; 
     134   
     135      CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 
     136      if (2 == axisDomainSrcOrder(elementPositionInGrid)) // It's domain 
     137      { 
     138        distributed=domainListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]]->isDistributed() ; 
     139        ep_lib::MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 
     140     
     141      } 
     142      else if (1 == axisDomainSrcOrder(elementPositionInGrid))//it's an axis 
     143      { 
     144        distributed=axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]]->isDistributed() ; 
     145        ep_lib::MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 
     146      } 
     147      else //it's a scalar 
     148      { 
     149        distributed_glo=false ; 
     150      }  
     151      isDistributed_=distributed_glo ; 
     152    } 
     153  } 
     154  return isDistributed_ ; 
     155 
    114156/*! 
    115157  This function computes the global indexes of grid source, which the grid destination is in demand. 
     
    130172 
    131173  typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap; 
    132  
    133   size_t indexSrcSize = 0; 
    134   for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
    135   { 
    136     TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 
    137                                            iteTransMap = transformationMapping_[idxTrans].end(); 
    138     TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 
    139  
    140     itTransWeight = itbTransWeight; 
    141     for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
    142     { 
    143        indexSrcSize += (itTransMap->second).size(); 
    144     } 
    145   } 
    146  
    147   bool isTransPosEmpty = transformationPosition_.empty(); 
    148   CArray<size_t,1> transPos; 
    149   if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 
    150   CArray<size_t,1> indexSrc(indexSrcSize); 
    151   indexSrcSize = 0; 
    152   for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
    153   { 
    154     TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 
    155                                            iteTransMap = transformationMapping_[idxTrans].end(); 
    156     TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 
    157  
    158     // Build mapping between global source element index and global destination element index. 
    159     itTransWeight = itbTransWeight; 
    160     for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
    161     { 
    162       const std::vector<int>& srcIndex = itTransMap->second; 
    163       for (int idx = 0; idx < srcIndex.size(); ++idx) 
    164       { 
    165         indexSrc(indexSrcSize) = srcIndex[idx]; 
    166         ++indexSrcSize; 
    167       } 
    168     } 
    169  
    170     if (!isTransPosEmpty) 
    171     { 
    172       TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 
    173       transPos(idxTrans) = itPosMap->second[0]; 
    174     } 
    175   } 
     174  int idx; 
    176175 
    177176  // compute position of elements on grids 
     
    184183  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
    185184  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
    186   CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 
    187  
    188   // Find out global index source of transformed element on corresponding process. 
    189   std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements()); 
    190   CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc;   
    191   for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
    192   { 
    193     if (idx == elementPositionInGrid) 
    194       computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]); 
    195     if (2 == axisDomainDstOrder(idx)) // It's domain 
    196     { 
    197       if (idx != elementPositionInGrid) 
    198         computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 
    199                                    domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 
    200                                    transPos, 
    201                                    globalElementIndexOnProc[idx]);       
    202  
    203     } 
    204     else if (1 == axisDomainDstOrder(idx))//it's an axis 
    205     { 
    206       if (idx != elementPositionInGrid) 
    207         computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 
    208                                  axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 
    209                                  transPos, 
    210                                  globalElementIndexOnProc[idx]); 
    211     } 
    212     else //it's a scalar 
    213     { 
    214       if (idx != elementPositionInGrid) 
    215         computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 
    216                                    scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 
    217                                    transPos, 
    218                                    globalElementIndexOnProc[idx]); 
    219  
    220     } 
    221   } 
    222  
    223   if (!isTransPosEmpty) 
    224   { 
    225     for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 
    226     { 
    227       if (idx != elementPositionInGrid) 
    228       { 
    229         boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it, 
    230                                                                  ite = globalElementIndexOnProc[idx].end(); 
    231         for (it = itb; it != ite; ++it) it->second.resize(1); 
    232       } 
    233     } 
    234   } 
    235  
     185  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;   
     186   
     187  bool isTransPosEmpty = transformationPosition_.empty(); 
     188  CArray<size_t,1> transPos; 
     189  if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 
     190  std::set<size_t> allIndexSrc; // All index of source, which can be scattered among processes, need for doing transformation  
     191   
     192  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
     193  { 
     194    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 
     195                                           iteTransMap = transformationMapping_[idxTrans].end(); 
     196    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 
     197 
     198    // Build mapping between global source element index and global destination element index. 
     199    itTransWeight = itbTransWeight; 
     200    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
     201    { 
     202      const std::vector<int>& srcIndex = itTransMap->second; 
     203      for (idx = 0; idx < srcIndex.size(); ++idx) 
     204        allIndexSrc.insert(srcIndex[idx]); 
     205    } 
     206 
     207    if (!isTransPosEmpty) 
     208    { 
     209      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 
     210      transPos(idxTrans) = itPosMap->second[0]; 
     211    } 
     212  } 
     213 
     214  size_t indexSrcSize = 0; 
     215  CArray<size_t,1> indexSrc(allIndexSrc.size()); 
     216  for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it, ++indexSrcSize) 
     217    indexSrc(indexSrcSize) = *it; 
     218 
     219  // Flag to indicate whether we will recompute distribution of source global index  on processes 
     220  bool computeGlobalIndexOnProc = false;  
     221  if (indexElementSrc_.size() != allIndexSrc.size()) 
     222    computeGlobalIndexOnProc = true;   
     223  else 
     224  { 
     225    for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it) 
     226      if (0 == indexElementSrc_.count(*it)) 
     227      { 
     228        computeGlobalIndexOnProc = true; 
     229        break;         
     230      } 
     231  } 
     232 
     233  if (computeGlobalIndexOnProc) 
     234    indexElementSrc_.swap(allIndexSrc); 
     235       
     236  int sendValue = (computeGlobalIndexOnProc) ? 1 : 0; 
     237  int recvValue = 0; 
     238  ep_lib::MPI_Allreduce(&sendValue, &recvValue, 1, MPI_INT, MPI_SUM, client->intraComm); 
     239  computeGlobalIndexOnProc = (0 < recvValue); 
     240 
     241//  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 
     242 
     243  if (computeGlobalIndexOnProc || !computedProcSrcNonTransformedElement_) 
     244  {     
     245    { 
     246      CClientClientDHTInt::Index2VectorInfoTypeMap tmp ; 
     247      globalIndexOfTransformedElementOnProc_.swap(tmp) ; 
     248    } 
     249    // Find out global index source of transformed element on corresponding process.     
     250    if (globalElementIndexOnProc_.empty()) 
     251      globalElementIndexOnProc_.resize(axisDomainDstOrder.numElements()); 
     252     
     253    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     254    { 
     255       
     256      if (idx == elementPositionInGrid) 
     257        computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc_); //globalElementIndexOnProc[idx]); 
     258      if (!computedProcSrcNonTransformedElement_) 
     259      { 
     260        if (2 == axisDomainDstOrder(idx)) // It's domain 
     261        { 
     262          if (idx != elementPositionInGrid) 
     263            computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 
     264                                       domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 
     265                                       transPos, 
     266                                       globalElementIndexOnProc_[idx]);       
     267 
     268        } 
     269        else if (1 == axisDomainDstOrder(idx))//it's an axis 
     270        { 
     271          if (idx != elementPositionInGrid) 
     272            computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 
     273                                     axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 
     274                                     transPos, 
     275                                     globalElementIndexOnProc_[idx]); 
     276        } 
     277        else //it's a scalar 
     278        { 
     279          if (idx != elementPositionInGrid) 
     280            computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 
     281                                       scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 
     282                                       transPos, 
     283                                       globalElementIndexOnProc_[idx]); 
     284 
     285        } 
     286      } 
     287    } 
     288 
     289    if (!isTransPosEmpty && !computedProcSrcNonTransformedElement_) 
     290    { 
     291      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
     292      { 
     293        if (idx != elementPositionInGrid) 
     294        { 
     295          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     296                                                                   ite = globalElementIndexOnProc_[idx].end(); 
     297          for (it = itb; it != ite; ++it) it->second.resize(1); 
     298        } 
     299      } 
     300    } 
     301 
     302/*       
     303    if (!computedProcSrcNonTransformedElement_) 
     304    { 
     305      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
     306      { 
     307        if (idx != elementPositionInGrid) 
     308        { 
     309          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     310                                                                   ite = globalElementIndexOnProc_[idx].end(); 
     311          for (it = itb; it != ite; ++it) procOfNonTransformedElements_.insert(it->first); 
     312          if (procOfNonTransformedElements_.size() == nbClient) 
     313            break; 
     314        } 
     315      } 
     316    } 
     317    
     318    // Processes contain the source index of transformed element 
     319    std::set<int> procOfTransformedElement;  
     320    CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc.begin(), 
     321                                                           itIdxe = globalIndexOfTransformedElementOnProc.end(), itIdx; 
     322    for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 
     323    { 
     324      std::vector<int>& tmp = itIdx->second; 
     325      for (int i = 0; i < tmp.size(); ++i) 
     326        procOfTransformedElement.insert(tmp[i]); 
     327      if (tmp.size() == nbClient) 
     328        break; 
     329    }                                                            
     330     
     331    std::set<int>& commonProc = (procOfTransformedElement.size() < procOfNonTransformedElements_.size()) ? procOfTransformedElement  
     332                              : (!procOfNonTransformedElements_.empty() ? procOfNonTransformedElements_ : procOfTransformedElement); 
     333     
     334    std::vector<int> procContainSrcElementIdx(commonProc.size()); 
     335    int count = 0; 
     336    for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) 
     337      procContainSrcElementIdx[count++] = *it; 
     338 
     339    procContainSrcElementIdx_.swap(procContainSrcElementIdx);     
     340*/ 
     341     
     342    if (procElementList_.empty()) procElementList_.resize(axisDomainDstOrder.numElements()) ; 
     343    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     344    { 
     345      std::set<int>& procList=procElementList_[idx] ; 
     346      std::set<int> commonTmp ; 
     347      if (idx == elementPositionInGrid) 
     348      { 
     349          set<int> tmpSet ;  
     350          procList.swap(tmpSet) ; 
     351          CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc_.begin(), 
     352                                                                 itIdxe = globalIndexOfTransformedElementOnProc_.end(), itIdx; 
     353          for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 
     354          { 
     355             std::vector<int>& tmp = itIdx->second; 
     356             for (int i = 0; i < tmp.size(); ++i) procList.insert(tmp[i]); 
     357             if (tmp.size() == nbClient) 
     358             break; 
     359          } 
     360      } 
     361      else 
     362      { 
     363        if (!computedProcSrcNonTransformedElement_) 
     364        { 
     365          set<int> tmpSet ;  
     366          procList.swap(tmpSet) ; 
     367          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     368                                                                   ite = globalElementIndexOnProc_[idx].end(); 
     369          for (it = itb; it != ite; ++it) 
     370          { 
     371            procList.insert(it->first); 
     372            if (procList.size() == nbClient)  break; 
     373          } 
     374        } 
     375      } 
     376 
     377      if (idx==0) commonProc_= procList ; 
     378      else 
     379      { 
     380        for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) 
     381          if (procList.count(*it)==1) commonTmp.insert(*it) ; 
     382        commonProc_.swap(commonTmp) ; 
     383      } 
     384    } 
     385    std::vector<int> procContainSrcElementIdx(commonProc_.size()); 
     386    int count = 0; 
     387    for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) procContainSrcElementIdx[count++] = *it; 
     388    procContainSrcElementIdx_.swap(procContainSrcElementIdx); 
     389     
     390        // For the first time, surely we calculate proc containing non transformed elements 
     391    if (!computedProcSrcNonTransformedElement_) computedProcSrcNonTransformedElement_ = true; 
     392  } 
     393   
    236394  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
    237395  { 
     
    243401 
    244402    // Build mapping between global source element index and global destination element index. 
    245     boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc[elementPositionInGrid]); 
    246     boost::unordered_map<int,int> tmpCounter; 
     403    boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc_[elementPositionInGrid]); 
     404    std::set<int> tmpCounter; 
    247405    itTransWeight = itbTransWeight; 
    248406    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
     
    250408      const std::vector<int>& srcIndex = itTransMap->second; 
    251409      const std::vector<double>& weight = itTransWeight->second; 
    252       for (int idx = 0; idx < srcIndex.size(); ++idx) 
     410      for (idx = 0; idx < srcIndex.size(); ++idx) 
    253411      { 
    254412        src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx])); 
    255         if (1 == globalIndexOfTransformedElementOnProc.count(srcIndex[idx]) && (0 == tmpCounter.count(srcIndex[idx]))) 
    256         { 
    257           tmpCounter[srcIndex[idx]] = 1; 
    258           std::vector<int>& srcProc = globalIndexOfTransformedElementOnProc[srcIndex[idx]]; 
    259           for (int j = 0; j < srcProc.size(); ++j) 
    260             globalElementIndexOnProc[elementPositionInGrid][srcProc[j]].push_back(srcIndex[idx]); 
    261         } 
    262       } 
    263     } 
    264  
     413        if (0 == tmpCounter.count(srcIndex[idx])) 
     414        {           
     415          tmpCounter.insert(srcIndex[idx]); 
     416        
     417          vector<int>& rankSrc = globalIndexOfTransformedElementOnProc_[srcIndex[idx]] ; 
     418          for (int n=0;n<rankSrc.size();++n) 
     419          { 
     420            if (commonProc_.count(rankSrc[n])==1) globalElementIndexOnProc_[elementPositionInGrid][rankSrc[n]].push_back(srcIndex[idx]); 
     421          } 
     422//          for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 
     423//            globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 
     424        } 
     425      } 
     426    } 
     427   
    265428    if (!isTransPosEmpty) 
    266429    { 
    267       for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 
     430      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
    268431      { 
    269432        if (idx != elementPositionInGrid) 
    270433        { 
    271           boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it, 
    272                                                                    ite = globalElementIndexOnProc[idx].end(); 
     434          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     435                                                                   ite = globalElementIndexOnProc_[idx].end(); 
    273436          for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans); 
    274437        } 
    275438      } 
    276     } 
    277  
    278     std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false)); 
    279     boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite; 
    280     for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 
    281     { 
    282       itb = globalElementIndexOnProc[idx].begin(); 
    283       ite = globalElementIndexOnProc[idx].end(); 
    284       for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true; 
    285     } 
    286  
    287     // Determine procs which contain global source index 
    288     std::vector<bool> intersectedProc(nbClient, true); 
    289     for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
    290     { 
    291       std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(), 
    292                      intersectedProc.begin(), intersectedProc.begin(), 
    293                      std::logical_and<bool>()); 
    294     } 
    295  
    296     std::vector<int> srcRank; 
    297     for (int idx = 0; idx < nbClient; ++idx) 
    298     { 
    299       if (intersectedProc[idx]) srcRank.push_back(idx); 
    300439    } 
    301440 
    302441    // Ok, now compute global index of grid source and ones of grid destination 
    303442    computeGlobalGridIndexMapping(elementPositionInGrid, 
    304                                   srcRank, 
     443                                  procContainSrcElementIdx_, //srcRank, 
    305444                                  src2DstMap, 
    306445                                  gridSrc, 
    307446                                  gridDst, 
    308                                   globalElementIndexOnProc, 
     447                                  globalElementIndexOnProc_, 
    309448                                  globaIndexWeightFromSrcToDst); 
    310   } 
     449  }   
    311450 } 
    312451 
     
    316455  \param [in] srcRank rank of client from which we demand global index of element source 
    317456  \param [in] src2DstMap mapping of global index of element source and global index of element destination 
    318   \param[in] gridSrc Grid source 
    319   \param[in] gridDst Grid destination 
    320   \param[in] globalElementIndexOnProc Global index of element source on different client rank 
    321   \param[out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination 
     457  \param [in] gridSrc Grid source 
     458  \param [in] gridDst Grid destination 
     459  \param [in] globalElementIndexOnProc Global index of element source on different client rank 
     460  \param [out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination 
    322461*/ 
    323462void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid, 
     
    329468                                                                   SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 
    330469{ 
     470  SourceDestinationIndexMap globaIndexWeightFromSrcToDst_tmp ; 
     471   
     472  CContext* context = CContext::getCurrent(); 
     473  CContextClient* client=context->client; 
     474  int clientRank = client->clientRank; 
     475   
    331476  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
    332477  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     
    369514  size_t globalDstSize = 1; 
    370515  domainIndex = axisIndex = scalarIndex = 0; 
     516  set<size_t>  globalSrcStoreIndex ; 
     517   
    371518  for (int idx = 0; idx < nbElement; ++idx) 
    372519  { 
     
    392539  } 
    393540 
     541  std::map< std::pair<size_t,size_t>, int > rankMap ; 
     542  std::map< std::pair<size_t,size_t>, int >:: iterator rankMapIt ; 
     543   
    394544  for (int i = 0; i < srcRank.size(); ++i) 
    395545  { 
     
    451601        for (int k = 0; k < globalElementDstIndexSize; ++k) 
    452602        { 
    453           globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 
     603           
     604          globaIndexWeightFromSrcToDst_tmp[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 
     605          rankMapIt=rankMap.find(make_pair(globalSrcIndex,globalDstVecIndex[k])) ; 
     606          if (rankMapIt==rankMap.end()) rankMap[make_pair(globalSrcIndex,globalDstVecIndex[k])] = rankSrc ; 
     607          else if (rankSrc==clientRank) rankMapIt->second = rankSrc ; 
    454608        } 
    455609        ++idxLoop[0]; 
     
    458612    } 
    459613  } 
     614 
     615  // eliminate redondant global src point owned by differrent processes. 
     616  // Avoid as possible to tranfer data from an other process if the src point is also owned by current process  
     617      int rankSrc ; 
     618      size_t globalSrcIndex ; 
     619      size_t globalDstIndex ; 
     620      double weight ; 
     621  
     622      SourceDestinationIndexMap::iterator rankIt,rankIte ; 
     623      boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > >::iterator globalSrcIndexIt, globalSrcIndexIte ; 
     624      std::vector<std::pair<size_t,double> >::iterator vectIt,vectIte ; 
     625    
     626      rankIt=globaIndexWeightFromSrcToDst_tmp.begin() ; rankIte=globaIndexWeightFromSrcToDst_tmp.end() ; 
     627      for(;rankIt!=rankIte;++rankIt) 
     628      { 
     629        rankSrc = rankIt->first ; 
     630        globalSrcIndexIt = rankIt->second.begin() ; globalSrcIndexIte = rankIt->second.end() ; 
     631        for(;globalSrcIndexIt!=globalSrcIndexIte;++globalSrcIndexIt) 
     632        {  
     633          globalSrcIndex = globalSrcIndexIt->first ; 
     634          vectIt = globalSrcIndexIt->second.begin() ; vectIte = globalSrcIndexIt->second.end() ; 
     635          for(vectIt; vectIt!=vectIte; vectIt++) 
     636          { 
     637            globalDstIndex = vectIt->first ; 
     638            weight = vectIt->second ; 
     639            if (eliminateRedondantSrc_) 
     640            { 
     641              if (rankMap[make_pair(globalSrcIndex,globalDstIndex)] == rankSrc)   
     642                globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ; 
     643            } 
     644            else globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ; 
     645         } 
     646       } 
     647     } 
     648 
    460649} 
    461650 
     
    507696  for (int idx = 0; idx < nIndexSize; ++idx) 
    508697  { 
    509     globalIndex = axisSrc->index(idx); 
    510     globalIndex2ProcRank[globalIndex].push_back(clientRank); 
     698    if (axisSrc->mask(idx)) 
     699    { 
     700      globalIndex = axisSrc->index(idx); 
     701      globalIndex2ProcRank[globalIndex].push_back(clientRank); 
     702    } 
    511703  } 
    512704 
     
    574766  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 
    575767  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 
     768   
    576769  if (destGlobalIndexPositionInGrid.isEmpty()) 
    577770  { 
     
    581774      j_ind=domainSrc->j_index(idx) ; 
    582775 
    583       globalIndex = i_ind + j_ind * niGlobSrc; 
    584       globalIndex2ProcRank[globalIndex].resize(1); 
    585       globalIndex2ProcRank[globalIndex][0] = clientRank; 
     776      if (domainSrc->localMask(idx)) 
     777      { 
     778        globalIndex = i_ind + j_ind * niGlobSrc; 
     779        globalIndex2ProcRank[globalIndex].resize(1); 
     780        globalIndex2ProcRank[globalIndex][0] = clientRank; 
     781      } 
    586782    } 
    587783  } 
     
    590786    for (int idx = 0; idx < nIndexSize; ++idx) 
    591787    { 
    592       globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank); 
     788//      if (domainSrc->localMask(idx)) -> not necessairy, mask seem to be included in  destGlobalIndexPositionInGrid(idx)    (ym) 
     789        globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank); 
    593790    } 
    594791  } 
     
    647844  } 
    648845} 
     846 
     847 
     848 
     849 
     850 
     851 
     852void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 
     853                                                                                 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest) 
     854{ 
     855 
     856  CContext* context = CContext::getCurrent(); 
     857  CContextClient* client = context->client; 
     858  int nbClient = client->clientSize; 
     859 
     860  computePositionElements(gridDst, gridSrc); 
     861  std::vector<CScalar*> scalarListDstP = gridDst->getScalars(); 
     862  std::vector<CAxis*> axisListDstP = gridDst->getAxis(); 
     863  std::vector<CDomain*> domainListDstP = gridDst->getDomains(); 
     864  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order; 
     865  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars(); 
     866  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     867  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     868  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;   
     869 
     870  int nElement=axisDomainSrcOrder.numElements() ; 
     871  int indSrc=1 ; 
     872  int indDst=1 ; 
     873  vector<int> nIndexSrc(nElement) ; 
     874  vector<int> nIndexDst(nElement) ; 
     875  vector< CArray<bool,1>* > maskSrc(nElement) ; 
     876  vector< CArray<bool,1>* > maskDst(nElement) ; 
     877     
     878  int nlocalIndexSrc=1 ; 
     879  int nlocalIndexDest=1 ; 
     880  CArray<bool,1> maskScalar(1) ; 
     881  maskScalar  = true ; 
     882   
     883   
     884  for(int i=0 ; i<nElement; i++) 
     885  { 
     886    int dimElement = axisDomainSrcOrder(i); 
     887    if (2 == dimElement) //domain 
     888    { 
     889      CDomain* domain=domainListSrcP[elementPositionInGridSrc2DomainPosition_[i]] ; 
     890      nIndexSrc[i] = domain->i_index.numElements() ; 
     891      maskSrc[i]=&domain->localMask ; 
     892    } 
     893    else if (1 == dimElement) //axis 
     894    { 
     895      CAxis* axis=axisListSrcP[elementPositionInGridSrc2AxisPosition_[i]] ; 
     896      nIndexSrc[i] = axis->index.numElements() ; 
     897      maskSrc[i]=&axis->mask ; 
     898    } 
     899    else  //scalar 
     900    { 
     901      nIndexSrc[i]=1 ; 
     902      maskSrc[i]=&maskScalar ; 
     903    } 
     904    nlocalIndexSrc=nlocalIndexSrc*nIndexSrc[i] ; 
     905  } 
     906 
     907 
     908 
     909  int offset=1 ; 
     910  for(int i=0 ; i<nElement; i++) 
     911  { 
     912    int dimElement = axisDomainDstOrder(i); 
     913    if (2 == dimElement) //domain 
     914    { 
     915      CDomain* domain=domainListDstP[elementPositionInGridDst2DomainPosition_[i]] ; 
     916      int nIndex=domain->i_index.numElements() ; 
     917      CArray<bool,1>& localMask=domain->localMask ; 
     918      int nbInd=0 ; 
     919      for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ; 
     920      nIndexDst[i] = nbInd ; 
     921      maskDst[i]=&domain->localMask ; 
     922    } 
     923    else if (1 == dimElement) //axis 
     924    { 
     925      CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[i]] ; 
     926      int nIndex=axis->index.numElements() ; 
     927      CArray<bool,1>& localMask=axis->mask ; 
     928      int nbInd=0 ; 
     929      for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ; 
     930      nIndexDst[i] = nbInd ; 
     931      maskDst[i]=&axis->mask ; 
     932    } 
     933    else  //scalar 
     934    { 
     935      nIndexDst[i]=1 ; 
     936      maskDst[i]=&maskScalar ; 
     937    } 
     938    if (i<elementPositionInGrid) offset=offset*nIndexDst[i] ; 
     939    nlocalIndexDest=nlocalIndexDest*nIndexDst[i] ; 
     940  } 
     941 
     942 
     943 
     944 
     945 
     946 
     947  vector<int> dstLocalInd ; 
     948  int dimElement = axisDomainDstOrder(elementPositionInGrid); 
     949  if (2 == dimElement) //domain 
     950  { 
     951    CDomain* domain = domainListDstP[elementPositionInGridDst2DomainPosition_[elementPositionInGrid]] ; 
     952    int ni_glo=domain->ni_glo ; 
     953    int nj_glo=domain->nj_glo ; 
     954    int nindex_glo=ni_glo*nj_glo ; 
     955    dstLocalInd.resize(nindex_glo,-1) ; 
     956    int nIndex=domain->i_index.numElements() ; 
     957    CArray<bool,1>& localMask=domain->localMask ; 
     958    int unmaskedInd=0 ; 
     959    int globIndex ; 
     960    for(int i=0;i<nIndex;i++) 
     961    { 
     962      if (localMask(i)) 
     963      { 
     964        globIndex=domain->j_index(i)*ni_glo+domain->i_index(i) ; 
     965        dstLocalInd[globIndex]=unmaskedInd ; 
     966        unmaskedInd++ ; 
     967      } 
     968    } 
     969  } 
     970  else if (1 == dimElement) //axis 
     971  { 
     972    CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[elementPositionInGrid]] ; 
     973    int nindex_glo=axis->n_glo ; 
     974    dstLocalInd.resize(nindex_glo,-1) ; 
     975    int nIndex=axis->index.numElements() ; 
     976    CArray<bool,1>& localMask=axis->mask ; // axis mask must include later data_index 
     977    int unmaskedInd=0 ; 
     978    for(int i=0;i<nIndex;i++) 
     979    { 
     980      if (localMask(i)) 
     981      { 
     982        dstLocalInd[axis->index(i)]=unmaskedInd ; 
     983        unmaskedInd++ ; 
     984      } 
     985    } 
     986  } 
     987  else  //scalar 
     988  { 
     989    dstLocalInd.resize(1) ;  
     990    dstLocalInd[0]=0 ;  
     991  } 
     992 
     993// just get the local src mask 
     994  CArray<bool,1> localMaskOnSrcGrid; 
     995  gridSrc->getLocalMask(localMaskOnSrcGrid) ; 
     996// intermediate grid, mask is not initialized => set up mask to true 
     997  if (localMaskOnSrcGrid.isEmpty()) 
     998  { 
     999    localMaskOnSrcGrid.resize(nlocalIndexSrc) ; 
     1000    localMaskOnSrcGrid=true ; 
     1001  } 
     1002   
     1003 
     1004  localMaskOnGridDest.resize(nlocalIndexDest,false) ; 
     1005 
     1006  vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ; 
     1007    
     1008  for(int t=0;t<transformationMapping_.size();++t) 
     1009  { 
     1010    TransformationIndexMap::const_iterator   itTransMap = transformationMapping_[t].begin(), 
     1011                                             iteTransMap = transformationMapping_[t].end(); 
     1012    TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[t].begin(); 
     1013    dstIndWeight[t].resize(nIndexSrc[elementPositionInGrid]) ; 
     1014     
     1015    for(;itTransMap!=iteTransMap;++itTransMap,++itTransWeight) 
     1016    { 
     1017      int dst=dstLocalInd[itTransMap->first] ; 
     1018      if (dst!=-1) 
     1019      { 
     1020        const vector<int>& srcs=itTransMap->second; 
     1021        const vector<double>& weights=itTransWeight->second; 
     1022        for(int i=0;i<srcs.size() ;i++) dstIndWeight[t][srcs[i]].push_back(pair<int,double>(dst*offset+t,weights[i])) ; 
     1023      } 
     1024    } 
     1025  } 
     1026  int srcInd=0 ;   
     1027  int currentInd ; 
     1028  int t=0 ;   
     1029  int srcIndCompressed=0 ; 
     1030   
     1031  nonDistributedrecursiveFunct(nElement-1,true,elementPositionInGrid,maskSrc,maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight,   
     1032                               currentInd,localSrc,localDst,weight, localMaskOnSrcGrid, localMaskOnGridDest ); 
     1033                
     1034} 
     1035 
     1036 
     1037void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 
     1038                    vector<int>& localSrc, vector<int>& localDst, vector<double>& weight,  CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest ) 
     1039{ 
     1040  int masked_ ; 
     1041  if (currentPos!=elementPositionInGrid) 
     1042  { 
     1043    if (currentPos!=0) 
     1044    { 
     1045      CArray<bool,1>& mask = *maskSrc[currentPos] ; 
     1046      
     1047      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1048      { 
     1049        masked_=masked ; 
     1050        if (!mask(i)) masked_=false ; 
     1051        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 
     1052      } 
     1053    } 
     1054    else 
     1055    { 
     1056      CArray<bool,1>& mask = *maskSrc[currentPos] ; 
     1057      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1058      { 
     1059        if (masked && mask(i)) 
     1060        { 
     1061          if (dstIndWeight[t][currentInd].size()>0) 
     1062          { 
     1063            for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it) 
     1064            { 
     1065              if (localMaskOnGridSrc(srcInd)) 
     1066              { 
     1067                localSrc.push_back(srcIndCompressed) ; 
     1068                localDst.push_back(it->first) ; 
     1069                weight.push_back(it->second) ; 
     1070                localMaskOnGridDest[it->first]=true ; 
     1071              } 
     1072              (it->first)++ ; 
     1073            } 
     1074          } 
     1075          if (t < dstIndWeight.size()-1) t++ ; 
     1076          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ; 
     1077        } 
     1078        srcInd++ ; 
     1079      } 
     1080    } 
     1081  } 
     1082  else 
     1083  { 
     1084  
     1085    if (currentPos!=0) 
     1086    { 
     1087 
     1088      CArray<bool,1>& mask = *maskSrc[currentPos] ; 
     1089      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1090      { 
     1091        t=0 ; 
     1092        masked_=masked ; 
     1093        if (!mask(i)) masked_=false ;  
     1094        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight , i,  localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 
     1095      } 
     1096    } 
     1097    else 
     1098    { 
     1099      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1100      { 
     1101        if (masked) 
     1102        { 
     1103          t=0 ;         
     1104          if (dstIndWeight[t][i].size()>0) 
     1105          { 
     1106            for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it) 
     1107            { 
     1108              if (localMaskOnGridSrc(srcInd)) 
     1109              { 
     1110                localSrc.push_back(srcIndCompressed) ; 
     1111                localDst.push_back(it->first) ; 
     1112                weight.push_back(it->second) ; 
     1113                localMaskOnGridDest[it->first]=true ; 
     1114              } 
     1115              (it->first)++ ; 
     1116            } 
     1117           } 
     1118          if (t < dstIndWeight.size()-1) t++ ; 
     1119          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ; 
     1120        } 
     1121        srcInd++ ; 
     1122      } 
     1123    } 
     1124  } 
     1125 
     1126} 
     1127 
     1128 
     1129 
     1130 
     1131 
     1132 
     1133 
     1134 
     1135 
     1136 
    6491137 
    6501138/*! 
Note: See TracChangeset for help on using the changeset viewer.