Changeset 841


Ignore:
Timestamp:
04/26/16 16:03:51 (6 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

Location:
XIOS/trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/filter/spatial_transform_filter.cpp

    r832 r841  
    100100    CContextClient* client = CContext::getCurrent()->client; 
    101101 
    102     const std::map<int, CArray<int,1> >& localIndexToSend = gridTransformation->getLocalIndexToSendFromGridSource(); 
    103     const std::map<int, std::vector<std::vector<std::pair<int,double> > > >& localIndexToReceive = gridTransformation->getLocalIndexToReceiveOnGridDest(); 
     102    const std::list<CGridTransformation::SendingIndexGridSourceMap>& listLocalIndexSend = gridTransformation->getLocalIndexToSendFromGridSource(); 
     103    const std::list<CGridTransformation::RecvIndexGridDestinationMap>& listLocalIndexToReceive = gridTransformation->getLocalIndexToReceiveOnGridDest(); 
     104    const std::list<size_t>& listNbLocalIndexToReceive = gridTransformation->getNbLocalIndexToReceiveOnGridDest(); 
    104105 
    105     dataDest = 0.0; 
     106    CArray<double,1> dataCurrentDest(dataSrc.copy()); 
    106107 
    107     // Sending data from field sources to do transformations 
    108     std::map<int, CArray<int,1> >::const_iterator itbSend = localIndexToSend.begin(), itSend, 
    109                                                   iteSend = localIndexToSend.end(); 
    110     int idxSendBuff = 0; 
    111     std::vector<double*> sendBuff(localIndexToSend.size()); 
    112     for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
     108    std::list<CGridTransformation::SendingIndexGridSourceMap>::const_iterator itListSend  = listLocalIndexSend.begin(), 
     109                                                                              iteListSend = listLocalIndexSend.end(); 
     110    std::list<CGridTransformation::RecvIndexGridDestinationMap>::const_iterator itListRecv = listLocalIndexToReceive.begin(); 
     111    std::list<size_t>::const_iterator itNbListRecv = listNbLocalIndexToReceive.begin(); 
     112 
     113    for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv) 
    113114    { 
    114       if (0 != itSend->second.numElements()) 
    115         sendBuff[idxSendBuff] = new double[itSend->second.numElements()]; 
     115      CArray<double,1> dataCurrentSrc(dataCurrentDest); 
     116      const CGridTransformation::SendingIndexGridSourceMap& localIndexToSend = *itListSend; 
     117 
     118      // Sending data from field sources to do transformations 
     119      std::map<int, CArray<int,1> >::const_iterator itbSend = localIndexToSend.begin(), itSend, 
     120                                                    iteSend = localIndexToSend.end(); 
     121      int idxSendBuff = 0; 
     122      std::vector<double*> sendBuff(localIndexToSend.size()); 
     123      for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
     124      { 
     125        if (0 != itSend->second.numElements()) 
     126          sendBuff[idxSendBuff] = new double[itSend->second.numElements()]; 
     127      } 
     128 
     129      idxSendBuff = 0; 
     130      std::vector<MPI_Request> sendRecvRequest; 
     131      for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
     132      { 
     133        int destRank = itSend->first; 
     134        const CArray<int,1>& localIndex_p = itSend->second; 
     135        int countSize = localIndex_p.numElements(); 
     136        for (int idx = 0; idx < countSize; ++idx) 
     137        { 
     138          sendBuff[idxSendBuff][idx] = dataCurrentSrc(localIndex_p(idx)); 
     139        } 
     140        sendRecvRequest.push_back(MPI_Request()); 
     141        MPI_Isend(sendBuff[idxSendBuff], countSize, MPI_DOUBLE, destRank, 12, client->intraComm, &sendRecvRequest.back()); 
     142      } 
     143 
     144      // Receiving data on destination fields 
     145      const CGridTransformation::RecvIndexGridDestinationMap& localIndexToReceive = *itListRecv; 
     146      CGridTransformation::RecvIndexGridDestinationMap::const_iterator itbRecv = localIndexToReceive.begin(), itRecv, 
     147                                                                       iteRecv = localIndexToReceive.end(); 
     148      int recvBuffSize = 0; 
     149      for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += itRecv->second.size(); //(recvBuffSize < itRecv->second.size()) 
     150                                                                       //? itRecv->second.size() : recvBuffSize; 
     151      double* recvBuff; 
     152      if (0 != recvBuffSize) recvBuff = new double[recvBuffSize]; 
     153      int currentBuff = 0; 
     154      for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
     155      { 
     156        int srcRank = itRecv->first; 
     157        int countSize = itRecv->second.size(); 
     158        sendRecvRequest.push_back(MPI_Request()); 
     159        MPI_Irecv(recvBuff + currentBuff, countSize, MPI_DOUBLE, srcRank, 12, client->intraComm, &sendRecvRequest.back()); 
     160        currentBuff += countSize; 
     161      } 
     162      std::vector<MPI_Status> status(sendRecvRequest.size()); 
     163      MPI_Waitall(sendRecvRequest.size(), &sendRecvRequest[0], &status[0]); 
     164 
     165      dataCurrentDest.resize(*itNbListRecv); 
     166      dataCurrentDest = 0.0; 
     167      currentBuff = 0; 
     168      for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
     169      { 
     170        int countSize = itRecv->second.size(); 
     171        for (int idx = 0; idx < countSize; ++idx) 
     172        { 
     173          const std::vector<std::pair<int,double> >& localIndex_p = itRecv->second[idx]; 
     174          int numIndex = localIndex_p.size(); 
     175          for (int i = 0; i < numIndex; ++i) 
     176          { 
     177            dataCurrentDest(localIndex_p[i].first) += *(recvBuff+currentBuff+idx) * localIndex_p[i].second; 
     178          } 
     179        } 
     180        currentBuff += countSize; 
     181      } 
     182 
     183      idxSendBuff = 0; 
     184      for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
     185      { 
     186        if (0 != itSend->second.numElements()) 
     187          delete [] sendBuff[idxSendBuff]; 
     188      } 
     189      if (0 != recvBuffSize) delete [] recvBuff; 
    116190    } 
     191    if (dataCurrentDest.numElements() != dataDest.numElements()) 
     192    ERROR("CSpatialTransformFilterEngine::apply(const CArray<double, 1>& dataSrc, CArray<double,1>& dataDest)", 
     193          "Incoherent between the received size and expected size" << 
     194          "Expected size: " << dataDest.numElements() << 
     195          "Received size: " << dataCurrentDest.numElements()); 
    117196 
    118     idxSendBuff = 0; 
    119     std::vector<MPI_Request> sendRequest; 
    120     for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
    121     { 
    122       int destRank = itSend->first; 
    123       const CArray<int,1>& localIndex_p = itSend->second; 
    124       int countSize = localIndex_p.numElements(); 
    125       for (int idx = 0; idx < countSize; ++idx) 
    126       { 
    127         sendBuff[idxSendBuff][idx] = dataSrc(localIndex_p(idx)); 
    128       } 
    129       sendRequest.push_back(MPI_Request()); 
    130       MPI_Isend(sendBuff[idxSendBuff], countSize, MPI_DOUBLE, destRank, 12, client->intraComm, &sendRequest.back()); 
    131     } 
    132  
    133     // Receiving data on destination fields 
    134     std::map<int,std::vector<std::vector<std::pair<int,double> > > >::const_iterator itbRecv = localIndexToReceive.begin(), itRecv, 
    135                                                                                      iteRecv = localIndexToReceive.end(); 
    136     int recvBuffSize = 0; 
    137     for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize = (recvBuffSize < itRecv->second.size()) 
    138                                                                      ? itRecv->second.size() : recvBuffSize; 
    139     double* recvBuff; 
    140     if (0 != recvBuffSize) recvBuff = new double[recvBuffSize]; 
    141     for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) 
    142     { 
    143       MPI_Status status; 
    144       int srcRank = itRecv->first; 
    145       int countSize = itRecv->second.size(); 
    146       MPI_Recv(recvBuff, recvBuffSize, MPI_DOUBLE, srcRank, 12, client->intraComm, &status); 
    147       int countBuff = 0; 
    148       MPI_Get_count(&status, MPI_DOUBLE, &countBuff); 
    149       if (countBuff != countSize) 
    150         ERROR("CSpatialTransformFilterEngine::apply(const CArray<double, 1>& dataSrc, CArray<double,1>& dataDest)", 
    151               "Incoherent between the received size and expected size"); 
    152       for (int idx = 0; idx < countSize; ++idx) 
    153       { 
    154         const std::vector<std::pair<int,double> >& localIndex_p = itRecv->second[idx]; 
    155         int numIndex = localIndex_p.size(); 
    156         for (int i = 0; i < numIndex; ++i) 
    157         { 
    158           dataDest(localIndex_p[i].first) += recvBuff[idx] * localIndex_p[i].second; 
    159         } 
    160       } 
    161     } 
    162  
    163  
    164     if (!sendRequest.empty()) MPI_Waitall(sendRequest.size(), &sendRequest[0], MPI_STATUSES_IGNORE); 
    165     idxSendBuff = 0; 
    166     for (itSend = itbSend; itSend != iteSend; ++itSend, ++idxSendBuff) 
    167     { 
    168       if (0 != itSend->second.numElements()) 
    169         delete [] sendBuff[idxSendBuff]; 
    170     } 
    171     if (0 != recvBuffSize) delete [] recvBuff; 
     197    dataDest = dataCurrentDest; 
    172198  } 
    173199} // namespace xios 
  • XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp

    r833 r841  
    8383      { 
    8484        size_t srcGridSize = globalIndexSrcGrid[idx].size(); 
    85         globaIndexWeightFromDestToSource[(it->first)].reserve(srcGridSize); 
     85//        globaIndexWeightFromDestToSource[(it->first)].reserve(srcGridSize); 
     86        globaIndexWeightFromDestToSource[(it->first)].resize(srcGridSize); 
    8687        for (int i = 0; i < srcGridSize; ++i) 
    8788        { 
    88           globaIndexWeightFromDestToSource[(it->first)].push_back(make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]))); 
     89          globaIndexWeightFromDestToSource[(it->first)][i] = (make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]))); 
    8990        } 
    9091      } 
  • 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} 
  • XIOS/trunk/src/transformation/grid_transformation.hpp

    r832 r841  
    3737  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType; 
    3838  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap; 
     39  typedef std::map<int, CArray<int,1> > SendingIndexGridSourceMap; 
     40  typedef std::map<int,std::vector<std::vector<std::pair<int,double> > > > RecvIndexGridDestinationMap; 
    3941 
    4042public: 
     
    4547  void computeAll(const std::vector<CArray<double,1>* >& dataAuxInput=std::vector<CArray<double,1>* >(), Time timeStamp = 0); 
    4648 
    47   const std::map<int, CArray<int,1> >& getLocalIndexToSendFromGridSource() const; 
    48   const std::map<int, std::vector<std::vector<std::pair<int,double> > > >& getLocalIndexToReceiveOnGridDest() const; 
     49  const std::list<SendingIndexGridSourceMap>& getLocalIndexToSendFromGridSource() const; 
     50  const std::list<RecvIndexGridDestinationMap>& getLocalIndexToReceiveOnGridDest() const; 
     51  const std::list<size_t>& getNbLocalIndexToReceiveOnGridDest() const; 
     52 
    4953  CGrid* getGridSource() { return originalGridSource_; } 
    5054  CGrid* getGridDestination() { return gridDestination_; } 
     
    6468  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo); 
    6569  void setUpGrid(int elementPositionInGrid, ETranformationType transType, int nbTransformation); 
    66   void computeFinalTransformationMapping(); 
    67   void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource); 
    68   void updateFinalGridDestination(); 
     70//  void computeFinalTransformationMapping(); 
     71//  void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource); 
     72  void computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource); 
     73//  void updateFinalGridDestination(); 
    6974  bool isSpecialTransformation(ETranformationType transType); 
    7075 
     
    96101 
    97102  //! Local index of data to send from grid source 
    98   std::map<int, CArray<int,1> > localIndexToSendFromGridSource_; 
     103  std::list<SendingIndexGridSourceMap> localIndexToSendFromGridSource_; 
    99104 
    100105  //! Local index of data to receive on grid destination 
    101   std::map<int,std::vector<std::vector<std::pair<int,double> > > > localIndexToReceiveOnGridDest_; 
     106  std::list<RecvIndexGridDestinationMap> localIndexToReceiveOnGridDest_; 
     107 
     108  //! Number of local index of data to receive on grid destination 
     109  std::list<size_t> nbLocalIndexOnGridDest_; 
    102110 
    103111  //! Position of axis and domain in grid 
Note: See TracChangeset for help on using the changeset viewer.