Changeset 1037 for XIOS/dev/branch_yushan/src/node
- Timestamp:
- 01/25/17 16:25:17 (7 years ago)
- Location:
- XIOS/dev/branch_yushan/src/node
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/branch_yushan/src/node/axis.cpp
r995 r1037 264 264 isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 265 265 (!this->n.isEmpty() && (this->n != this->n_glo)); 266 267 // A same stupid condition to make sure that if there is only one client, axis268 // should be considered to be distributed. This should be a temporary solution269 isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize);270 266 } 271 267 -
XIOS/dev/branch_yushan/src/node/context.cpp
r1033 r1037 339 339 } 340 340 341 //! Server side: Put server into a loop in order to listen message from client 342 bool CContext::eventLoop(void) 343 { 344 return server->eventLoop(); 345 } 346 341 347 //! Try to send the buffers and receive possible answers 342 348 bool CContext::checkBuffersAndListen(void) 343 349 { 344 350 client->checkBuffers(); 345 346 bool hasTmpBufferedEvent = client->hasTemporarilyBufferedEvent(); 347 if (hasTmpBufferedEvent) 348 hasTmpBufferedEvent = !client->sendTemporarilyBufferedEvent(); 349 350 // Don't process events if there is a temporarily buffered event 351 return server->eventLoop(!hasTmpBufferedEvent); 351 return server->eventLoop(); 352 352 } 353 353 … … 389 389 void CContext::closeDefinition(void) 390 390 { 391 int myRank; 392 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 393 394 //printf("myRank = %d, hasClient = %d, hasServer = %d\n", myRank, hasClient, hasServer); 395 391 396 // There is nothing client need to send to server 392 397 if (hasClient) 393 398 { 394 399 // After xml is parsed, there are some more works with post processing 395 postProcessing(); 396 } 397 setClientServerBuffer(); 400 postProcessing(); 401 //printf("myRank = %d, postProcessing OK\n", myRank); 402 } 403 setClientServerBuffer(); //printf("myRank = %d, setClientServerBuffer OK\n", myRank); 398 404 399 405 if (hasClient && !hasServer) 400 406 { 401 407 // Send all attributes of current context to server 402 this->sendAllAttributesToServer(); 408 this->sendAllAttributesToServer(); //printf("myRank = %d, this->sendAllAttributesToServer OK\n", myRank); 403 409 404 410 // Send all attributes of current calendar 405 411 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(); 412 //printf("myRank = %d, CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer OK\n", myRank); 406 413 407 414 // We have enough information to send to server 408 415 // First of all, send all enabled files 409 sendEnabledFiles(); 416 sendEnabledFiles(); //printf("myRank = %d, sendEnabledFiles OK\n", myRank); 410 417 411 418 // Then, send all enabled fields 412 sendEnabledFields(); 419 sendEnabledFields(); //printf("myRank = %d, sendEnabledFields OK\n", myRank); 413 420 414 421 // At last, we have all info of domain and axis, then send them 415 sendRefDomainsAxis(); 422 sendRefDomainsAxis(); //printf("myRank = %d, sendRefDomainsAxis OK\n", myRank); 416 423 417 424 // After that, send all grid (if any) 418 sendRefGrid(); 425 sendRefGrid(); //printf("myRank = %d, sendRefGrid OK\n", myRank); 419 426 } 420 427 421 428 // We have a xml tree on the server side and now, it should be also processed 422 if (hasClient && !hasServer) sendPostProcessing(); 429 if (hasClient && !hasServer) sendPostProcessing(); 423 430 424 431 // There are some processings that should be done after all of above. For example: check mask or index 425 432 if (hasClient) 426 433 { 427 this->buildFilterGraphOfEnabledFields(); 428 buildFilterGraphOfFieldsWithReadAccess(); 429 this->solveAllRefOfEnabledFields(true); 434 this->buildFilterGraphOfEnabledFields(); //printf("myRank = %d, buildFilterGraphOfEnabledFields OK\n", myRank); 435 buildFilterGraphOfFieldsWithReadAccess(); //printf("myRank = %d, buildFilterGraphOfFieldsWithReadAccess OK\n", myRank); 436 this->solveAllRefOfEnabledFields(true); //printf("myRank = %d, solveAllRefOfEnabledFields OK\n", myRank); 430 437 } 431 438 … … 434 441 435 442 // Nettoyage de l'arborescence 436 if (hasClient && !hasServer) CleanTree(); // Only on client side??443 if (hasClient && !hasServer) CleanTree(); 437 444 438 445 if (hasClient) 439 446 { 440 sendCreateFileHeader(); 441 442 startPrefetchingOfEnabledReadModeFiles(); 447 sendCreateFileHeader(); //printf("myRank = %d, sendCreateFileHeader OK\n", myRank); 448 449 startPrefetchingOfEnabledReadModeFiles(); //printf("myRank = %d, startPrefetchingOfEnabledReadModeFiles OK\n", myRank); 443 450 } 444 451 } … … 479 486 { 480 487 int size = this->enabledFiles.size(); 488 481 489 for (int i = 0; i < size; ++i) 482 490 { … … 566 574 { 567 575 const std::vector<CFile*> allFiles = CFile::getAll(); 568 const CDate& initDate = calendar->getInitDate();569 576 570 577 for (unsigned int i = 0; i < allFiles.size(); i++) … … 572 579 { 573 580 if (allFiles[i]->enabled.getValue()) // Si l'attribut 'enabled' est fixé à vrai. 574 {575 if ((initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep()))576 {577 error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl578 << "Output frequency in file \""<<allFiles[i]->getFileOutputName()579 <<"\" is less than the time step. File will not be written."<<endl;580 }581 else582 581 enabledFiles.push_back(allFiles[i]); 583 }584 582 } 585 else 586 { 587 if ( (initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep())) 588 { 589 error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl 590 << "Output frequency in file \""<<allFiles[i]->getFileOutputName() 591 <<"\" is less than the time step. File will not be written."<<endl; 592 } 593 else 594 enabledFiles.push_back(allFiles[i]); // otherwise true by default 595 } 583 else enabledFiles.push_back(allFiles[i]); // otherwise true by default 584 596 585 597 586 if (enabledFiles.size() == 0) … … 812 801 void CContext::postProcessing() 813 802 { 803 int myRank; 804 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 805 806 //printf("myRank = %d, in postProcessing, isPostProcessed = %d\n", myRank, isPostProcessed); 814 807 if (isPostProcessed) return; 815 808 … … 820 813 ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 821 814 // Calendar first update to set the current date equals to the start date 822 calendar->update(0); 815 calendar->update(0); //printf("myRank = %d, calendar->update(0) OK\n", myRank); 823 816 824 817 // Find all inheritance in xml structure 825 this->solveAllInheritance(); 818 this->solveAllInheritance(); //printf("myRank = %d, this->solveAllInheritance OK\n", myRank); 826 819 827 820 // Check if some axis, domains or grids are eligible to for compressed indexed output. 828 821 // Warning: This must be done after solving the inheritance and before the rest of post-processing 829 checkAxisDomainsGridsEligibilityForCompressedOutput(); 822 checkAxisDomainsGridsEligibilityForCompressedOutput(); //printf("myRank = %d, checkAxisDomainsGridsEligibilityForCompressedOutput OK\n", myRank); 830 823 831 824 // Check if some automatic time series should be generated 832 825 // Warning: This must be done after solving the inheritance and before the rest of post-processing 833 prepareTimeseries(); 826 prepareTimeseries(); //printf("myRank = %d, prepareTimeseries OK\n", myRank); 834 827 835 828 //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 836 this->findEnabledFiles(); 837 this->findEnabledReadModeFiles(); 829 this->findEnabledFiles(); //printf("myRank = %d, this->findEnabledFiles OK\n", myRank); 830 this->findEnabledReadModeFiles(); //printf("myRank = %d, this->findEnabledReadModeFiles OK\n", myRank); 838 831 839 832 // Find all enabled fields of each file 840 this->findAllEnabledFields(); 841 this->findAllEnabledFieldsInReadModeFiles(); 833 this->findAllEnabledFields(); //printf("myRank = %d, this->findAllEnabledFields OK\n", myRank); 834 this->findAllEnabledFieldsInReadModeFiles(); //printf("myRank = %d, this->findAllEnabledFieldsInReadModeFiles OK\n", myRank); 842 835 843 836 if (hasClient && !hasServer) 844 837 { 845 838 // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 846 this->readAttributesOfEnabledFieldsInReadModeFiles(); 839 this->readAttributesOfEnabledFieldsInReadModeFiles(); //printf("myRank = %d, this->readAttributesOfEnabledFieldsInReadModeFiles OK\n", myRank); 847 840 } 848 841 849 842 // Only search and rebuild all reference objects of enable fields, don't transform 850 this->solveOnlyRefOfEnabledFields(false); 843 this->solveOnlyRefOfEnabledFields(false); //printf("myRank = %d, this->solveOnlyRefOfEnabledFields(false) OK\n", myRank); 851 844 852 845 // Search and rebuild all reference object of enabled fields 853 this->solveAllRefOfEnabledFields(false); 846 this->solveAllRefOfEnabledFields(false); //printf("myRank = %d, this->solveAllRefOfEnabledFields(false) OK\n", myRank); 854 847 855 848 // Find all fields with read access from the public API 856 findFieldsWithReadAccess(); 849 findFieldsWithReadAccess(); //printf("myRank = %d, findFieldsWithReadAccess OK\n", myRank); 857 850 // and solve the all reference for them 858 solveAllRefOfFieldsWithReadAccess(); 851 solveAllRefOfFieldsWithReadAccess(); //printf("myRank = %d, solveAllRefOfFieldsWithReadAccess OK\n", myRank); 859 852 860 853 isPostProcessed = true; … … 1240 1233 event.push(*itRank,1,msg); 1241 1234 client->sendEvent(event); 1242 1243 1235 } 1236 else client->sendEvent(event); 1244 1237 } 1245 1238 -
XIOS/dev/branch_yushan/src/node/context.hpp
r1033 r1037 93 93 94 94 // Put sever or client into loop state 95 bool eventLoop(void); 96 95 97 bool checkBuffersAndListen(void); 96 98 -
XIOS/dev/branch_yushan/src/node/domain.cpp
r995 r1037 698 698 computeNGlobDomain(); 699 699 checkZoom(); 700 700 701 701 isDistributed_ = !((!ni.isEmpty() && (ni == ni_glo) && !nj.isEmpty() && (nj == nj_glo)) || 702 702 (!i_index.isEmpty() && i_index.numElements() == ni_glo*nj_glo)); 703 704 // A stupid condition to make sure that if there is only one client, domain705 // should be considered to be distributed. This should be a temporary solution706 isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize);707 703 } 708 704 … … 1307 1303 void CDomain::checkAttributesOnClientAfterTransformation() 1308 1304 { 1309 CContext* context=CContext::getCurrent() ; 1310 1305 int myRank; 1306 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 1307 1308 CContext* context=CContext::getCurrent() ; //printf("myRank = %d, CContext::getCurrent OK\n", myRank); 1309 1310 //printf("myRank = %d, this->isClientAfterTransformationChecked = %d\n", myRank, this->isClientAfterTransformationChecked); 1311 1311 if (this->isClientAfterTransformationChecked) return; 1312 //printf("myRank = %d, context->hasClient = %d\n", myRank, context->hasClient); 1312 1313 if (context->hasClient) 1313 1314 { 1314 this->checkMask(); 1315 if (hasLonLat || hasArea || isCompressible_) this->computeConnectedServer(); 1316 if (hasLonLat) this->completeLonLatClient(); 1315 this->checkMask(); //printf("myRank = %d, this->checkMask OK\n", myRank); 1316 //printf("myRank = %d, hasLonLat = %d, hasArea = %d, isCompressible_ = %d\n", myRank, hasLonLat, hasArea, isCompressible_); 1317 if (hasLonLat || hasArea || isCompressible_) 1318 { 1319 //printf("myRank = %d, start this->computeConnectedServer\n", myRank); 1320 this->computeConnectedServer(); 1321 //printf("myRank = %d, this->computeConnectedServer OK\n", myRank); 1322 } 1323 //printf("myRank = %d, hasLonLat = %d\n", myRank, hasLonLat); 1324 if (hasLonLat) 1325 { 1326 this->completeLonLatClient(); 1327 //printf("myRank = %d, this->completeLonLatClient OK\n", myRank); 1328 } 1317 1329 } 1318 1330 … … 1448 1460 void CDomain::computeConnectedServer(void) 1449 1461 { 1462 int myRank; 1463 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 1464 1450 1465 CContext* context=CContext::getCurrent() ; 1451 1466 CContextClient* client=context->client ; … … 1534 1549 } 1535 1550 } 1551 1536 1552 1537 1553 size_t globalSizeIndex = 1, indexBegin, indexEnd; … … 1555 1571 indexEnd = indexBegin + range - 1; 1556 1572 } 1557 1573 1558 1574 CServerDistributionDescription serverDescription(nGlobDomain_, nbServer); 1559 1575 if (isUnstructed_) serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0); 1560 1576 else serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 1); 1561 1577 1578 //printf("myRank = %d, check 7 OK\n", myRank); 1579 1562 1580 CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), 1563 1581 client->intraComm); 1564 clientServerMap->computeServerIndexMapping(globalIndexDomain); 1582 //printf("myRank = %d new OK\n", myRank); 1583 1584 clientServerMap->computeServerIndexMapping(globalIndexDomain); 1585 //printf("myRank = %d, clientServerMap->computeServerIndexMapping(globalIndexDomain) OK\n", myRank); 1586 1565 1587 const CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); 1588 //printf("myRank = %d, clientServerMap->getGlobalIndexOnServer OK\n", myRank); 1589 1590 //printf("myRank = %d, check 8 OK\n", myRank); 1566 1591 1567 1592 CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexDomainOnServer.begin(), … … 1597 1622 } 1598 1623 1624 //printf("myRank = %d, check 9 OK\n", myRank); 1625 1599 1626 connectedServerRank_.clear(); 1600 1627 for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) { … … 1605 1632 1606 1633 delete clientServerMap; 1634 //printf("myRank = %d, check 10 OK\n", myRank); 1607 1635 } 1608 1636 -
XIOS/dev/branch_yushan/src/node/field.cpp
r1018 r1037 36 36 , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false) 37 37 , useCompressedOutput(false) 38 , hasTimeInstant(false) 39 , hasTimeCentered(false) 40 , wasDataAlreadyReceivedFromServer(false) 41 , isEOF(false) 38 , isReadDataRequestPending(false) 42 39 { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 43 40 … … 50 47 , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false) 51 48 , useCompressedOutput(false) 52 , hasTimeInstant(false) 53 , hasTimeCentered(false) 54 , wasDataAlreadyReceivedFromServer(false) 55 , isEOF(false) 49 , isReadDataRequestPending(false) 56 50 { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 57 51 … … 253 247 } 254 248 255 bool CField::sendReadDataRequest(const CDate& tsDataRequested)249 void CField::sendReadDataRequest(void) 256 250 { 257 251 CContext* context = CContext::getCurrent(); 258 252 CContextClient* client = context->client; 259 253 260 lastDataRequestedFromServer = tsDataRequested; 261 262 if (!isEOF) // No need to send the request if we already know we are at EOF 263 { 264 CEventClient event(getType(), EVENT_ID_READ_DATA); 265 if (client->isServerLeader()) 266 { 267 CMessage msg; 268 msg << getId(); 269 const std::list<int>& ranks = client->getRanksServerLeader(); 270 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 271 event.push(*itRank, 1, msg); 272 client->sendEvent(event); 273 } 274 else client->sendEvent(event); 275 } 276 else 277 serverSourceFilter->signalEndOfStream(tsDataRequested); 278 279 return !isEOF; 254 lastDataRequestedFromServer = context->getCalendar()->getCurrentDate(); 255 isReadDataRequestPending = true; 256 257 CEventClient event(getType(), EVENT_ID_READ_DATA); 258 if (client->isServerLeader()) 259 { 260 CMessage msg; 261 msg << getId(); 262 const std::list<int>& ranks = client->getRanksServerLeader(); 263 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 264 event.push(*itRank, 1, msg); 265 client->sendEvent(event); 266 } 267 else client->sendEvent(event); 280 268 } 281 269 … … 288 276 const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate(); 289 277 290 bool dataRequested = false;291 292 while (currentDate >= lastDataRequestedFromServer)293 { 294 info(20) << "currentDate : " << currentDate <<endl ;295 info(20) << "lastDataRequestedFromServer : " << lastDataRequestedFromServer <<endl ;296 info(20) << "file->output_freq.getValue() : " << file->output_freq.getValue() <<endl ;297 info(20) << "lastDataRequestedFromServer + file->output_freq.getValue() : " << lastDataRequestedFromServer + file->output_freq <<endl ;298 299 dataRequested |= sendReadDataRequest(lastDataRequestedFromServer + file->output_freq);300 } 301 302 return dataRequested;278 bool requestData = (currentDate >= lastDataRequestedFromServer + file->output_freq.getValue()); 279 280 if (requestData) 281 { 282 cout<<"currentDate : "<<currentDate<<endl ; 283 cout<<"lastDataRequestedFromServer : "<<lastDataRequestedFromServer<<endl ; 284 cout<<"file->output_freq.getValue() : "<<file->output_freq.getValue()<<endl ; 285 cout<<"lastDataRequestedFromServer + file->output_freq.getValue() : "<<lastDataRequestedFromServer + file->output_freq.getValue()<<endl ; 286 287 sendReadDataRequest(); 288 } 289 290 return requestData; 303 291 } 304 292 … … 322 310 323 311 map<int, CArray<double,1> >::iterator it; 324 if (!grid->doGridHaveDataDistributed()) 325 { 326 if (client->isServerLeader()) 327 { 328 if (!data_srv.empty()) 329 { 330 it = data_srv.begin(); 331 const std::list<int>& ranks = client->getRanksServerLeader(); 332 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 333 { 334 msgs.push_back(CMessage()); 335 CMessage& msg = msgs.back(); 336 msg << getId(); 337 if (hasData) 338 msg << getNStep() - 1 << it->second; 339 else 340 msg << int(-1); 341 event.push(*itRank, 1, msg); 342 } 343 } 344 client->sendEvent(event); 345 } 346 else 347 { 348 // if (!data_srv.empty()) 349 // { 350 // it = data_srv.begin(); 351 // const std::list<int>& ranks = client->getRanksServerNotLeader(); 352 // for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 353 // { 354 // msgs.push_back(CMessage()); 355 // CMessage& msg = msgs.back(); 356 // msg << getId(); 357 // if (hasData) 358 // msg << getNStep() - 1 << it->second; 359 // else 360 // msg << int(-1); 361 // event.push(*itRank, 1, msg); 362 // } 363 // } 364 client->sendEvent(event); 365 } 366 } 367 else 368 { 369 for (it = data_srv.begin(); it != data_srv.end(); it++) 370 { 371 msgs.push_back(CMessage()); 372 CMessage& msg = msgs.back(); 373 msg << getId(); 374 if (hasData) 375 msg << getNStep() - 1 << it->second; 376 else 377 msg << int(-1); 378 event.push(it->first, grid->nbSenders[it->first], msg); 379 } 380 client->sendEvent(event); 381 } 312 for (it = data_srv.begin(); it != data_srv.end(); it++) 313 { 314 msgs.push_back(CMessage()); 315 CMessage& msg = msgs.back(); 316 msg << getId(); 317 if (hasData) 318 msg << getNStep() - 1 << it->second; 319 else 320 msg << int(-1); 321 event.push(it->first, grid->nbSenders[it->first], msg); 322 } 323 client->sendEvent(event); 382 324 } 383 325 … … 402 344 this->incrementNStep(); 403 345 346 347 404 348 if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 405 349 return false; … … 435 379 std::map<int, CArray<double,1> > data; 436 380 381 bool isEOF = false; 382 437 383 for (int i = 0; i < ranks.size(); i++) 438 384 { … … 447 393 } 448 394 449 if ( wasDataAlreadyReceivedFromServer)450 lastDataReceivedFromServer = lastDataReceivedFromServer + file->output_freq;395 if (isEOF) 396 serverSourceFilter->signalEndOfStream(lastDataRequestedFromServer); 451 397 else 452 { 453 lastDataReceivedFromServer = context->getCalendar()->getInitDate(); 454 wasDataAlreadyReceivedFromServer = true; 455 } 456 457 if (isEOF) 458 serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer); 459 else 460 serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data); 398 serverSourceFilter->streamDataFromServer(lastDataRequestedFromServer, data); 399 400 isReadDataRequestPending = false; 461 401 } 462 402 … … 681 621 void CField::solveAllReferenceEnabledField(bool doSending2Server) 682 622 { 683 CContext* context = CContext::getCurrent(); 684 solveOnlyReferenceEnabledField(doSending2Server); 623 int myRank; 624 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 625 626 CContext* context = CContext::getCurrent(); //printf("my_Rank = %d, CContext* context = CContext::getCurrent OK\n", myRank); 627 solveOnlyReferenceEnabledField(doSending2Server); //printf("my_Rank = %d, solveOnlyReferenceEnabledField(doSending2Server) OK\n", myRank); 685 628 686 629 if (!areAllReferenceSolved) … … 690 633 if (context->hasClient) 691 634 { 692 solveRefInheritance(true); 693 if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false); 635 solveRefInheritance(true); //printf("my_Rank = %d, solveRefInheritance(true) OK\n", myRank); 636 if (hasDirectFieldReference()) 637 { 638 getDirectFieldReference()->solveAllReferenceEnabledField(false); 639 //printf("my_Rank = %d, getDirectFieldReference()->solveAllReferenceEnabledField(false) OK\n", myRank); 640 } 694 641 } 695 642 else if (context->hasServer) 643 { 696 644 solveServerOperation(); 697 698 solveGridReference(); 699 } 700 701 solveGridDomainAxisRef(doSending2Server); 645 //printf("my_Rank = %d, solveServerOperation OK\n", myRank); 646 } 647 648 solveGridReference(); //printf("my_Rank = %d, solveGridReference OK\n", myRank); 649 } 650 651 solveGridDomainAxisRef(doSending2Server); //printf("my_Rank = %d, solveGridDomainAxisRef(doSending2Server) OK\n", myRank); 702 652 703 653 if (context->hasClient) 704 654 { 705 solveTransformedGrid(); 706 } 707 708 solveCheckMaskIndex(doSending2Server); 655 solveTransformedGrid(); //printf("my_Rank = %d, solveTransformedGrid OK\n", myRank); 656 } 657 658 solveCheckMaskIndex(doSending2Server); //printf("FIELD.CPP: my_Rank = %d, solveCheckMaskIndex(doSending2Server) OK\n", myRank); 709 659 } 710 660 … … 783 733 { 784 734 // Check if we have an expression to parse 785 if (hasExpression()) 786 { 787 boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 788 boost::shared_ptr<COutputPin> filter = expr->reduce(gc, *this); 789 790 // Check if a spatial transformation is needed 791 if (!field_ref.isEmpty()) 792 { 793 CGrid* gridRef = CField::get(field_ref)->grid; 794 795 if (grid && grid != gridRef && grid->hasTransform()) 796 { 797 bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 798 double defaultValue = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 799 std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, hasMissingValue, defaultValue); 800 801 filter->connectOutput(filters.first, 0); 802 filter = filters.second; 803 } 804 } 805 806 instantDataFilter = filter; 735 if (!content.empty()) 736 { 737 boost::scoped_ptr<IFilterExprNode> expr(parseExpr(content + '\0')); 738 instantDataFilter = expr->reduce(gc, *this); 807 739 } 808 740 // Check if we have a reference on another field … … 811 743 // Check if the data is to be read from a file 812 744 else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) 813 instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 814 freq_offset.isEmpty() ? NoneDu : freq_offset, 815 true)); 745 instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid, 746 freq_offset.isEmpty() ? NoneDu : freq_offset)); 816 747 else // The data might be passed from the model 817 { 818 bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 819 double defaultValue = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 820 instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 821 ignoreMissingValue, defaultValue)); } 748 instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid)); 822 749 } 823 750 … … 858 785 // Check if a spatial transformation is needed 859 786 if (grid && grid != fieldRef->grid && grid->hasTransform()) 860 { 861 bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 862 double defaultValue = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 863 filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue); 864 } 787 { 788 double defaultValue = 0.0; 789 if (!default_value.isEmpty()) defaultValue = this->default_value; 790 filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, defaultValue); 791 } 792 865 793 else 866 794 filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc)); … … 882 810 boost::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc) 883 811 { 884 if (instantDataFilter || !hasExpression())812 if (instantDataFilter || content.empty()) 885 813 ERROR("COutputPin* CField::getSelfReference(CGarbageCollector& gc)", 886 814 "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); … … 891 819 { 892 820 if (!serverSourceFilter) 893 serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 894 freq_offset.isEmpty() ? NoneDu : freq_offset, 895 true)); 821 serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid, 822 freq_offset.isEmpty() ? NoneDu : freq_offset)); 896 823 897 824 selfReferenceFilter = serverSourceFilter; 898 825 } 899 826 else if (!field_ref.isEmpty()) 900 { 901 CField* fieldRef = CField::get(field_ref); 902 fieldRef->buildFilterGraph(gc, false); 903 selfReferenceFilter = fieldRef->getInstantDataFilter(); 904 } 827 selfReferenceFilter = getFieldReference(gc); 905 828 else 906 829 { 907 830 if (!clientSourceFilter) 908 { 909 bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 910 double defaultValue = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 911 clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 912 ignoreMissingValue, defaultValue)); 913 } 831 clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid)); 914 832 915 833 selfReferenceFilter = clientSourceFilter; … … 945 863 946 864 const bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 947 865 948 866 boost::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 949 867 CContext::getCurrent()->getCalendar()->getInitDate(), … … 957 875 return it->second; 958 876 } 959 960 /*!961 * Returns the temporal filter corresponding to the field's temporal operation962 * for the specified operation frequency.963 *964 * \param gc the garbage collector to use965 * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed966 * \return the output pin corresponding to the requested temporal filter967 */968 969 boost::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)970 {971 if (instantDataFilter || !hasExpression())972 ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)",973 "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");974 975 if (!selfReferenceFilter) getSelfReference(gc) ;976 977 if (serverSourceFilter || clientSourceFilter)978 {979 if (operation.isEmpty())980 ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",981 << "An operation must be defined for field \"" << getId() << "\".");982 983 if (freq_op.isEmpty()) freq_op.setValue(TimeStep);984 if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu);985 986 const bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);987 988 boost::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,989 CContext::getCurrent()->getCalendar()->getInitDate(),990 freq_op, freq_offset, outFreq,991 ignoreMissingValue, ignoreMissingValue ? default_value : 0.0));992 selfReferenceFilter->connectOutput(temporalFilter, 0);993 return temporalFilter ;994 }995 else if (!field_ref.isEmpty())996 {997 CField* fieldRef = CField::get(field_ref);998 fieldRef->buildFilterGraph(gc, false);999 return fieldRef->getTemporalDataFilter(gc, outFreq) ;1000 }1001 }1002 877 1003 878 //---------------------------------------------------------------- … … 1153 1028 else if (grid && grid->hasTransform() && !grid->isTransformed()) 1154 1029 { 1155 // Temporarily deactivate the self-transformation of grid 1156 //grid->transformGrid(grid); 1030 grid->transformGrid(grid); 1157 1031 } 1158 1032 } … … 1430 1304 } 1431 1305 1432 /*!1433 * Returns string arithmetic expression associated to the field.1434 * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string.1435 */1436 const string& CField::getExpression(void)1437 {1438 if (!expr.isEmpty() && content.empty())1439 {1440 content = expr;1441 expr.reset();1442 }1443 1444 return content;1445 }1446 1447 bool CField::hasExpression(void) const1448 {1449 return (!expr.isEmpty() || !content.empty());1450 }1451 1452 1306 DEFINE_REF_FUNC(Field,field) 1453 1307 } // namespace xios -
XIOS/dev/branch_yushan/src/node/field.hpp
r1017 r1037 124 124 boost::shared_ptr<COutputPin> getSelfReference(CGarbageCollector& gc); 125 125 boost::shared_ptr<COutputPin> getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq); 126 boost::shared_ptr<COutputPin> getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq);127 126 128 127 // virtual void fromBinary(StdIStream& is); … … 143 142 void recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers); 144 143 void writeField(void); 145 bool sendReadDataRequest(const CDate& tsDataRequested);144 void sendReadDataRequest(void); 146 145 bool sendReadDataRequestIfNeeded(void); 147 146 static void recvReadDataRequest(CEventServer& event); … … 179 178 const std::vector<StdString>& getRefDomainAxisIds(); 180 179 181 const string& getExpression(void);182 bool hasExpression(void) const;183 184 180 public: 185 181 /// Propriétés privées /// … … 195 191 bool isEOF; 196 192 CDate lastlast_Write_srv, last_Write_srv, last_operation_srv; 197 CDate lastDataRequestedFromServer, lastDataReceivedFromServer; 198 bool wasDataAlreadyReceivedFromServer; 193 CDate lastDataRequestedFromServer; 199 194 200 195 map<int,boost::shared_ptr<func::CFunctor> > foperation_srv; … … 206 201 bool isReferenceSolved; 207 202 std::vector<StdString> domAxisScalarIds_; 203 bool isReadDataRequestPending; 208 204 bool useCompressedOutput; 209 210 // Two variable to identify the time_counter meta data written in file, which has no time_counter211 bool hasTimeInstant;212 bool hasTimeCentered;213 205 214 206 DECLARE_REF_FUNC(Field,field) -
XIOS/dev/branch_yushan/src/node/field_impl.hpp
r1007 r1037 19 19 { 20 20 if (clientSourceFilter) 21 { 21 22 clientSourceFilter->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 22 else if (instantDataFilter) 23 } 24 else if (!field_ref.isEmpty() || !content.empty()) 23 25 ERROR("void CField::setData(const CArray<double, N>& _data)", 24 26 << "Impossible to receive data from the model for a field [ id = " << getId() << " ] with a reference or an arithmetic operation."); -
XIOS/dev/branch_yushan/src/node/file.cpp
r1013 r1037 17 17 #include "mpi.hpp" 18 18 19 19 20 namespace xios { 20 21 … … 29 30 setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); 30 31 } 32 33 31 34 32 35 CFile::CFile(const StdString & id) … … 38 41 setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); 39 42 } 43 40 44 41 45 CFile::~CFile(void) … … 235 239 const int recordOffset = record_offset.isEmpty() ? 0 : record_offset; 236 240 237 // set<CAxis*> setAxis; 238 // set<CDomain*> setDomains; 239 set<StdString> setAxis; 240 set<StdString> setDomains; 241 241 set<CAxis*> setAxis; 242 set<CDomain*> setDomains; 243 242 244 std::vector<CField*>::iterator it, end = this->enabledFields.end(); 243 245 for (it = this->enabledFields.begin(); it != end; it++) … … 247 249 std::vector<CAxis*> vecAxis = field->grid->getAxis(); 248 250 for (size_t i = 0; i < vecAxis.size(); ++i) 249 setAxis.insert(vecAxis[i]->getAxisOutputName()); 250 // setAxis.insert(vecAxis[i]); 251 setAxis.insert(vecAxis[i]); 251 252 std::vector<CDomain*> vecDomains = field->grid->getDomains(); 252 253 for (size_t i = 0; i < vecDomains.size(); ++i) 253 setDomains.insert(vecDomains[i]->getDomainOutputName()); 254 // setDomains.insert(vecDomains[i]); 254 setDomains.insert(vecDomains[i]); 255 255 256 256 field->resetNStep(recordOffset); … … 264 264 if (allDomainEmpty) MPI_Comm_free(&fileComm); 265 265 266 //if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered);266 if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 267 267 if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; 268 268 } … … 375 375 if (pos2!=std::string::npos) 376 376 { 377 middlePart=filename.substr(pos1,pos2-pos1) ; 377 middlePart=filename.substr(pos1,pos2-pos1) ; 378 cout<<pos2<<endl ; 378 379 pos2+=strEndDate.size() ; 379 380 lastPart=filename.substr(pos2,filename.size()-pos2) ; … … 580 581 this->data_in->closeFile(); 581 582 } 583 582 584 if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm); 585 583 586 } 584 587 //---------------------------------------------------------------- … … 715 718 { 716 719 int size = this->enabledFields.size(); 720 717 721 for (int i = 0; i < size; ++i) 718 722 { … … 745 749 int size = this->enabledFields.size(); 746 750 for (int i = 0; i < size; ++i) 747 this->enabledFields[i]->sendReadDataRequest( CContext::getCurrent()->getCalendar()->getCurrentDate());751 this->enabledFields[i]->sendReadDataRequest(); 748 752 } 749 753 -
XIOS/dev/branch_yushan/src/node/file.hpp
r957 r1037 12 12 #include "attribute_enum_impl.hpp" 13 13 #include "mpi.hpp" 14 #ifdef _usingEP 15 #include "ep_declaration.hpp" 16 #endif 14 17 15 18 namespace xios { -
XIOS/dev/branch_yushan/src/node/grid.cpp
r1008 r1037 166 166 void CGrid::checkAttributesAfterTransformation() 167 167 { 168 setAxisList(); 169 std::vector<CAxis*> axisListP = this->getAxis(); 168 int myRank; 169 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 170 171 setAxisList(); //printf("myRank = %d, setAxisList OK\n", myRank); 172 std::vector<CAxis*> axisListP = this->getAxis(); //printf("myRank = %d, this->getAxis OK\n", myRank); 170 173 if (!axisListP.empty()) 171 174 { 172 175 int idx = 0; 173 176 axisPositionInGrid_.resize(0); 177 174 178 for (int i = 0; i < axis_domain_order.numElements(); ++i) 175 179 { … … 179 183 axisPositionInGrid_.push_back(idx); 180 184 ++idx; 185 //printf("myRank = %d, axisPositionInGrid_.push_back OK\n", myRank); 181 186 } 182 187 else if (2 == elementDimension) idx += 2; … … 186 191 { 187 192 axisListP[i]->checkAttributesOnClientAfterTransformation(globalDim_,axisPositionInGrid_[i]); 188 } 189 } 190 191 setDomainList(); 192 std::vector<CDomain*> domListP = this->getDomains(); 193 //printf("myRank = %d, axisListP[%d/%d]->checkAttributesOnClientAfterTransformation OK\n", myRank, i, axisListP.size()); 194 } 195 } 196 197 setDomainList(); //printf("myRank = %d, setDomainList OK\n", myRank); 198 std::vector<CDomain*> domListP = this->getDomains(); //printf("myRank = %d, this->getDomains OK\n", myRank); 193 199 if (!domListP.empty()) 194 200 { 195 201 for (int i = 0; i < domListP.size(); ++i) 196 202 { 203 //printf("myRank = %d, start domListP[%d]->checkAttributesOnClientAfterTransformation\n", myRank, i); 197 204 domListP[i]->checkAttributesOnClientAfterTransformation(); 205 //printf("myRank = %d, domListP[%d]->checkAttributesOnClientAfterTransformation OK\n", myRank, i); 198 206 } 199 207 } … … 272 280 void CGrid::checkMaskIndex(bool doSendingIndex) 273 281 { 274 CContext* context = CContext::getCurrent(); 282 int myRank; 283 MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 284 285 CContext* context = CContext::getCurrent(); 275 286 CContextClient* client=context->client; 276 287 … … 278 289 { 279 290 if (context->hasClient) 280 if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; } 291 if (this->isChecked && doSendingIndex && !isIndexSent) 292 { 293 sendIndexScalarGrid(); 294 this->isIndexSent = true; 295 } 281 296 282 297 if (this->isChecked) return; 283 284 298 if (context->hasClient) 285 299 { … … 287 301 } 288 302 289 if (!(this->hasTransform() && !this->isTransformed())) 290 this->isChecked = true; 303 this->isChecked = true; 291 304 return; 292 305 } 293 306 294 307 if (context->hasClient) 295 if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; } 308 if (this->isChecked && doSendingIndex && !isIndexSent) 309 { 310 sendIndex(); 311 this->isIndexSent = true; 312 } 296 313 297 314 if (this->isChecked) return; … … 299 316 if (context->hasClient) 300 317 { 301 this->checkAttributesAfterTransformation(); 302 this->checkMask(); 303 this->computeIndex(); 318 this->checkAttributesAfterTransformation(); 319 this->checkMask(); 320 this->computeIndex(); 304 321 } 305 306 if (!(this->hasTransform() && !this->isTransformed())) 307 this->isChecked = true; 308 309 if (!(this->hasTransform() && (!this->isGenerated()))) 310 this->isChecked = true; 322 this->isChecked = true; 311 323 } 312 324 … … 1051 1063 int rank = *itRank; 1052 1064 int nb = 1; 1053 storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 1065 storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 1054 1066 listOutIndex.push_back(CArray<size_t,1>(nb)); 1055 1067 … … 1063 1075 } 1064 1076 1065 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));1066 1077 listMsg.push_back(CMessage()); 1067 1078 listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); … … 1072 1083 } 1073 1084 else 1074 {1075 const std::list<int>& ranks = client->getRanksServerNotLeader();1076 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1077 {1078 int rank = *itRank;1079 int nb = 1;1080 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));1081 CArray<int, 1>& outLocalIndexToServer = storeIndex_fromSrv[rank];1082 for (int k = 0; k < nb; ++k)1083 {1084 outLocalIndexToServer(k) = 0;1085 }1086 }1087 1085 client->sendEvent(event); 1088 }1089 1086 } 1090 1087 … … 1114 1111 outLocalIndexToServer(idx) = itIndex->second; 1115 1112 } 1116 1113 1114 //int nbClient = client->clientSize; // This stupid variable signals the servers the number of client connect to them 1117 1115 const std::list<int>& ranks = client->getRanksServerLeader(); 1118 1116 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1119 1117 { 1120 1118 storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1121 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));1122 1119 listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 1123 1120 … … 1129 1126 client->sendEvent(event); 1130 1127 } 1131 else 1132 { 1133 int indexSize = globalLocalIndexSendToServer.size(); 1134 CArray<int,1> outLocalIndexToServer(indexSize); 1135 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 1136 { 1137 outLocalIndexToServer(idx) = itIndex->second; 1138 } 1139 1140 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1141 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1142 { 1143 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1144 } 1128 else 1145 1129 client->sendEvent(event); 1146 }1147 1130 } 1148 1131 else … … 1177 1160 nb = globalIndexTmp[rank].size(); 1178 1161 1179 storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb))); 1162 storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb))); 1180 1163 listOutIndex.push_back(CArray<size_t,1>(nb)); 1181 1164 … … 1189 1172 } 1190 1173 1191 storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));1192 1174 listMsg.push_back(CMessage()); 1193 1175 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); -
XIOS/dev/branch_yushan/src/node/grid.hpp
r988 r1037 221 221 222 222 map<int, CArray<int, 1> > storeIndex_toSrv; 223 map<int, CArray<int, 1> > storeIndex_fromSrv;224 223 map<int,int> nbSenders; 225 224 -
XIOS/dev/branch_yushan/src/node/interpolate_domain.cpp
r1014 r1037 48 48 } 49 49 50 if (this->mode.isEmpty()) this->mode.setValue(mode_attr::compute); 51 if (this->write_weight.isEmpty()) this->write_weight.setValue(false); 50 StdString weightFile = "interpolation_weights_" + domainSrc->getDomainOutputName(); 52 51 53 StdString weightFile; 54 switch (this->mode) 55 { 56 case mode_attr::read: 57 if (this->weight_filename.isEmpty()) 58 { 59 if (!this->write_weight) 52 if (!this->mode.isEmpty()) 53 { 54 if (mode_attr::read == this->mode) 55 { 56 if (this->file.isEmpty()) 57 { 60 58 ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 61 59 << "Read mode is activated but there is no file specified." << std::endl 62 60 << "Please define a correct file containing interpolation weights with option 'file'. "); 63 } 64 else 65 { 66 weightFile = this->weight_filename; 67 ifstream f(weightFile.c_str()); 68 if (!f.good()) 69 ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 70 << "Read mode is activated but file " << weightFile << " doesn't exist." << std::endl 71 << "Please check this file "); 72 } 73 break; 74 case mode_attr::compute: 75 break; 76 case mode_attr::read_or_compute: 77 if (!this->weight_filename.isEmpty() && !this->write_weight) 78 { 79 weightFile = this->weight_filename; 80 ifstream f(weightFile.c_str()); 81 if (!f.good()) 82 ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 83 << "read_or_compute mode is activated but file " << weightFile << " doesn't exist." << std::endl 84 << "Please check this file "); 85 } 86 break; 87 default: 88 break; 61 } 62 else 63 { 64 weightFile = this->file; 65 ifstream f(weightFile.c_str()); 66 if (!f.good()) 67 ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 68 << "Read mode is activated but file " << weightFile << " doesn't exist." << std::endl 69 << "Please check this file "); 70 } 71 } 72 else 73 { 74 if (file.isEmpty()) 75 this->file.setValue(weightFile); 76 } 77 } 78 else 79 { 80 if (!file.isEmpty()) // set mode read 81 { 82 weightFile = this->file; 83 ifstream f(weightFile.c_str()); 84 if (!f.good()) // file doesn't exist 85 this->mode.setValue(mode_attr::write); 86 else 87 this->mode.setValue(mode_attr::read); 88 } 89 else // only calculate weights() Mode set write but there is no file) 90 { 91 this->mode.setValue(mode_attr::write); 92 } 89 93 } 90 94 -
XIOS/dev/branch_yushan/src/node/interpolate_domain.hpp
r1004 r1037 50 50 virtual ~CInterpolateDomain(void); 51 51 52 virtual void checkValid(CDomain* domainSource);52 virtual void checkValid(CDomain* axisDest); 53 53 54 54 /// Accesseurs statiques /// -
XIOS/dev/branch_yushan/src/node/mesh.cpp
r1002 r1037 11 11 /// ////////////////////// Définitions ////////////////////// /// 12 12 13 CMesh::CMesh(void) : nbNodesGlo (0), nbEdgesGlo(0)14 , node_start (0), node_count(0)15 , edge_start (0), edge_count(0)16 , nbFaces_ (0), nbNodes_(0), nbEdges_(0)17 , nodesAreWritten (false), edgesAreWritten(false), facesAreWritten(false)13 CMesh::CMesh(void) : nbNodesGlo{0}, nbEdgesGlo{0} 14 , node_start{0}, node_count{0} 15 , edge_start{0}, edge_count{0} 16 , nbFaces_{0}, nbNodes_{0}, nbEdges_{0} 17 , nodesAreWritten{false}, edgesAreWritten{false}, facesAreWritten{false} 18 18 , node_lon(), node_lat() 19 19 , edge_lon(), edge_lat(), edge_nodes() 20 20 , face_lon(), face_lat() 21 21 , face_nodes() 22 , pNodeGlobalIndex (NULL), pEdgeGlobalIndex(NULL)22 , pNodeGlobalIndex{NULL}, pEdgeGlobalIndex{NULL} 23 23 { 24 24 } … … 91 91 seed ^= sizetHash(first) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 92 92 } 93 return seed ; 94 } 95 96 ///---------------------------------------------------------------- 97 /*! 98 * \fn size_t generateEdgeIndex(size_t first, size_t second, int rank) 99 * Generates an edge index. 100 * If the same edge is generated by two processes, each process will have its own edge index. 101 * \param [in] first Edge node. 102 * \param [in] second Edge node. 103 * \param [in] rank MPI process rank. 104 */ 105 size_t generateEdgeIndex(size_t first, size_t second, int rank) 106 { 107 size_t seed = rank ; 108 if (first < second) 109 { 110 seed = hashPair(seed, first); 111 seed = hashPair(seed, second); 112 } 113 else 114 { 115 seed = hashPair(seed, second); 116 seed = hashPair(seed, first); 117 } 118 93 119 return seed ; 94 120 } … … 115 141 return seed ; 116 142 } 117 118 ///----------------------------------------------------------------119 /*!120 * \fn size_t generateNodeIndex(vector<size_t>& valList)121 * Generates a node index unique for all processes.122 * \param [in] valList Vector storing four node hashes.123 */124 size_t generateNodeIndex(vector<size_t>& valList)125 {126 // Sort is needed to avoid problems for nodes with lon = 0 generated by faces in east and west semisphere127 vector<size_t> vec = valList;128 sort (vec.begin(), vec.end());129 size_t seed = vec[0] ;130 int it = 1;131 for(; it != vec.size(); ++it)132 {133 seed = hashPair(seed, vec[it]);134 }135 return seed ;136 }137 138 143 139 144 ///---------------------------------------------------------------- … … 595 600 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2Idx; 596 601 CArray<size_t,1> nodeHashList(nbEdges_*nvertex*4); 597 int nbHash = 0;598 602 for (int ne = 0; ne < nbEdges_; ++ne) 599 603 { … … 605 609 if (nodeHash2Idx[hashValues[nh]].size() == 0) 606 610 { 607 nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues ));611 nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues, mpiRank)); 608 612 nodeHash2Idx[hashValues[nh]].push_back(mpiRank); 609 nodeHashList(nbHash) = hashValues[nh];610 ++nbHash;611 613 } 612 }613 }614 }615 nodeHashList.resizeAndPreserve(nbHash);614 nodeHashList((ne*nvertex + nv)*4 + nh) = hashValues[nh]; 615 } 616 } 617 } 616 618 617 619 // (2.2) Generating global node indexes 618 // The ownership criterion: priority of the process ofsmaller index620 // The ownership criterion: priority of the process holding the smaller index 619 621 // Maps generated in this step are: 620 // Maps generated in this step are: 621 // nodeHash2Info = <hash, [[idx, rankMin], [idx, rank1], [idx, rank3]..]> 622 // nodeIdx2Idx = <idx, <rankOwner, idx>> 623 624 CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 625 dhtNodeHash.computeIndexInfoMapping(nodeHashList); 626 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 627 628 629 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2Idx; 630 CArray<size_t,1> nodeIdxList(nbEdges_*nvertex*4); 631 size_t nIdx = 0; 632 633 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 634 { 635 size_t rankMin = (it->second)[1]; 636 size_t idx = (it->second)[0]; 637 for (int i = 2; i < (it->second).size();) 638 { 639 if ( (it->second)[i+1] < rankMin) 640 { 641 idx = (it->second)[i]; 642 rankMin = (it->second)[i+1]; 643 (it->second)[i+1] = (it->second)[i-1]; 644 } 645 i += 2; 646 } 647 if (nodeIdx2Idx.count(idx) == 0) 648 { 649 if (mpiRank == rankMin) 650 { 651 nodeIdx2Idx[idx].push_back(rankMin); 652 nodeIdx2Idx[idx].push_back(idx); 653 } 654 nodeIdxList(nIdx) = idx; 655 ++nIdx; 656 } 657 } 658 nodeIdxList.resizeAndPreserve(nIdx); 659 660 // CDHTAutoIndexing will not give consistent node numbering for varying number of procs. => 661 // Solution: global node indexing by hand. 662 // Maps modified in this step: 663 // nodeIdx2Idx = <idx, idxGlo> 664 int nodeCount = nodeIdx2Idx.size(); 665 int nodeStart, nbNodes; 666 MPI_Scan(&nodeCount, &nodeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 667 int nNodes = nodeStart; 668 MPI_Bcast(&nNodes, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 669 nbNodesGlo = nNodes; 670 671 nodeStart -= nodeCount; 672 node_start = nodeStart; 673 node_count = nodeCount; 674 CClientClientDHTSizet::Index2VectorInfoTypeMap dummyMap; // just a dummy map used to ensure that each node is numbered only once 675 size_t count = 0; 676 677 for (int ne = 0; ne < nbEdges_; ++ne) 678 { 679 for (int nv = 0; nv < nvertex; ++nv) 680 { 681 vector<size_t> hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 682 size_t nodeIdx = generateNodeIndex(hashValues); 683 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeIdx2Idx.find(nodeIdx); 684 if (it != nodeIdx2Idx.end()) 685 { 686 if (dummyMap.count(nodeIdx) == 0) 687 { 688 dummyMap[nodeIdx].push_back(nodeIdx); 689 (it->second)[1] = node_start + count; 690 ++count; 691 } 692 } 693 } 694 } 695 696 CClientClientDHTSizet dhtNodeIdx(nodeIdx2Idx, comm); 697 dhtNodeIdx.computeIndexInfoMapping(nodeIdxList); 698 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdx2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 622 // nodeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 623 // nodeIdx2IdxMin = <idx, idxMin> 624 // nodeIdx2IdxGlo = <idxMin, idxMin> 625 626 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 627 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 628 CArray<size_t,1> nodeIdxMinList(nbEdges_*nvertex); 629 630 CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 631 dhtNodeHash.computeIndexInfoMapping(nodeHashList); 632 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 633 size_t iIdxMin = 0; 634 635 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 636 { 637 size_t idx = (it->second)[0]; 638 size_t idxMin = (it->second)[0]; 639 for (int i = 2; i < (it->second).size();) 640 { 641 if (mpiRank == (it->second)[i+1]) 642 { 643 idx = (it->second)[i]; 644 } 645 if ((it->second)[i] < idxMin) 646 { 647 idxMin = (it->second)[i]; 648 (it->second)[i] = (it->second)[i-2]; 649 } 650 i += 2; 651 } 652 (it->second)[0] = idxMin; 653 if (nodeIdx2IdxMin.count(idx) == 0) 654 { 655 nodeIdx2IdxMin[idx].push_back(idxMin); 656 if (idx == idxMin) 657 nodeIdx2IdxGlo[idxMin].push_back(idxMin); 658 nodeIdxMinList(iIdxMin) = idxMin; 659 ++iIdxMin; 660 } 661 } 662 nodeIdxMinList.resizeAndPreserve(iIdxMin); 663 CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 664 CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 665 dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 666 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 667 // nodeIdx2IdxGlo holds global indexes only for nodes owned by a process 668 // nodeIdxMin2IdxGlo holds global indexes for all nodes generated by a process 699 669 700 670 // (2.3) Saving variables: node_lon, node_lat, edge_nodes 701 671 // Creating map nodeHash2IdxGlo <hash, idxGlo> 702 672 // Creating map edgeHash2IdxGlo <hash, idxGlo> 703 //nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal();704 //node_count = dhtNodeIdxGlo.getIndexCount();705 //node_start = dhtNodeIdxGlo.getIndexStart();673 nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 674 node_count = dhtNodeIdxGlo.getIndexCount(); 675 node_start = dhtNodeIdxGlo.getIndexStart(); 706 676 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2IdxGlo; 707 677 node_lon.resize(node_count); … … 715 685 { 716 686 hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 717 size_t myIdx = generateNodeIndex(hashValues); 718 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = nodeIdx2IdxGlo.find(myIdx); 719 idxGlo = (itIdx->second)[1]; 720 721 if (mpiRank == (itIdx->second)[0]) 722 { 687 size_t myIdx = generateNodeIndex(hashValues, mpiRank); 688 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = nodeIdx2IdxMin.find(myIdx); 689 size_t ownerIdx = (itIdx->second)[0]; 690 691 if (myIdx == ownerIdx) 692 { 693 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdx2IdxGlo.find(myIdx); 694 idxGlo = (itIdxGlo->second)[0]; 723 695 // node_lon(idxGlo - node_start) = (bounds_lon(nv, ne) == 360.) ? (0.) : (bounds_lon(nv, ne)); 724 696 node_lon(idxGlo - node_start) = bounds_lon(nv, ne); 725 697 node_lat(idxGlo - node_start) = bounds_lat(nv, ne); 726 698 } 699 else 700 { 701 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdxMin2IdxGlo.find(ownerIdx); 702 idxGlo = (itIdxGlo->second)[0]; 703 } 704 727 705 edge_nodes(nv,ne) = idxGlo; 728 706 for (int nh = 0; nh < 4; ++nh) … … 815 793 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Rank; 816 794 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 817 CArray<size_t,1> edgeIdx List(nbFaces_*nvertex);795 CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 818 796 size_t iIdx = 0; 819 797 … … 846 824 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 847 825 { 848 edgeIdx List(iIdx) = edgeIdxGlo;826 edgeIdxGloList(iIdx) = edgeIdxGlo; 849 827 ++iIdx; 850 828 } 851 829 edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 830 edgeHash2Rank[edgeHash].push_back(itEdgeHash->first); 852 831 edgeHash2Rank[edgeHash].push_back(mpiRank); 853 edgeHash2Rank[edgeHash].push_back(itEdgeHash->second[0]);854 832 } 855 833 else … … 859 837 } 860 838 } 861 edgeIdx List.resizeAndPreserve(iIdx);839 edgeIdxGloList.resizeAndPreserve(iIdx); 862 840 863 841 // (1.3) Saving remaining variables edge_faces and face_faces … … 868 846 dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 869 847 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 870 871 // edgeHash2Info = <edgeHash, < rank1, idxGlo, rank2, idxGlo>> 872 int edgeCount = 0; 848 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHashMin2IdxGlo; 849 850 // edgeHash2Info = <edgeHash, <idxGlo, rank1, idxGlo, rank2>> 851 // edgeHashMin2IdxGlo = <edgeHashMin, idxGlo> 873 852 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 874 853 { 875 854 vector <size_t> edgeInfo = it->second; 876 if (edgeInfo[0] == mpiRank) 877 { 878 ++edgeCount; 879 } 880 } 881 882 int edgeStart, nbEdges; 883 MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 884 int nEdges = edgeStart; 885 MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 886 nbEdgesGlo = nEdges; 887 888 // edges to be splitted equally between procs 889 if ( (nbEdgesGlo % mpiSize) == 0) 890 { 891 edge_count = nbEdgesGlo/mpiSize; 892 edge_start = mpiRank*edge_count; 893 } 894 else 895 { 896 if (mpiRank == (mpiSize - 1) ) 897 { 898 edge_count = nbEdgesGlo/mpiSize; 899 edge_start = mpiRank*(nbEdgesGlo/mpiSize + 1); 900 } 901 else 902 { 903 edge_count = nbEdgesGlo/mpiSize + 1; 904 edge_start = mpiRank*edge_count; 905 } 906 } 907 CArray<size_t,1> edgeIdxGloList(edge_count); 908 for (int i = 0; i < edge_count; ++i) 909 { 910 edgeIdxGloList(i) = i + edge_start; 911 } 912 913 CClientClientDHTSizet dhtEdgeIdxGlo2Face (edgeIdxGlo2Face, comm); 855 if (edgeInfo.size() == 4) // two processes generate the same edge 856 if (edgeInfo[1] > edgeInfo[3]) 857 edgeInfo[1] = edgeInfo[3]; 858 if (edgeInfo[1] == mpiRank) 859 edgeHashMin2IdxGlo[it->first].push_back(edgeInfo[0]); 860 } 861 862 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeHashMin2IdxGlo, comm); 863 edge_count = dhtEdgeIdxGlo.getIndexCount(); 864 edge_start = dhtEdgeIdxGlo.getIndexStart(); 865 866 edge_faces.resize(2, edge_count); 867 face_faces.resize(nvertex, nbFaces_); 868 914 869 CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 915 dhtEdgeIdxGlo2Face.computeIndexInfoMapping(edgeIdxGloList); 916 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdgeIdxGlo2Face.getInfoIndexMap(); 917 dhtEdge2Face.computeIndexInfoMapping(edgeIdxList); 918 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 919 920 921 edge_faces.resize(2, edge_count); 922 for (int i = 0; i < edge_count; ++i) 923 { 924 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdxGlo2FaceIdx.find(i + edge_start); 925 int indexGlo = it->first; 926 vector<size_t> faces = it->second; 927 int face1 = faces[0]; 928 edge_faces(0, indexGlo - edge_start) = face1; 929 if (faces.size() == 2) 930 { 931 int face2 = faces[1]; 932 edge_faces(1, indexGlo - edge_start) = face2; 933 } 934 else 935 { 936 edge_faces(1, indexGlo - edge_start) = -999; 937 } 938 } 939 940 size_t tmp; 941 vector<size_t> tmpVec; 942 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2FaceIdx.begin(); it != edgeIdx2FaceIdx.end(); it++) 943 { 944 tmp = it->first; 945 tmpVec = it->second; 946 tmp++; 947 } 948 949 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2, itIndex; 950 face_faces.resize(nvertex, nbFaces_); 870 dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 871 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 872 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2; 873 951 874 for (int nf = 0; nf < nbFaces_; ++nf) 952 875 { … … 973 896 size_t faceIdxGlo = nbFacesAccum + nf; 974 897 size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 975 itEdgeHash = edgeHash2Info.find(edgeHash); 976 int edgeIdxGlo = (itEdgeHash->second)[1]; 977 978 if ( (itEdgeHash->second)[0] == mpiRank) 898 itEdgeHash = edgeHash2IdxGlo.find(edgeHash); 899 if (itEdgeHash != edgeHashMin2IdxGlo.end()) 979 900 { 980 itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 901 int edgeIdxGlo = itEdgeHash->second[0]; 902 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 981 903 int face1 = itFace1->second[0]; 982 904 if (itFace1->second.size() == 1) 983 905 { 906 edge_faces(0, edgeIdxGlo - edge_start) = face1; 907 edge_faces(1, edgeIdxGlo - edge_start) = -999; 984 908 face_faces(nv1, nf) = 999999; 985 909 } … … 987 911 { 988 912 int face2 = itFace1->second[1]; 913 edge_faces(0, edgeIdxGlo - edge_start) = face1; 914 edge_faces(1, edgeIdxGlo - edge_start) = face2; 989 915 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 990 916 } … … 992 918 else 993 919 { 994 itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 920 itEdgeHash = edgeHashMin2IdxGlo.find(edgeHash); 921 size_t edgeIdxGlo = itEdgeHash->second[0]; 922 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 995 923 int face1 = itFace1->second[0]; 996 924 int face2 = itFace1->second[1]; … … 1029 957 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 1030 958 CArray<size_t,1> edgeHashList(nbFaces_*nvertex); 1031 int nEdgeHash = 0;1032 959 for (int nf = 0; nf < nbFaces_; ++nf) 1033 960 { … … 1051 978 face_nodes(nv1,nf) = it1->second[0]; 1052 979 size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 1053 if (edgeHash2Idx.count(edgeHash) == 0) 1054 { 1055 edgeHash2Idx[edgeHash].push_back(edgeHash); 1056 edgeHash2Idx[edgeHash].push_back(mpiRank); 1057 edgeHashList(nEdgeHash) = edgeHash; 1058 ++nEdgeHash; 1059 } 1060 } 1061 } 1062 edgeHashList.resizeAndPreserve(nEdgeHash); 1063 1064 // (2.3) Generating global edge indexes 1065 // The ownership criterion: priority of the process with smaller rank 980 edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(it1->second[0], it2->second[0], mpiRank)); 981 edgeHash2Idx[edgeHash].push_back(mpiRank); 982 edgeHashList(nf*nvertex + nv1) = edgeHash; 983 } 984 } 985 986 // (2.2) Generating global edge indexes 987 // The ownership criterion: priority of the process holding the smaller index 1066 988 // Maps generated in this step are: 1067 // edgeIdx2Idx = = <idx, <rankOwner, idx>> 1068 // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>> 989 // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 990 // edgeIdx2IdxMin = = <idx, idxMin> 991 // edgeIdx2IdxGlo = <idxMin, idxGlo> 1069 992 1070 993 CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 1071 994 dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 1072 995 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 1073 // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 1074 1075 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 996 997 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 998 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 999 CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 1000 size_t iIdxMin = 0; 1076 1001 1077 1002 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 1078 1003 { 1079 size_t rankMin = (it->second)[1];1004 size_t idxMin = (it->second)[0]; 1080 1005 size_t idx = (it->second)[0]; 1081 1082 1006 for (int i = 2; i < (it->second).size();) 1083 1007 { 1084 if ((it->second)[i+1] < rankMin) 1085 { 1086 rankMin = (it->second)[i+1]; 1008 if (mpiRank == (it->second)[i+1]) 1009 { 1087 1010 idx = (it->second)[i]; 1088 (it->second)[i+1] = (it->second)[i-1]; 1011 } 1012 if ((it->second)[i] < idxMin) 1013 { 1014 idxMin = (it->second)[i]; 1015 (it->second)[i] = (it->second)[i-2]; 1089 1016 } 1090 1017 i += 2; 1091 1018 } 1092 if (edgeIdx2Idx.count(idx) == 0) 1093 { 1094 if (mpiRank == rankMin) 1095 { 1096 edgeIdx2Idx[idx].push_back(rankMin); 1097 edgeIdx2Idx[idx].push_back(idx); 1098 } 1099 } 1100 } 1101 1102 int edgeCount = edgeIdx2Idx.size(); 1103 int edgeStart, nbEdges; 1104 MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 1105 int nEdges = edgeStart; 1106 MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 1107 nbEdgesGlo = nEdges; 1108 1109 edgeStart -= edgeCount; 1110 edge_start = edgeStart; 1111 edge_count = edgeCount; 1112 CClientClientDHTSizet::Index2VectorInfoTypeMap dummyEdgeMap; 1113 int count = 0; 1019 (it->second)[0] = idxMin; 1020 if (edgeIdx2IdxMin.count(idx) == 0) 1021 { 1022 edgeIdx2IdxMin[idx].push_back(idxMin); 1023 if (idx == idxMin) 1024 edgeIdx2IdxGlo[idxMin].push_back(idxMin); 1025 edgeIdxMinList(iIdxMin) = idxMin; 1026 ++iIdxMin; 1027 } 1028 } 1029 edgeIdxMinList.resizeAndPreserve(iIdxMin); 1030 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 1031 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 1032 dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 1033 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 1034 // edgeIdx2IdxGlo holds global indexes only for edges owned by a process 1035 // edgeIdxMin2IdxGlo holds global indexes for all edges generated by a process 1036 1037 // (2.3) Saving variables: edge_lon, edge_lat, face_edges 1038 nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 1039 edge_count = dhtEdgeIdxGlo.getIndexCount(); 1040 edge_start = dhtEdgeIdxGlo.getIndexStart(); 1041 edge_lon.resize(edge_count); 1042 edge_lat.resize(edge_count); 1043 edge_nodes.resize(2, edge_count); 1044 face_edges.resize(nvertex, nbFaces_); 1045 1046 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 1047 CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 1048 size_t iIdx = 0; 1114 1049 1115 1050 for (int nf = 0; nf < nbFaces_; ++nf) … … 1133 1068 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 1134 1069 } 1135 size_t nodeIdxGlo1 = it1->second[0];1136 size_t nodeIdxGlo2 = it2->second[0];1137 1138 if (nodeIdxGlo1 != nodeIdxGlo2)1139 {1140 size_t edgeIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2);1141 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2Idx.find(edgeIdx);1142 if (it != edgeIdx2Idx.end())1143 {1144 if (dummyEdgeMap.count(edgeIdx) == 0)1145 {1146 dummyEdgeMap[edgeIdx].push_back(edgeIdx);1147 (it->second)[1] = edge_start + count;1148 ++count;1149 }1150 }1151 }1152 }1153 }1154 1155 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2Idx, comm);1156 dhtEdgeIdx.computeIndexInfoMapping(edgeHashList);1157 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2IdxGlo = dhtEdgeIdx.getInfoIndexMap();1158 1159 // (2.4) Saving variables: edge_lon, edge_lat, face_edges1160 edge_lon.resize(edge_count);1161 edge_lat.resize(edge_count);1162 edge_nodes.resize(2, edge_count);1163 face_edges.resize(nvertex, nbFaces_);1164 1165 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face;1166 CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex);1167 size_t iIdx = 0;1168 1169 for (int nf = 0; nf < nbFaces_; ++nf)1170 {1171 for (int nv1 = 0; nv1 < nvertex; ++nv1)1172 {1173 // Getting global indexes of edge's nodes1174 int nh1 = 0;1175 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation1176 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1));1177 while (it1 == nodeHash2IdxGlo.end())1178 {1179 ++nh1;1180 it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1));1181 }1182 int nh2 = 0;1183 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2));1184 while (it2 == nodeHash2IdxGlo.end())1185 {1186 ++nh2;1187 it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2));1188 }1189 1070 // Getting edge global index 1190 1071 size_t nodeIdxGlo1 = it1->second[0]; 1191 1072 size_t nodeIdxGlo2 = it2->second[0]; 1192 size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2);1073 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1193 1074 if (nodeIdxGlo1 != nodeIdxGlo2) 1194 1075 { 1195 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 1196 int edgeIdxGlo = (itIdx->second)[1]; 1076 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1077 size_t ownerIdx = (itIdx->second)[0]; 1078 int edgeIdxGlo = 0; 1197 1079 size_t faceIdxGlo = nbFacesAccum + nf; 1198 1080 1199 if (m piRank == (itIdx->second)[0])1081 if (myIdx == ownerIdx) 1200 1082 { 1083 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1084 edgeIdxGlo = (itIdxGlo->second)[0]; 1201 1085 double edgeLon; 1202 1086 double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); … … 1212 1096 edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 1213 1097 } 1098 else 1099 { 1100 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1101 edgeIdxGlo = (itIdxGlo->second)[0]; 1102 } 1214 1103 face_edges(nv1,nf) = edgeIdxGlo; 1215 1104 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) … … 1228 1117 edgeIdxGloList.resizeAndPreserve(iIdx); 1229 1118 1230 // (2. 5) Saving remaining variables edge_faces and face_faces1119 // (2.4) Saving remaining variables edge_faces and face_faces 1231 1120 edge_faces.resize(2, edge_count); 1232 1121 face_faces.resize(nvertex, nbFaces_); … … 1236 1125 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 1237 1126 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdxGlo1, itNodeIdxGlo2; 1238 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx;1239 1127 1240 1128 for (int nf = 0; nf < nbFaces_; ++nf) … … 1261 1149 size_t nodeIdxGlo2 = it2->second[0]; 1262 1150 1263 size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1264 itIdx = edgeIdx2IdxGlo.find(myIdx); 1151 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1152 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1153 size_t ownerIdx = (itIdx->second)[0]; 1265 1154 size_t faceIdxGlo = nbFacesAccum + nf; 1266 int edgeIdxGlo = (itIdx->second)[1]; 1267 1268 if (mpiRank == (itIdx->second)[0]) 1269 { 1155 1156 if (myIdx == ownerIdx) 1157 { 1158 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1159 int edgeIdxGlo = (itIdxGlo->second)[0]; 1270 1160 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1271 1161 int face1 = it1->second[0]; … … 1286 1176 else 1287 1177 { 1178 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1179 size_t edgeIdxGlo = (itIdxGlo->second)[0]; 1288 1180 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1289 1181 int face1 = it1->second[0]; … … 1308 1200 { 1309 1201 hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 1310 // size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 1311 size_t nodeIndex = generateNodeIndex(hashValues); 1202 size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 1312 1203 for (int nh = 0; nh < 4; ++nh) 1313 1204 { … … 1325 1216 1326 1217 // (3.2) Generating global node indexes 1327 // The ownership criterion: priority of the process with smaller rank. 1328 // With any other criterion it is not possible to have consistent node indexing for different number of procs. 1218 // The ownership criterion: priority of the process holding the smaller index 1329 1219 // Maps generated in this step are: 1330 // nodeHash2Info = <hash, [[idx, rankMin], [idx, rank1], [idx, rank3]..]> 1331 // nodeIdx2Idx = <idx, <rankOwner, idx>> 1220 // nodeHash2Info = <hash, [[idxMin, rankMin], [idx1, rank1], [idx3, rank3]..]> 1221 // nodeIdx2IdxMin = = <idx, idxMin> 1222 // nodeIdx2IdxGlo = <idxMin, idxGlo> 1332 1223 1333 1224 CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); … … 1335 1226 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 1336 1227 1337 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2Idx; 1338 CArray<size_t,1> nodeIdxList(nbFaces_*nvertex*4); 1339 size_t nIdx = 0; 1228 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 1229 CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 1230 CArray<size_t,1> nodeIdxMinList(nbFaces_*nvertex*4); 1231 size_t iIdxMin = 0; 1340 1232 1341 1233 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 1342 1234 { 1343 size_t rankMin = (it->second)[1];1235 size_t idxMin = (it->second)[0]; 1344 1236 size_t idx = (it->second)[0]; 1345 1237 for (int i = 2; i < (it->second).size();) 1346 1238 { 1347 if ( (it->second)[i+1] < rankMin)1239 if (mpiRank == (it->second)[i+1]) 1348 1240 { 1349 1241 idx = (it->second)[i]; 1350 rankMin = (it->second)[i+1]; 1351 (it->second)[i+1] = (it->second)[i-1]; 1242 } 1243 if ((it->second)[i] < idxMin) 1244 { 1245 idxMin = (it->second)[i]; 1246 (it->second)[i] = (it->second)[i-2]; 1352 1247 } 1353 1248 i += 2; 1354 1249 } 1355 if (nodeIdx2Idx.count(idx) == 0) 1356 { 1357 if (mpiRank == rankMin) 1358 { 1359 nodeIdx2Idx[idx].push_back(rankMin); 1360 nodeIdx2Idx[idx].push_back(idx); 1361 } 1362 nodeIdxList(nIdx) = idx; 1363 ++nIdx; 1364 } 1365 } 1366 1367 // CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2Idx, comm); 1368 // CDHTAutoIndexing will not give consistent node numbering for varying number of procs. => 1369 // Solution: global node indexing by hand. 1370 // Maps modified in this step: 1371 // nodeIdx2Idx = <idx, idxGlo> 1372 int nodeCount = nodeIdx2Idx.size(); 1373 int nodeStart, nbNodes; 1374 MPI_Scan(&nodeCount, &nodeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 1375 int nNodes = nodeStart; 1376 MPI_Bcast(&nNodes, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 1377 nbNodesGlo = nNodes; 1378 1379 nodeStart -= nodeCount; 1380 node_start = nodeStart; 1381 node_count = nodeCount; 1382 CClientClientDHTSizet::Index2VectorInfoTypeMap dummyMap; // just a dummy map used to ensure that each node is numbered only once 1383 size_t count = 0; 1384 1385 for (int nf = 0; nf < nbFaces_; ++nf) 1386 { 1387 for (int nv = 0; nv < nvertex; ++nv) 1388 { 1389 vector<size_t> hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 1390 size_t nodeIdx = generateNodeIndex(hashValues); 1391 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeIdx2Idx.find(nodeIdx); 1392 if (it != nodeIdx2Idx.end()) 1393 { 1394 if (dummyMap.count(nodeIdx) == 0) 1395 { 1396 dummyMap[nodeIdx].push_back(nodeIdx); 1397 (it->second)[1] = node_start + count; 1398 ++count; 1399 } 1400 } 1401 } 1402 } 1403 nodeIdxList.resizeAndPreserve(nIdx); 1404 CClientClientDHTSizet dhtNodeIdx(nodeIdx2Idx, comm); 1405 dhtNodeIdx.computeIndexInfoMapping(nodeIdxList); 1406 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdx2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 1250 (it->second)[0] = idxMin; 1251 if (nodeIdx2IdxMin.count(idx) == 0) 1252 { 1253 nodeIdx2IdxMin[idx].push_back(idxMin); 1254 if (idx == idxMin) 1255 nodeIdx2IdxGlo[idxMin].push_back(idxMin); 1256 nodeIdxMinList(iIdxMin) = idxMin; 1257 ++iIdxMin; 1258 } 1259 } 1260 1261 nodeIdxMinList.resizeAndPreserve(iIdxMin); 1262 CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 1263 CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 1264 dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 1265 CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 1407 1266 1408 1267 // (3.3) Saving node data: node_lon, node_lat, and face_nodes 1409 1268 // Generating edgeHash2Info = <hash, <idx, rank>> and edgeHashList 1410 //nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal();1411 //node_count = dhtNodeIdxGlo.getIndexCount();1412 //node_start = dhtNodeIdxGlo.getIndexStart();1269 nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 1270 node_count = dhtNodeIdxGlo.getIndexCount(); 1271 node_start = dhtNodeIdxGlo.getIndexStart(); 1413 1272 node_lon.resize(node_count); 1414 1273 node_lat.resize(node_count); … … 1427 1286 vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 1428 1287 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1429 size_t nodeIdx1 = generateNodeIndex(hashValues1);1430 size_t nodeIdx2 = generateNodeIndex(hashValues2);1431 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2Idx Glo.find(nodeIdx1);1432 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2Idx Glo.find(nodeIdx2);1433 size_t owner Rank= (itNodeIdx1->second)[0];1434 nodeIdxGlo1 = (itNodeIdx1->second)[1]; 1435 nodeIdxGlo2 = (itNodeIdx2->second)[1];1436 1437 if (mpiRank == ownerRank)1438 {1288 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1289 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1290 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxMin.find(myNodeIdx1); 1291 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxMin.find(myNodeIdx2); 1292 size_t ownerNodeIdx = (itNodeIdx1->second)[0]; 1293 1294 if (myNodeIdx1 == ownerNodeIdx) 1295 { 1296 itNodeIdxGlo1 = nodeIdx2IdxGlo.find(myNodeIdx1); 1297 nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1439 1298 node_lon(nodeIdxGlo1 - node_start) = bounds_lon(nv1, nf); 1440 1299 node_lat(nodeIdxGlo1 - node_start) = bounds_lat(nv1, nf); 1441 1300 } 1301 else 1302 { 1303 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find(ownerNodeIdx); 1304 nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1305 } 1306 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((itNodeIdx2->second)[0]); 1307 nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1442 1308 if (nodeIdxGlo1 != nodeIdxGlo2) 1443 1309 { 1444 1310 size_t edgeHash = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1445 edgeHash2Idx[edgeHash].push_back( edgeHash);1311 edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank)); 1446 1312 edgeHash2Idx[edgeHash].push_back(mpiRank); 1447 1313 edgeHashList(nEdgeHash) = edgeHash; … … 1455 1321 // (3.4) Generating global edge indexes 1456 1322 // Maps generated in this step are: 1457 // edgeIdx2Idx = = <idx, <rankOwner, idx>>1458 // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>>1323 // edgeIdx2IdxMin = = <idx, idxMin> 1324 // edgeIdx2IdxGlo = <idxMin, idxGlo> 1459 1325 1460 1326 CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); … … 1463 1329 // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 1464 1330 1465 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 1331 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 1332 CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 1333 CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 1334 iIdxMin = 0; 1466 1335 1467 1336 for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 1468 1337 { 1469 size_t rankMin = (it->second)[1];1338 size_t idxMin = (it->second)[0]; 1470 1339 size_t idx = (it->second)[0]; 1471 1340 1472 1341 for (int i = 2; i < (it->second).size();) 1473 1342 { 1474 if ((it->second)[i+1] < rankMin) 1475 { 1476 rankMin = (it->second)[i+1]; 1343 if (mpiRank == (it->second)[i+1]) 1344 { 1477 1345 idx = (it->second)[i]; 1478 (it->second)[i+1] = (it->second)[i-1]; 1346 } 1347 if ((it->second)[i] < idxMin) 1348 { 1349 idxMin = (it->second)[i]; 1350 (it->second)[i] = (it->second)[i-2]; 1479 1351 } 1480 1352 i += 2; 1481 1353 } 1482 if (edgeIdx2Idx.count(idx) == 0) 1483 { 1484 if (mpiRank == rankMin) 1485 { 1486 edgeIdx2Idx[idx].push_back(rankMin); 1487 edgeIdx2Idx[idx].push_back(idx); 1488 } 1489 } 1490 } 1491 1492 int edgeCount = edgeIdx2Idx.size(); 1493 int edgeStart, nbEdges; 1494 MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 1495 int nEdges = edgeStart; 1496 MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 1497 nbEdgesGlo = nEdges; 1498 1499 edgeStart -= edgeCount; 1500 edge_start = edgeStart; 1501 edge_count = edgeCount; 1502 CClientClientDHTSizet::Index2VectorInfoTypeMap dummyEdgeMap; 1503 count = 0; 1504 1505 for (int nf = 0; nf < nbFaces_; ++nf) 1506 { 1507 for (int nv1 = 0; nv1 < nvertex; ++nv1) 1508 { 1509 int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 1510 vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 1511 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1512 size_t nodeIdx1 = generateNodeIndex(hashValues1); 1513 size_t nodeIdx2 = generateNodeIndex(hashValues2); 1514 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxGlo.find(nodeIdx1); 1515 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxGlo.find(nodeIdx2); 1516 nodeIdxGlo1 = (itNodeIdx1->second)[1]; 1517 nodeIdxGlo2 = (itNodeIdx2->second)[1]; 1518 1519 if (nodeIdxGlo1 != nodeIdxGlo2) 1520 { 1521 size_t edgeIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1522 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2Idx.find(edgeIdx); 1523 if (it != edgeIdx2Idx.end()) 1524 { 1525 if (dummyEdgeMap.count(edgeIdx) == 0) 1526 { 1527 dummyEdgeMap[edgeIdx].push_back(edgeIdx); 1528 (it->second)[1] = edge_start + count; 1529 ++count; 1530 } 1531 } 1532 } 1533 } 1534 } 1535 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2Idx, comm); 1536 dhtEdgeIdx.computeIndexInfoMapping(edgeHashList); 1537 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 1354 (it->second)[0] = idxMin; 1355 if (edgeIdx2IdxMin.count(idx) == 0) 1356 { 1357 edgeIdx2IdxMin[idx].push_back(idxMin); 1358 if (idx == idxMin) 1359 edgeIdx2IdxGlo[idxMin].push_back(idxMin); 1360 edgeIdxMinList(iIdxMin) = idxMin; 1361 ++iIdxMin; 1362 } 1363 } 1364 edgeIdxMinList.resizeAndPreserve(iIdxMin); 1365 CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 1366 CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 1367 dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 1368 CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 1538 1369 1539 1370 // (3.5) Saving variables: edge_lon, edge_lat, face_edges 1540 1371 // Creating map edgeIdxGlo2Face <idxGlo, face> 1541 // nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 1542 // edge_count = dhtEdgeIdxGlo.getIndexCount();1543 // edge_start = dhtEdgeIdxGlo.getIndexStart();1544 1372 1373 nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 1374 edge_count = dhtEdgeIdxGlo.getIndexCount(); 1375 edge_start = dhtEdgeIdxGlo.getIndexStart(); 1545 1376 edge_lon.resize(edge_count); 1546 1377 edge_lat.resize(edge_count); … … 1562 1393 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1563 1394 1564 size_t nodeIdx1 = generateNodeIndex(hashValues1); 1565 size_t nodeIdx2 = generateNodeIndex(hashValues2); 1566 it1 = nodeIdx2IdxGlo.find(nodeIdx1); 1567 it2 = nodeIdx2IdxGlo.find(nodeIdx2); 1568 size_t nodeIdxGlo1 = (it1->second)[1]; 1569 size_t nodeIdxGlo2 = (it2->second)[1]; 1395 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1396 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1397 it1 = nodeIdx2IdxMin.find(myNodeIdx1); 1398 it2 = nodeIdx2IdxMin.find(myNodeIdx2); 1399 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 1400 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 1401 size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1402 size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1570 1403 1571 1404 if (nodeIdxGlo1 != nodeIdxGlo2) 1572 1405 { 1573 size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1574 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 1575 int edgeIdxGlo = (itIdx->second)[1]; 1406 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1407 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1408 size_t ownerIdx = (itIdx->second)[0]; 1409 int edgeIdxGlo; 1576 1410 size_t faceIdxGlo = nbFacesAccum + nf; 1577 1411 1578 if (m piRank == (itIdx->second)[0])1412 if (myIdx == ownerIdx) 1579 1413 { 1414 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1415 edgeIdxGlo = (itIdxGlo->second)[0]; 1580 1416 double edgeLon; 1581 1417 double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); … … 1591 1427 edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 1592 1428 } 1429 else 1430 { 1431 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1432 edgeIdxGlo = (itIdxGlo->second)[0]; 1433 } 1593 1434 face_edges(nv1,nf) = edgeIdxGlo; 1594 1435 if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) … … 1624 1465 vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 1625 1466 1626 size_t myNodeIdx1 = generateNodeIndex(hashValues1 );1627 size_t myNodeIdx2 = generateNodeIndex(hashValues2 );1467 size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 1468 size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 1628 1469 if (myNodeIdx1 != myNodeIdx2) 1629 1470 { 1630 it1 = nodeIdx2IdxGlo.find(myNodeIdx1); 1631 it2 = nodeIdx2IdxGlo.find(myNodeIdx2); 1632 size_t nodeIdxGlo1 = (it1->second)[1]; 1633 size_t nodeIdxGlo2 = (it2->second)[1]; 1634 size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 1635 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 1636 int edgeIdxGlo = (itIdx->second)[1]; 1637 1471 it1 = nodeIdx2IdxMin.find(myNodeIdx1); 1472 it2 = nodeIdx2IdxMin.find(myNodeIdx2); 1473 itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 1474 itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 1475 size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 1476 size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 1477 1478 size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 1479 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 1480 size_t ownerIdx = (itIdx->second)[0]; 1638 1481 size_t faceIdxGlo = nbFacesAccum + nf; 1639 1482 1640 if (m piRank == (itIdx->second)[0])1483 if (myIdx == ownerIdx) 1641 1484 { 1485 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 1486 int edgeIdxGlo = (itIdxGlo->second)[0]; 1642 1487 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1643 1488 int face1 = it1->second[0]; … … 1655 1500 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1656 1501 } 1657 } 1502 } // myIdx == ownerIdx 1658 1503 else 1659 1504 { 1505 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 1506 size_t edgeIdxGlo = (itIdxGlo->second)[0]; 1660 1507 it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 1661 1508 int face1 = it1->second[0]; 1662 1509 int face2 = it1->second[1]; 1663 1510 face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 1664 } 1511 } // myIdx != ownerIdx 1665 1512 } // myNodeIdx1 != myNodeIdx2 1666 1513 else … … 1668 1515 } 1669 1516 } 1670 1671 1517 } 1672 1518 facesAreWritten = true;
Note: See TracChangeset
for help on using the changeset viewer.