Changeset 509 for XIOS/trunk/src/node/file.cpp
- Timestamp:
- 11/13/14 15:09:14 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/file.cpp
r501 r509 18 18 19 19 namespace xios { 20 20 21 21 /// ////////////////////// Définitions ////////////////////// /// 22 22 … … 24 24 : CObjectTemplate<CFile>(), CFileAttributes() 25 25 , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) 26 { 26 { 27 27 setVirtualFieldGroup() ; 28 28 setVirtualVariableGroup() ; … … 32 32 : CObjectTemplate<CFile>(id), CFileAttributes() 33 33 , vFieldGroup(), data_out(), enabledFields(), fileComm(MPI_COMM_NULL) 34 { 34 { 35 35 setVirtualFieldGroup() ; 36 36 setVirtualVariableGroup() ; … … 41 41 42 42 ///--------------------------------------------------------------- 43 43 //! Get name of file 44 44 StdString CFile::GetName(void) { return (StdString("file")); } 45 45 StdString CFile::GetDefName(void){ return (CFile::GetName()); } … … 47 47 48 48 //---------------------------------------------------------------- 49 49 /*! 50 \brief Get data that will be written out. 51 Each enabled file in xml represents a physical netcdf file. 52 This function allows to access to data to be written out into netcdf file 53 \return data written out. 54 */ 50 55 boost::shared_ptr<CDataOutput> CFile::getDataOutput(void) const 51 56 { … … 53 58 } 54 59 60 /*! 61 \brief Get virtual field group 62 In each file, there always exists a field group which is the ancestor of all 63 fields in the file. This is considered be virtual because it is created automatically during 64 file initialization and it normally doesn't appear on xml file 65 \return Pointer to field group 66 */ 55 67 CFieldGroup* CFile::getVirtualFieldGroup(void) const 56 68 { … … 58 70 } 59 71 72 /*! 73 \brief Get virtual variable group 74 In each file, there always exists a variable group which is the ancestor of all 75 variable in the file. This is considered be virtual because it is created automatically during 76 file initialization and it normally doesn't appear on xml file 77 \return Pointer to variable group 78 */ 60 79 CVariableGroup* CFile::getVirtualVariableGroup(void) const 61 80 { … … 63 82 } 64 83 84 //! Get all fields of a file 65 85 std::vector<CField*> CFile::getAllFields(void) const 66 86 { 67 87 return (this->vFieldGroup->getAllChildren()); 68 88 } 69 89 90 //! Get all variables of a file 70 91 std::vector<CVariable*> CFile::getAllVariables(void) const 71 92 { … … 74 95 75 96 //---------------------------------------------------------------- 76 77 std::vector<CField*> CFile::getEnabledFields(int default_outputlevel, 97 /*! 98 \brief Get all enabled fields of file 99 A field is considered to be enabled if it fullfil these conditions: it is enabled, inside a enabled file 100 and its own level is not larger than file output level. 101 \param [in] default_outputlevel default value output level of file 102 \param [in] default_level default value level of field 103 \param [in] default_enabled flag determine by default if field is enabled 104 \return Vector of pointers of enabled fields 105 */ 106 std::vector<CField*> CFile::getEnabledFields(int default_outputlevel, 78 107 int default_level, 79 108 bool default_enabled) … … 88 117 89 118 std::vector<CField*> newEnabledFields; 90 119 91 120 for ( it = this->enabledFields.begin() ; it != this->enabledFields.end(); it++ ) 92 121 { … … 112 141 // { it--; this->enabledFields.erase(it+1); continue; } 113 142 } 114 143 115 144 // CField* field_tmp=(*it).get() ; 116 145 // shared_ptr<CField> sptfield=*it ; … … 130 159 131 160 //---------------------------------------------------------------- 132 161 //! Change virtual field group to a new one 133 162 void CFile::setVirtualFieldGroup(CFieldGroup* newVFieldGroup) 134 { 135 this->vFieldGroup = newVFieldGroup; 136 } 137 163 { 164 this->vFieldGroup = newVFieldGroup; 165 } 166 167 //! Change virtual variable group to new one 138 168 void CFile::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) 139 { 140 this->vVariableGroup = newVVariableGroup; 141 } 142 143 //---------------------------------------------------------------- 144 169 { 170 this->vVariableGroup = newVVariableGroup; 171 } 172 173 //---------------------------------------------------------------- 174 //! Create virtual field group, which is done normally on initializing file 145 175 void CFile::setVirtualFieldGroup(void) 146 176 { … … 148 178 } 149 179 180 //! Create virtual variable group, which is done normally on initializing file 150 181 void CFile::setVirtualVariableGroup(void) 151 182 { … … 168 199 return false ; 169 200 } 170 201 202 //! Initialize a file in order to write into it 171 203 void CFile::initFile(void) 172 204 { … … 174 206 CDate& currentDate=context->calendar->getCurrentDate() ; 175 207 CContextServer* server=context->server ; 176 208 177 209 if (! sync_freq.isEmpty()) syncFreq = CDuration::FromString(sync_freq.getValue()); 178 210 if (! split_freq.isEmpty()) splitFreq = CDuration::FromString(split_freq.getValue()); … … 194 226 nbDomain=setDomain.size() ; 195 227 196 // create sub communicator for file 228 // create sub communicator for file 197 229 int color=allDomainEmpty?0:1 ; 198 230 MPI_Comm_split(server->intraComm,color,server->intraCommRank,&fileComm) ; 199 231 if (allDomainEmpty) MPI_Comm_free(&fileComm) ; 200 232 // 201 202 } 203 233 234 } 235 236 //! Verify state of a file 204 237 void CFile::checkFile(void) 205 238 { … … 208 241 checkSplit() ; 209 242 } 210 211 243 244 245 /*! 246 \brief Verify if synchronisation should be done 247 If syn option is enabled, syn frequence and current time will be used to 248 calculate the moment to syn file(s) 249 \return True if it is the moment to synchronize file, otherwise false 250 */ 212 251 bool CFile::checkSync(void) 213 252 { … … 225 264 return false ; 226 265 } 227 228 266 267 /*! 268 \brief Verify if splitting should be done 269 If split option is enabled, split frequence and current time will be used to 270 calculate the moment to split file 271 \return True if it is the moment to split file, otherwise false 272 */ 229 273 bool CFile::checkSplit(void) 230 274 { … … 235 279 if (currentDate > *lastSplit+splitFreq) 236 280 { 237 *lastSplit=*lastSplit+splitFreq ; 281 *lastSplit=*lastSplit+splitFreq ; 238 282 std::vector<CField*>::iterator it, end = this->enabledFields.end(); 239 283 for (it = this->enabledFields.begin() ;it != end; it++) (*it)->resetNStep() ; … … 244 288 return false ; 245 289 } 246 290 291 /*! 292 \brief Create header of netcdf file 293 There are some information to fill in header of each netcdf. 294 */ 247 295 void CFile::createHeader(void) 248 296 { 249 297 CContext* context = CContext::getCurrent() ; 250 298 CContextServer* server=context->server ; 251 299 252 300 if (!allDomainEmpty) 253 301 { … … 273 321 oss<<"_"<<lastSplit->getStr(splitFormat)<<"-"<< (*lastSplit+(splitFreq-1*Second)).getStr(splitFormat); 274 322 } 275 323 276 324 bool multifile=true ; 277 325 if (!type.isEmpty()) … … 280 328 else if (type==type_attr::multiple_file) multifile=true ; 281 329 282 } 330 } 283 331 #ifndef USING_NETCDF_PAR 284 332 if (!multifile) … … 288 336 } 289 337 #endif 290 if (multifile) 338 if (multifile) 291 339 { 292 340 int commSize, commRank ; 293 341 MPI_Comm_size(fileComm,&commSize) ; 294 342 MPI_Comm_rank(fileComm,&commRank) ; 295 296 if (server->intraCommSize > 1) 343 344 if (server->intraCommSize > 1) 297 345 { 298 346 oss << "_" ; 299 347 int width=0 ; int n=commSize-1 ; 300 348 while(n != 0) { n=n/10 ; width++ ;} 301 if (!min_digits.isEmpty()) 349 if (!min_digits.isEmpty()) 302 350 if (width<min_digits) width=min_digits ; 303 351 oss.width(width) ; … … 314 362 if (par_access.getValue()=="independent") isCollective=false ; 315 363 else if (par_access.getValue()=="collective") isCollective=true ; 316 else 364 else 317 365 { 318 366 ERROR("void Context::createDataOutput(void)", … … 332 380 } 333 381 this->data_out->writeTimeDimension(); 334 382 335 383 for (it = this->enabledFields.begin() ;it != end; it++) 336 384 { … … 338 386 this->data_out->writeField(field); 339 387 } 340 388 341 389 vector<CVariable*> listVars = getAllVariables() ; 342 390 for (vector<CVariable*>::iterator it = listVars.begin() ;it != listVars.end(); it++) this-> data_out-> writeAttribute(*it) ; 343 391 344 392 this->data_out->definition_end(); 345 393 } 346 394 } 347 395 396 //! Close file 348 397 void CFile::close(void) 349 398 { … … 351 400 delete lastSplit ; 352 401 if (!allDomainEmpty) 353 if (isOpen) 402 if (isOpen) 354 403 { 355 404 this->data_out->closeFile(); … … 359 408 //---------------------------------------------------------------- 360 409 410 /*! 411 \brief Parse xml file and write information into file object 412 \param [in] node xmld node corresponding in xml file 413 */ 361 414 void CFile::parse(xml::CXMLNode & node) 362 415 { 363 416 SuperClass::parse(node); 364 417 365 418 if (node.goToChildElement()) 366 419 { … … 376 429 //---------------------------------------------------------------- 377 430 431 /*! 432 \brief Represent a file in form of string with all its info 433 \return String 434 */ 378 435 StdString CFile::toString(void) const 379 436 { … … 391 448 392 449 //---------------------------------------------------------------- 393 450 451 /*! 452 \brief Find all inheritace among objects in a file. 453 \param [in] apply (true) write attributes of parent into ones of child if they are empty 454 (false) write attributes of parent into a new container of child 455 \param [in] parent 456 */ 394 457 void CFile::solveDescInheritance(bool apply, const CAttributeMap * const parent) 395 458 { 396 459 SuperClassAttribute::setAttributes(parent,apply); 397 this->getVirtualFieldGroup()->solveDescInheritance(apply, NULL); 460 this->getVirtualFieldGroup()->solveDescInheritance(apply, NULL); 398 461 this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); 399 462 } … … 401 464 //---------------------------------------------------------------- 402 465 403 void CFile::processEnabledFile(void) 404 { 405 if (output_freq.isEmpty()) ERROR("void CFile::processEnabledFile(void)", 406 <<"File attribute <<output_freq>> is undefined"); 407 solveFieldRefInheritance(true) ; 408 getEnabledFields() ; 409 processEnabledFields() ; 410 } 411 412 void CFile::processEnabledFields(void) 413 { 414 for (unsigned int i = 0; i < this->enabledFields.size(); i++) 415 { 416 this->enabledFields[i]->processEnabledField() ; 417 } 418 } 419 466 // void CFile::processEnabledFile(void) 467 // { 468 // if (output_freq.isEmpty()) ERROR("void CFile::processEnabledFile(void)", 469 // <<"File attribute <<output_freq>> is undefined"); 470 // solveFieldRefInheritance(true) ; 471 // getEnabledFields() ; 472 // processEnabledFields() ; 473 // } 474 475 // void CFile::processEnabledFields(void) 476 // { 477 // for (unsigned int i = 0; i < this->enabledFields.size(); i++) 478 // { 479 // this->enabledFields[i]->processEnabledField() ; 480 // } 481 // } 482 483 /*! 484 \brief Resolve all reference of active fields. 485 In order to know exactly which data each active field has, a search for all its 486 reference to find its parents or/and its base reference object must be done. Moreover 487 during this search, there are some information that can only be sent to server AFTER 488 all information of active fields are created on server side, e.g: checking mask or index 489 \param [in] sendToServer: Send all info to server (true) or only a part of it (false) 490 */ 491 void CFile::solveAllRefOfEnabledFields(bool sendToServer) 492 { 493 int size = this->enabledFields.size(); 494 for (int i = 0; i < size; ++i) 495 { 496 this->enabledFields[i]->solveAllReferenceEnabledField(sendToServer); 497 } 498 } 499 500 /*! 501 \brief Contruct all expression related to active fields. 502 Each field can do some expressions which appear on the xml file, and itself can be 503 a result of an expression among some other fields. This function builds all possible expression 504 relating to active fields. 505 */ 506 void CFile::buildAllExpressionOfEnabledFields() 507 { 508 int size = this->enabledFields.size(); 509 for (int i = 0; i < size; ++i) 510 { 511 this->enabledFields[i]->buildAllExpressionEnabledField(); 512 } 513 } 514 420 515 void CFile::solveFieldRefInheritance(bool apply) 421 516 { … … 441 536 this->enabledFields[i]->solveOperation(); 442 537 } 443 538 444 539 void CFile::solveEFExpression(void) 445 540 { 446 541 for (unsigned int i = 0; i < this->enabledFields.size(); i++) 447 542 this->enabledFields[i]->buildExpression(); 448 } 449 450 543 } 544 545 /*! 546 \brief Add a field into file. 547 A field is added into file and it will be written out if the file is enabled and 548 level of this field is smaller than level_output. A new field won't be created if one 549 with id has already existed 550 \param [in] id String identity of new field 551 \return Pointer to added (or already existed) field 552 */ 451 553 CField* CFile::addField(const string& id) 452 554 { … … 454 556 } 455 557 558 /*! 559 \brief Add a field group into file. 560 A field group is added into file and it will play a role as parents for fields. 561 A new field group won't be created if one with id has already existed 562 \param [in] id String identity of new field group 563 \return Pointer to added (or already existed) field group 564 */ 456 565 CFieldGroup* CFile::addFieldGroup(const string& id) 457 566 { 458 567 return vFieldGroup->createChildGroup(id) ; 459 568 } 460 569 570 /*! 571 \brief Add a variable into file. 572 A variable is added into file and if one with id has already existed, pointer to 573 it will be returned. 574 Variable as long as attributes are information container of file. 575 However, whereas attributes are "fixed" information, variables provides a more flexible way to user 576 to fill in (extra) information for a file. 577 \param [in] id String identity of new variable 578 \return Pointer to added (or already existed) variable 579 */ 461 580 CVariable* CFile::addVariable(const string& id) 462 581 { … … 464 583 } 465 584 585 /*! 586 \brief Add a variable group into file. 587 A variable group is added into file and it will play a role as parents for variables. 588 A new variable group won't be created if one with id has already existed 589 \param [in] id String identity of new variable group 590 \return Pointer to added (or already existed) variable group 591 */ 466 592 CVariableGroup* CFile::addVariableGroup(const string& id) 467 593 { 468 594 return vVariableGroup->createChildGroup(id) ; 469 595 } 470 471 596 597 /*! 598 \brief Send a message to create a field on server side 599 \param[in] id String identity of field that will be created on server 600 */ 472 601 void CFile::sendAddField(const string& id) 473 602 { 474 603 CContext* context=CContext::getCurrent() ; 475 604 476 605 if (! context->hasServer ) 477 606 { 478 607 CContextClient* client=context->client ; 479 608 480 CEventClient event(this->getType(),EVENT_ID_ADD_FIELD) ; 609 CEventClient event(this->getType(),EVENT_ID_ADD_FIELD) ; 481 610 if (client->isServerLeader()) 482 611 { … … 489 618 else client->sendEvent(event) ; 490 619 } 491 492 } 493 620 621 } 622 623 /*! 624 \brief Send a message to create a field group on server side 625 \param[in] id String identity of field group that will be created on server 626 */ 494 627 void CFile::sendAddFieldGroup(const string& id) 495 628 { … … 499 632 CContextClient* client=context->client ; 500 633 501 CEventClient event(this->getType(),EVENT_ID_ADD_FIELD_GROUP) ; 634 CEventClient event(this->getType(),EVENT_ID_ADD_FIELD_GROUP) ; 502 635 if (client->isServerLeader()) 503 636 { … … 510 643 else client->sendEvent(event) ; 511 644 } 512 513 } 514 645 646 } 647 648 /*! 649 \brief Receive a message annoucing the creation of a field on server side 650 \param[in] event Received event 651 */ 515 652 void CFile::recvAddField(CEventServer& event) 516 653 { 517 654 518 655 CBufferIn* buffer=event.subEvents.begin()->buffer; 519 656 string id; … … 521 658 get(id)->recvAddField(*buffer) ; 522 659 } 523 524 660 661 /*! 662 \brief Receive a message annoucing the creation of a field on server side 663 \param[in] buffer Buffer containing message 664 */ 525 665 void CFile::recvAddField(CBufferIn& buffer) 526 666 { … … 530 670 } 531 671 672 /*! 673 \brief Receive a message annoucing the creation of a field group on server side 674 \param[in] event Received event 675 */ 532 676 void CFile::recvAddFieldGroup(CEventServer& event) 533 677 { 534 678 535 679 CBufferIn* buffer=event.subEvents.begin()->buffer; 536 680 string id; … … 538 682 get(id)->recvAddFieldGroup(*buffer) ; 539 683 } 540 541 684 685 /*! 686 \brief Receive a message annoucing the creation of a field group on server side 687 \param[in] buffer Buffer containing message 688 */ 542 689 void CFile::recvAddFieldGroup(CBufferIn& buffer) 543 690 { … … 546 693 addFieldGroup(id) ; 547 694 } 548 549 550 551 552 553 554 555 556 557 558 695 696 /*! 697 \brief Send messages to duplicate all variables on server side 698 Because each variable has also its attributes. So first thing to do is replicate 699 all these attributes on server side. Because variable can have a value, the second thing 700 is to duplicate this value on server, too. 701 */ 702 void CFile::sendAddAllVariables() 703 { 704 if (!getAllVariables().empty()) 705 { 706 // Firstly, it's necessary to add virtual variable group 707 sendAddVariableGroup(getVirtualVariableGroup()->getId()); 708 709 // Okie, now we can add to this variable group 710 std::vector<CVariable*> allVar = getAllVariables(); 711 std::vector<CVariable*>::const_iterator it = allVar.begin(); 712 std::vector<CVariable*>::const_iterator itE = allVar.end(); 713 714 for (; it != itE; ++it) 715 { 716 std::cout << "Variable Files " << (*it)->getId() << std::endl; 717 this->sendAddVariable((*it)->getId()); 718 (*it)->sendAllAttributesToServer(); 719 (*it)->sendValue(); 720 } 721 } 722 } 723 724 /*! 725 \brief Send a message to create a variable on server side 726 A variable always belongs to a variable group 727 \param[in] id String identity of variable that will be created on server 728 */ 559 729 void CFile::sendAddVariable(const string& id) 560 730 { 561 731 CContext* context=CContext::getCurrent() ; 562 732 563 733 if (! context->hasServer ) 564 734 { 565 735 CContextClient* client=context->client ; 566 736 567 CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE) ; 737 CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE) ; 568 738 if (client->isServerLeader()) 569 739 { … … 576 746 else client->sendEvent(event) ; 577 747 } 578 579 } 580 748 749 } 750 751 /*! 752 \brief Send a message to create a variable group on server side 753 \param[in] id String identity of variable group that will be created on server 754 */ 581 755 void CFile::sendAddVariableGroup(const string& id) 582 756 { … … 586 760 CContextClient* client=context->client ; 587 761 588 CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP) ; 762 CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP) ; 589 763 if (client->isServerLeader()) 590 764 { … … 597 771 else client->sendEvent(event) ; 598 772 } 599 600 } 601 773 774 } 775 776 /*! 777 \brief Receive a message annoucing the creation of a variable on server side 778 \param[in] event Received event 779 */ 602 780 void CFile::recvAddVariable(CEventServer& event) 603 781 { 604 782 605 783 CBufferIn* buffer=event.subEvents.begin()->buffer; 606 784 string id; … … 608 786 get(id)->recvAddVariable(*buffer) ; 609 787 } 610 611 788 789 /*! 790 \brief Receive a message annoucing the creation of a variable on server side 791 \param[in] buffer Buffer containing message 792 */ 612 793 void CFile::recvAddVariable(CBufferIn& buffer) 613 794 { … … 617 798 } 618 799 800 /*! 801 \brief Receive a message annoucing the creation of a variable group on server side 802 \param[in] event Received event 803 */ 619 804 void CFile::recvAddVariableGroup(CEventServer& event) 620 805 { 621 806 622 807 CBufferIn* buffer=event.subEvents.begin()->buffer; 623 808 string id; … … 625 810 get(id)->recvAddVariableGroup(*buffer) ; 626 811 } 627 628 812 813 /*! 814 \brief Receive a message annoucing the creation of a variable group on server side 815 \param[in] buffer Buffer containing message 816 */ 629 817 void CFile::recvAddVariableGroup(CBufferIn& buffer) 630 818 { … … 634 822 } 635 823 636 637 638 639 824 /*! 825 \brief Sending all active (enabled) fields from client to server. 826 Each field is identified uniquely by its string identity. Not only should we 827 send the id to server but also we need to send ids of reference domain and reference axis. 828 With these two id, it's easier to make reference to grid where all data should be written. 829 Remark: This function must be called AFTER all active (enabled) files have been created on the server side 830 */ 831 void CFile::sendEnabledFields() 832 { 833 int size = this->enabledFields.size(); 834 CField* fieldPtr(0); 835 for (int i = 0; i < size; ++i) 836 { 837 fieldPtr = this->enabledFields[i]; 838 if (fieldPtr->name.isEmpty()) fieldPtr->name.setValue(fieldPtr->getBaseFieldReference()->getId()); 839 std::cout << "Enabled Fields " << i << " " << CField::get(fieldPtr)->getId() << std::endl; 840 this->sendAddField(fieldPtr->getId()); 841 fieldPtr->sendAllAttributesToServer(); 842 fieldPtr->sendAddAllVariables(); 843 } 844 } 845 846 /*! 847 \brief Dispatch event received from client 848 Whenever a message is received in buffer of server, it will be processed depending on 849 its event type. A new event type should be added in the switch list to make sure 850 it processed on server side. 851 \param [in] event: Received message 852 */ 640 853 bool CFile::dispatchEvent(CEventServer& event) 641 854 { … … 649 862 return true ; 650 863 break ; 651 864 652 865 case EVENT_ID_ADD_FIELD_GROUP : 653 866 recvAddFieldGroup(event) ; 654 867 return true ; 655 break ; 656 868 break ; 869 657 870 case EVENT_ID_ADD_VARIABLE : 658 871 recvAddVariable(event) ; 659 872 return true ; 660 873 break ; 661 874 662 875 case EVENT_ID_ADD_VARIABLE_GROUP : 663 876 recvAddVariableGroup(event) ; 664 877 return true ; 665 break ; 878 break ; 666 879 default : 667 880 ERROR("bool CFile::dispatchEvent(CEventServer& event)", <<"Unknown Event") ; … … 670 883 } 671 884 } 672 673 674 675 885 886 887 888 676 889 ///--------------------------------------------------------------- 677 890
Note: See TracChangeset
for help on using the changeset viewer.