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