Ignore:
Timestamp:
01/10/18 16:17:57 (6 years ago)
Author:
ymipsl
Message:

2 update for spatial tranformations :

  • One bug fix introduce in r1389 concerning domain interpolation or other distributed spatial distransfomation
  • Specific optimisation for transformation on element wich is not distributed across processes

This optimisation is experimental and will be activated only when using a variable in xios context :

<variable id="activate_non_distributed_transformation" type="bool">true</variable>

Later when more succesfull test, the variable use will removed...

YM

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

Legend:

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

    r1389 r1399  
    1313#include "utils.hpp" 
    1414#include "timer.hpp" 
     15#include "mpi.hpp" 
    1516 
    1617namespace xios { 
     
    1920 : transformationMapping_(), transformationWeight_(), transformationPosition_(), 
    2021   idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(), 
    21    computedProcSrcNonTransformedElement_(false), eliminateRedondantSrc_(true) 
     22   computedProcSrcNonTransformedElement_(false), eliminateRedondantSrc_(true), isDistributedComputed_(false) 
    2223{ 
    2324} 
     
    114115} 
    115116 
     117bool CGenericAlgorithmTransformation::isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst) 
     118{ 
     119 
     120  if (!isDistributedComputed_) 
     121  { 
     122    CContext* context = CContext::getCurrent(); 
     123    CContextClient* client = context->client; 
     124   
     125    computePositionElements(gridSrc, gridDst); 
     126    std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars(); 
     127    std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     128    std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     129    int distributed, distributed_glo ; 
     130   
     131    CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 
     132    if (2 == axisDomainSrcOrder(elementPositionInGrid)) // It's domain 
     133    { 
     134      distributed=domainListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]]->isDistributed() ; 
     135      MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 
     136     
     137    } 
     138    else if (1 == axisDomainSrcOrder(elementPositionInGrid))//it's an axis 
     139    { 
     140      distributed=axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]]->isDistributed() ; 
     141      MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 
     142    } 
     143    else //it's a scalar 
     144    { 
     145      distributed_glo=false ; 
     146    }  
     147    isDistributed_=distributed_glo ; 
     148    isDistributedComputed_=true ; 
     149  } 
     150  return isDistributed_ ; 
     151 
    116152/*! 
    117153  This function computes the global indexes of grid source, which the grid destination is in demand. 
     
    200236 
    201237  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 
    202    
     238 
    203239  if (computeGlobalIndexOnProc || !computedProcSrcNonTransformedElement_) 
    204240  {     
     
    294330    procContainSrcElementIdx_.swap(procContainSrcElementIdx);     
    295331*/ 
    296     std::set<int> commonProc ; 
     332     
    297333    if (procElementList_.empty()) procElementList_.resize(axisDomainDstOrder.numElements()) ; 
    298334    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 
     
    330366      } 
    331367 
    332       if (idx==0) commonProc.swap(procList) ; 
     368      if (idx==0) commonProc_.swap(procList) ; 
    333369      else 
    334370      { 
    335         for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) 
     371        for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) 
    336372          if (procList.count(*it)==1) commonTmp.insert(*it) ; 
    337         commonProc.swap(commonTmp) ; 
    338       } 
    339     } 
    340     std::vector<int> procContainSrcElementIdx(commonProc.size()); 
     373        commonProc_.swap(commonTmp) ; 
     374      } 
     375    } 
     376    std::vector<int> procContainSrcElementIdx(commonProc_.size()); 
    341377    int count = 0; 
    342     for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) procContainSrcElementIdx[count++] = *it; 
     378    for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) procContainSrcElementIdx[count++] = *it; 
    343379    procContainSrcElementIdx_.swap(procContainSrcElementIdx); 
    344380     
     
    370406          tmpCounter.insert(srcIndex[idx]); 
    371407        
    372           for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 
    373             globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 
     408          vector<int>& rankSrc = globalIndexOfTransformedElementOnProc[srcIndex[idx]] ; 
     409          for (int n=0;n<rankSrc.size();++n) 
     410          { 
     411            if (commonProc_.count(rankSrc[n])==1) globalElementIndexOnProc_[elementPositionInGrid][rankSrc[n]].push_back(srcIndex[idx]); 
     412          } 
     413//          for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 
     414//            globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 
    374415        } 
    375416      } 
     
    787828} 
    788829 
     830 
     831 
     832 
     833 
     834 
     835void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 
     836                                                                                 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest) 
     837{ 
     838 
     839  CContext* context = CContext::getCurrent(); 
     840  CContextClient* client = context->client; 
     841  int nbClient = client->clientSize; 
     842 
     843  computePositionElements(gridDst, gridSrc); 
     844  std::vector<CScalar*> scalarListDstP = gridDst->getScalars(); 
     845  std::vector<CAxis*> axisListDstP = gridDst->getAxis(); 
     846  std::vector<CDomain*> domainListDstP = gridDst->getDomains(); 
     847  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order; 
     848  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars(); 
     849  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 
     850  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 
     851  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;   
     852 
     853  int nElement=axisDomainSrcOrder.numElements() ; 
     854  int indSrc=1 ; 
     855  int indDst=1 ; 
     856  vector<int> nIndexSrc(nElement) ; 
     857  vector<int> nIndexDst(nElement) ; 
     858  int nlocalIndexDest=1 ; 
     859   
     860  for(int i=0 ; i<nElement; i++) 
     861  { 
     862    int dimElement = axisDomainSrcOrder(i); 
     863    if (2 == dimElement) //domain 
     864    { 
     865      CDomain* domain=domainListSrcP[elementPositionInGridSrc2DomainPosition_[i]] ; 
     866      nIndexSrc[i] = domain->i_index.numElements() ; 
     867    } 
     868    else if (1 == dimElement) //axis 
     869    { 
     870      CAxis* axis=axisListSrcP[elementPositionInGridSrc2DomainPosition_[i]] ; 
     871      nIndexSrc[i] = axis->index.numElements() ; 
     872    } 
     873    else  //scalar 
     874    { 
     875      nIndexSrc[i]=1 ; 
     876    } 
     877  } 
     878 
     879  int offset=1 ; 
     880  for(int i=0 ; i<nElement; i++) 
     881  { 
     882    int dimElement = axisDomainDstOrder(i); 
     883    if (2 == dimElement) //domain 
     884    { 
     885      CDomain* domain=domainListDstP[elementPositionInGridDst2DomainPosition_[i]] ; 
     886      nIndexDst[i] = domain->i_index.numElements() ; 
     887    } 
     888    else if (1 == dimElement) //axis 
     889    { 
     890      CAxis* axis = axisListDstP[elementPositionInGridDst2DomainPosition_[i]] ; 
     891      nIndexDst[i] = axis->index.numElements() ; 
     892    } 
     893    else  //scalar 
     894    { 
     895      nIndexDst[i]=1 ; 
     896    } 
     897    if (i<elementPositionInGrid) offset=offset*nIndexDst[i] ; 
     898    nlocalIndexDest=nlocalIndexDest*nIndexDst[i] ; 
     899  } 
     900 
     901  vector<int> dstLocalInd ; 
     902  int dimElement = axisDomainDstOrder(elementPositionInGrid); 
     903  if (2 == dimElement) //domain 
     904  { 
     905    CDomain* domain = domainListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]] ; 
     906    int ni_glo=domain->ni_glo ; 
     907    int nj_glo=domain->nj_glo ; 
     908    int nindex_glo=ni_glo*nj_glo ; 
     909    dstLocalInd.resize(nindex_glo,-1) ; 
     910    int nIndex=domain->i_index.numElements() ; 
     911    for(int i=0;i<nIndex;i++) 
     912    { 
     913      int globIndex=domain->j_index(i)*ni_glo+domain->i_index(i) ; 
     914      dstLocalInd[globIndex]=i ; 
     915    } 
     916  } 
     917  else if (1 == dimElement) //axis 
     918  { 
     919    CAxis* axis = axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]] ; 
     920    int nindex_glo=axis->n_glo ; 
     921    dstLocalInd.resize(nindex_glo,-1) ; 
     922    int nIndex=axis->index.numElements() ; 
     923    for(int i=0;i<nIndex;i++) 
     924    { 
     925      dstLocalInd[axis->index(i)]=i ; 
     926    } 
     927  } 
     928  else  //scalar 
     929  { 
     930    dstLocalInd.resize(1) ;  
     931    dstLocalInd[0]=0 ;  
     932  } 
     933 
     934// just get the local src mask 
     935  CArray<bool,1> localMaskOnSrcGrid; 
     936  gridSrc->getLocalMask(localMaskOnSrcGrid) ;  
     937   
     938 
     939  localMaskOnGridDest.resize(nlocalIndexDest,false) ; 
     940 
     941  vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ; 
     942    
     943  for(int t=0;t<transformationMapping_.size();++t) 
     944  { 
     945    TransformationIndexMap::const_iterator   itTransMap = transformationMapping_[t].begin(), 
     946                                             iteTransMap = transformationMapping_[t].end(); 
     947    TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[t].begin(); 
     948    dstIndWeight[t].resize(nIndexSrc[elementPositionInGrid]) ; 
     949     
     950    for(;itTransMap!=iteTransMap;++itTransMap,++itTransWeight) 
     951    { 
     952      int dst=dstLocalInd[itTransMap->first] ; 
     953      if (dst!=-1) 
     954      { 
     955        const vector<int>& srcs=itTransMap->second; 
     956        const vector<double>& weights=itTransWeight->second; 
     957        for(int i=0;i<srcs.size() ;i++) dstIndWeight[t][srcs[i]].push_back(pair<int,double>(dst*offset+t,weights[i])) ; 
     958      } 
     959    } 
     960  } 
     961  int srcInd=0 ;   
     962  int currentInd ; 
     963  int t=0 ;   
     964 
     965   
     966  nonDistributedrecursiveFunct(nElement-1,elementPositionInGrid,srcInd, nIndexSrc, t, dstIndWeight,   
     967                               currentInd,localSrc,localDst,weight, localMaskOnSrcGrid, localMaskOnGridDest ); 
     968                
     969} 
     970 
     971 
     972void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, int elementPositionInGrid, int& srcInd, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 
     973                    vector<int>& localSrc, vector<int>& localDst, vector<double>& weight,  CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest ) 
     974{ 
     975  if (currentPos!=elementPositionInGrid) 
     976  { 
     977    if (currentPos!=0) 
     978    { 
     979      for(int i=0;i<nIndexSrc[currentPos];i++) 
     980      { 
     981        nonDistributedrecursiveFunct(currentPos-1, elementPositionInGrid, srcInd, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 
     982      } 
     983    } 
     984    else 
     985    { 
     986      for(int i=0;i<nIndexSrc[currentPos];i++) 
     987      { 
     988        if (dstIndWeight[t][currentInd].size()>0) 
     989        { 
     990          for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it) 
     991          { 
     992            if (localMaskOnGridSrc(srcInd)) 
     993            { 
     994              localSrc.push_back(srcInd) ; 
     995              localDst.push_back(it->first) ; 
     996              weight.push_back(it->second) ; 
     997              localMaskOnGridDest[it->first]=true ; 
     998            } 
     999            (it->first)++ ; 
     1000          } 
     1001        } 
     1002        srcInd++ ; 
     1003        if (t < dstIndWeight.size()-1) t++ ; 
     1004      } 
     1005    } 
     1006  } 
     1007  else 
     1008  { 
     1009  
     1010    if (currentPos!=0) 
     1011    { 
     1012 
     1013 
     1014      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1015      { 
     1016        t=0 ; 
     1017        nonDistributedrecursiveFunct(currentPos-1, elementPositionInGrid, srcInd, nIndexSrc, t, dstIndWeight , i,  localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 
     1018      } 
     1019    } 
     1020    else 
     1021    { 
     1022      for(int i=0;i<nIndexSrc[currentPos];i++) 
     1023      { 
     1024        t=0 ;         
     1025        if (dstIndWeight[t][i].size()>0) 
     1026        { 
     1027          for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it) 
     1028          { 
     1029            if (localMaskOnGridSrc(srcInd)) 
     1030            { 
     1031              localSrc.push_back(srcInd) ; 
     1032              localDst.push_back(it->first) ; 
     1033              weight.push_back(it->second) ; 
     1034              localMaskOnGridDest[it->first]=true ; 
     1035            } 
     1036            (it->first)++ ; 
     1037          } 
     1038        } 
     1039        srcInd++ ; 
     1040        if (t < dstIndWeight.size()-1) t++ ; 
     1041      } 
     1042    } 
     1043  } 
     1044 
     1045} 
     1046 
     1047 
     1048 
     1049 
     1050 
     1051 
     1052 
     1053 
     1054 
     1055 
     1056 
    7891057/*! 
    7901058  Compute index mapping between element source and element destination with an auxiliary inputs which determine 
  • XIOS/dev/XIOS_DEV_CMIP6/src/transformation/generic_algorithm_transformation.hpp

    r1389 r1399  
    5252  virtual ~CGenericAlgorithmTransformation() {} 
    5353 
     54  bool isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst) ; 
     55 
    5456  void computeGlobalSourceIndex(int elementPositionInGrid, 
    5557                               CGrid* gridSrc, 
     
    8587  */ 
    8688  void computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs = std::vector<CArray<double,1>* >()); 
     89  void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 
     90                                                  vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest); 
     91  void nonDistributedrecursiveFunct(int currentPos, int elementPositionInGrid, int& srcInd, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 
     92                                     vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest) ; 
    8793 
    8894protected: 
     
    126132 
    127133protected: 
     134  //! indicate if the transformation is performed on a distributed element 
     135  bool isDistributed_ ; 
     136  //! indicate if the method  isDistributedTransformation has been called before 
     137  bool isDistributedComputed_ ; 
     138   
    128139  //! Map between global index of destination element and source element 
    129140  std::vector<TransformationIndexMap> transformationMapping_; 
     
    144155  std::vector<int> procContainSrcElementIdx_;  // List of processes containing source index of transformed elements 
    145156//  std::set<int> procOfNonTransformedElements_; // Processes contain the source index of non-transformed elements 
     157  std::set<int> commonProc_; 
    146158  std::vector< set<int> > procElementList_ ; // List of processes containing source index of elements 
    147159 
  • XIOS/dev/XIOS_DEV_CMIP6/src/transformation/grid_transformation.cpp

    r1158 r1399  
    1616#include "grid.hpp" 
    1717#include <boost/unordered_map.hpp> 
     18#include "timer.hpp" 
    1819 
    1920namespace xios { 
     
    389390      // ComputeTransformation of global index of each element 
    390391      int elementPosition = it->first; 
    391       algo->computeGlobalSourceIndex(elementPosition, 
    392                                      gridSource_, 
    393                                      tmpGridDestination_, 
    394                                      globaIndexWeightFromSrcToDst); 
    395  
    396       // Compute transformation of global indexes among grids 
    397       computeTransformationMapping(globaIndexWeightFromSrcToDst); 
    398  
     392      bool nonDistributedActivated = CXios::getin<bool>("activate_non_distributed_transformation",false); 
     393       
     394      if (nonDistributedActivated && !algo->isDistributedTransformation(elementPositionInGrid, gridSource_, tmpGridDestination_) ) 
     395      { 
     396        vector<int> localSrc ; 
     397        vector<int> localDst ; 
     398        vector<double> weight ; 
     399        localMaskOnGridDest_.push_back(vector<bool>()) ; 
     400        CTimer::get("computeTransformationMappingNonDistributed").resume();   
     401        algo->computeTransformationMappingNonDistributed(elementPosition, gridSource_, tmpGridDestination_,  
     402                                                         localSrc, localDst, weight, localMaskOnGridDest_.back()) ; 
     403        CTimer::get("computeTransformationMappingNonDistributed").suspend();   
     404 
     405        CTimer::get("computeTransformationMappingConvert").resume();   
     406        nbLocalIndexOnGridDest_.push_back(localMaskOnGridDest_.back().size()) ; 
     407        int clientRank=client->clientRank ; 
     408        { 
     409          SendingIndexGridSourceMap tmp; 
     410          localIndexToSendFromGridSource_.push_back(tmp) ; 
     411          SendingIndexGridSourceMap& src=localIndexToSendFromGridSource_.back() ; 
     412          CArray<int,1> arrayTmp ; 
     413          src.insert( pair<int,CArray<int,1> >(clientRank,arrayTmp)) ; 
     414          CArray<int,1>& array=src[clientRank] ; 
     415          array.resize(localSrc.size()) ; 
     416          for(int i=0;i< localSrc.size();++i) array(i)=localSrc[i]  ;     
     417        } 
     418        { 
     419          RecvIndexGridDestinationMap tmp; 
     420          localIndexToReceiveOnGridDest_.push_back(tmp) ; 
     421          RecvIndexGridDestinationMap& dst=localIndexToReceiveOnGridDest_.back() ; 
     422          vector<pair<int,double> > vectTmp ; 
     423          dst.insert( pair<int,vector<pair<int,double> >  >(clientRank,vectTmp)) ; 
     424          vector<pair<int,double> >& vect=dst[clientRank] ; 
     425          vect.resize(localDst.size()) ; 
     426          for(int i=0;i< localDst.size();++i) vect[i]=pair<int,double>(localDst[i],weight[i])  ;       
     427        } 
     428        CTimer::get("computeTransformationMappingConvert").suspend();   
     429      } 
     430      else 
     431      { 
     432        CTimer::get("computeGlobalSourceIndex").resume();            
     433        algo->computeGlobalSourceIndex(elementPosition, 
     434                                       gridSource_, 
     435                                       tmpGridDestination_, 
     436                                       globaIndexWeightFromSrcToDst); 
     437                                      
     438        CTimer::get("computeGlobalSourceIndex").suspend();            
     439        CTimer::get("computeTransformationMapping").resume();      
     440        // Compute transformation of global indexes among grids 
     441        computeTransformationMapping(globaIndexWeightFromSrcToDst); 
     442        CTimer::get("computeTransformationMapping").suspend();  
     443      }  
    399444      if (1 < nbNormalAlgos_) 
    400445      { 
Note: See TracChangeset for help on using the changeset viewer.