- Timestamp:
- 03/22/18 10:43:20 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/branch_openmp/src/transformation/generic_algorithm_transformation.cpp
r1328 r1460 12 12 #include "client_client_dht_template.hpp" 13 13 #include "utils.hpp" 14 #include "timer.hpp" 15 #include "mpi.hpp" 14 16 15 17 namespace xios { … … 17 19 CGenericAlgorithmTransformation::CGenericAlgorithmTransformation() 18 20 : transformationMapping_(), transformationWeight_(), transformationPosition_(), 19 idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA) 21 idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(), 22 computedProcSrcNonTransformedElement_(false), eliminateRedondantSrc_(true), isDistributedComputed_(false) 20 23 { 21 24 } … … 112 115 } 113 116 117 bool CGenericAlgorithmTransformation::isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst) 118 { 119 120 if (!isDistributedComputed_) 121 { 122 isDistributedComputed_=true ; 123 if (!eliminateRedondantSrc_) isDistributed_=true ; 124 else 125 { 126 CContext* context = CContext::getCurrent(); 127 CContextClient* client = context->client; 128 129 computePositionElements(gridSrc, gridDst); 130 std::vector<CScalar*> scalarListSrcP = gridSrc->getScalars(); 131 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 132 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 133 int distributed, distributed_glo ; 134 135 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 136 if (2 == axisDomainSrcOrder(elementPositionInGrid)) // It's domain 137 { 138 distributed=domainListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]]->isDistributed() ; 139 ep_lib::MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 140 141 } 142 else if (1 == axisDomainSrcOrder(elementPositionInGrid))//it's an axis 143 { 144 distributed=axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]]->isDistributed() ; 145 ep_lib::MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ; 146 } 147 else //it's a scalar 148 { 149 distributed_glo=false ; 150 } 151 isDistributed_=distributed_glo ; 152 } 153 } 154 return isDistributed_ ; 155 } 114 156 /*! 115 157 This function computes the global indexes of grid source, which the grid destination is in demand. … … 130 172 131 173 typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap; 132 133 size_t indexSrcSize = 0; 134 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 135 { 136 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 137 iteTransMap = transformationMapping_[idxTrans].end(); 138 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 139 140 itTransWeight = itbTransWeight; 141 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 142 { 143 indexSrcSize += (itTransMap->second).size(); 144 } 145 } 146 147 bool isTransPosEmpty = transformationPosition_.empty(); 148 CArray<size_t,1> transPos; 149 if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 150 CArray<size_t,1> indexSrc(indexSrcSize); 151 indexSrcSize = 0; 152 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 153 { 154 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 155 iteTransMap = transformationMapping_[idxTrans].end(); 156 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 157 158 // Build mapping between global source element index and global destination element index. 159 itTransWeight = itbTransWeight; 160 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 161 { 162 const std::vector<int>& srcIndex = itTransMap->second; 163 for (int idx = 0; idx < srcIndex.size(); ++idx) 164 { 165 indexSrc(indexSrcSize) = srcIndex[idx]; 166 ++indexSrcSize; 167 } 168 } 169 170 if (!isTransPosEmpty) 171 { 172 TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 173 transPos(idxTrans) = itPosMap->second[0]; 174 } 175 } 174 int idx; 176 175 177 176 // compute position of elements on grids … … 184 183 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 185 184 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 186 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 187 188 // Find out global index source of transformed element on corresponding process. 189 std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements()); 190 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 191 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 192 { 193 if (idx == elementPositionInGrid) 194 computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]); 195 if (2 == axisDomainDstOrder(idx)) // It's domain 196 { 197 if (idx != elementPositionInGrid) 198 computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 199 domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 200 transPos, 201 globalElementIndexOnProc[idx]); 202 203 } 204 else if (1 == axisDomainDstOrder(idx))//it's an axis 205 { 206 if (idx != elementPositionInGrid) 207 computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 208 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 209 transPos, 210 globalElementIndexOnProc[idx]); 211 } 212 else //it's a scalar 213 { 214 if (idx != elementPositionInGrid) 215 computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 216 scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 217 transPos, 218 globalElementIndexOnProc[idx]); 219 220 } 221 } 222 223 if (!isTransPosEmpty) 224 { 225 for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 226 { 227 if (idx != elementPositionInGrid) 228 { 229 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it, 230 ite = globalElementIndexOnProc[idx].end(); 231 for (it = itb; it != ite; ++it) it->second.resize(1); 232 } 233 } 234 } 235 185 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 186 187 bool isTransPosEmpty = transformationPosition_.empty(); 188 CArray<size_t,1> transPos; 189 if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 190 std::set<size_t> allIndexSrc; // All index of source, which can be scattered among processes, need for doing transformation 191 192 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 193 { 194 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 195 iteTransMap = transformationMapping_[idxTrans].end(); 196 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 197 198 // Build mapping between global source element index and global destination element index. 199 itTransWeight = itbTransWeight; 200 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 201 { 202 const std::vector<int>& srcIndex = itTransMap->second; 203 for (idx = 0; idx < srcIndex.size(); ++idx) 204 allIndexSrc.insert(srcIndex[idx]); 205 } 206 207 if (!isTransPosEmpty) 208 { 209 TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 210 transPos(idxTrans) = itPosMap->second[0]; 211 } 212 } 213 214 size_t indexSrcSize = 0; 215 CArray<size_t,1> indexSrc(allIndexSrc.size()); 216 for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it, ++indexSrcSize) 217 indexSrc(indexSrcSize) = *it; 218 219 // Flag to indicate whether we will recompute distribution of source global index on processes 220 bool computeGlobalIndexOnProc = false; 221 if (indexElementSrc_.size() != allIndexSrc.size()) 222 computeGlobalIndexOnProc = true; 223 else 224 { 225 for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it) 226 if (0 == indexElementSrc_.count(*it)) 227 { 228 computeGlobalIndexOnProc = true; 229 break; 230 } 231 } 232 233 if (computeGlobalIndexOnProc) 234 indexElementSrc_.swap(allIndexSrc); 235 236 int sendValue = (computeGlobalIndexOnProc) ? 1 : 0; 237 int recvValue = 0; 238 ep_lib::MPI_Allreduce(&sendValue, &recvValue, 1, MPI_INT, MPI_SUM, client->intraComm); 239 computeGlobalIndexOnProc = (0 < recvValue); 240 241 // CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 242 243 if (computeGlobalIndexOnProc || !computedProcSrcNonTransformedElement_) 244 { 245 { 246 CClientClientDHTInt::Index2VectorInfoTypeMap tmp ; 247 globalIndexOfTransformedElementOnProc_.swap(tmp) ; 248 } 249 // Find out global index source of transformed element on corresponding process. 250 if (globalElementIndexOnProc_.empty()) 251 globalElementIndexOnProc_.resize(axisDomainDstOrder.numElements()); 252 253 for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 254 { 255 256 if (idx == elementPositionInGrid) 257 computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc_); //globalElementIndexOnProc[idx]); 258 if (!computedProcSrcNonTransformedElement_) 259 { 260 if (2 == axisDomainDstOrder(idx)) // It's domain 261 { 262 if (idx != elementPositionInGrid) 263 computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 264 domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 265 transPos, 266 globalElementIndexOnProc_[idx]); 267 268 } 269 else if (1 == axisDomainDstOrder(idx))//it's an axis 270 { 271 if (idx != elementPositionInGrid) 272 computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 273 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 274 transPos, 275 globalElementIndexOnProc_[idx]); 276 } 277 else //it's a scalar 278 { 279 if (idx != elementPositionInGrid) 280 computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 281 scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 282 transPos, 283 globalElementIndexOnProc_[idx]); 284 285 } 286 } 287 } 288 289 if (!isTransPosEmpty && !computedProcSrcNonTransformedElement_) 290 { 291 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 292 { 293 if (idx != elementPositionInGrid) 294 { 295 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 296 ite = globalElementIndexOnProc_[idx].end(); 297 for (it = itb; it != ite; ++it) it->second.resize(1); 298 } 299 } 300 } 301 302 /* 303 if (!computedProcSrcNonTransformedElement_) 304 { 305 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 306 { 307 if (idx != elementPositionInGrid) 308 { 309 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 310 ite = globalElementIndexOnProc_[idx].end(); 311 for (it = itb; it != ite; ++it) procOfNonTransformedElements_.insert(it->first); 312 if (procOfNonTransformedElements_.size() == nbClient) 313 break; 314 } 315 } 316 } 317 318 // Processes contain the source index of transformed element 319 std::set<int> procOfTransformedElement; 320 CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc.begin(), 321 itIdxe = globalIndexOfTransformedElementOnProc.end(), itIdx; 322 for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 323 { 324 std::vector<int>& tmp = itIdx->second; 325 for (int i = 0; i < tmp.size(); ++i) 326 procOfTransformedElement.insert(tmp[i]); 327 if (tmp.size() == nbClient) 328 break; 329 } 330 331 std::set<int>& commonProc = (procOfTransformedElement.size() < procOfNonTransformedElements_.size()) ? procOfTransformedElement 332 : (!procOfNonTransformedElements_.empty() ? procOfNonTransformedElements_ : procOfTransformedElement); 333 334 std::vector<int> procContainSrcElementIdx(commonProc.size()); 335 int count = 0; 336 for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) 337 procContainSrcElementIdx[count++] = *it; 338 339 procContainSrcElementIdx_.swap(procContainSrcElementIdx); 340 */ 341 342 if (procElementList_.empty()) procElementList_.resize(axisDomainDstOrder.numElements()) ; 343 for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 344 { 345 std::set<int>& procList=procElementList_[idx] ; 346 std::set<int> commonTmp ; 347 if (idx == elementPositionInGrid) 348 { 349 set<int> tmpSet ; 350 procList.swap(tmpSet) ; 351 CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc_.begin(), 352 itIdxe = globalIndexOfTransformedElementOnProc_.end(), itIdx; 353 for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 354 { 355 std::vector<int>& tmp = itIdx->second; 356 for (int i = 0; i < tmp.size(); ++i) procList.insert(tmp[i]); 357 if (tmp.size() == nbClient) 358 break; 359 } 360 } 361 else 362 { 363 if (!computedProcSrcNonTransformedElement_) 364 { 365 set<int> tmpSet ; 366 procList.swap(tmpSet) ; 367 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 368 ite = globalElementIndexOnProc_[idx].end(); 369 for (it = itb; it != ite; ++it) 370 { 371 procList.insert(it->first); 372 if (procList.size() == nbClient) break; 373 } 374 } 375 } 376 377 if (idx==0) commonProc_= procList ; 378 else 379 { 380 for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) 381 if (procList.count(*it)==1) commonTmp.insert(*it) ; 382 commonProc_.swap(commonTmp) ; 383 } 384 } 385 std::vector<int> procContainSrcElementIdx(commonProc_.size()); 386 int count = 0; 387 for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) procContainSrcElementIdx[count++] = *it; 388 procContainSrcElementIdx_.swap(procContainSrcElementIdx); 389 390 // For the first time, surely we calculate proc containing non transformed elements 391 if (!computedProcSrcNonTransformedElement_) computedProcSrcNonTransformedElement_ = true; 392 } 393 236 394 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 237 395 { … … 243 401 244 402 // Build mapping between global source element index and global destination element index. 245 boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc [elementPositionInGrid]);246 boost::unordered_map<int,int> tmpCounter;403 boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc_[elementPositionInGrid]); 404 std::set<int> tmpCounter; 247 405 itTransWeight = itbTransWeight; 248 406 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) … … 250 408 const std::vector<int>& srcIndex = itTransMap->second; 251 409 const std::vector<double>& weight = itTransWeight->second; 252 for (i nt idx = 0; idx < srcIndex.size(); ++idx)410 for (idx = 0; idx < srcIndex.size(); ++idx) 253 411 { 254 412 src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx])); 255 if (1 == globalIndexOfTransformedElementOnProc.count(srcIndex[idx]) && (0 == tmpCounter.count(srcIndex[idx]))) 256 { 257 tmpCounter[srcIndex[idx]] = 1; 258 std::vector<int>& srcProc = globalIndexOfTransformedElementOnProc[srcIndex[idx]]; 259 for (int j = 0; j < srcProc.size(); ++j) 260 globalElementIndexOnProc[elementPositionInGrid][srcProc[j]].push_back(srcIndex[idx]); 261 } 262 } 263 } 264 413 if (0 == tmpCounter.count(srcIndex[idx])) 414 { 415 tmpCounter.insert(srcIndex[idx]); 416 417 vector<int>& rankSrc = globalIndexOfTransformedElementOnProc_[srcIndex[idx]] ; 418 for (int n=0;n<rankSrc.size();++n) 419 { 420 if (commonProc_.count(rankSrc[n])==1) globalElementIndexOnProc_[elementPositionInGrid][rankSrc[n]].push_back(srcIndex[idx]); 421 } 422 // for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 423 // globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 424 } 425 } 426 } 427 265 428 if (!isTransPosEmpty) 266 429 { 267 for (i nt idx = 0; idx < globalElementIndexOnProc.size(); ++idx)430 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 268 431 { 269 432 if (idx != elementPositionInGrid) 270 433 { 271 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc [idx].begin(), it,272 ite = globalElementIndexOnProc [idx].end();434 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 435 ite = globalElementIndexOnProc_[idx].end(); 273 436 for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans); 274 437 } 275 438 } 276 }277 278 std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false));279 boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite;280 for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)281 {282 itb = globalElementIndexOnProc[idx].begin();283 ite = globalElementIndexOnProc[idx].end();284 for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true;285 }286 287 // Determine procs which contain global source index288 std::vector<bool> intersectedProc(nbClient, true);289 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)290 {291 std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(),292 intersectedProc.begin(), intersectedProc.begin(),293 std::logical_and<bool>());294 }295 296 std::vector<int> srcRank;297 for (int idx = 0; idx < nbClient; ++idx)298 {299 if (intersectedProc[idx]) srcRank.push_back(idx);300 439 } 301 440 302 441 // Ok, now compute global index of grid source and ones of grid destination 303 442 computeGlobalGridIndexMapping(elementPositionInGrid, 304 srcRank,443 procContainSrcElementIdx_, //srcRank, 305 444 src2DstMap, 306 445 gridSrc, 307 446 gridDst, 308 globalElementIndexOnProc ,447 globalElementIndexOnProc_, 309 448 globaIndexWeightFromSrcToDst); 310 } 449 } 311 450 } 312 451 … … 316 455 \param [in] srcRank rank of client from which we demand global index of element source 317 456 \param [in] src2DstMap mapping of global index of element source and global index of element destination 318 \param [in] gridSrc Grid source319 \param [in] gridDst Grid destination320 \param [in] globalElementIndexOnProc Global index of element source on different client rank321 \param [out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination457 \param [in] gridSrc Grid source 458 \param [in] gridDst Grid destination 459 \param [in] globalElementIndexOnProc Global index of element source on different client rank 460 \param [out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination 322 461 */ 323 462 void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid, … … 329 468 SourceDestinationIndexMap& globaIndexWeightFromSrcToDst) 330 469 { 470 SourceDestinationIndexMap globaIndexWeightFromSrcToDst_tmp ; 471 472 CContext* context = CContext::getCurrent(); 473 CContextClient* client=context->client; 474 int clientRank = client->clientRank; 475 331 476 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 332 477 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); … … 369 514 size_t globalDstSize = 1; 370 515 domainIndex = axisIndex = scalarIndex = 0; 516 set<size_t> globalSrcStoreIndex ; 517 371 518 for (int idx = 0; idx < nbElement; ++idx) 372 519 { … … 392 539 } 393 540 541 std::map< std::pair<size_t,size_t>, int > rankMap ; 542 std::map< std::pair<size_t,size_t>, int >:: iterator rankMapIt ; 543 394 544 for (int i = 0; i < srcRank.size(); ++i) 395 545 { … … 451 601 for (int k = 0; k < globalElementDstIndexSize; ++k) 452 602 { 453 globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 603 604 globaIndexWeightFromSrcToDst_tmp[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second )); 605 rankMapIt=rankMap.find(make_pair(globalSrcIndex,globalDstVecIndex[k])) ; 606 if (rankMapIt==rankMap.end()) rankMap[make_pair(globalSrcIndex,globalDstVecIndex[k])] = rankSrc ; 607 else if (rankSrc==clientRank) rankMapIt->second = rankSrc ; 454 608 } 455 609 ++idxLoop[0]; … … 458 612 } 459 613 } 614 615 // eliminate redondant global src point owned by differrent processes. 616 // Avoid as possible to tranfer data from an other process if the src point is also owned by current process 617 int rankSrc ; 618 size_t globalSrcIndex ; 619 size_t globalDstIndex ; 620 double weight ; 621 622 SourceDestinationIndexMap::iterator rankIt,rankIte ; 623 boost::unordered_map<size_t, std::vector<std::pair<size_t,double> > >::iterator globalSrcIndexIt, globalSrcIndexIte ; 624 std::vector<std::pair<size_t,double> >::iterator vectIt,vectIte ; 625 626 rankIt=globaIndexWeightFromSrcToDst_tmp.begin() ; rankIte=globaIndexWeightFromSrcToDst_tmp.end() ; 627 for(;rankIt!=rankIte;++rankIt) 628 { 629 rankSrc = rankIt->first ; 630 globalSrcIndexIt = rankIt->second.begin() ; globalSrcIndexIte = rankIt->second.end() ; 631 for(;globalSrcIndexIt!=globalSrcIndexIte;++globalSrcIndexIt) 632 { 633 globalSrcIndex = globalSrcIndexIt->first ; 634 vectIt = globalSrcIndexIt->second.begin() ; vectIte = globalSrcIndexIt->second.end() ; 635 for(vectIt; vectIt!=vectIte; vectIt++) 636 { 637 globalDstIndex = vectIt->first ; 638 weight = vectIt->second ; 639 if (eliminateRedondantSrc_) 640 { 641 if (rankMap[make_pair(globalSrcIndex,globalDstIndex)] == rankSrc) 642 globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ; 643 } 644 else globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ; 645 } 646 } 647 } 648 460 649 } 461 650 … … 507 696 for (int idx = 0; idx < nIndexSize; ++idx) 508 697 { 509 globalIndex = axisSrc->index(idx); 510 globalIndex2ProcRank[globalIndex].push_back(clientRank); 698 if (axisSrc->mask(idx)) 699 { 700 globalIndex = axisSrc->index(idx); 701 globalIndex2ProcRank[globalIndex].push_back(clientRank); 702 } 511 703 } 512 704 … … 574 766 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank; 575 767 globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor())); 768 576 769 if (destGlobalIndexPositionInGrid.isEmpty()) 577 770 { … … 581 774 j_ind=domainSrc->j_index(idx) ; 582 775 583 globalIndex = i_ind + j_ind * niGlobSrc; 584 globalIndex2ProcRank[globalIndex].resize(1); 585 globalIndex2ProcRank[globalIndex][0] = clientRank; 776 if (domainSrc->localMask(idx)) 777 { 778 globalIndex = i_ind + j_ind * niGlobSrc; 779 globalIndex2ProcRank[globalIndex].resize(1); 780 globalIndex2ProcRank[globalIndex][0] = clientRank; 781 } 586 782 } 587 783 } … … 590 786 for (int idx = 0; idx < nIndexSize; ++idx) 591 787 { 592 globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank); 788 // if (domainSrc->localMask(idx)) -> not necessairy, mask seem to be included in destGlobalIndexPositionInGrid(idx) (ym) 789 globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank); 593 790 } 594 791 } … … 647 844 } 648 845 } 846 847 848 849 850 851 852 void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst, 853 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest) 854 { 855 856 CContext* context = CContext::getCurrent(); 857 CContextClient* client = context->client; 858 int nbClient = client->clientSize; 859 860 computePositionElements(gridDst, gridSrc); 861 std::vector<CScalar*> scalarListDstP = gridDst->getScalars(); 862 std::vector<CAxis*> axisListDstP = gridDst->getAxis(); 863 std::vector<CDomain*> domainListDstP = gridDst->getDomains(); 864 CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order; 865 std::vector<CScalar*> scalarListSrcP = gridSrc->getScalars(); 866 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 867 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 868 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 869 870 int nElement=axisDomainSrcOrder.numElements() ; 871 int indSrc=1 ; 872 int indDst=1 ; 873 vector<int> nIndexSrc(nElement) ; 874 vector<int> nIndexDst(nElement) ; 875 vector< CArray<bool,1>* > maskSrc(nElement) ; 876 vector< CArray<bool,1>* > maskDst(nElement) ; 877 878 int nlocalIndexSrc=1 ; 879 int nlocalIndexDest=1 ; 880 CArray<bool,1> maskScalar(1) ; 881 maskScalar = true ; 882 883 884 for(int i=0 ; i<nElement; i++) 885 { 886 int dimElement = axisDomainSrcOrder(i); 887 if (2 == dimElement) //domain 888 { 889 CDomain* domain=domainListSrcP[elementPositionInGridSrc2DomainPosition_[i]] ; 890 nIndexSrc[i] = domain->i_index.numElements() ; 891 maskSrc[i]=&domain->localMask ; 892 } 893 else if (1 == dimElement) //axis 894 { 895 CAxis* axis=axisListSrcP[elementPositionInGridSrc2AxisPosition_[i]] ; 896 nIndexSrc[i] = axis->index.numElements() ; 897 maskSrc[i]=&axis->mask ; 898 } 899 else //scalar 900 { 901 nIndexSrc[i]=1 ; 902 maskSrc[i]=&maskScalar ; 903 } 904 nlocalIndexSrc=nlocalIndexSrc*nIndexSrc[i] ; 905 } 906 907 908 909 int offset=1 ; 910 for(int i=0 ; i<nElement; i++) 911 { 912 int dimElement = axisDomainDstOrder(i); 913 if (2 == dimElement) //domain 914 { 915 CDomain* domain=domainListDstP[elementPositionInGridDst2DomainPosition_[i]] ; 916 int nIndex=domain->i_index.numElements() ; 917 CArray<bool,1>& localMask=domain->localMask ; 918 int nbInd=0 ; 919 for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ; 920 nIndexDst[i] = nbInd ; 921 maskDst[i]=&domain->localMask ; 922 } 923 else if (1 == dimElement) //axis 924 { 925 CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[i]] ; 926 int nIndex=axis->index.numElements() ; 927 CArray<bool,1>& localMask=axis->mask ; 928 int nbInd=0 ; 929 for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ; 930 nIndexDst[i] = nbInd ; 931 maskDst[i]=&axis->mask ; 932 } 933 else //scalar 934 { 935 nIndexDst[i]=1 ; 936 maskDst[i]=&maskScalar ; 937 } 938 if (i<elementPositionInGrid) offset=offset*nIndexDst[i] ; 939 nlocalIndexDest=nlocalIndexDest*nIndexDst[i] ; 940 } 941 942 943 944 945 946 947 vector<int> dstLocalInd ; 948 int dimElement = axisDomainDstOrder(elementPositionInGrid); 949 if (2 == dimElement) //domain 950 { 951 CDomain* domain = domainListDstP[elementPositionInGridDst2DomainPosition_[elementPositionInGrid]] ; 952 int ni_glo=domain->ni_glo ; 953 int nj_glo=domain->nj_glo ; 954 int nindex_glo=ni_glo*nj_glo ; 955 dstLocalInd.resize(nindex_glo,-1) ; 956 int nIndex=domain->i_index.numElements() ; 957 CArray<bool,1>& localMask=domain->localMask ; 958 int unmaskedInd=0 ; 959 int globIndex ; 960 for(int i=0;i<nIndex;i++) 961 { 962 if (localMask(i)) 963 { 964 globIndex=domain->j_index(i)*ni_glo+domain->i_index(i) ; 965 dstLocalInd[globIndex]=unmaskedInd ; 966 unmaskedInd++ ; 967 } 968 } 969 } 970 else if (1 == dimElement) //axis 971 { 972 CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[elementPositionInGrid]] ; 973 int nindex_glo=axis->n_glo ; 974 dstLocalInd.resize(nindex_glo,-1) ; 975 int nIndex=axis->index.numElements() ; 976 CArray<bool,1>& localMask=axis->mask ; // axis mask must include later data_index 977 int unmaskedInd=0 ; 978 for(int i=0;i<nIndex;i++) 979 { 980 if (localMask(i)) 981 { 982 dstLocalInd[axis->index(i)]=unmaskedInd ; 983 unmaskedInd++ ; 984 } 985 } 986 } 987 else //scalar 988 { 989 dstLocalInd.resize(1) ; 990 dstLocalInd[0]=0 ; 991 } 992 993 // just get the local src mask 994 CArray<bool,1> localMaskOnSrcGrid; 995 gridSrc->getLocalMask(localMaskOnSrcGrid) ; 996 // intermediate grid, mask is not initialized => set up mask to true 997 if (localMaskOnSrcGrid.isEmpty()) 998 { 999 localMaskOnSrcGrid.resize(nlocalIndexSrc) ; 1000 localMaskOnSrcGrid=true ; 1001 } 1002 1003 1004 localMaskOnGridDest.resize(nlocalIndexDest,false) ; 1005 1006 vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ; 1007 1008 for(int t=0;t<transformationMapping_.size();++t) 1009 { 1010 TransformationIndexMap::const_iterator itTransMap = transformationMapping_[t].begin(), 1011 iteTransMap = transformationMapping_[t].end(); 1012 TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[t].begin(); 1013 dstIndWeight[t].resize(nIndexSrc[elementPositionInGrid]) ; 1014 1015 for(;itTransMap!=iteTransMap;++itTransMap,++itTransWeight) 1016 { 1017 int dst=dstLocalInd[itTransMap->first] ; 1018 if (dst!=-1) 1019 { 1020 const vector<int>& srcs=itTransMap->second; 1021 const vector<double>& weights=itTransWeight->second; 1022 for(int i=0;i<srcs.size() ;i++) dstIndWeight[t][srcs[i]].push_back(pair<int,double>(dst*offset+t,weights[i])) ; 1023 } 1024 } 1025 } 1026 int srcInd=0 ; 1027 int currentInd ; 1028 int t=0 ; 1029 int srcIndCompressed=0 ; 1030 1031 nonDistributedrecursiveFunct(nElement-1,true,elementPositionInGrid,maskSrc,maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, 1032 currentInd,localSrc,localDst,weight, localMaskOnSrcGrid, localMaskOnGridDest ); 1033 1034 } 1035 1036 1037 void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd, 1038 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest ) 1039 { 1040 int masked_ ; 1041 if (currentPos!=elementPositionInGrid) 1042 { 1043 if (currentPos!=0) 1044 { 1045 CArray<bool,1>& mask = *maskSrc[currentPos] ; 1046 1047 for(int i=0;i<nIndexSrc[currentPos];i++) 1048 { 1049 masked_=masked ; 1050 if (!mask(i)) masked_=false ; 1051 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 1052 } 1053 } 1054 else 1055 { 1056 CArray<bool,1>& mask = *maskSrc[currentPos] ; 1057 for(int i=0;i<nIndexSrc[currentPos];i++) 1058 { 1059 if (masked && mask(i)) 1060 { 1061 if (dstIndWeight[t][currentInd].size()>0) 1062 { 1063 for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it) 1064 { 1065 if (localMaskOnGridSrc(srcInd)) 1066 { 1067 localSrc.push_back(srcIndCompressed) ; 1068 localDst.push_back(it->first) ; 1069 weight.push_back(it->second) ; 1070 localMaskOnGridDest[it->first]=true ; 1071 } 1072 (it->first)++ ; 1073 } 1074 } 1075 if (t < dstIndWeight.size()-1) t++ ; 1076 if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ; 1077 } 1078 srcInd++ ; 1079 } 1080 } 1081 } 1082 else 1083 { 1084 1085 if (currentPos!=0) 1086 { 1087 1088 CArray<bool,1>& mask = *maskSrc[currentPos] ; 1089 for(int i=0;i<nIndexSrc[currentPos];i++) 1090 { 1091 t=0 ; 1092 masked_=masked ; 1093 if (!mask(i)) masked_=false ; 1094 nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight , i, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ; 1095 } 1096 } 1097 else 1098 { 1099 for(int i=0;i<nIndexSrc[currentPos];i++) 1100 { 1101 if (masked) 1102 { 1103 t=0 ; 1104 if (dstIndWeight[t][i].size()>0) 1105 { 1106 for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it) 1107 { 1108 if (localMaskOnGridSrc(srcInd)) 1109 { 1110 localSrc.push_back(srcIndCompressed) ; 1111 localDst.push_back(it->first) ; 1112 weight.push_back(it->second) ; 1113 localMaskOnGridDest[it->first]=true ; 1114 } 1115 (it->first)++ ; 1116 } 1117 } 1118 if (t < dstIndWeight.size()-1) t++ ; 1119 if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ; 1120 } 1121 srcInd++ ; 1122 } 1123 } 1124 } 1125 1126 } 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 649 1137 650 1138 /*!
Note: See TracChangeset
for help on using the changeset viewer.