[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