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

Enea Zaffanella zaffanella at cs.unipr.it
Mon Jul 13 09:41:43 CEST 2009


Module: ppl/ppl
Branch: master
Commit: ff28fdbc4a1fc2016fe249373caa755e05ff5961
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=ff28fdbc4a1fc2016fe249373caa755e05ff5961

Author: Enea Zaffanella <zaffanella at 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




More information about the PPL-devel mailing list