Changeset 1216


Ignore:
Timestamp:
07/17/17 16:16:11 (7 years ago)
Author:
mhnguyen
Message:

Performance improvement of vertical interpolation

+) Reduce a number of unnesscessary function callings on calculating weights of interpolation

Test
+) On Curie
+) Ok

Location:
XIOS/dev/XIOS_DEV_CMIP6/src/transformation
Files:
2 edited

Legend:

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

    r1201 r1216  
    1212#include "client_client_dht_template.hpp" 
    1313#include "utils.hpp" 
     14#include "timer.hpp" 
    1415 
    1516namespace xios { 
     
    1718CGenericAlgorithmTransformation::CGenericAlgorithmTransformation() 
    1819 : transformationMapping_(), transformationWeight_(), transformationPosition_(), 
    19    idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA) 
     20   idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(), 
     21   computedProcSrcNonTransformedElement_(false) 
    2022{ 
    2123} 
     
    130132 
    131133  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   } 
     134  int idx; 
    176135 
    177136  // compute position of elements on grids 
     
    184143  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
    185144  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  
     145  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;   
     146   
     147  bool isTransPosEmpty = transformationPosition_.empty(); 
     148  CArray<size_t,1> transPos; 
     149  if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 
     150  std::set<size_t> allIndexSrc; 
     151   
     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 (idx = 0; idx < srcIndex.size(); ++idx) 
     164        allIndexSrc.insert(srcIndex[idx]); 
     165    } 
     166 
     167    if (!isTransPosEmpty) 
     168    { 
     169      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 
     170      transPos(idxTrans) = itPosMap->second[0]; 
     171    } 
     172  } 
     173 
     174  size_t indexSrcSize = 0; 
     175  CArray<size_t,1> indexSrc(allIndexSrc.size()); 
     176  for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it, ++indexSrcSize) 
     177    indexSrc(indexSrcSize) = *it; 
     178 
     179  // Flag to indicate whether we will recompute distribution of source global index  on processes 
     180  bool computeGlobalIndexOnProc = false;  
     181  if (indexElementSrc_.size() != allIndexSrc.size()) 
     182    computeGlobalIndexOnProc = true;   
     183  else 
     184  { 
     185    for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it) 
     186      if (0 == indexElementSrc_.count(*it)) 
     187      { 
     188        computeGlobalIndexOnProc = true; 
     189        break;         
     190      } 
     191  } 
     192 
     193  if (computeGlobalIndexOnProc) 
     194    indexElementSrc_.swap(allIndexSrc); 
     195       
     196  int sendValue = (computeGlobalIndexOnProc) ? 1 : 0; 
     197  int recvValue = 0; 
     198  MPI_Allreduce(&sendValue, &recvValue, 1, MPI_INT, MPI_SUM, client->intraComm); 
     199  computeGlobalIndexOnProc = (1 == recvValue); 
     200 
     201  if (computeGlobalIndexOnProc) 
     202  {     
     203    // Find out global index source of transformed element on corresponding process.     
     204    if (globalElementIndexOnProc_.empty()) 
     205      globalElementIndexOnProc_.resize(axisDomainDstOrder.numElements()); 
     206    CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc;   
     207    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     208    { 
     209      if (idx == elementPositionInGrid) 
     210        computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]); 
     211      if (!computedProcSrcNonTransformedElement_) 
     212      { 
     213        if (2 == axisDomainDstOrder(idx)) // It's domain 
     214        { 
     215          if (idx != elementPositionInGrid) 
     216            computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 
     217                                       domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 
     218                                       transPos, 
     219                                       globalElementIndexOnProc_[idx]);       
     220 
     221        } 
     222        else if (1 == axisDomainDstOrder(idx))//it's an axis 
     223        { 
     224          if (idx != elementPositionInGrid) 
     225            computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 
     226                                     axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 
     227                                     transPos, 
     228                                     globalElementIndexOnProc_[idx]); 
     229        } 
     230        else //it's a scalar 
     231        { 
     232          if (idx != elementPositionInGrid) 
     233            computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 
     234                                       scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 
     235                                       transPos, 
     236                                       globalElementIndexOnProc_[idx]); 
     237 
     238        } 
     239      } 
     240    } 
     241 
     242    if (!isTransPosEmpty && !computedProcSrcNonTransformedElement_) 
     243    { 
     244      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
     245      { 
     246        if (idx != elementPositionInGrid) 
     247        { 
     248          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     249                                                                   ite = globalElementIndexOnProc_[idx].end(); 
     250          for (it = itb; it != ite; ++it) it->second.resize(1); 
     251        } 
     252      } 
     253    } 
     254       
     255    if (!computedProcSrcNonTransformedElement_) 
     256    { 
     257      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
     258      { 
     259        if (idx != elementPositionInGrid) 
     260        { 
     261          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     262                                                                   ite = globalElementIndexOnProc_[idx].end(); 
     263          for (it = itb; it != ite; ++it) procOfNonTransformedElements_.insert(it->first); 
     264          if (procOfNonTransformedElements_.size() == nbClient) 
     265            break; 
     266        } 
     267      } 
     268    } 
     269    
     270    // Processes contain the source index of transformed element 
     271    std::set<int> procOfTransformedElement;  
     272    CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc.begin(), 
     273                                                           itIdxe = globalIndexOfTransformedElementOnProc.end(), itIdx; 
     274    for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 
     275    { 
     276      std::vector<int>& tmp = itIdx->second; 
     277      for (int i = 0; i < tmp.size(); ++i) 
     278        procOfTransformedElement.insert(tmp[i]); 
     279      if (tmp.size() == nbClient) 
     280        break; 
     281    }                                                            
     282     
     283    std::set<int>& commonProc = (procOfTransformedElement.size() < procOfNonTransformedElements_.size()) ? procOfTransformedElement  
     284                              : (!procOfNonTransformedElements_.empty() ? procOfNonTransformedElements_ : procOfTransformedElement); 
     285     
     286    std::vector<int> procContainSrcElementIdx(commonProc.size()); 
     287    int count = 0; 
     288    for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) 
     289      procContainSrcElementIdx[count++] = *it; 
     290 
     291    procContainSrcElementIdx_.swap(procContainSrcElementIdx);     
     292 
     293        // For the first time, surely we calculate proc containing non transformed elements 
     294    if (!computedProcSrcNonTransformedElement_) 
     295      computedProcSrcNonTransformedElement_ = true; 
     296  } 
     297   
    236298  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 
    237299  { 
     
    243305 
    244306    // 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; 
     307    boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc_[elementPositionInGrid]); 
     308    std::set<int> tmpCounter; 
    247309    itTransWeight = itbTransWeight; 
    248310    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 
     
    250312      const std::vector<int>& srcIndex = itTransMap->second; 
    251313      const std::vector<double>& weight = itTransWeight->second; 
    252       for (int idx = 0; idx < srcIndex.size(); ++idx) 
     314      for (idx = 0; idx < srcIndex.size(); ++idx) 
    253315      { 
    254316        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  
     317        if (0 == tmpCounter.count(srcIndex[idx])) 
     318        {           
     319          tmpCounter.insert(srcIndex[idx]); 
     320          for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 
     321            globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 
     322        } 
     323      } 
     324    } 
     325   
    265326    if (!isTransPosEmpty) 
    266327    { 
    267       for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 
     328      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 
    268329      { 
    269330        if (idx != elementPositionInGrid) 
    270331        { 
    271           boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it, 
    272                                                                    ite = globalElementIndexOnProc[idx].end(); 
     332          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 
     333                                                                   ite = globalElementIndexOnProc_[idx].end(); 
    273334          for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans); 
    274335        } 
    275336      } 
    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); 
    300337    } 
    301338 
    302339    // Ok, now compute global index of grid source and ones of grid destination 
    303340    computeGlobalGridIndexMapping(elementPositionInGrid, 
    304                                   srcRank, 
     341                                  procContainSrcElementIdx_, //srcRank, 
    305342                                  src2DstMap, 
    306343                                  gridSrc, 
    307344                                  gridDst, 
    308                                   globalElementIndexOnProc, 
     345                                  globalElementIndexOnProc_, 
    309346                                  globaIndexWeightFromSrcToDst); 
    310   } 
     347  }   
    311348 } 
    312349 
  • XIOS/dev/XIOS_DEV_CMIP6/src/transformation/generic_algorithm_transformation.hpp

    r1158 r1216  
    137137  AlgoTransType type_; 
    138138 
     139  std::set<StdSize> indexElementSrc_; 
     140 
     141  std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc_; 
     142 
     143  std::vector<int> procContainSrcElementIdx_;  // List of processes containing source index of transformed elements 
     144  std::set<int> procOfNonTransformedElements_; // Processes contain the source index of non-transformed elements 
     145 
     146 
     147  bool computedProcSrcNonTransformedElement_; // Flag to indicate whether we computed proc containing non transformed elements 
     148 
    139149  std::map<int, int> elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_; 
    140150  std::map<int, int> elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_; 
Note: See TracChangeset for help on using the changeset viewer.