|
MoochoPack : Framework for Large-Scale Optimization Algorithms Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include "MoochoPack_MoochoSolver.hpp" 00030 00031 #include "MoochoPack_NLPAlgoConfigMamaJama.hpp" 00032 #include "MoochoPack_NLPAlgoConfigIP.hpp" 00033 00034 #include "MoochoPack_NLPSolverClientInterfaceSetOptions.hpp" 00035 #include "MoochoPack_NLPAlgoClientInterface.hpp" 00036 #include "MoochoPack_NLPAlgoContainer.hpp" 00037 #include "MoochoPack_NLPAlgoState.hpp" 00038 #include "MoochoPack_MoochoTrackerSummaryStd.hpp" 00039 #include "MoochoPack_MoochoTrackerConsoleStd.hpp" 00040 #include "MoochoPack_MoochoTrackerStatsStd.hpp" 00041 #include "IterationPack_AlgorithmTrackerComposite.hpp" 00042 #include "NLPInterfacePack_NLPFirstOrder.hpp" 00043 #include "NLPInterfacePack_NLPDirect.hpp" 00044 #include "NLPInterfacePack_test_nlp_first_order.hpp" 00045 #include "NLPInterfacePack_test_nlp_direct.hpp" 00046 #include "OptionsFromStreamPack_OptionsFromStream.hpp" 00047 #include "StopWatchPack_stopwatch.hpp" 00048 #include "OptionsFromStreamPack_StringToIntMap.hpp" 00049 #include "OptionsFromStreamPack_StringToBool.hpp" 00050 #include "Teuchos_Workspace.hpp" 00051 #include "Teuchos_TestForException.hpp" 00052 #include "Teuchos_oblackholestream.hpp" 00053 #include "Teuchos_VerboseObject.hpp" 00054 #include "Teuchos_GlobalMPISession.hpp" 00055 #include "Teuchos_TimeMonitor.hpp" 00056 #include "Teuchos_Utils.hpp" 00057 00058 namespace MoochoPack { 00059 00060 // Initialization and algorithm configuration 00061 00062 MoochoSolver::MoochoSolver( 00063 const std::string &options_file_name 00064 ,const std::string &extra_options_str 00065 ) 00066 :reconfig_solver_(true) 00067 ,workspace_MB_(-1.0) 00068 ,obj_scale_(1.0) 00069 ,test_nlp_(true) 00070 ,print_algo_(true) 00071 ,algo_timing_(true) 00072 ,generate_stats_file_(false) 00073 ,print_opt_grp_not_accessed_(true) 00074 ,throw_exceptions_(false) 00075 ,output_file_tag_("") 00076 ,do_console_outputting_(true) 00077 ,do_summary_outputting_(true) 00078 ,do_journal_outputting_(true) 00079 ,do_algo_outputting_(true) 00080 ,configuration_(MAMA_JAMA) 00081 ,output_to_black_hole_(OUTPUT_TO_BLACK_HOLE_DEFAULT) 00082 ,file_context_postfix_("") 00083 ,file_proc_postfix_("") 00084 { 00085 00086 Teuchos::RCP<Teuchos::FancyOStream> 00087 defaultOut = Teuchos::VerboseObjectBase::getDefaultOStream(); 00088 error_out_used_ = defaultOut; 00089 00090 set_output_context(""); 00091 00092 commandLineOptionsFromStreamProcessor_.options_file_name_opt_name( 00093 "moocho-options-file"); 00094 commandLineOptionsFromStreamProcessor_.options_file_name_opt_doc( 00095 "Set the name of the MOOCHO options file in the OptionsFromStream format." 00096 " File is ignored if it does not exist!"); 00097 commandLineOptionsFromStreamProcessor_.options_file_name(options_file_name); 00098 00099 commandLineOptionsFromStreamProcessor_.extra_options_str_opt_name( 00100 "moocho-extra-options"); 00101 commandLineOptionsFromStreamProcessor_.extra_options_str_opt_doc( 00102 "Extra MOOCHO options specified in the format" 00103 " \"OptGrp1{name1=val1,...,namen=valn}:OptGr2{name1=val1,...,namen=valn}:...\""); 00104 commandLineOptionsFromStreamProcessor_.extra_options_str(extra_options_str); 00105 00106 } 00107 00108 OptionsFromStreamPack::CommandLineOptionsFromStreamProcessor& 00109 MoochoSolver::commandLineOptionsFromStreamProcessor() 00110 { 00111 return commandLineOptionsFromStreamProcessor_; 00112 } 00113 00114 const OptionsFromStreamPack::CommandLineOptionsFromStreamProcessor& 00115 MoochoSolver::commandLineOptionsFromStreamProcessor() const 00116 { 00117 return commandLineOptionsFromStreamProcessor_; 00118 } 00119 00120 void MoochoSolver::setup_commandline_processor( 00121 Teuchos::CommandLineProcessor *clp 00122 ) 00123 { 00124 commandLineOptionsFromStreamProcessor_.setup_commandline_processor(clp); 00125 } 00126 00127 void MoochoSolver::set_output_context( 00128 const std::string &file_context_postfix 00129 ,EOutputToBlackHole output_to_black_hole 00130 ,const int procRank_in 00131 ,const int numProcs_in 00132 ) 00133 { 00134 00135 file_context_postfix_ = file_context_postfix; 00136 00137 output_to_black_hole_ = output_to_black_hole; 00138 00139 Teuchos::RCP<Teuchos::FancyOStream> 00140 defaultOut = Teuchos::VerboseObjectBase::getDefaultOStream(); 00141 00142 const int procRank 00143 = ( procRank_in >= 0 ? procRank_in : Teuchos::GlobalMPISession::getRank() ); 00144 const int numProcs 00145 = ( numProcs_in > 0 ? numProcs_in : Teuchos::GlobalMPISession::getNProc() ); 00146 00147 if(output_to_black_hole_==OUTPUT_TO_BLACK_HOLE_DEFAULT) { 00148 if( numProcs > 1 && defaultOut->getOutputToRootOnly() >= 0 ) { 00149 output_to_black_hole_ 00150 = ( defaultOut->getOutputToRootOnly()==procRank 00151 ? OUTPUT_TO_BLACK_HOLE_FALSE 00152 : OUTPUT_TO_BLACK_HOLE_TRUE 00153 ); 00154 } 00155 else { 00156 output_to_black_hole_ = OUTPUT_TO_BLACK_HOLE_FALSE; 00157 } 00158 } 00159 00160 if( numProcs > 1 ) { 00161 file_proc_postfix_ = Teuchos::Utils::getParallelExtension(procRank,numProcs); 00162 } 00163 else { 00164 file_proc_postfix_ = ""; 00165 } 00166 00167 summary_out_ = Teuchos::null; 00168 journal_out_ = Teuchos::null; 00169 algo_out_ = Teuchos::null; 00170 00171 summary_out_used_ = Teuchos::null; 00172 journal_out_used_ = Teuchos::null; 00173 algo_out_used_ = Teuchos::null; 00174 stats_out_used_ = Teuchos::null; 00175 00176 } 00177 00178 void MoochoSolver::set_nlp(const nlp_ptr_t& nlp) 00179 { 00180 nlp_ = nlp; 00181 reconfig_solver_ = true; 00182 } 00183 00184 const MoochoSolver::nlp_ptr_t& 00185 MoochoSolver::get_nlp() const 00186 { 00187 return nlp_; 00188 } 00189 00190 void MoochoSolver::set_track(const track_ptr_t& track) 00191 { 00192 track_ = track; 00193 solver_.set_track(Teuchos::null); // Force the track objects to be rebuilt and added! 00194 } 00195 00196 const MoochoSolver::track_ptr_t& 00197 MoochoSolver::get_track() const 00198 { 00199 return track_; 00200 } 00201 00202 void MoochoSolver::set_config( const config_ptr_t& config ) 00203 { 00204 config_ = config; 00205 solver_.set_config(Teuchos::null); // Must unset the config object. 00206 reconfig_solver_ = true; 00207 } 00208 00209 const MoochoSolver::config_ptr_t& 00210 MoochoSolver::get_config() const 00211 { 00212 return config_; 00213 } 00214 00215 void MoochoSolver::set_options( const options_ptr_t& options ) 00216 { 00217 options_ = options; // Must totally free all of the references we 00218 const config_ptr_t // have to the current options. That includes 00219 &config = solver_.get_config(); // removing the options object for the configuration 00220 if(config.get()) // object. 00221 config->set_options(Teuchos::null); // ... 00222 options_used_ = options; 00223 commandLineOptionsFromStreamProcessor_.set_options(options); 00224 reconfig_solver_ = true; 00225 } 00226 00227 const MoochoSolver::options_ptr_t& 00228 MoochoSolver::get_options() const 00229 { 00230 return options_; 00231 } 00232 00233 void MoochoSolver::set_error_handling( 00234 bool throw_exceptions 00235 ,const ostream_ptr_t& error_out 00236 ) 00237 00238 { 00239 if( error_out_.get() != NULL ) { 00240 if( error_out.get() == NULL ) 00241 error_out_used_ = Teuchos::VerboseObjectBase::getDefaultOStream(); 00242 else 00243 error_out_used_ = error_out; 00244 } 00245 else if( error_out.get() != NULL ) { 00246 error_out_used_ = error_out; 00247 } 00248 throw_exceptions_ = throw_exceptions; 00249 error_out_ = error_out; 00250 } 00251 00252 bool MoochoSolver::throw_exceptions() const 00253 { 00254 return throw_exceptions_; 00255 } 00256 00257 const MoochoSolver::ostream_ptr_t& 00258 MoochoSolver::error_out() const 00259 { 00260 return error_out_; 00261 } 00262 00263 void MoochoSolver::set_console_out( const ostream_ptr_t& console_out ) 00264 { 00265 console_out_ = console_out; 00266 console_out_used_ = Teuchos::null; // Remove every reference to this ostream object! 00267 solver_.set_track(Teuchos::null); 00268 } 00269 00270 const MoochoSolver::ostream_ptr_t& 00271 MoochoSolver::get_console_out() const 00272 { 00273 return console_out_; 00274 } 00275 00276 void MoochoSolver::set_summary_out( const ostream_ptr_t& summary_out ) 00277 { 00278 summary_out_ = summary_out; 00279 summary_out_used_ = Teuchos::null; 00280 solver_.set_track(Teuchos::null); // Remove every reference to this ostream object! 00281 } 00282 00283 const MoochoSolver::ostream_ptr_t& 00284 MoochoSolver::get_summary_out() const 00285 { 00286 return summary_out_; 00287 } 00288 00289 void MoochoSolver::set_journal_out( const ostream_ptr_t& journal_out ) 00290 { 00291 journal_out_ = journal_out; 00292 journal_out_used_ = Teuchos::null; 00293 solver_.set_track(Teuchos::null); // Remove every reference to this ostream object! 00294 } 00295 00296 const MoochoSolver::ostream_ptr_t& 00297 MoochoSolver::get_journal_out() const 00298 { 00299 return journal_out_; 00300 } 00301 00302 void MoochoSolver::set_algo_out( const ostream_ptr_t& algo_out ) 00303 { 00304 algo_out_ = algo_out; 00305 algo_out_used_ = Teuchos::null; 00306 } 00307 00308 const MoochoSolver::ostream_ptr_t& 00309 MoochoSolver::get_algo_out() const 00310 { 00311 return algo_out_; 00312 } 00313 00314 Teuchos::RCP<std::ostream> 00315 MoochoSolver::generate_output_file(const std::string &fileNameBase) const 00316 { 00317 if( output_to_black_hole_ == OUTPUT_TO_BLACK_HOLE_TRUE ) 00318 return Teuchos::rcp(new Teuchos::oblackholestream()); 00319 std::string fileName = fileNameBase; 00320 if(file_context_postfix_.length()) 00321 fileName += "." + file_context_postfix_; 00322 if(file_proc_postfix_.length()) 00323 fileName += "." + file_proc_postfix_; 00324 if(output_file_tag_.length()) 00325 fileName += ( "." + output_file_tag_ ); 00326 fileName += ".out"; 00327 return Teuchos::rcp(new std::ofstream(fileName.c_str())); 00328 } 00329 00330 // Solve the NLP 00331 00332 void MoochoSolver::update_solver() const 00333 { 00334 00335 using std::endl; 00336 using std::setw; 00337 using StopWatchPack::stopwatch; 00338 using Teuchos::RCP; 00339 namespace ofsp = OptionsFromStreamPack; 00340 using ofsp::OptionsFromStream; 00341 using ofsp::StringToIntMap; 00342 using ofsp::StringToBool; 00343 00345 // Validate the input 00346 // 00347 00348 TEST_FOR_EXCEPTION( 00349 nlp_.get() == NULL, std::logic_error 00350 ,"MoochoSolver::update_solver() : Error, this->get_nlp().get() can not be NULL!" ); 00351 00352 00353 // 00354 // Get the options (or lack of) 00355 // 00356 00357 bool MoochoSolver_opt_grp_existed = true; 00358 00359 if(reconfig_solver_) { 00360 00361 if( options_used_.get() == NULL ) { 00362 if( options_.get() == NULL ) { 00363 options_used_ = commandLineOptionsFromStreamProcessor_.process_and_get_options(); 00364 } 00365 else 00366 options_used_ = options_; 00367 } 00368 00369 // 00370 // Read in some options for "MoochoSolver" if needed 00371 // 00372 00373 if( options_used_.get() ) { 00374 00375 options_used_->reset_unaccessed_options_groups(); 00376 00377 const std::string optgrp_name = "MoochoSolver"; 00378 OptionsFromStream::options_group_t optgrp = options_used_->options_group( optgrp_name ); 00379 if( OptionsFromStream::options_group_exists( optgrp ) ) { 00380 00381 const int num_opt = 12; 00382 enum EOptions { 00383 WORKSPACE_MB 00384 ,OBJ_SCALE 00385 ,TEST_NLP 00386 ,CONSOLE_OUTPUTTING 00387 ,SUMMARY_OUTPUTTING 00388 ,JOURNAL_OUTPUTTING 00389 ,ALGO_OUTPUTTING 00390 ,PRINT_ALGO 00391 ,ALGO_TIMING 00392 ,GENERATE_STATS_FILE 00393 ,PRINT_OPT_GRP_NOT_ACCESSED 00394 ,CONFIGURATION 00395 }; 00396 const char* SOptions[num_opt] = { 00397 "workspace_MB" 00398 ,"obj_scale" 00399 ,"test_nlp" 00400 ,"console_outputting" 00401 ,"summary_outputting" 00402 ,"journal_outputting" 00403 ,"algo_outputting" 00404 ,"print_algo" 00405 ,"algo_timing" 00406 ,"generate_stats_file" 00407 ,"print_opt_grp_not_accessed" 00408 ,"configuration" 00409 }; 00410 00411 const int num_config_opt = 2; 00412 00413 const char* SConfigOptions[num_config_opt] = { 00414 "mama_jama" 00415 ,"interior_point" 00416 }; 00417 00418 StringToIntMap config_map( optgrp_name, num_config_opt, SConfigOptions ); 00419 00420 StringToIntMap opt_map( optgrp_name, num_opt, SOptions ); 00421 00422 OptionsFromStream::options_group_t::const_iterator itr = optgrp.begin(); 00423 for( ; itr != optgrp.end(); ++itr ) { 00424 switch( (EOptions)opt_map( ofsp::option_name(itr) ) ) { 00425 case WORKSPACE_MB: 00426 workspace_MB_ = std::atof( ofsp::option_value(itr).c_str() ); 00427 break; 00428 case OBJ_SCALE: 00429 obj_scale_ = std::atof( ofsp::option_value(itr).c_str() ); 00430 break; 00431 case TEST_NLP: 00432 test_nlp_ = StringToBool( "test_nlp", ofsp::option_value(itr).c_str() ); 00433 break; 00434 case CONSOLE_OUTPUTTING: 00435 do_console_outputting_ = StringToBool( "console_outputting", ofsp::option_value(itr).c_str() ); 00436 break; 00437 case SUMMARY_OUTPUTTING: 00438 do_summary_outputting_ = StringToBool( "summary_outputting", ofsp::option_value(itr).c_str() ); 00439 break; 00440 case JOURNAL_OUTPUTTING: 00441 do_journal_outputting_ = StringToBool( "journal_outputting", ofsp::option_value(itr).c_str() ); 00442 break; 00443 case ALGO_OUTPUTTING: 00444 do_algo_outputting_ = StringToBool( "algo_outputting", ofsp::option_value(itr).c_str() ); 00445 break; 00446 case PRINT_ALGO: 00447 print_algo_ = StringToBool( "print_algo", ofsp::option_value(itr).c_str() ); 00448 break; 00449 case ALGO_TIMING: 00450 algo_timing_ = StringToBool( "algo_timing", ofsp::option_value(itr).c_str() ); 00451 break; 00452 case GENERATE_STATS_FILE: 00453 generate_stats_file_ = StringToBool( "generate_stats_file", ofsp::option_value(itr).c_str() ); 00454 break; 00455 case PRINT_OPT_GRP_NOT_ACCESSED: 00456 print_opt_grp_not_accessed_ = StringToBool( "algo_timing", ofsp::option_value(itr).c_str() ); 00457 break; 00458 case CONFIGURATION: 00459 configuration_ = config_map( ofsp::option_value(itr).c_str() ); 00460 break; 00461 default: 00462 TEST_FOR_EXCEPT(true); // this would be a local programming error only. 00463 } 00464 } 00465 } 00466 else { 00467 MoochoSolver_opt_grp_existed = false; 00468 } 00469 00470 } 00471 00472 } 00473 00474 // 00475 // Get the output streams if needed 00476 // 00477 00478 generate_output_streams(); 00479 00480 if( do_algo_outputting() && !MoochoSolver_opt_grp_existed ) 00481 *algo_out_used_ 00482 << "\nWarning! The options group \'MoochoSolver\' was not found.\n" 00483 "Using a default set of options ...\n"; 00484 00485 // 00486 // Configure the algorithm 00487 // 00488 00489 if(reconfig_solver_) { 00490 00491 // 00492 // Print the headers for the output files 00493 // 00494 00495 int prec = 8; 00496 if(do_summary_outputting()) 00497 summary_out_used_->precision(prec); 00498 if(do_journal_outputting()) 00499 *journal_out_used_ << std::setprecision(prec) << std::scientific; 00500 00501 if(do_algo_outputting()) 00502 *algo_out_used_ 00503 << "\n********************************************************************" 00504 << "\n*** Algorithm information output ***" 00505 << "\n*** ***" 00506 << "\n*** Below, information about how the the MOOCHO algorithm is ***" 00507 << "\n*** setup is given and is followed by detailed printouts of the ***" 00508 << "\n*** contents of the algorithm state object (i.e. iteration ***" 00509 << "\n*** quantities) and the algorithm description printout ***" 00510 << "\n*** (if the option MoochoSolver::print_algo = true is set). ***" 00511 << "\n********************************************************************\n"; 00512 if(do_summary_outputting()) 00513 *summary_out_used_ 00514 << "\n********************************************************************" 00515 << "\n*** Algorithm iteration summary output ***" 00516 << "\n*** ***" 00517 << "\n*** Below, a summary table of the SQP iterations is given as ***" 00518 << "\n*** well as a table of the CPU times for each step (if the ***" 00519 << "\n*** option MoochoSolver::algo_timing = true is set). ***" 00520 << "\n********************************************************************\n"; 00521 if(do_journal_outputting()) 00522 *journal_out_used_ 00523 << "\n********************************************************************" 00524 << "\n*** Algorithm iteration detailed journal output ***" 00525 << "\n*** ***" 00526 << "\n*** Below, detailed information about the SQP algorithm is given ***" 00527 << "\n*** while it is running. The amount of information that is ***" 00528 << "\n*** produced can be specified using the option ***" 00529 << "\n*** NLPSolverClientInterface::journal_output_level (the default ***" 00530 << "\n*** is PRINT_NOTHING and produces no output ***" 00531 << "\n********************************************************************\n"; 00532 00533 // Echo options. 00534 if(do_summary_outputting()) { 00535 *summary_out_used_ << "\n*** Echoing input options ...\n"; 00536 if(options_used_.get()) 00537 options_used_->print_options( *summary_out_used_ ); 00538 summary_out_used_->flush(); 00539 } 00540 if(do_algo_outputting()) { 00541 *algo_out_used_ << "\n*** Echoing input options ...\n"; 00542 if(options_used_.get()) 00543 options_used_->print_options( *algo_out_used_ ); 00544 algo_out_used_->flush(); 00545 } 00546 if(do_journal_outputting()) { 00547 *journal_out_used_ << "\n*** Echoing input options ...\n"; 00548 if(options_used_.get()) 00549 options_used_->print_options( *journal_out_used_ ); 00550 journal_out_used_->flush(); 00551 } 00552 00553 // 00554 // Allocate the workspace 00555 // 00556 00557 nlp_->set_options(options_used_); 00558 nlp_->initialize(); 00559 const int default_ws_scale = 10; 00560 if( workspace_MB_ < 0.0 ) { 00561 workspace_MB_ = nlp_->n() * default_ws_scale * 1e-6 * sizeof(value_type); 00562 if(do_algo_outputting()) 00563 *algo_out_used_ 00564 << "\nworkspace_MB < 0.0:\n" 00565 << "Setting workspace_MB = n * default_ws_scale * 1e-6 * sizeof(value_type) = " 00566 << nlp_->n() << " * " << default_ws_scale << " * 1e-6 * " << sizeof(value_type) 00567 << " = " << workspace_MB_ << " MB\n"; 00568 } 00569 if(do_summary_outputting()) 00570 *summary_out_used_ 00571 << "\nAllocating workspace_MB = " << workspace_MB_ << " megabytes of temporary " 00572 "workspace for automatic arrays only ...\n"; 00573 Teuchos::set_default_workspace_store( 00574 Teuchos::rcp(new Teuchos::WorkspaceStoreInitializeable(static_cast<size_t>(1e+6*workspace_MB_))) 00575 ); 00576 00577 // 00578 // Reconfigure the algorithm 00579 // 00580 00581 // Get and set up the configuration object 00582 config_ptr_t _config; 00583 if(config_.get() == NULL) { 00584 if (configuration_ == (EConfigOptions) INTERIOR_POINT) { 00585 _config = Teuchos::rcp(new NLPAlgoConfigIP()); 00586 } 00587 else { 00588 _config = Teuchos::rcp(new NLPAlgoConfigMamaJama()); 00589 } 00590 } 00591 else 00592 _config = config_; 00593 _config->set_options( options_used_ ); 00594 00595 if( do_summary_outputting() || do_journal_outputting() || do_algo_outputting() ) { 00596 std::ostringstream msg; 00597 msg << "\n*** Setting up to run MOOCHO on the NLP using a " 00598 << "configuration object of type \'" << typeName(*_config) << "\' ...\n"; 00599 if(do_summary_outputting()) 00600 *summary_out_used_ << msg.str(); 00601 if(do_journal_outputting()) 00602 *journal_out_used_ << msg.str(); 00603 if(do_algo_outputting()) 00604 *algo_out_used_ << msg.str(); 00605 } 00606 00607 // Set up the solver 00608 00609 solver_.set_nlp(nlp_); // Set the NLP object 00610 solver_.set_config(_config); // Set the configuration object 00611 00612 // Set the client interface options 00613 if(options_used_.get()) { 00614 NLPSolverClientInterfaceSetOptions 00615 solver_options_setter( &solver_ ); 00616 solver_options_setter.set_options( *options_used_ ); 00617 } 00618 00619 reconfig_solver_ = false; 00620 00621 // 00622 // Set up the track objects 00623 // 00624 00625 RCP<AlgorithmTrackerComposite> 00626 composite_track = Teuchos::rcp(new AlgorithmTrackerComposite(journal_out_used_)); 00627 if(do_console_outputting()) 00628 composite_track->tracks().push_back( 00629 Teuchos::rcp(new MoochoTrackerConsoleStd(console_out_used_,journal_out_used_)) ); 00630 if(do_summary_outputting()) 00631 composite_track->tracks().push_back( 00632 Teuchos::rcp(new MoochoTrackerSummaryStd(summary_out_used_,journal_out_used_)) ); 00633 if(stats_out_used_.get()) { 00634 composite_track->tracks().push_back( 00635 Teuchos::rcp(new MoochoTrackerStatsStd(stats_out_used_,stats_out_used_)) ); 00636 } 00637 if( track_.get() ) { 00638 track_->set_journal_out(journal_out_used_); 00639 composite_track->tracks().push_back( track_ ); 00640 } 00641 solver_.set_track( composite_track ); 00642 00643 // 00644 // Configure and print the algorithm if needed 00645 // 00646 00647 solver_.configure_algorithm(algo_out_used_.get()); 00648 if( do_algo_outputting() && print_algo_ ) 00649 solver_.print_algorithm(*algo_out_used_); 00650 00651 } 00652 00653 } 00654 00655 MoochoSolver::ESolutionStatus MoochoSolver::solve_nlp() const 00656 { 00657 using std::endl; 00658 using std::setw; 00659 using std::flush; 00660 using StopWatchPack::stopwatch; 00661 using Teuchos::RCP; 00662 00663 stopwatch timer; 00664 bool threw_exception = false; 00665 ESolutionStatus solve_return = SOLVE_RETURN_EXCEPTION; 00666 NLPSolverClientInterface::EFindMinReturn 00667 r_find_min = NLPSolverClientInterface::SOLUTION_FOUND; 00668 00669 try { 00670 00671 update_solver(); 00672 00673 { 00674 std::ostringstream os; 00675 os 00676 << "\n*****************************" 00677 << "\n*** MoochoSolver::solve() ***" 00678 << "\n*****************************\n"; 00679 *this->get_console_out() << os.str(); 00680 *this->get_summary_out() << os.str(); 00681 *this->get_journal_out() << os.str(); 00682 } 00683 // 00684 // Direct any output from the NLP to the journal output file 00685 // 00686 00687 EJournalOutputLevel olevel = solver_.journal_output_level(); 00688 Teuchos::VerboseObjectTempState<NLP> 00689 nlpOutputTempState(nlp_,Teuchos::getFancyOStream(journal_out_used_),convertToVerbLevel(olevel)); 00690 00691 // 00692 // Scale the NLP objective function 00693 // 00694 00695 nlp_->scale_f(obj_scale_); 00696 00697 // 00698 // Test the nlp if needed 00699 // 00700 00701 if(test_nlp_) { 00702 00703 const char msg1[] = "\ntest_nlp = true: Testing the NLP! ...\n"; 00704 if(do_console_outputting()) 00705 *console_out_used_ << msg1; 00706 if(do_summary_outputting()) 00707 *summary_out_used_ << msg1; 00708 if(do_journal_outputting()) 00709 *journal_out_used_ << msg1; 00710 if(NLPFirstOrder* nlp_foi = dynamic_cast<NLPFirstOrder*>(nlp_.get())) { 00711 const char msg[] = "\nTesting the supported NLPFirstOrder interface ...\n"; 00712 if(do_console_outputting()) 00713 *console_out_used_ << msg; 00714 if(do_summary_outputting()) 00715 *summary_out_used_ << msg; 00716 if(do_journal_outputting()) 00717 *journal_out_used_ << msg; 00718 const bool 00719 result = NLPInterfacePack::test_nlp_first_order( 00720 nlp_foi,options_used_.get() 00721 ,do_journal_outputting() ? journal_out_used_.get() : NULL 00722 ); 00723 if(!result) { 00724 const char msg[] = "\nNLPFirstOrder test failed (see journal file)! exiting!\n"; 00725 if(do_console_outputting()) 00726 *console_out_used_ << msg; 00727 if(do_summary_outputting()) 00728 *summary_out_used_ << msg; 00729 if(do_journal_outputting()) 00730 *journal_out_used_ << msg; 00731 solve_return = SOLVE_RETURN_NLP_TEST_FAILED; 00732 return solve_return; 00733 } 00734 } 00735 else if(NLPDirect* nlp_fod = dynamic_cast<NLPDirect*>(nlp_.get())) { 00736 const char msg[] = "\nTesting the supported NLPDirect interface ...\n"; 00737 if(do_console_outputting()) 00738 *console_out_used_ << msg; 00739 if(do_summary_outputting()) 00740 *summary_out_used_ << msg; 00741 if(do_journal_outputting()) 00742 *journal_out_used_ << msg; 00743 const bool 00744 result = NLPInterfacePack::test_nlp_direct( 00745 nlp_fod,options_used_.get() 00746 ,do_journal_outputting() ? journal_out_used_.get() : NULL 00747 ); 00748 if(!result) { 00749 const char msg[] = "\nNLPDirect test failed (see journal file)! exiting!\n"; 00750 if(do_console_outputting()) 00751 *console_out_used_ << msg; 00752 if(do_summary_outputting()) 00753 *summary_out_used_ << msg; 00754 if(do_journal_outputting()) 00755 *journal_out_used_ << msg; 00756 solve_return = SOLVE_RETURN_NLP_TEST_FAILED; 00757 return solve_return; 00758 } 00759 } 00760 const char msg2[] = "\nSuccessful end of testing of the nlp\n"; 00761 if(do_console_outputting()) 00762 *console_out_used_ << msg2; 00763 if(do_summary_outputting()) 00764 *summary_out_used_ << msg2; 00765 if(do_journal_outputting()) 00766 *journal_out_used_ << msg2; 00767 00768 } 00769 00770 // 00771 // Solve the NLP 00772 // 00773 00774 if(do_journal_outputting()) 00775 *journal_out_used_ 00776 << "\n************************************" 00777 << "\n*** MoochoSolver::solve_nlp() ***" 00778 << "\n************************************\n" 00779 << "\n*** Starting iterations ...\n\n"; 00780 00781 solver_.set_algo_timing(algo_timing_); 00782 timer.start(); 00783 r_find_min = solver_.find_min(); 00784 00785 } 00786 catch(const std::exception& excpt) { 00787 std::ostringstream msg; 00788 msg << "\nMoochoSolver: Caught an std::exception of type " 00789 << typeName(excpt) << " described as : " << excpt.what() << endl; 00790 *error_out_used_ << msg.str() << flush; 00791 if(do_summary_outputting()) 00792 *summary_out_used_ << msg.str() << flush; 00793 if(do_journal_outputting()) 00794 *journal_out_used_ << msg.str() << flush; 00795 if(throw_exceptions_) 00796 throw; 00797 threw_exception = true; 00798 } 00799 catch(...) { 00800 std::ostringstream msg; 00801 msg << "\nMoochoSolver: Caught an unknown exception (i.e. ...)\n"; 00802 *error_out_used_ << msg.str() << flush; 00803 if(do_summary_outputting()) 00804 *summary_out_used_ << msg.str() << flush; 00805 if(do_journal_outputting()) 00806 *journal_out_used_ << msg.str() << flush; 00807 if(throw_exceptions_) 00808 throw; 00809 threw_exception = true; 00810 } 00811 00812 timer.stop(); 00813 00814 if(threw_exception) { 00815 if(do_summary_outputting()) 00816 *summary_out_used_ << "\n\n****************************\n" 00817 << "**** Threw an exception ****\n"; 00818 solve_return = SOLVE_RETURN_EXCEPTION; 00819 } 00820 else { 00821 switch( r_find_min ) { 00822 case NLPSolverClientInterface::SOLUTION_FOUND: { 00823 if(do_summary_outputting()) 00824 *summary_out_used_ << "\n\n************************\n" 00825 << "**** Solution Found ****\n"; 00826 *error_out_used_ << "Solution Found!\n"; 00827 solve_return = SOLVE_RETURN_SOLVED; 00828 break; 00829 } 00830 case NLPSolverClientInterface::MAX_ITER_EXCEEDED: { 00831 if(do_summary_outputting()) 00832 *summary_out_used_ << "\n\n**********************************************\n" 00833 << "**** Maximun number of iteration exceeded ****\n"; 00834 *error_out_used_ << "Maximun number of iteration exceeded!\n"; 00835 solve_return = SOLVE_RETURN_MAX_ITER; 00836 break; 00837 } 00838 case NLPSolverClientInterface::MAX_RUN_TIME_EXCEEDED: { 00839 if(do_summary_outputting()) 00840 *summary_out_used_ << "\n\n**********************************\n" 00841 << "**** Maximun runtime exceeded ****\n"; 00842 *error_out_used_ << "Maximun runtime exceeded!\n"; 00843 solve_return = SOLVE_RETURN_MAX_RUN_TIME; 00844 break; 00845 } 00846 case NLPSolverClientInterface::ALGORITHMIC_ERROR: { 00847 if(do_summary_outputting()) 00848 *summary_out_used_ << "\n\n*********************************************\n" 00849 << "**** Some error occurred in the algorithm ****\n"; 00850 *error_out_used_ << "Some algorithmic error occurred!\n"; 00851 solve_return = SOLVE_RETURN_EXCEPTION; 00852 break; 00853 } 00854 } 00855 } 00856 00857 if(do_summary_outputting()) { 00858 *summary_out_used_ << "\n total time = " << timer.read() << " sec.\n"; 00859 if( solver_.algo_timing() ) { 00860 Teuchos::TimeMonitor::format().setRowsBetweenLines(100); 00861 solver_.print_algorithm_times( *summary_out_used_ ); 00862 *summary_out_used_ << "\n\n"; 00863 Teuchos::TimeMonitor::summarize(*summary_out_used_); 00864 } 00865 } 00866 00867 // Print workspace usage statistics 00868 if(do_summary_outputting()) 00869 *summary_out_used_ 00870 << "\n*** Statistics for automatic array workspace:" 00871 << "\nNumber of megabytes of preallocated workspace = " 00872 << workspace_MB_ 00873 << "\nNumber of allocations using preallocated workspace = " 00874 << Teuchos::get_default_workspace_store()->num_static_allocations() 00875 << "\nNumber of dynamic allocations beyond preallocated workspace = " 00876 << Teuchos::get_default_workspace_store()->num_dyn_allocations(); 00877 00878 // Print which options groups were not read 00879 if( do_algo_outputting() && print_opt_grp_not_accessed_ ) { 00880 *algo_out_used_ 00881 << "\n***************************************************************\n" 00882 "Warning, the following options groups where not accessed.\n" 00883 "An options group may not be accessed if it is not looked for\n" 00884 "or if an \"optional\" options group was looked from and the user\n" 00885 "spelled it incorrectly:\n\n"; 00886 if(options_used_.get()) 00887 options_used_->print_unaccessed_options_groups(*algo_out_used_); 00888 } 00889 00890 if(do_console_outputting()) 00891 console_out_used_->flush(); 00892 if(do_summary_outputting()) 00893 summary_out_used_->flush(); 00894 if(do_journal_outputting()) 00895 journal_out_used_->flush(); 00896 if(do_algo_outputting()) 00897 algo_out_used_->flush(); 00898 00899 return solve_return; 00900 00901 } 00902 00903 // Get the underlying solver object 00904 00905 NLPSolverClientInterface& MoochoSolver::get_solver() 00906 { 00907 update_solver(); 00908 return solver_; 00909 } 00910 00911 const NLPSolverClientInterface& MoochoSolver::get_solver() const 00912 { 00913 update_solver(); 00914 return solver_; 00915 } 00916 00917 // private 00918 00919 void MoochoSolver::generate_output_streams() const 00920 { 00921 if( do_console_outputting() && console_out_used_.get() == NULL ) { 00922 if( console_out_.get() == NULL ) { 00923 console_out_used_ = Teuchos::VerboseObjectBase::getDefaultOStream(); 00924 console_out_ = console_out_used_; 00925 } 00926 else { 00927 console_out_used_ = console_out_; 00928 } 00929 } 00930 if( do_summary_outputting() && summary_out_used_.get()==NULL ) { 00931 if( summary_out_.get() == NULL ) { 00932 summary_out_used_ = generate_output_file("MoochoSummary"); 00933 summary_out_ = summary_out_used_; 00934 } 00935 else { 00936 summary_out_used_ = summary_out_; 00937 } 00938 } 00939 if( do_journal_outputting() && journal_out_used_.get() == NULL ) { 00940 if( journal_out_.get() == NULL ) { 00941 journal_out_used_ = generate_output_file("MoochoJournal"); 00942 journal_out_ = journal_out_used_; 00943 } 00944 else { 00945 journal_out_used_ = journal_out_; 00946 } 00947 } 00948 else { 00949 journal_out_used_ = Teuchos::rcp(new Teuchos::oblackholestream()); 00950 } 00951 if( do_algo_outputting() && algo_out_used_.get() == NULL ) { 00952 if( algo_out_.get() == NULL ) { 00953 algo_out_used_ = generate_output_file("MoochoAlgo"); 00954 algo_out_ = algo_out_used_; 00955 } 00956 else { 00957 algo_out_used_ = algo_out_; 00958 } 00959 } 00960 if( generate_stats_file_ && stats_out_used_.get() == NULL ) { 00961 stats_out_used_ = generate_output_file("MoochoStats"); 00962 } 00963 } 00964 00965 } // end namespace MoochoPack
1.7.4