Changeset 841 for XIOS/trunk/src/filter
- Timestamp:
- 04/26/16 16:03:51 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/filter/spatial_transform_filter.cpp
r832 r841 100 100 CContextClient* client = CContext::getCurrent()->client; 101 101 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(); 104 105 105 dataDest = 0.0;106 CArray<double,1> dataCurrentDest(dataSrc.copy()); 106 107 107 // Sending data from field sources to do transformations108 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) 113 114 { 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; 116 190 } 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()); 117 196 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; 172 198 } 173 199 } // namespace xios
Note: See TracChangeset
for help on using the changeset viewer.