source: colin/trunk/src/ColinDriver.cpp @ 5736

Revision 5736, 8.4 KB checked in by jdsiiro, 5 years ago (diff)
  • switching PointSet? get_point() & set_point() to use Anys
  • cleaning up colin_driver() and removing the old colin_main() function
Line 
1/*  _________________________________________________________________________
2 *
3 *  COLIN: A Common Optimization Library INterface
4 *  Copyright (c) 2003, Sandia National Laboratories.
5 *  This software is distributed under the GNU Lesser General Public License.
6 *  For more information, see the README.html file in the top COLIN directory.
7 *  _________________________________________________________________________
8 */
9
10
11#include <colin/XMLProcessor.h>
12#include <colin/ApplicationMngr.h>
13#include <colin/OptSolver.h>
14#include <colin/SolverHandle.h>
15#include <colin/SolverMngr.h>
16#include <colin/AmplDriver.h>
17
18#include <utilib/OptionParser.h>
19#include <utilib/exception_mngr.h>
20#include <utilib/seconds.h>
21#include <utilib/CommonIO.h>
22#include <utilib/MPIStream.h>
23
24#include <tinyxml.h>
25
26using std::cerr;
27using std::endl;
28
29using std::string;
30using std::stringstream;
31using std::istringstream;
32using std::ostringstream;
33using std::list;
34using std::pair;
35
36
37namespace colin {
38
39namespace {
40
41int done(int return_code = 0)
42{
43   ucout << utilib::Flush;
44   ucerr << utilib::Flush;
45   utilib::CommonIO::end();
46
47#if defined(ACRO_HAVE_MPI)
48   utilib::uMPI::done();
49#endif
50   
51   colin::ApplicationMngr().clear();
52
53   return return_code;
54}
55
56}
57
58
59int colin_driver( int argc, char* argv[],
60                  const std::string codename, const std::string version )
61{
62   InitializeTiming();
63   double start_time = CPUSeconds();
64   
65#if defined(ACRO_HAVE_MPI)
66   utilib::uMPI::init(&argc, &argv, MPI_COMM_WORLD);
67#endif
68   
69   utilib::CommonIO::begin();
70   
71#if defined(ACRO_HAVE_MPI)
72   int rank = utilib::uMPI::rank;
73   if (utilib::uMPI::rank == 0)
74      utilib::CommonIO::end_tagging();
75#else
76   int rank = 0;
77#endif
78
79   utilib::OptionParser parser;
80   string usage = codename;
81   usage += " [options] <arg1> <arg2>";
82   parser.add_usage(usage);
83   usage = codename;
84   usage += " <*.nl> -AMPL";
85   usage += codename;
86   usage += " [options] <colin-xml-input>";
87   parser.add_usage(usage);
88   parser.description = "This is a COLIN optimizer executable.";
89   parser.epilog = "Additional optimizer options can be specified within "
90      "AMPL or the COLIN XML input.";
91   if (version != "")
92      parser.version(version);
93
94   bool verbose = false;
95   parser.add("verbose", verbose, "Verbose printing during optimization.");
96
97   bool debug_solver_params = false;
98   parser.add("debug-solver-params", debug_solver_params,
99              "Print solver option values before running it.");
100
101   string help_options = "";
102   parser.add("help-options", help_options,
103              "Print options for specified solver.");
104
105   bool help_solvers = false;
106   parser.add("help-solvers", help_solvers,
107              "Print the list of solvers supported by this executable.");
108
109   bool help_solvers_xml = false;
110   parser.add("help-solvers-xml", help_solvers_xml,
111              "Print the list of solvers supported by this executable to "
112              "a file using an XML format.");
113
114   int repetitions = 0;
115   parser.add("repetitions", repetitions,
116              "The number of times that the solver is rerun (to check that "
117              "solver reset() methods work).");
118
119   bool use_abort = false;
120   parser.add("use-abort", use_abort,
121              "Force an abort when an error occurs.");
122
123   //
124   // Parse the command line
125   //
126   try
127   {
128      parser.parse_args(argc, argv);
129   }
130   catch (std::runtime_error& err)
131   {
132      ucout << err.what() << endl
133            << "Type '" << codename << " --help' for more information."
134            << endl;
135      return done(1);
136   }
137   if ( parser.help_option() )
138   {
139      parser.write(ucout);
140      return done();
141   }
142   if ( parser.version_option() )
143   {
144      parser.print_version(ucout);
145      return done();
146   }
147
148   if ( help_solvers_xml )
149   {
150      list<pair<string, string> > info;
151      SolverMngr().get_solver_types(info);
152
153      ucout << "<COLINSolvers interface=\"" << codename
154            << "\" num=\"" << info.size() << "\">" << endl;
155      list<pair<string, string> >::iterator curr = info.begin();
156      list<pair<string, string> >::iterator end  = info.end();
157      while (curr != end)
158      {
159         ucout << "<Solver name=\"" << curr->first << "\">" << endl;
160         SolverHandle handle = SolverMngr().create_solver( curr->first );
161         //handle.solver()->options().write_parameters_xml(ucout);
162         ucout << "</Solver>" << endl;
163         curr++;
164      }
165      ucout << "</COLINSolvers>" << endl;
166      return done();
167   }
168
169   //
170   // Help - options for a solver
171   //
172   if ( help_options == "true" )
173      EXCEPTION_MNGR(std::runtime_error, "ERROR: using --help-options "
174                     "but no solver name is specified.");
175
176   if ( ! help_options.empty() )
177   {
178      colin::SolverHandle handle;
179      try
180      {
181         handle = SolverMngr().create_solver(help_options);
182      }
183      catch (std::exception& )
184      {
185         ucout << "Solver \"" << help_options << "\" not found!\n\n";
186         help_solvers=true;
187      }
188      if ( !handle.empty() )
189      {
190         ucout << "Options for solver \"" << help_options << "\"";
191         handle.solver()->options().write(ucout);
192         return done();
193      }
194   }
195   //
196   // Help - list solvers
197   //
198   if (help_solvers)
199   {
200      ucout << string('*', 77) << endl;
201      ucout << "Solvers defined in '" << codename << "'" << endl;
202      ucout << string('*', 77) << endl;
203
204      list<pair<string, string> > info;
205      SolverMngr().get_solver_types(info);
206      if (info.size() == 0)
207         ucout << "    None" << endl;
208      else
209      {
210         ucout << endl;
211         list<pair<string, string> >::iterator curr = info.begin();
212         list<pair<string, string> >::iterator end  = info.end();
213         while (curr != end)
214         {
215            {
216               ucout << "    " << curr->first << endl;
217               ucout << "         " << curr->second << endl;
218               curr++;
219            }
220         }
221         return done();
222      }
223   }
224
225   try
226   {
227      if (parser.args().size() == 2)
228      {
229         // 2) Load the XML file (root rank only)
230         TiXmlDocument doc;
231         if ( rank == 0 )
232         {
233            if ( !doc.LoadFile(argv[1]) )
234            {
235               cerr << "TinyXML Error : " << doc.ErrorDesc() << endl;
236               cerr << "TinyXML Error : Row " << doc.ErrorRow()
237                    << "  Column " << doc.ErrorCol() << endl;
238               EXCEPTION_MNGR(std::runtime_error,
239                              "colin_driver - Error processing filename \""
240                              << argv[1] << "\"");
241            }
242            if ( doc.RootElement()->ValueStr().compare("ColinInput") != 0 )
243               EXCEPTION_MNGR(std::runtime_error,
244                              "colin_driver - Error processing data from \""
245                              << argv[1] <<
246                              "\". The root element must be ColinInput.");
247         }
248
249#if defined (ACRO_HAVE_MPI)
250         // 3) Distribute the XML input to all other ranks
251         if ( utilib::uMPI::size > 1 )
252         {
253            utilib::MPIBroadcastStream bcast(0);
254            if ( rank == 0 )
255            {
256               ostringstream input_buf;
257               input_buf << doc;
258               bcast << input_buf.str();
259            }
260            else
261            {
262               string input_str;
263               bcast >> input_str;
264               istringstream input_buf(input_str);
265               input_buf >> doc;
266            }
267         }
268#endif
269
270         // 4) Process the XML input
271         XMLProcessor().process(doc.RootElement());
272
273         // 5) 5 is right out.
274      }
275      else if ((parser.args().size() == 3)  && (parser.args()[2] ==  "-AMPL"))
276      {
277         AMPL_driver(argc, argv, codename.c_str());
278      }
279      else
280      {
281         ucerr << "ERROR: expected exactly one argument: the xml spec "
282            "file; instead got " << (argc-1) << ":" << endl;
283         for(int i = 0; i < argc; ++i )
284            cerr << "          \"" << argv[i] << "\"" << endl;
285         ucout << "Type '" << codename << " --help' for usage information."
286               << endl;
287         return done(1);
288      }
289
290   }
291   catch (const std::exception& err)
292   {
293      ucerr << "Caught STL exception: " << err.what() << endl;
294      return done(1);
295   }
296   catch (const std::string& err)
297   {
298      ucerr << "Caught string exception: " << err << endl;
299      return done(1);
300   }
301   catch (const char* err)
302   {
303      ucerr << "Caught string exception: " << err << endl;
304      return done(1);
305   }
306
307   return done();
308}
309
310} // namespace colin
Note: See TracBrowser for help on using the repository browser.