[PPL-devel] [GIT] ppl/ppl(sparse_matrices): MIP_Problem: optimize process_pending_constraints() for sparse backends with fast random reads and/or writes.

Marco Poletti poletti.marco at gmail.com
Thu Apr 15 19:35:34 CEST 2010


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

Author: Marco Poletti <poletti.marco at gmail.com>
Date:   Thu Apr 15 19:20:19 2010 +0200

MIP_Problem: optimize process_pending_constraints() for sparse backends with fast random reads and/or writes.

---

 src/MIP_Problem.cc |   59 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/MIP_Problem.cc b/src/MIP_Problem.cc
index 6d819cc..651ecb0 100644
--- a/src/MIP_Problem.cc
+++ b/src/MIP_Problem.cc
@@ -717,11 +717,14 @@ PPL::MIP_Problem::process_pending_constraints() {
     ? artificial_index : 0;
 
   typedef process_pending_constraints_helper_struct buffer_element_t;
-  // Used to improve performance, ordering writes to tableau_k.
-  std::vector<buffer_element_t> buffer;
 
-  // Used to optimize access to tableau_k below.
+#ifdef PPL_SPARSE_BACKEND_SLOW_RANDOM_READS
+  // Used to optimize access to tableau_k.
   std::vector<std::pair<dimension_type, dimension_type> > vars_in_base;
+#endif
+
+  // Used to improve performance, ordering writes to tableau_k.
+  std::vector<buffer_element_t> buffer;
 
   // Proceed with the insertion of the constraints.
   for (dimension_type k = tableau_num_rows, i = input_cs.size();
@@ -729,6 +732,8 @@ PPL::MIP_Problem::process_pending_constraints() {
     if (is_tableau_constraint[i]) {
       // Copy the original constraint in the tableau.
       matrix_row_reference_type tableau_k = tableau[--k];
+
+#ifdef PPL_SPARSE_BACKEND_SLOW_RANDOM_WRITES
       const Constraint& cs_i = input_cs[i];
       for (dimension_type sd = cs_i.space_dimension(); sd-- > 0; ) {
         const Coefficient& current_coefficient =
@@ -785,12 +790,44 @@ PPL::MIP_Problem::process_pending_constraints() {
         }
         buffer.clear();
       }
-      // The following loops are equivalent to this simpler (but slower) loop.
-      //
-      // for (dimension_type j = base_size; j-- > 0; )
-      //   if (k != j && base[j] != 0 && tableau_k.get(base[j]) != 0)
-      //    linear_combine(tableau_k, tableau[j], base[j]);
+#else // defined(PPL_SPARSE_BACKEND_SLOW_RANDOM_WRITES)
+      const Constraint& cs_i = input_cs[i];
+      for (dimension_type sd = cs_i.space_dimension(); sd-- > 0; ) {
+        const Coefficient& current_coefficient =
+          cs_i.coefficient(Variable(sd));
+        // The test against 0 is not needed, but improves performance.
+        if (current_coefficient != 0) {
+          tableau_k[mapping[sd + 1].first] = current_coefficient;
+          // Split if needed.
+          if (mapping[sd + 1].second != 0)
+            neg_assign(tableau_k[mapping[sd + 1].second],
+                       current_coefficient);
+        }
+      }
+      const Coefficient& cs_i_inhomogeneous_term = cs_i.inhomogeneous_term();
+      // The test against 0 is not needed, but improves performance.
+      if (cs_i_inhomogeneous_term != 0) {
+        tableau_k[mapping[0].first] = cs_i_inhomogeneous_term;
+        // Split if needed.
+        if (mapping[0].second != 0)
+          neg_assign(tableau_k[mapping[0].second], cs_i_inhomogeneous_term);
+      }
 
+      // Add the slack variable, if needed.
+      if (cs_i.is_inequality()) {
+        neg_assign(tableau_k[--slack_index], Coefficient_one());
+        // If the constraint is already satisfied, we will not use artificial
+        // variables to compute a feasible base: this to speed up
+        // the algorithm.
+        if (satisfied_ineqs[i]) {
+          base[k] = slack_index;
+          worked_out_row[k] = true;
+        }
+      }
+#endif // defined(PPL_SPARSE_BACKEND_SLOW_RANDOM_WRITES)
+
+
+#ifdef PPL_SPARSE_BACKEND_SLOW_RANDOM_READS
       // We need to sort accesses by base[j], not by j.
 
       for (dimension_type j = base_size; j-- > 0; )
@@ -825,6 +862,12 @@ PPL::MIP_Problem::process_pending_constraints() {
       }
 
       vars_in_base.clear();
+
+#else // defined(PPL_SPARSE_BACKEND_SLOW_RANDOM_READS)
+      for (dimension_type j = base_size; j-- > 0; )
+        if (k != j && base[j] != 0 && tableau_k.get(base[j]) != 0)
+         linear_combine(tableau_k, tableau[j], base[j]);
+#endif // defined(PPL_SPARSE_BACKEND_SLOW_RANDOM_READS)
     }
 
   // We negate the row if tableau[i][0] <= 0 to get the inhomogeneous term > 0.




More information about the PPL-devel mailing list