Changeset 841 for XIOS/trunk/src/filter


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/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 
Note: See TracChangeset for help on using the changeset viewer.