[GIT] ppl/ppl(master): Added deterministic timeout predicates to the Prolog language interface.

Module: ppl/ppl Branch: master Commit: ff28fdbc4a1fc2016fe249373caa755e05ff5961 URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=ff28fdbc4a1fc...
Author: Enea Zaffanella zaffanella@cs.unipr.it Date: Mon Jul 13 09:24:12 2009 +0200
Added deterministic timeout predicates to the Prolog language interface.
---
interfaces/Prolog/Prolog_interface.dox | 22 ++++++ ...erface_generator_prolog_procedure_generators.m4 | 2 + interfaces/Prolog/ppl_prolog_common.cc | 68 +++++++++++++++++++- interfaces/Prolog/ppl_prolog_common.defs.hh | 28 +++++++- 4 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/interfaces/Prolog/Prolog_interface.dox b/interfaces/Prolog/Prolog_interface.dox index 9af2b30..d4f5f14 100644 --- a/interfaces/Prolog/Prolog_interface.dox +++ b/interfaces/Prolog/Prolog_interface.dox @@ -435,6 +435,28 @@ that are included with all instantiations of the Prolog interfaces.
<EM>Resets the timeout time so that the computation is not interrupted.</EM>
+<P><CODE> ppl_set_deterministic_timeout(+Weight) </CODE><BR> + + <EM>Computations taking exponential time will be interrupted + some time after reaching the <CODE>Weight</CODE> complexity threshold. + If the computation is interrupted that way, the current timeout + exception atom will be thrown. + <CODE>Weight</CODE> must be strictly greater than zero.</EM> + <P> + <EM>NOTE:</EM> This "timeout" checking functionality is said to be + <EM>deterministic</EM> because it is not based on actual elapsed time. + Its behavior will only depend on (some of the) computations performed + in the PPL library and it will be otherwise independent from the + computation environment (CPU, operating system, compiler, etc.). + The weight mechanism is under alpha testing: client applications + should be ready to reconsider the tuning of these weight thresholds + when upgrading to newer version of the PPL. + +<P><CODE> ppl_reset_deterministic_timeout </CODE><BR> + + <EM>Resets the deterministic timeout so that the computation is not + interrupted.</EM> + <P><CODE> ppl_set_rounding_for_PPL </CODE><BR>
<EM>Sets the FPU rounding mode so that the PPL abstractions based on diff --git a/interfaces/Prolog/ppl_interface_generator_prolog_procedure_generators.m4 b/interfaces/Prolog/ppl_interface_generator_prolog_procedure_generators.m4 index 220395d..ed75f67 100644 --- a/interfaces/Prolog/ppl_interface_generator_prolog_procedure_generators.m4 +++ b/interfaces/Prolog/ppl_interface_generator_prolog_procedure_generators.m4 @@ -54,6 +54,8 @@ ppl_set_timeout_exception_atom/1 *nofail, ppl_timeout_exception_atom/1, ppl_set_timeout/1 *nofail, ppl_reset_timeout/0 *nofail, +ppl_set_deterministic_timeout/1 *nofail, +ppl_reset_deterministic_timeout/0 *nofail, ppl_new_MIP_Problem_from_space_dimension/2, ppl_new_MIP_Problem/5, ppl_new_MIP_Problem_from_MIP_Problem/2, diff --git a/interfaces/Prolog/ppl_prolog_common.cc b/interfaces/Prolog/ppl_prolog_common.cc index ec88eb0..100e6e9 100644 --- a/interfaces/Prolog/ppl_prolog_common.cc +++ b/interfaces/Prolog/ppl_prolog_common.cc @@ -599,6 +599,12 @@ handle_exception() {
Parma_Watchdog_Library::Watchdog* p_timeout_object = 0;
+typedef +Parma_Watchdog_Library::Threshold_Watcher +<Parma_Polyhedra_Library::Weightwatch_Traits> Weightwatch; + +Weightwatch* p_deterministic_timeout_object = 0; + void reset_timeout() { if (p_timeout_object) { @@ -607,7 +613,16 @@ reset_timeout() { abandon_expensive_computations = 0; } } -#endif + +void +reset_deterministic_timeout() { + if (p_deterministic_timeout_object) { + delete p_deterministic_timeout_object; + p_deterministic_timeout_object = 0; + abandon_expensive_computations = 0; + } +} +#endif // PPL_WATCHDOG_LIBRARY_ENABLED
Prolog_atom timeout_exception_atom;
@@ -622,6 +637,17 @@ handle_exception(const timeout_exception&) { Prolog_raise_exception(et); }
+void +handle_exception(const deterministic_timeout_exception&) { +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED + assert(p_deterministic_timeout_object); + reset_deterministic_timeout(); +#endif + Prolog_term_ref et = Prolog_new_term_ref(); + Prolog_put_atom(et, timeout_exception_atom); + Prolog_raise_exception(et); +} + Prolog_term_ref variable_term(dimension_type varid) { Prolog_term_ref v = Prolog_new_term_ref(); @@ -1374,6 +1400,12 @@ term_to_complexity_class(Prolog_term_ref t, const char* where) {
using namespace Parma_Polyhedra_Library::Interfaces::Prolog;
+#ifdef PPL_WATCHDOG_LIBRARY_ENABLED +template <> Weightwatch::Initialize +Weightwatch::init = Weightwatch::Initialize(); +#endif // PPL_WATCHDOG_LIBRARY_ENABLED + + extern "C" Prolog_foreign_return_type ppl_version_major(Prolog_term_ref t_v) { try { @@ -1595,6 +1627,40 @@ ppl_reset_timeout() { }
extern "C" Prolog_foreign_return_type +ppl_set_deterministic_timeout(Prolog_term_ref t_weight) { + try { +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED + // In case a deterministic timeout was already set. + reset_deterministic_timeout(); + static deterministic_timeout_exception e; + unsigned weight + = term_to_unsigned<unsigned>(t_weight, + "ppl_set_deterministic_timeout/1"); + p_deterministic_timeout_object = + new Weightwatch(weight, abandon_expensive_computations, e); + return PROLOG_SUCCESS; +#else + used(t_weight); + return PROLOG_FAILURE; +#endif + } + CATCH_ALL; +} + +extern "C" Prolog_foreign_return_type +ppl_reset_deterministic_timeout() { + try { +#ifdef PPL_WATCHDOG_LIBRARY_ENABLED + reset_deterministic_timeout(); + return PROLOG_SUCCESS; +#else + return PROLOG_FAILURE; +#endif + } + CATCH_ALL; +} + +extern "C" Prolog_foreign_return_type ppl_Coefficient_is_bounded() { try { if (std::numeric_limits<Coefficient>::is_bounded) diff --git a/interfaces/Prolog/ppl_prolog_common.defs.hh b/interfaces/Prolog/ppl_prolog_common.defs.hh index cc7e7e4..dfede01 100644 --- a/interfaces/Prolog/ppl_prolog_common.defs.hh +++ b/interfaces/Prolog/ppl_prolog_common.defs.hh @@ -421,7 +421,8 @@ handle_exception(const std::exception& e); void handle_exception();
-class timeout_exception : public Parma_Polyhedra_Library::Throwable { +class timeout_exception + : public Parma_Polyhedra_Library::Throwable { public: void throw_me() const { throw *this; @@ -429,13 +430,25 @@ public: int priority() const { return 0; } - timeout_exception() { - } };
void handle_exception(const timeout_exception&);
+class deterministic_timeout_exception + : public Parma_Polyhedra_Library::Throwable { +public: + void throw_me() const { + throw *this; + } + int priority() const { + return 0; + } +}; + +void +handle_exception(const deterministic_timeout_exception&); + #define CATCH_ALL \ catch (const Prolog_unsigned_out_of_range& e) { \ handle_exception(e); \ @@ -485,6 +498,9 @@ handle_exception(const timeout_exception&); catch (const timeout_exception& e) { \ handle_exception(e); \ } \ + catch (const deterministic_timeout_exception& e) { \ + handle_exception(e); \ + } \ catch(const std::overflow_error& e) { \ handle_exception(e); \ } \ @@ -688,6 +704,12 @@ extern "C" Prolog_foreign_return_type ppl_reset_timeout();
extern "C" Prolog_foreign_return_type +ppl_set_deterministic_timeout(Prolog_term_ref t_weight); + +extern "C" Prolog_foreign_return_type +ppl_reset_deterministic_timeout(); + +extern "C" Prolog_foreign_return_type ppl_Coefficient_is_bounded();
extern "C" Prolog_foreign_return_type
participants (1)
-
Enea Zaffanella