Changeset 862
- Timestamp:
- 06/09/16 11:32:27 (9 years ago)
- Location:
- XIOS/trunk/src/transformation
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp
r833 r862 265 265 CDomain* dom = domListP[0]; 266 266 size_t vecAxisValueSize = dom->i_index.numElements(); 267 int niGlobDom = dom->ni_glo.getValue(); 267 268 vecAxisValue.resize(vecAxisValueSize); 268 269 if (transPosition_.empty()) … … 271 272 for (size_t idx = 0; idx < vecAxisValueSize; ++idx) 272 273 { 273 transPosition_[idx].resize(2); 274 transPosition_[idx][0] = (dom->i_index)(idx); 275 transPosition_[idx][1] = (dom->j_index)(idx); 274 transPosition_[idx].resize(1); 275 transPosition_[idx][0] = (dom->i_index)(idx) + niGlobDom * (dom->j_index)(idx); 276 // transPosition_[idx][0] = (dom->i_index)(idx); 277 // transPosition_[idx][1] = (dom->j_index)(idx); 276 278 } 277 279 } -
XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
r829 r862 11 11 #include "axis_algorithm_inverse.hpp" 12 12 #include "axis_algorithm_zoom.hpp" 13 #include "context.hpp" 14 #include "context_client.hpp" 15 #include "client_client_dht_template.hpp" 13 16 14 17 namespace xios { … … 27 30 CAxisAlgorithmTransformation::~CAxisAlgorithmTransformation() 28 31 { 32 } 33 34 void CAxisAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex, 35 boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc) 36 { 37 CContext* context = CContext::getCurrent(); 38 CContextClient* client=context->client; 39 int clientRank = client->clientRank; 40 int clientSize = client->clientSize; 41 42 size_t globalIndex; 43 int nIndexSize = axisSrc_->index.numElements(); 44 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 45 globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 46 for (int idx = 0; idx < nIndexSize; ++idx) 47 { 48 globalIndex = axisSrc_->index(idx); 49 globalIndex2ProcRank[globalIndex].push_back(clientRank); 50 } 51 52 CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 53 dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex); 54 55 std::vector<int> countIndex(clientSize,0); 56 const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 57 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 58 ite = computedGlobalIndexOnProc.end(); 59 for (it = itb; it != ite; ++it) 60 { 61 const std::vector<int>& procList = it->second; 62 for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 63 } 64 65 globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor())); 66 for (int idx = 0; idx < clientSize; ++idx) 67 { 68 if (0 != countIndex[idx]) 69 { 70 globalAxisIndexOnProc[idx].resize(countIndex[idx]); 71 countIndex[idx] = 0; 72 } 73 } 74 75 for (it = itb; it != ite; ++it) 76 { 77 const std::vector<int>& procList = it->second; 78 for (int idx = 0; idx < procList.size(); ++idx) 79 { 80 globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 81 ++countIndex[procList[idx]]; 82 } 83 } 29 84 } 30 85 -
XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
r829 r862 39 39 void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs); 40 40 41 void computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex, 42 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 43 41 44 protected: 42 45 //! Global index of an axis on grid destination -
XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
r829 r862 9 9 10 10 #include "domain_algorithm_transformation.hpp" 11 #include "context.hpp" 12 #include "context_client.hpp" 13 #include "client_client_dht_template.hpp" 11 14 12 15 namespace xios { … … 23 26 void CDomainAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs) 24 27 { 28 } 29 30 void CDomainAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalDomainIndex, 31 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc) 32 { 33 CContext* context = CContext::getCurrent(); 34 CContextClient* client=context->client; 35 int clientRank = client->clientRank; 36 int clientSize = client->clientSize; 37 38 int niGlob = domainSrc_->ni_glo.getValue(); 39 int njGlob = domainSrc_->nj_glo.getValue(); 40 size_t globalIndex; 41 int nIndexSize = domainSrc_->i_index.numElements(), i_ind, j_ind; 42 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 43 globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 44 for (int idx = 0; idx < nIndexSize; ++idx) 45 { 46 i_ind=domainSrc_->i_index(idx) ; 47 j_ind=domainSrc_->j_index(idx) ; 48 49 globalIndex = i_ind + j_ind * niGlob; 50 globalIndex2ProcRank[globalIndex].push_back(clientRank); 51 } 52 53 CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 54 dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex); 55 56 std::vector<int> countIndex(clientSize,0); 57 const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 58 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 59 ite = computedGlobalIndexOnProc.end(); 60 for (it = itb; it != ite; ++it) 61 { 62 const std::vector<int>& procList = it->second; 63 for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 64 } 65 66 globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor())); 67 for (int idx = 0; idx < clientSize; ++idx) 68 { 69 if (0 != countIndex[idx]) 70 { 71 globalDomainIndexOnProc[idx].resize(countIndex[idx]); 72 countIndex[idx] = 0; 73 } 74 } 75 76 for (it = itb; it != ite; ++it) 77 { 78 const std::vector<int>& procList = it->second; 79 for (int idx = 0; idx < procList.size(); ++idx) 80 { 81 globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 82 ++countIndex[procList[idx]]; 83 } 84 } 25 85 } 26 86 -
XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
r829 r862 39 39 void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&); 40 40 41 void computeExchangeGlobalIndex(const CArray<size_t,1>& globalDomainIndex, 42 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 41 43 protected: 42 44 inline void domainGlobalIndex(const int& index, const int& niGlob, const int& njGlob, -
XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
r843 r862 8 8 */ 9 9 #include "generic_algorithm_transformation.hpp" 10 #include "context.hpp" 11 #include "context_client.hpp" 12 #include "client_client_dht_template.hpp" 10 13 11 14 namespace xios { … … 26 29 and the weighted value as well as global index from grid index source 27 30 */ 31 //void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid, 32 // const std::vector<int>& gridDestGlobalDim, 33 // const std::vector<int>& gridSrcGlobalDim, 34 // const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 35 // DestinationIndexMap& globaIndexWeightFromDestToSource) 36 //{ 37 // bool isTransPosEmpty = transformationPosition_.empty(); 38 // for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 39 // { 40 // TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 41 // iteTransMap = transformationMapping_[idxTrans].end(); 42 // TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[idxTrans].begin(); 43 // 44 // // If transformation position exists 45 // TransformationIndexMap::const_iterator itTransPos, iteTransPos; 46 // if (!isTransPosEmpty) 47 // { 48 // itTransPos = transformationPosition_[idxTrans].begin(), 49 // iteTransPos = transformationPosition_[idxTrans].end(); 50 // } 51 // std::vector<int> emptyTransPos; 52 // 53 // std::vector<std::vector<size_t> > globalIndexSrcGrid; 54 // std::vector<std::pair<size_t,int> > globalLocalIndexDest; 55 // for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 56 // { 57 // if (!isTransPosEmpty) 58 // { 59 // this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 60 // itTransMap->second, 61 // itTransPos->second, 62 // elementPositionInGrid, 63 // gridDestGlobalDim, 64 // gridSrcGlobalDim, 65 // globalLocalIndexGridDestSendToServer, 66 // globalLocalIndexDest, 67 // globalIndexSrcGrid); 68 // ++itTransPos; 69 // } 70 // else 71 // { 72 // this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 73 // itTransMap->second, 74 // emptyTransPos, 75 // elementPositionInGrid, 76 // gridDestGlobalDim, 77 // gridSrcGlobalDim, 78 // globalLocalIndexGridDestSendToServer, 79 // globalLocalIndexDest, 80 // globalIndexSrcGrid); 81 // } 82 // std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end(); 83 // const std::vector<double>& currentVecWeight = itTransWeight->second; 84 // 85 // for (size_t idx = 0; it != ite; ++it, ++idx) 86 // { 87 // size_t srcGridSize = globalIndexSrcGrid[idx].size(); 88 //// globaIndexWeightFromDestToSource[(it->first)].resize(srcGridSize); 89 // DestinationGlobalIndex& tmp = globaIndexWeightFromDestToSource[(it->first)]; 90 // tmp.resize(srcGridSize); 91 // for (int i = 0; i < srcGridSize; ++i) 92 // { 93 // tmp[i].first = it->second; 94 // tmp[i].second = make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]); 95 //// globaIndexWeightFromDestToSource[(it->first)][i] = (make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]))); 96 // } 97 // } 98 // } 99 // } 100 //} 101 102 /*! 103 This function computes the global indexes of grid source, which the grid destination is in demand. 104 \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order), 105 then position of axis in grid is 1 and domain is positioned at 0. 106 \param[in] gridSrc Grid source 107 \param[in] gridDst Grid destination 108 \param[in] globaIndexWeightFromSrcToDst mapping of each global index source and weight to index destination 109 */ 28 110 void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid, 29 const std::vector<int>& gridDestGlobalDim, 30 const std::vector<int>& gridSrcGlobalDim, 31 const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 32 DestinationIndexMap& globaIndexWeightFromDestToSource) 33 { 111 CGrid* gridSrc, 112 CGrid* gridDst, 113 SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 114 { 115 CContext* context = CContext::getCurrent(); 116 CContextClient* client = context->client; 117 int nbClient = client->clientSize; 118 119 typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap; 34 120 bool isTransPosEmpty = transformationPosition_.empty(); 35 121 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 36 122 { 37 123 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 38 iteTransMap = transformationMapping_[idxTrans].end(); 39 TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[idxTrans].begin(); 40 41 // If transformation position exists 42 TransformationIndexMap::const_iterator itTransPos, iteTransPos; 124 iteTransMap = transformationMapping_[idxTrans].end(); 125 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 126 SrcToDstMap src2DstMap; 127 src2DstMap.rehash(std::ceil(transformationMapping_[idxTrans].size()/src2DstMap.max_load_factor())); 128 129 int indexSrcSize = 0; 130 itTransWeight = itbTransWeight; 131 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 132 { 133 indexSrcSize += (itTransMap->second).size(); 134 } 135 136 CArray<size_t,1> indexSrc(indexSrcSize); 137 int indexSrcIndex = 0; 138 // Build mapping between global source element index and global destination element index. 139 itTransWeight = itbTransWeight; 140 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 141 { 142 const std::vector<int>& srcIndex = itTransMap->second; 143 const std::vector<double>& weight = itTransWeight->second; 144 for (int idx = 0; idx < srcIndex.size(); ++idx) 145 { 146 src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx])); 147 indexSrc(indexSrcIndex) = srcIndex[idx]; 148 ++indexSrcIndex; 149 } 150 } 151 152 std::vector<CAxis*> axisListDestP = gridDst->getAxis(); 153 std::vector<CDomain*> domainListDestP = gridDst->getDomains(); 154 CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order; 155 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 156 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 157 CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order; 158 159 CArray<size_t,1> transPos; 43 160 if (!isTransPosEmpty) 44 161 { 45 itTransPos = transformationPosition_[idxTrans].begin(), 46 iteTransPos = transformationPosition_[idxTrans].end(); 47 } 48 std::vector<int> emptyTransPos; 49 50 std::vector<std::vector<size_t> > globalIndexSrcGrid; 51 std::vector<std::pair<size_t,int> > globalLocalIndexDest; 52 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 53 { 54 if (!isTransPosEmpty) 162 transPos.resize(transformationPosition_[idxTrans].size()); 163 TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(), 164 itePosMap = transformationPosition_[idxTrans].end(); 165 for (int idx = 0; itPosMap != itePosMap; ++itPosMap, ++idx) 166 transPos(idx) = itPosMap->second[0]; 167 } 168 // Find out global index source of transformed element on corresponding process. 169 std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements()); 170 int axisIndex = 0, domainIndex = 0; 171 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 172 { 173 if (idx == elementPositionInGrid) 174 computeExchangeGlobalIndex(indexSrc, globalElementIndexOnProc[idx]); 175 if (axisDomainDstOrder(idx)) // It's domain 55 176 { 56 this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 57 itTransMap->second, 58 itTransPos->second, 59 elementPositionInGrid, 60 gridDestGlobalDim, 61 gridSrcGlobalDim, 62 globalLocalIndexGridDestSendToServer, 63 globalLocalIndexDest, 64 globalIndexSrcGrid); 65 ++itTransPos; 177 if (idx != elementPositionInGrid) 178 computeExchangeDomainIndex(domainListDestP[domainIndex], 179 domainListSrcP[domainIndex], 180 transPos, 181 globalElementIndexOnProc[idx]); 182 ++domainIndex; 183 66 184 } 67 else 185 else //it's an axis 68 186 { 69 this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first, 70 itTransMap->second, 71 emptyTransPos, 72 elementPositionInGrid, 73 gridDestGlobalDim, 74 gridSrcGlobalDim, 75 globalLocalIndexGridDestSendToServer, 76 globalLocalIndexDest, 77 globalIndexSrcGrid); 187 if (idx != elementPositionInGrid) 188 computeExchangeAxisIndex(axisListDestP[axisIndex], 189 axisListSrcP[axisIndex], 190 transPos, 191 globalElementIndexOnProc[idx]); 192 ++axisIndex; 193 78 194 } 79 std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end(); 80 const std::vector<double>& currentVecWeight = itTransWeight->second; 81 82 for (size_t idx = 0; it != ite; ++it, ++idx) 195 } 196 197 std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false)); 198 199 boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite; 200 for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 201 { 202 itb = globalElementIndexOnProc[idx].begin(); 203 ite = globalElementIndexOnProc[idx].end(); 204 for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true; 205 } 206 207 // Determine procs which contain global source index 208 std::vector<bool> intersectedProc(nbClient, true); 209 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 210 { 211 std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(), 212 intersectedProc.begin(), intersectedProc.begin(), 213 std::logical_and<bool>()); 214 } 215 216 std::vector<int> srcRank; 217 for (int idx = 0; idx < nbClient; ++idx) 218 { 219 if (intersectedProc[idx]) srcRank.push_back(idx); 220 } 221 222 // Ok, now compute global index of grid source and ones of grid destination 223 computeGlobalGridIndexMapping(elementPositionInGrid, 224 srcRank, 225 src2DstMap, 226 gridDst, 227 gridSrc, 228 globalElementIndexOnProc, 229 globaIndexWeightFromSrcToDst); 230 } 231 } 232 233 /*! 234 Compute mapping of global index of grid source and grid destination 235 \param [in] elementPositionInGrid position of element in grid. E.x: grid composed of domain and axis, domain has position 0 and axis 1. 236 \param [in] srcRank rank of client from which we demand global index of element source 237 \param [in] src2DstMap mapping of global index of element source and global index of element destination 238 \param[in] gridSrc Grid source 239 \param[in] gridDst Grid destination 240 \param[in] globalElementIndexOnProc Global index of element source on different client rank 241 \param[out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination 242 */ 243 void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid, 244 const std::vector<int>& srcRank, 245 boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap, 246 CGrid* gridSrc, 247 CGrid* gridDst, 248 std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc, 249 SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 250 { 251 std::vector<CAxis*> axisListDestP = gridDst->getAxis(); 252 std::vector<CDomain*> domainListDestP = gridDst->getDomains(); 253 CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order; 254 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 255 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 256 CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order; 257 size_t nbElement = axisDomainSrcOrder.numElements(); 258 std::vector<size_t> nGlobSrc(nbElement), nGlobDst(nbElement); 259 size_t globalSrcSize = 1, globalDstSize = 1; 260 int domainIndex = 0; 261 int axisIndex = 0; 262 for (int idx = 0; idx < nbElement; ++idx) 263 { 264 nGlobSrc[idx] = globalSrcSize; 265 nGlobDst[idx] = globalDstSize; 266 bool isDomain = axisDomainSrcOrder(idx); 267 268 // If this is a domain 269 if (isDomain) 270 { 271 globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue(); 272 globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue(); 273 ++domainIndex; 274 } 275 else // So it's an axis 276 { 277 globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue(); 278 globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue(); 279 ++axisIndex; 280 } 281 } 282 283 for (int i = 0; i < srcRank.size(); ++i) 284 { 285 size_t ssize = 1; 286 int rankSrc = srcRank[i]; 287 for (int idx = 0; idx < nbElement; ++idx) 288 { 289 ssize *= (globalElementIndexOnProc[idx][rankSrc]).size(); 290 } 291 292 std::vector<int> idxLoop(nbElement,0); 293 std::vector<int> currentIndexSrc(nbElement, 0); 294 std::vector<int> currentIndexDst(nbElement, 0); 295 int innnerLoopSize = (globalElementIndexOnProc[0])[rankSrc].size(); 296 size_t idx = 0; 297 while (idx < ssize) 298 { 299 for (int ind = 0; ind < nbElement; ++ind) 83 300 { 84 size_t srcGridSize = globalIndexSrcGrid[idx].size(); 85 // globaIndexWeightFromDestToSource[(it->first)].resize(srcGridSize); 86 DestinationGlobalIndex& tmp = globaIndexWeightFromDestToSource[(it->first)]; 87 tmp.resize(srcGridSize); 88 for (int i = 0; i < srcGridSize; ++i) 301 if (idxLoop[ind] == (globalElementIndexOnProc[ind])[rankSrc].size()) 89 302 { 90 tmp[i].first = it->second; 91 tmp[i].second = make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]); 92 // globaIndexWeightFromDestToSource[(it->first)][i] = (make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]))); 303 idxLoop[ind] = 0; 304 ++idxLoop[ind+1]; 93 305 } 306 307 currentIndexDst[ind] = currentIndexSrc[ind] = (globalElementIndexOnProc[ind])[rankSrc][idxLoop[ind]]; 94 308 } 95 } 96 } 97 } 98 309 310 for (int ind = 0; ind < innnerLoopSize; ++ind) 311 { 312 currentIndexSrc[0] = (globalElementIndexOnProc[0])[rankSrc][ind]; 313 int globalElementDstIndexSize = 0; 314 if (1 == src2DstMap.count(currentIndexSrc[elementPositionInGrid])) 315 { 316 globalElementDstIndexSize = src2DstMap[currentIndexSrc[elementPositionInGrid]].size(); 317 } 318 std::vector<size_t> globalDstVecIndex(globalElementDstIndexSize,0); 319 size_t globalSrcIndex = 0; 320 for (int idxElement = 0; idxElement < nbElement; ++idxElement) 321 { 322 if (idxElement == elementPositionInGrid) 323 { 324 for (int k = 0; k < globalElementDstIndexSize; ++k) 325 { 326 globalDstVecIndex[k] += src2DstMap[currentIndexSrc[elementPositionInGrid]][k].first * nGlobDst[idxElement]; 327 } 328 } 329 else 330 { 331 for (int k = 0; k < globalElementDstIndexSize; ++k) 332 { 333 globalDstVecIndex[k] += currentIndexDst[idxElement] * nGlobDst[idxElement]; 334 } 335 } 336 globalSrcIndex += currentIndexSrc[idxElement] * nGlobSrc[idxElement]; 337 } 338 339 for (int k = 0; k < globalElementDstIndexSize; ++k) 340 { 341 globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 342 } 343 ++idxLoop[0]; 344 } 345 idx += innnerLoopSize; 346 } 347 } 348 } 349 350 /*! 351 Find out proc and global index of axis source which axis destination is on demande 352 \param[in] axisDst Axis destination 353 \param[in] axisSrc Axis source 354 \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid. 355 \param[out] globalAxisIndexOnProc Global index of axis source on different procs 356 */ 357 void CGenericAlgorithmTransformation::computeExchangeAxisIndex(CAxis* axisDst, 358 CAxis* axisSrc, 359 CArray<size_t,1>& destGlobalIndexPositionInGrid, 360 boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc) 361 { 362 CContext* context = CContext::getCurrent(); 363 CContextClient* client=context->client; 364 int clientRank = client->clientRank; 365 int clientSize = client->clientSize; 366 367 size_t globalIndex; 368 int nIndexSize = axisSrc->index.numElements(); 369 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 370 globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 371 for (int idx = 0; idx < nIndexSize; ++idx) 372 { 373 globalIndex = axisSrc->index(idx); 374 globalIndex2ProcRank[globalIndex].push_back(clientRank); 375 } 376 377 CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 378 CArray<size_t,1> globalAxisIndex(axisDst->index.numElements()); 379 for (int idx = 0; idx < globalAxisIndex.numElements(); ++idx) 380 { 381 globalAxisIndex(idx) = axisDst->index(idx); 382 } 383 dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex); 384 385 std::vector<int> countIndex(clientSize,0); 386 const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 387 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 388 ite = computedGlobalIndexOnProc.end(); 389 for (it = itb; it != ite; ++it) 390 { 391 const std::vector<int>& procList = it->second; 392 for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 393 } 394 395 globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor())); 396 for (int idx = 0; idx < clientSize; ++idx) 397 { 398 if (0 != countIndex[idx]) 399 { 400 globalAxisIndexOnProc[idx].resize(countIndex[idx]); 401 countIndex[idx] = 0; 402 } 403 } 404 405 for (it = itb; it != ite; ++it) 406 { 407 const std::vector<int>& procList = it->second; 408 for (int idx = 0; idx < procList.size(); ++idx) 409 { 410 globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 411 ++countIndex[procList[idx]]; 412 } 413 } 414 } 415 416 /*! 417 Find out proc and global index of domain source which domain destination is on demande 418 \param[in] domainDst Domain destination 419 \param[in] domainSrc Domain source 420 \param[in] destGlobalIndexPositionInGrid Relative position of domain corresponds to other element of grid. 421 \param[out] globalDomainIndexOnProc Global index of domain source on different procs 422 */ 423 void CGenericAlgorithmTransformation::computeExchangeDomainIndex(CDomain* domainDst, 424 CDomain* domainSrc, 425 CArray<size_t,1>& destGlobalIndexPositionInGrid, 426 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc) 427 { 428 CContext* context = CContext::getCurrent(); 429 CContextClient* client=context->client; 430 int clientRank = client->clientRank; 431 int clientSize = client->clientSize; 432 433 int niGlob = domainSrc->ni_glo.getValue(); 434 int njGlob = domainSrc->nj_glo.getValue(); 435 size_t globalIndex; 436 int nIndexSize = domainSrc->i_index.numElements(), i_ind, j_ind; 437 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 438 globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 439 for (int idx = 0; idx < nIndexSize; ++idx) 440 { 441 i_ind=domainSrc->i_index(idx) ; 442 j_ind=domainSrc->j_index(idx) ; 443 444 globalIndex = i_ind + j_ind * niGlob; 445 globalIndex2ProcRank[globalIndex].push_back(clientRank); 446 } 447 448 CArray<size_t,1> globalDomainIndex; 449 if (destGlobalIndexPositionInGrid.isEmpty()) 450 { 451 globalDomainIndex.resize(domainDst->i_index.numElements()); 452 nIndexSize = domainDst->i_index.numElements(); 453 454 for (int idx = 0; idx < nIndexSize; ++idx) 455 { 456 i_ind=domainDst->i_index(idx) ; 457 j_ind=domainDst->j_index(idx) ; 458 459 globalDomainIndex(idx) = i_ind + j_ind * niGlob; 460 } 461 } 462 else 463 { 464 globalDomainIndex = destGlobalIndexPositionInGrid; 465 // for (int idx = 0; idx < destGlobalIndexPositionInGrid.size(); ++idx) 466 // { 467 // globalDomainIndex(idx) = destGlobalIndexPositionInGrid[idx]; 468 // } 469 } 470 471 CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm); 472 dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex); 473 474 std::vector<int> countIndex(clientSize,0); 475 const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap(); 476 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it, 477 ite = computedGlobalIndexOnProc.end(); 478 for (it = itb; it != ite; ++it) 479 { 480 const std::vector<int>& procList = it->second; 481 for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]]; 482 } 483 484 globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor())); 485 for (int idx = 0; idx < clientSize; ++idx) 486 { 487 if (0 != countIndex[idx]) 488 { 489 globalDomainIndexOnProc[idx].resize(countIndex[idx]); 490 countIndex[idx] = 0; 491 } 492 } 493 494 for (it = itb; it != ite; ++it) 495 { 496 const std::vector<int>& procList = it->second; 497 for (int idx = 0; idx < procList.size(); ++idx) 498 { 499 globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first; 500 ++countIndex[procList[idx]]; 501 } 502 } 503 } 504 505 /*! 506 Compute index mapping between element source and element destination with an auxiliary inputs which determine 507 position of each mapped index in global index of grid destination. 508 \param [in] dataAuxInputs auxiliary inputs 509 */ 99 510 void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs) 100 511 { -
XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
r843 r862 15 15 16 16 namespace xios { 17 class CGrid; 18 class CDomain; 19 class CAxis; 20 17 21 /*! 18 22 \class CGenericAlgorithmTransformation … … 27 31 // Mapping between global index map of DESTINATION and its local index with pair of global index of SOURCE and weights 28 32 typedef boost::unordered_map<size_t, DestinationGlobalIndex> DestinationIndexMap; 33 // 34 typedef boost::unordered_map<int, boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > > > SourceDestinationIndexMap; 29 35 30 36 protected: 31 37 typedef boost::unordered_map<size_t,int> GlobalLocalMap; 38 protected: 39 typedef boost::unordered_map<int, std::vector<int> > TransformationIndexMap; 40 typedef boost::unordered_map<int, std::vector<double> > TransformationWeightMap; 41 typedef boost::unordered_map<int, std::vector<int> > TransformationPositionMap; 32 42 33 43 public: … … 36 46 virtual ~CGenericAlgorithmTransformation() {} 37 47 48 // void computeGlobalSourceIndex(int elementPositionInGrid, 49 // const std::vector<int>& gridDestGlobalDim, 50 // const std::vector<int>& gridSrcGlobalDim, 51 // const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 52 // DestinationIndexMap& globaIndexWeightFromDestToSource); 53 38 54 void computeGlobalSourceIndex(int elementPositionInGrid, 39 const std::vector<int>& gridDestGlobalDim, 40 const std::vector<int>& gridSrcGlobalDim, 41 const GlobalLocalMap& globalLocalIndexGridDestSendToServer, 42 DestinationIndexMap& globaIndexWeightFromDestToSource); 55 CGrid* gridSrc, 56 CGrid* gridDst, 57 SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); 43 58 44 59 std::vector<StdString> getIdAuxInputs(); … … 72 87 virtual void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&) = 0; 73 88 89 virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalElementIndex, 90 boost::unordered_map<int,std::vector<size_t> >& globalElementIndexOnProc) = 0; 91 92 void computeGlobalGridIndexMapping(int elementPositionInGrid, 93 const std::vector<int>& srcRank, 94 boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap, 95 CGrid* gridDst, 96 CGrid* gridSrc, 97 std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc, 98 SourceDestinationIndexMap& globaIndexWeightFromSrcToDst); 99 100 void computeExchangeDomainIndex(CDomain* domainDst, 101 CDomain* domainSrc, 102 CArray<size_t,1>& destGlobalIndexPositionInGrid, 103 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc); 104 105 void computeExchangeAxisIndex(CAxis* axisDst, 106 CAxis* axisSrc, 107 CArray<size_t,1>& destGlobalIndexPositionInGrid, 108 boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc); 109 74 110 protected: 75 typedef boost::unordered_map<int, std::vector<int> > TransformationIndexMap;76 typedef boost::unordered_map<int, std::vector<double> > TransformationWeightMap;77 typedef boost::unordered_map<int, std::vector<int> > TransformationPositionMap;78 79 111 //! Map between global index of destination element and source element 80 112 std::vector<TransformationIndexMap> transformationMapping_; -
XIOS/trunk/src/transformation/grid_transformation.cpp
r858 r862 94 94 if (false == (gridDestination_->axis_domain_order)(i)) 95 95 { 96 axisPositionInGrid.push_back(idx); 97 ++idx; 96 axisPositionInGrid.push_back(i); 97 // axisPositionInGrid.push_back(idx); 98 // ++idx; 98 99 } 99 100 else 100 101 { 101 ++idx; 102 domPositionInGrid.push_back(idx); 103 ++idx; 102 domPositionInGrid.push_back(i); 103 // ++idx; 104 // domPositionInGrid.push_back(idx); 105 // ++idx; 104 106 } 105 107 } … … 120 122 if (false == (gridDestination_->axis_domain_order)(i)) 121 123 { 122 initializeAxisAlgorithms(idx); 123 ++idx; 124 initializeAxisAlgorithms(i); 125 // initializeAxisAlgorithms(idx); 126 // ++idx; 124 127 } 125 128 else 126 129 { 127 ++idx; 128 initializeDomainAlgorithms(idx); 129 ++idx; 130 initializeDomainAlgorithms(i); 131 // ++idx; 132 // initializeDomainAlgorithms(idx); 133 // ++idx; 130 134 } 131 135 } … … 356 360 -) Make current grid destination become grid source in the next transformation 357 361 */ 362 //void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs, Time timeStamp) 363 //{ 364 // if (nbAlgos_ < 1) return; 365 // if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; } 366 // if (dynamicalTransformation_) 367 // { 368 // if (timeStamp_.insert(timeStamp).second) 369 // DestinationIndexMap().swap(currentGridIndexToOriginalGridIndex_); // Reset map 370 // else 371 // return; 372 // } 373 // 374 // CContext* context = CContext::getCurrent(); 375 // CContextClient* client = context->client; 376 // 377 // ListAlgoType::const_iterator itb = listAlgos_.begin(), 378 // ite = listAlgos_.end(), it; 379 // 380 // CGenericAlgorithmTransformation* algo = 0; 381 // int nbAgloTransformation = 0; // Only count for executed transformation. Generate domain is a special one, not executed in the list 382 // for (it = itb; it != ite; ++it) 383 // { 384 // int elementPositionInGrid = it->first; 385 // ETranformationType transType = (it->second).first; 386 // int transformationOrder = (it->second).second; 387 // DestinationIndexMap globaIndexWeightFromDestToSource; 388 // 389 // // First of all, select an algorithm 390 // if (!dynamicalTransformation_ || (algoTransformation_.size() < listAlgos_.size())) 391 // { 392 // selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]); 393 // algo = algoTransformation_.back(); 394 // } 395 // else 396 // algo = algoTransformation_[std::distance(itb, it)]; 397 // 398 // if (0 != algo) // Only registered transformation can be executed 399 // { 400 // algo->computeIndexSourceMapping(dataAuxInputs); 401 // 402 // // Recalculate the distribution of grid destination 403 // CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 404 // const CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer(); 405 // 406 // // ComputeTransformation of global index of each element 407 // std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension(); 408 // std::vector<int> gridSrcDimensionSize = gridSource_->getGlobalDimension(); 409 // int elementPosition = it->first; 410 // algo->computeGlobalSourceIndex(elementPosition, 411 // gridDestinationDimensionSize, 412 // gridSrcDimensionSize, 413 // globalLocalIndexGridDestSendToServer, 414 // globaIndexWeightFromDestToSource); 415 // 416 // // Compute transformation of global indexes among grids 417 // computeTransformationMapping(globaIndexWeightFromDestToSource); 418 // 419 // // Update number of local index on each transformation 420 // nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 421 // 422 // if (1 < nbAlgos_) 423 // { 424 // // Now grid destination becomes grid source in a new transformation 425 // if (nbAgloTransformation != (nbAlgos_-1)) setUpGrid(elementPositionInGrid, transType, nbAgloTransformation); 426 // } 427 // ++nbAgloTransformation; 428 // } 429 // } 430 //} 431 358 432 void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs, Time timeStamp) 359 433 { … … 386 460 ETranformationType transType = (it->second).first; 387 461 int transformationOrder = (it->second).second; 388 DestinationIndexMap globaIndexWeightFromDestToSource;462 SourceDestinationIndexMap globaIndexWeightFromSrcToDst; 389 463 390 464 // First of all, select an algorithm … … 401 475 algo->computeIndexSourceMapping(dataAuxInputs); 402 476 403 // Recalculate the distribution of grid destination404 CDistributionClient distributionClientDest(client->clientRank, gridDestination_);405 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer();406 407 477 // ComputeTransformation of global index of each element 408 std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();409 std::vector<int> gridSrcDimensionSize = gridSource_->getGlobalDimension();410 478 int elementPosition = it->first; 411 479 algo->computeGlobalSourceIndex(elementPosition, 412 gridDestinationDimensionSize, 413 gridSrcDimensionSize, 414 globalLocalIndexGridDestSendToServer, 415 globaIndexWeightFromDestToSource); 480 gridSource_, 481 gridDestination_, 482 globaIndexWeightFromSrcToDst); 416 483 417 484 // Compute transformation of global indexes among grids 418 computeTransformationMapping(globaIndexWeightFromDestToSource); 419 420 // Update number of local index on each transformation 421 nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 485 computeTransformationMapping(globaIndexWeightFromSrcToDst); 422 486 423 487 if (1 < nbAlgos_) … … 435 499 \param [in] globalIndexWeightFromDestToSource global index mapping between grid destination and grid source 436 500 */ 437 void CGridTransformation::computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource)501 void CGridTransformation::computeTransformationMapping(const SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 438 502 { 439 503 CContext* context = CContext::getCurrent(); 440 504 CContextClient* client = context->client; 441 442 CTransformationMapping transformationMap(gridDestination_, gridSource_); 443 444 transformationMap.computeTransformationMapping(globalIndexWeightFromDestToSource); 445 446 const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 447 CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv; 448 itbMapRecv = globalIndexToReceive.begin(); 449 iteMapRecv = globalIndexToReceive.end(); 505 int nbClient = client->clientSize; 506 int clientRank = client->clientRank; 507 508 // Recalculate the distribution of grid destination 509 CDistributionClient distributionClientDest(client->clientRank, gridDestination_); 510 CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridDestSendToServer = distributionClientDest.getGlobalLocalDataSendToServer(); 511 // Update number of local index on each transformation 512 nbLocalIndexOnGridDest_.push_back(globalLocalIndexGridDestSendToServer.size()); 513 514 // Find out number of index sent from grid source and number of index received on grid destination 515 SourceDestinationIndexMap::const_iterator itbIndex = globaIndexWeightFromSrcToDst.begin(), 516 iteIndex = globaIndexWeightFromSrcToDst.end(), itIndex; 517 typedef boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > > SendIndexMap; 518 std::map<int,int> sendRankSizeMap,recvRankSizeMap; 519 int connectedClient = globaIndexWeightFromSrcToDst.size(); 520 int* recvCount=new int[nbClient]; 521 int* displ=new int[nbClient]; 522 int* sendRankBuff=new int[connectedClient]; 523 int* sendSizeBuff=new int[connectedClient]; 524 int n = 0; 525 for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex, ++n) 526 { 527 sendRankBuff[n] = itIndex->first; 528 const SendIndexMap& sendIndexMap = itIndex->second; 529 SendIndexMap::const_iterator itbSend = sendIndexMap.begin(), iteSend = sendIndexMap.end(), itSend; 530 int sendSize = 0; 531 for (itSend = itbSend; itSend != iteSend; ++itSend) 532 { 533 sendSize += itSend->second.size(); 534 } 535 sendSizeBuff[n] = sendSize; 536 sendRankSizeMap[itIndex->first] = sendSize; 537 } 538 MPI_Allgather(&connectedClient,1,MPI_INT,recvCount,1,MPI_INT,client->intraComm); 539 540 displ[0]=0 ; 541 for(int n=1;n<nbClient;n++) displ[n]=displ[n-1]+recvCount[n-1]; 542 int recvSize=displ[nbClient-1]+recvCount[nbClient-1]; 543 int* recvRankBuff=new int[recvSize]; 544 int* recvSizeBuff=new int[recvSize]; 545 MPI_Allgatherv(sendRankBuff,connectedClient,MPI_INT,recvRankBuff,recvCount,displ,MPI_INT,client->intraComm); 546 MPI_Allgatherv(sendSizeBuff,connectedClient,MPI_INT,recvSizeBuff,recvCount,displ,MPI_INT,client->intraComm); 547 for (int i = 0; i < nbClient; ++i) 548 { 549 int currentPos = displ[i]; 550 for (int j = 0; j < recvCount[i]; ++j) 551 if (recvRankBuff[currentPos+j] == clientRank) 552 { 553 recvRankSizeMap[i] = recvSizeBuff[currentPos+j]; 554 } 555 } 556 557 558 559 // Sending global index of grid source to corresponding process as well as the corresponding mask 560 std::vector<MPI_Request> requests; 561 std::vector<MPI_Status> status; 562 boost::unordered_map<int, unsigned char* > recvMaskDst; 563 boost::unordered_map<int, unsigned long* > recvGlobalIndexSrc; 564 for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 565 { 566 int recvRank = itRecv->first; 567 int recvSize = itRecv->second; 568 recvMaskDst[recvRank] = new unsigned char [recvSize]; 569 recvGlobalIndexSrc[recvRank] = new unsigned long [recvSize]; 570 571 requests.push_back(MPI_Request()); 572 MPI_Irecv(recvGlobalIndexSrc[recvRank], recvSize, MPI_UNSIGNED_LONG, recvRank, 46, client->intraComm, &requests.back()); 573 requests.push_back(MPI_Request()); 574 MPI_Irecv(recvMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 47, client->intraComm, &requests.back()); 575 } 576 577 boost::unordered_map<int, CArray<size_t,1> > globalIndexDst; 578 boost::unordered_map<int, CArray<double,1> > weightDst; 579 boost::unordered_map<int, unsigned char* > sendMaskDst; 580 boost::unordered_map<int, unsigned long* > sendGlobalIndexSrc; 581 for (itIndex = itbIndex; itIndex != iteIndex; ++itIndex) 582 { 583 int sendRank = itIndex->first; 584 int sendSize = sendRankSizeMap[sendRank]; 585 const SendIndexMap& sendIndexMap = itIndex->second; 586 SendIndexMap::const_iterator itbSend = sendIndexMap.begin(), iteSend = sendIndexMap.end(), itSend; 587 globalIndexDst[sendRank].resize(sendSize); 588 weightDst[sendRank].resize(sendSize); 589 sendMaskDst[sendRank] = new unsigned char [sendSize]; 590 sendGlobalIndexSrc[sendRank] = new unsigned long [sendSize]; 591 int countIndex = 0; 592 for (itSend = itbSend; itSend != iteSend; ++itSend) 593 { 594 const std::vector<std::pair<size_t,double> >& dstWeight = itSend->second; 595 for (int idx = 0; idx < dstWeight.size(); ++idx) 596 { 597 globalIndexDst[sendRank](countIndex) = dstWeight[idx].first; 598 weightDst[sendRank](countIndex) = dstWeight[idx].second; 599 if (0 < globalLocalIndexGridDestSendToServer.count(dstWeight[idx].first)) 600 sendMaskDst[sendRank][countIndex] = 1; 601 else 602 sendMaskDst[sendRank][countIndex] = 0; 603 sendGlobalIndexSrc[sendRank][countIndex] = itSend->first; 604 ++countIndex; 605 } 606 } 607 608 // Send global index source and mask 609 requests.push_back(MPI_Request()); 610 MPI_Isend(sendGlobalIndexSrc[sendRank], sendSize, MPI_UNSIGNED_LONG, sendRank, 46, client->intraComm, &requests.back()); 611 requests.push_back(MPI_Request()); 612 MPI_Isend(sendMaskDst[sendRank], sendSize, MPI_UNSIGNED_CHAR, sendRank, 47, client->intraComm, &requests.back()); 613 } 614 615 status.resize(requests.size()); 616 MPI_Waitall(requests.size(), &requests[0], &status[0]); 617 618 // Okie, now use the mask to identify which index source we need to send, then also signal the destination which masked index we will return 619 std::vector<MPI_Request>().swap(requests); 620 std::vector<MPI_Status>().swap(status); 621 // Okie, on destination side, we will wait for information of masked index of source 622 for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 623 { 624 int recvRank = itSend->first; 625 int recvSize = itSend->second; 626 627 requests.push_back(MPI_Request()); 628 MPI_Irecv(sendMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 48, client->intraComm, &requests.back()); 629 } 630 631 // Ok, now we fill in local index of grid source (we even count for masked index) 632 CDistributionClient distributionClientSrc(client->clientRank, gridSource_); 633 CDistributionClient::GlobalLocalDataMap& globalLocalIndexGridSrcSendToServer = distributionClientSrc.getGlobalLocalDataSendToServer(); 634 localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 635 SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 636 for (std::map<int,int>::const_iterator itRecv = recvRankSizeMap.begin(); itRecv != recvRankSizeMap.end(); ++itRecv) 637 { 638 int recvRank = itRecv->first; 639 int recvSize = itRecv->second; 640 unsigned char* recvMask = recvMaskDst[recvRank]; 641 unsigned long* recvIndexSrc = recvGlobalIndexSrc[recvRank]; 642 int realSendSize = 0; 643 for (int idx = 0; idx < recvSize; ++idx) 644 { 645 if (0 != (*(recvMask+idx))) // OKie, now we have a demand from non-masked index destination 646 if (0 < globalLocalIndexGridSrcSendToServer.count(*(recvIndexSrc+idx))) // check whether index source is masked 647 ++realSendSize; 648 else // inform the destination that this index is masked 649 *(recvMask+idx) = 0; 650 } 651 652 tmpSend[recvRank].resize(realSendSize); 653 realSendSize = 0; 654 for (int idx = 0; idx < recvSize; ++idx) 655 { 656 if (0 != (*(recvMask+idx))) // OKie, now we have a demand from non-masked index destination 657 { 658 tmpSend[recvRank](realSendSize) = globalLocalIndexGridSrcSendToServer[*(recvIndexSrc+idx)]; 659 ++realSendSize; 660 } 661 } 662 663 // Okie, now inform the destination which source index are masked 664 requests.push_back(MPI_Request()); 665 MPI_Isend(recvMaskDst[recvRank], recvSize, MPI_UNSIGNED_CHAR, recvRank, 48, client->intraComm, &requests.back()); 666 } 667 status.resize(requests.size()); 668 MPI_Waitall(requests.size(), &requests[0], &status[0]); 669 670 // Cool, now we can fill in local index of grid destination (counted for masked index) 450 671 localIndexToReceiveOnGridDest_.push_back(RecvIndexGridDestinationMap()); 451 672 RecvIndexGridDestinationMap& recvTmp = localIndexToReceiveOnGridDest_.back(); 452 for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv) 453 { 454 int sourceRank = itMapRecv->first; 455 int numGlobalIndex = (itMapRecv->second).size(); 456 recvTmp[sourceRank].resize(numGlobalIndex); 457 for (int i = 0; i < numGlobalIndex; ++i) 458 { 459 recvTmp[sourceRank][i] = make_pair((itMapRecv->second)[i].localIndex,(itMapRecv->second)[i].weight); 460 } 461 } 462 463 // Find out local index on grid source (to send) 464 const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping(); 465 CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap; 466 itbMap = globalIndexToSend.begin(); 467 iteMap = globalIndexToSend.end(); 468 localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 469 SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 470 for (itMap = itbMap; itMap != iteMap; ++itMap) 471 { 472 int destRank = itMap->first; 473 int vecSize = itMap->second.size(); 474 tmpSend[destRank].resize(vecSize); 475 for (int idx = 0; idx < vecSize; ++idx) 476 { 477 tmpSend[destRank](idx) = itMap->second[idx].first; 478 } 479 } 480 } 673 for (std::map<int,int>::const_iterator itSend = sendRankSizeMap.begin(); itSend != sendRankSizeMap.end(); ++itSend) 674 { 675 int recvRank = itSend->first; 676 int recvSize = itSend->second; 677 unsigned char* recvMask = sendMaskDst[recvRank]; 678 679 CArray<size_t,1>& recvIndexDst = globalIndexDst[recvRank]; 680 CArray<double,1>& recvWeightDst = weightDst[recvRank]; 681 int realRecvSize = 0; 682 for (int idx = 0; idx < recvSize; ++idx) 683 { 684 if (0 != *(recvMask+idx)) // OKie, now we have a non-masked index destination 685 ++realRecvSize; 686 } 687 688 int localIndexDst; 689 recvTmp[recvRank].resize(realRecvSize); 690 realRecvSize = 0; 691 for (int idx = 0; idx < recvSize; ++idx) 692 { 693 if (0 != *(recvMask+idx)) // OKie, now we have a demand from non-masked index destination 694 { 695 recvTmp[recvRank][realRecvSize].first = globalLocalIndexGridDestSendToServer[recvIndexDst(idx)]; 696 recvTmp[recvRank][realRecvSize].second = recvWeightDst(idx); 697 ++realRecvSize; 698 } 699 } 700 } 701 702 delete [] recvCount; 703 delete [] displ; 704 delete [] sendRankBuff; 705 delete [] recvRankBuff; 706 delete [] sendSizeBuff; 707 delete [] recvSizeBuff; 708 709 boost::unordered_map<int, unsigned char* >::const_iterator itChar; 710 for (itChar = sendMaskDst.begin(); itChar != sendMaskDst.end(); ++itChar) 711 delete [] itChar->second; 712 for (itChar = recvMaskDst.begin(); itChar != recvMaskDst.end(); ++itChar) 713 delete [] itChar->second; 714 boost::unordered_map<int, unsigned long* >::const_iterator itLong; 715 for (itLong = sendGlobalIndexSrc.begin(); itLong != sendGlobalIndexSrc.end(); ++itLong) 716 delete [] itLong->second; 717 for (itLong = recvGlobalIndexSrc.begin(); itLong != recvGlobalIndexSrc.end(); ++itLong) 718 delete [] itLong->second; 719 720 } 721 722 ///*! 723 // Compute exchange index between grid source and grid destination 724 // \param [in] globalIndexWeightFromDestToSource global index mapping between grid destination and grid source 725 //*/ 726 //void CGridTransformation::computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource) 727 //{ 728 // CContext* context = CContext::getCurrent(); 729 // CContextClient* client = context->client; 730 // 731 // CTransformationMapping transformationMap(gridDestination_, gridSource_); 732 // 733 // transformationMap.computeTransformationMapping(globalIndexWeightFromDestToSource); 734 // 735 // const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping(); 736 // CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv; 737 // itbMapRecv = globalIndexToReceive.begin(); 738 // iteMapRecv = globalIndexToReceive.end(); 739 // localIndexToReceiveOnGridDest_.push_back(RecvIndexGridDestinationMap()); 740 // RecvIndexGridDestinationMap& recvTmp = localIndexToReceiveOnGridDest_.back(); 741 // for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv) 742 // { 743 // int sourceRank = itMapRecv->first; 744 // int numGlobalIndex = (itMapRecv->second).size(); 745 // recvTmp[sourceRank].resize(numGlobalIndex); 746 // for (int i = 0; i < numGlobalIndex; ++i) 747 // { 748 // recvTmp[sourceRank][i] = make_pair((itMapRecv->second)[i].localIndex,(itMapRecv->second)[i].weight); 749 // } 750 // } 751 // 752 // // Find out local index on grid source (to send) 753 // const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping(); 754 // CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap; 755 // itbMap = globalIndexToSend.begin(); 756 // iteMap = globalIndexToSend.end(); 757 // localIndexToSendFromGridSource_.push_back(SendingIndexGridSourceMap()); 758 // SendingIndexGridSourceMap& tmpSend = localIndexToSendFromGridSource_.back(); 759 // for (itMap = itbMap; itMap != iteMap; ++itMap) 760 // { 761 // int destRank = itMap->first; 762 // int vecSize = itMap->second.size(); 763 // tmpSend[destRank].resize(vecSize); 764 // for (int idx = 0; idx < vecSize; ++idx) 765 // { 766 // tmpSend[destRank](idx) = itMap->second[idx].first; 767 // } 768 // } 769 //} 481 770 482 771 bool CGridTransformation::isSpecialTransformation(ETranformationType transType) -
XIOS/trunk/src/transformation/grid_transformation.hpp
r842 r862 39 39 typedef std::map<int, CArray<int,1> > SendingIndexGridSourceMap; 40 40 typedef std::map<int,std::vector<std::pair<int,double> > > RecvIndexGridDestinationMap; 41 // typedef std::map<int,std::vector<std::vector<std::pair<int,double> > > > RecvIndexGridDestinationMap;41 typedef CGenericAlgorithmTransformation::SourceDestinationIndexMap SourceDestinationIndexMap; 42 42 43 43 public: … … 71 71 // void computeFinalTransformationMapping(); 72 72 // void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource); 73 void computeTransformationMapping(const DestinationIndexMap& globalIndexWeightFromDestToSource);73 void computeTransformationMapping(const SourceDestinationIndexMap& globalIndexWeightFromSrcToDest); 74 74 // void updateFinalGridDestination(); 75 75 bool isSpecialTransformation(ETranformationType transType);
Note: See TracChangeset
for help on using the changeset viewer.