Ignore:
Timestamp:
04/26/16 16:03:51 (8 years ago)
Author:
mhnguyen
Message:

Changing the way to create virtual grid during transformation.

+)Instead of establishing relation between source grid of current transformation and
the original source grid (source grid of the first transformation), each transformation
keeps its list of source grid and destination, which will be used in interpolation.
+) Clean some redundant codes

Test
+) All official tests pass
+) interpolation tests pass

File:
1 edited

Legend:

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

    r832 r841  
    410410                                     globaIndexWeightFromDestToSource); 
    411411 
     412      // Compute transformation of global indexes among grids 
     413      computeTransformationMapping(globaIndexWeightFromDestToSource); 
     414 
    412415      if (1 < nbAlgos_) 
    413416      { 
    414         // Compute transformation of global indexes among grids 
    415         computeTransformationFromOriginalGridSource(globaIndexWeightFromDestToSource); 
    416  
    417417        // Now grid destination becomes grid source in a new transformation 
    418418        if (nbAgloTransformation != (nbAlgos_-1)) setUpGrid(elementPositionInGrid, transType, nbAgloTransformation); 
    419419      } 
    420       else 
    421       { 
    422         currentGridIndexToOriginalGridIndex_.swap(globaIndexWeightFromDestToSource); 
    423       } 
    424  
    425420      ++nbAgloTransformation; 
    426421    } 
    427422  } 
    428  
    429   if (0 != nbAgloTransformation) 
    430   { 
    431     updateFinalGridDestination(); 
    432     computeFinalTransformationMapping(); 
    433   } 
    434 } 
    435  
    436  
    437 /*! 
    438   After applying the algorithms, there are some informations on grid destination needing change, for now, there are: 
    439    +) mask 
    440 */ 
    441 void CGridTransformation::updateFinalGridDestination() 
     423} 
     424 
     425/*! 
     426  Compute exchange index between grid source and grid destination 
     427  \param [in] globalIndexWeightFromDestToSource global index mapping between grid destination and grid source 
     428*/ 
     429void CGridTransformation::computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource) 
    442430{ 
    443431  CContext* context = CContext::getCurrent(); 
    444432  CContextClient* client = context->client; 
    445433 
    446   //First of all, retrieve info of local mask of grid destination 
    447   CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 
    448   const std::vector<int>& localMaskIndexOnClientDest = distributionClientDest.getLocalMaskIndexOnClient(); 
    449   const CDistributionClient::GlobalLocalDataMap& globalIndexOnClientDest = distributionClientDest.getGlobalLocalDataSendToServer(); 
    450  
    451   CDistributionClient::GlobalLocalDataMap::const_iterator itbArr, itArr, iteArr; 
    452   itbArr = globalIndexOnClientDest.begin(); 
    453   iteArr = globalIndexOnClientDest.end(); 
    454  
    455   DestinationIndexMap::const_iterator iteGlobalMap = currentGridIndexToOriginalGridIndex_.end(); 
    456   const size_t sfmax = NumTraits<unsigned long>::sfmax(); 
    457   int maskIndexNum = 0; 
    458   for (itArr = itbArr; itArr != iteArr; ++itArr) 
    459   { 
    460     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(itArr->first)) 
    461     { 
    462       const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[itArr->first]; 
    463       for (int idx = 0; idx < vecIndex.size(); ++idx) 
    464       { 
    465         if (sfmax == (vecIndex[idx].second).first) 
    466         { 
    467           ++maskIndexNum; 
    468           break; 
    469         } 
    470       } 
    471     } 
    472   } 
    473  
    474   CArray<int,1> maskIndexToModify(maskIndexNum); 
    475   maskIndexNum = 0; 
    476   for (itArr = itbArr; itArr != iteArr; ++itArr) 
    477   { 
    478     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(itArr->first)) 
    479     { 
    480       const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[itArr->first]; 
    481       for (int idx = 0; idx < vecIndex.size(); ++idx) 
    482       { 
    483         if (sfmax == (vecIndex[idx].second).first) 
    484         { 
    485           int localIdx = std::distance(itbArr, itArr); 
    486           maskIndexToModify(maskIndexNum) = localMaskIndexOnClientDest[localIdx]; 
    487           ++maskIndexNum; 
    488           break; 
    489         } 
    490       } 
    491     } 
    492   } 
    493  
    494   gridDestination_->modifyMask(maskIndexToModify); 
    495 } 
    496  
    497 /*! 
    498   A transformation from a grid source to grid destination often passes several intermediate grids, which play a role of 
    499 temporary grid source and/or grid destination. This function makes sure that global index of original grid source are mapped correctly to 
    500 the final grid destination 
    501 */ 
    502 void CGridTransformation::computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource) 
    503 { 
    504   CContext* context = CContext::getCurrent(); 
    505   CContextClient* client = context->client; 
    506  
    507   if (currentGridIndexToOriginalGridIndex_.empty()) 
    508   { 
    509     currentGridIndexToOriginalGridIndex_ = globaIndexMapFromDestToSource; 
    510     return; 
    511   } 
    512  
    513434  CTransformationMapping transformationMap(gridDestination_, gridSource_); 
    514435 
    515     // Then compute transformation mapping among clients 
    516   transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource); 
    517  
    518   const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 
    519   const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping(); 
    520  
    521  // Sending global index of original grid source 
    522   CTransformationMapping::SentIndexMap::const_iterator itbSend = globalIndexToSend.begin(), itSend, 
    523                                                        iteSend = globalIndexToSend.end(); 
    524  int sendBuffSize = 0; 
    525  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size(); 
    526  // We use the first element of each block to send number of element in this block 
    527  sendBuffSize += globalIndexToSend.size(); 
    528  
    529  
    530  typedef unsigned long Scalar; 
    531  Scalar* sendBuff, *currentSendBuff; 
    532  if (0 != sendBuffSize) sendBuff = new Scalar [sendBuffSize]; 
    533  for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax(); 
    534  
    535  std::map<int, MPI_Request> requestsCurrentGrid, requestsOriginalGridGlobalIndex, requestsOriginalGridLocalIndex, requestsWeightGrid; 
    536  DestinationIndexMap::const_iterator iteGlobalIndex = currentGridIndexToOriginalGridIndex_.end(); 
    537  
    538   // Only send global index of original source corresponding to non-masked index 
    539   // Use first position of each block to specify the number of elemnt in this block 
    540  int globalIndexOriginalSrcSendBuffSize = 0; 
    541  int currentBuffPosition = 0; 
    542  for (itSend = itbSend; itSend != iteSend; ++itSend) 
    543  { 
    544    int destRank = itSend->first; 
    545    const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second; 
    546    int countSize  = globalIndexOfCurrentGridSourceToSend.size(); 
    547    size_t countBlock = 0; 
    548    for (int idx = 0; idx < countSize; ++idx) 
    549    { 
    550      size_t index = globalIndexOfCurrentGridSourceToSend[idx].second; 
    551      if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index)) 
    552      { 
    553        globalIndexOriginalSrcSendBuffSize += currentGridIndexToOriginalGridIndex_[index].size() + 1; // 1 for number of elements in this block 
    554        sendBuff[idx+currentBuffPosition+1] = index; 
    555        countBlock += currentGridIndexToOriginalGridIndex_[index].size() + 1; 
    556      } 
    557    } 
    558    sendBuff[currentBuffPosition] = countBlock; 
    559    currentSendBuff = sendBuff + currentBuffPosition; 
    560    MPI_Isend(currentSendBuff, countSize +1, MPI_UNSIGNED_LONG, destRank, MPI_GRID_TRANSFORMATION_CURRENT_GRID_INDEX, client->intraComm, &requestsCurrentGrid[destRank]); 
    561    currentBuffPosition += countSize + 1; 
    562  } 
    563  
    564  Scalar* sendOriginalGlobalIndexBuff, *currentOriginalGlobalIndexSendBuff; 
    565  if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcSendBuffSize]; 
    566  double* sendOriginalWeightBuff, *currentOriginalWeightSendBuff; 
    567  if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalWeightBuff = new double [globalIndexOriginalSrcSendBuffSize]; 
    568  
    569  currentBuffPosition = 0; 
    570  for (itSend = itbSend; itSend != iteSend; ++itSend) 
    571  { 
    572    int destRank = itSend->first; 
    573    const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second; 
    574    int countSize = globalIndexOfCurrentGridSourceToSend.size(); 
    575    int increaseStep = 0; 
    576    for (int idx = 0; idx < countSize; ++idx) 
    577    { 
    578      size_t index = globalIndexOfCurrentGridSourceToSend[idx].second; 
    579      if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index)) 
    580      { 
    581        size_t vectorSize = currentGridIndexToOriginalGridIndex_[index].size(); 
    582        sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = vectorSize; 
    583        sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (double)vectorSize; 
    584        const std::vector<std::pair<int, std::pair<size_t,double> > >& indexWeightPair = currentGridIndexToOriginalGridIndex_[index]; 
    585        for (size_t i = 0; i < vectorSize; ++i) 
    586        { 
    587          ++increaseStep; 
    588          sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = (indexWeightPair[i].second).first; 
    589          sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (indexWeightPair[i].second).second; 
    590        } 
    591        ++increaseStep; 
    592      } 
    593    } 
    594  
    595    currentOriginalGlobalIndexSendBuff = sendOriginalGlobalIndexBuff + currentBuffPosition; 
    596    currentOriginalWeightSendBuff = sendOriginalWeightBuff + currentBuffPosition; 
    597    if (0 != increaseStep) 
    598    { 
    599      MPI_Isend(currentOriginalGlobalIndexSendBuff, increaseStep, MPI_UNSIGNED_LONG, destRank, 
    600                MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &requestsOriginalGridGlobalIndex[destRank]); 
    601      MPI_Isend(currentOriginalWeightSendBuff, increaseStep, MPI_DOUBLE, destRank, 
    602                MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &requestsWeightGrid[destRank]); 
    603    } 
    604    currentBuffPosition += increaseStep; 
    605  } 
    606  
    607  
    608  // Receiving global index of grid source sending from current grid source 
    609  CTransformationMapping::ReceivedIndexMap::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv, 
    610                                                           iteRecv = globalIndexToReceive.end(); 
    611  int recvBuffSize = 0; 
    612  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size(); 
    613  recvBuffSize += globalIndexToReceive.size(); 
    614  
    615  Scalar* recvBuff, *currentRecvBuff; 
    616  if (0 != recvBuffSize) recvBuff = new Scalar [recvBuffSize]; 
    617  for (StdSize idx = 0; idx < recvBuffSize; ++idx) recvBuff[idx] = NumTraits<Scalar>::sfmax(); 
    618  
    619  std::map<int,int> countBlockMap; 
    620  int globalIndexOriginalSrcRecvBuffSize = 0; 
    621  int currentRecvBuffPosition = 0; 
    622  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
    623  { 
    624    MPI_Status status; 
    625    int srcRank = itRecv->first; 
    626    int countSize = (itRecv->second).size(); 
    627    currentRecvBuff = recvBuff + currentRecvBuffPosition; 
    628    MPI_Recv(currentRecvBuff, countSize +1, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_CURRENT_GRID_INDEX, client->intraComm, &status); 
    629    globalIndexOriginalSrcRecvBuffSize += *currentRecvBuff; 
    630    countBlockMap[srcRank] = *currentRecvBuff; 
    631    currentRecvBuffPosition += countSize +1; 
    632  } 
    633  
    634  Scalar* recvOriginalGlobalIndexBuff, *currentOriginalGlobalIndexRecvBuff; 
    635  if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcRecvBuffSize]; 
    636  double* recvOriginalWeightBuff, *currentOriginalWeightRecvBuff; 
    637  if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalWeightBuff = new double [globalIndexOriginalSrcRecvBuffSize]; 
    638  
    639  int countBlock = 0; 
    640  currentRecvBuffPosition = 0; 
    641  currentBuffPosition = 0; 
    642  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
    643  { 
    644    MPI_Status statusGlobalIndex, statusLocalIndex, statusWeight; 
    645    int srcRank = itRecv->first; 
    646    countBlock = countBlockMap[srcRank]; 
    647    currentOriginalGlobalIndexRecvBuff = recvOriginalGlobalIndexBuff + currentBuffPosition; 
    648    currentOriginalWeightRecvBuff = recvOriginalWeightBuff + currentBuffPosition; 
    649    if (0 != countBlock) 
    650    { 
    651      MPI_Recv(currentOriginalGlobalIndexRecvBuff, countBlock, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &statusGlobalIndex); 
    652      MPI_Recv(currentOriginalWeightRecvBuff, countBlock, MPI_DOUBLE, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &statusWeight); 
    653    } 
    654    currentBuffPosition += countBlock; 
    655  } 
    656  
    657  // We process everything in here, even case of masked index 
    658  // The way to process masked index needs discussing 
    659  const size_t sfmax = NumTraits<unsigned long>::sfmax(); 
    660  DestinationIndexMap currentToOriginalTmp; 
    661  
    662  currentRecvBuffPosition = 0; 
    663  currentRecvBuff = recvBuff; 
    664  currentOriginalGlobalIndexRecvBuff  = recvOriginalGlobalIndexBuff; 
    665  currentOriginalWeightRecvBuff = recvOriginalWeightBuff; 
    666  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
    667  { 
    668    int countBlockRank = countBlockMap[itRecv->first]; 
    669  
    670    ++currentRecvBuff;  // it's very subtle here, pay attention 
    671    int countSize = (itRecv->second).size(); 
    672    for (int idx = 0; idx < countSize; ++idx) 
    673    { 
    674       ++currentRecvBuff; 
    675      int ssize = (itRecv->second)[idx].size(); 
    676      if (sfmax != *currentRecvBuff) 
    677      { 
    678        if (0 != countBlockRank) 
    679        { 
    680          countBlock = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition); 
    681          for (int i = 0; i < ssize; ++i) 
    682          { 
    683            for (int j = 0; j < countBlock; ++j) 
    684            { 
    685              size_t globalOriginalIndex = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition+j+1); 
    686              int currentGridLocalIndex = (itRecv->second)[idx][i].first; 
    687              double weightGlobal = *(currentOriginalWeightRecvBuff+currentRecvBuffPosition+j+1) * (itRecv->second)[idx][i].second.second; 
    688              currentToOriginalTmp[(itRecv->second)[idx][i].second.first].push_back(make_pair(currentGridLocalIndex,make_pair(globalOriginalIndex,weightGlobal))); 
    689            } 
    690          } 
    691          currentRecvBuffPosition += countBlock+1; 
    692        } 
    693      } 
    694 //     else 
    695 //     { 
    696 //       for (int i = 0; i < ssize; ++i) 
    697 //       { 
    698 //         currentToOriginalTmp[(itRecv->second)[idx][i].first].push_back(make_pair(sfmax,1.0)); 
    699 //       } 
    700 //     } 
    701    } 
    702  } 
    703  
    704  currentGridIndexToOriginalGridIndex_.swap(currentToOriginalTmp); 
    705  
    706  std::map<int, MPI_Request>::iterator itRequest; 
    707  for (itRequest = requestsCurrentGrid.begin(); itRequest != requestsCurrentGrid.end(); ++itRequest) 
    708    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE); 
    709  for (itRequest = requestsOriginalGridGlobalIndex.begin(); itRequest != requestsOriginalGridGlobalIndex.end(); ++itRequest) 
    710    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE); 
    711  for (itRequest = requestsWeightGrid.begin(); itRequest != requestsWeightGrid.end(); ++itRequest) 
    712    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE); 
    713  
    714  if (0 != sendBuffSize) delete [] sendBuff; 
    715  if (0 != recvBuffSize) delete [] recvBuff; 
    716  if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalGlobalIndexBuff; 
    717  if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalWeightBuff; 
    718  if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalGlobalIndexBuff; 
    719  if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalWeightBuff; 
    720 } 
    721  
    722 /*! 
    723   Compute transformation mapping between grid source and grid destination 
    724   The transformation between grid source and grid destination is represented in form of mapping between global index 
    725 of two grids. Then local index mapping between data on each grid will be found out thanks to these global indexes 
    726 */ 
    727 void CGridTransformation::computeFinalTransformationMapping() 
    728 { 
    729   CContext* context = CContext::getCurrent(); 
    730   CContextClient* client = context->client; 
    731  
    732   CTransformationMapping transformationMap(gridDestination_, originalGridSource_); 
    733  
    734   transformationMap.computeTransformationMapping(currentGridIndexToOriginalGridIndex_); 
     436  transformationMap.computeTransformationMapping(globalIndexWeightFromDestToSource); 
    735437 
    736438  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 
     
    738440  itbMapRecv = globalIndexToReceive.begin(); 
    739441  iteMapRecv = globalIndexToReceive.end(); 
     442  nbLocalIndexOnGridDest_.push_back(globalIndexWeightFromDestToSource.size()); 
     443  localIndexToReceiveOnGridDest_.push_back(RecvIndexGridDestinationMap()); 
     444  RecvIndexGridDestinationMap& recvTmp = localIndexToReceiveOnGridDest_.back(); 
    740445  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv) 
    741446  { 
    742447    int sourceRank = itMapRecv->first; 
    743448    int numGlobalIndex = (itMapRecv->second).size(); 
    744     localIndexToReceiveOnGridDest_[sourceRank].resize(numGlobalIndex); 
     449    recvTmp[sourceRank].resize(numGlobalIndex); 
    745450    for (int i = 0; i < numGlobalIndex; ++i) 
    746451    { 
     
    749454      { 
    750455        const std::pair<int, std::pair<size_t,double> >& tmpPair = (itMapRecv->second)[i][idx]; 
    751         localIndexToReceiveOnGridDest_[sourceRank][i].push_back(make_pair(tmpPair.first, tmpPair.second.second)); 
     456        recvTmp[sourceRank][i].push_back(make_pair(tmpPair.first, tmpPair.second.second)); 
    752457      } 
    753458    } 
     
    759464  itbMap = globalIndexToSend.begin(); 
    760465  iteMap = globalIndexToSend.end(); 
     466  localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 
     467  SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 
    761468  for (itMap = itbMap; itMap != iteMap; ++itMap) 
    762469  { 
    763470    int destRank = itMap->first; 
    764471    int vecSize = itMap->second.size(); 
    765     localIndexToSendFromGridSource_[destRank].resize(vecSize); 
     472    tmpSend[destRank].resize(vecSize); 
    766473    for (int idx = 0; idx < vecSize; ++idx) 
    767474    { 
    768       localIndexToSendFromGridSource_[destRank](idx) = itMap->second[idx].first; 
     475      tmpSend[destRank](idx) = itMap->second[idx].first; 
    769476    } 
    770477  } 
     
    791498  \return local index of data 
    792499*/ 
    793 const std::map<int, CArray<int,1> >& CGridTransformation::getLocalIndexToSendFromGridSource() const 
     500const std::list<CGridTransformation::SendingIndexGridSourceMap>& CGridTransformation::getLocalIndexToSendFromGridSource() const 
    794501{ 
    795502  return localIndexToSendFromGridSource_; 
     
    800507  \return local index of data 
    801508*/ 
    802 const std::map<int,std::vector<std::vector<std::pair<int,double> > > >& CGridTransformation::getLocalIndexToReceiveOnGridDest() const 
     509const std::list<CGridTransformation::RecvIndexGridDestinationMap>& CGridTransformation::getLocalIndexToReceiveOnGridDest() const 
    803510{ 
    804511  return localIndexToReceiveOnGridDest_; 
    805512} 
    806513 
    807 } 
     514const std::list<size_t>& CGridTransformation::getNbLocalIndexToReceiveOnGridDest() const 
     515{ 
     516  return nbLocalIndexOnGridDest_; 
     517} 
     518 
     519} 
Note: See TracChangeset for help on using the changeset viewer.