void ScriptBase<Space>::runMeta(const Options& o, Script* s) { using namespace std; ofstream sol_file, log_file; ostream& s_out = select_ostream(o.out_file(), sol_file); ostream& l_out = select_ostream(o.log_file(), log_file); try { switch (o.mode()) { case SM_GIST: #ifdef GECODE_HAS_GIST { Gist::Print<Script> pi(o.name()); Gist::VarComparator<Script> vc(o.name()); Gist::Options opt; opt.inspect.click(&pi); opt.inspect.compare(&vc); opt.clone = false; opt.c_d = o.c_d(); opt.a_d = o.a_d(); for (int i=0; o.inspect.click(i) != NULL; i++) opt.inspect.click(o.inspect.click(i)); for (int i=0; o.inspect.solution(i) != NULL; i++) opt.inspect.solution(o.inspect.solution(i)); for (int i=0; o.inspect.move(i) != NULL; i++) opt.inspect.move(o.inspect.move(i)); for (int i=0; o.inspect.compare(i) != NULL; i++) opt.inspect.compare(o.inspect.compare(i)); if (s == NULL) s = new Script(o); (void) GistEngine<Engine<Script> >::explore(s, opt); } break; // If Gist is not available, fall through #endif case SM_SOLUTION: { l_out << o.name() << endl; Support::Timer t; int i = o.solutions(); t.start(); if (s == NULL) s = new Script(o); unsigned int n_p = s->propagators(); unsigned int n_b = s->branchers(); Search::Options so; so.threads = o.threads(); so.c_d = o.c_d(); so.a_d = o.a_d(); so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.interrupt()); so.cutoff = createCutoff(o); so.clone = false; so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U; if (o.interrupt()) CombinedStop::installCtrlHandler(true); { Meta<Engine,Script> e(s,so); if (o.print_last()) { Script* px = NULL; do { Script* ex = e.next(); if (ex == NULL) { if (px != NULL) { px->print(s_out); delete px; } break; } else { delete px; px = ex; } } while (--i != 0); } else { do { Script* ex = e.next(); if (ex == NULL) break; ex->print(s_out); delete ex; } while (--i != 0); } if (o.interrupt()) CombinedStop::installCtrlHandler(false); Search::Statistics stat = e.statistics(); s_out << endl; if (e.stopped()) { l_out << "Search engine stopped..." << endl << "\treason: "; int r = static_cast<CombinedStop*>(so.stop)->reason(stat,so); if (r & CombinedStop::SR_INT) l_out << "user interrupt " << endl; else { if (r & CombinedStop::SR_NODE) l_out << "node "; if (r & CombinedStop::SR_FAIL) l_out << "fail "; if (r & CombinedStop::SR_TIME) l_out << "time "; l_out << "limit reached" << endl << endl; } } l_out << "Initial" << endl << "\tpropagators: " << n_p << endl << "\tbranchers: " << n_b << endl << endl << "Summary" << endl << "\truntime: "; stop(t, l_out); l_out << endl << "\tsolutions: " << ::abs(static_cast<int>(o.solutions()) - i) << endl << "\tpropagations: " << stat.propagate << endl << "\tnodes: " << stat.node << endl << "\tfailures: " << stat.fail << endl << "\trestarts: " << stat.restart << endl << "\tno-goods: " << stat.nogood << endl << "\tpeak depth: " << stat.depth << endl #ifdef GECODE_PEAKHEAP << "\tpeak memory: " << static_cast<int>((heap.peak()+1023) / 1024) << " KB" << endl #endif << endl; } delete so.stop; } break; case SM_STAT: { l_out << o.name() << endl; Support::Timer t; int i = o.solutions(); t.start(); if (s == NULL) s = new Script(o); unsigned int n_p = s->propagators(); unsigned int n_b = s->branchers(); Search::Options so; so.clone = false; so.threads = o.threads(); so.c_d = o.c_d(); so.a_d = o.a_d(); so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.interrupt()); so.cutoff = createCutoff(o); so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U; if (o.interrupt()) CombinedStop::installCtrlHandler(true); { Meta<Engine,Script> e(s,so); do { Script* ex = e.next(); if (ex == NULL) break; delete ex; } while (--i != 0); if (o.interrupt()) CombinedStop::installCtrlHandler(false); Search::Statistics stat = e.statistics(); l_out << endl << "\tpropagators: " << n_p << endl << "\tbranchers: " << n_b << endl << "\truntime: "; stop(t, l_out); l_out << endl << "\tsolutions: " << ::abs(static_cast<int>(o.solutions()) - i) << endl << "\tpropagations: " << stat.propagate << endl << "\tnodes: " << stat.node << endl << "\tfailures: " << stat.fail << endl << "\trestarts: " << stat.restart << endl << "\tno-goods: " << stat.nogood << endl << "\tpeak depth: " << stat.depth << endl #ifdef GECODE_PEAKHEAP << "\tpeak memory: " << static_cast<int>((heap.peak()+1023) / 1024) << " KB" << endl #endif << endl; } delete so.stop; } break; case SM_TIME: { l_out << o.name() << endl; Support::Timer t; double* ts = new double[o.samples()]; bool stopped = false; for (unsigned int s = o.samples(); !stopped && s--; ) { t.start(); for (unsigned int k = o.iterations(); !stopped && k--; ) { unsigned int i = o.solutions(); Script* s = new Script(o); Search::Options so; so.clone = false; so.threads = o.threads(); so.c_d = o.c_d(); so.a_d = o.a_d(); so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), false); so.cutoff = createCutoff(o); so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U; { Meta<Engine,Script> e(s,so); do { Script* ex = e.next(); if (ex == NULL) break; delete ex; } while (--i != 0); if (e.stopped()) stopped = true; } delete so.stop; } ts[s] = t.stop() / o.iterations(); } if (stopped) { l_out << "\tSTOPPED" << endl; } else { double m = am(ts,o.samples()); double d = dev(ts,o.samples()) * 100.0; l_out << "\truntime: " << setw(20) << right << showpoint << fixed << setprecision(6) << m << "ms" << setprecision(2) << " (" << d << "% deviation)" << endl; } delete [] ts; } break; } } catch (Exception& e) { cerr << "Exception: " << e.what() << "." << endl << "Stopping..." << endl; if (sol_file.is_open()) sol_file.close(); if (log_file.is_open()) log_file.close(); exit(EXIT_FAILURE); } if (sol_file.is_open()) sol_file.close(); if (log_file.is_open()) log_file.close(); }