remove OMP support from glop

This commit is contained in:
Laurent Perron
2019-05-28 15:27:21 +02:00
parent 24a4e28e31
commit c65d042e74
2 changed files with 32 additions and 104 deletions

View File

@@ -13,10 +13,6 @@
#include "ortools/glop/primal_edge_norms.h"
#ifdef OMP
#include <omp.h>
#endif
#include "ortools/base/timer.h"
#include "ortools/lp_data/lp_utils.h"
@@ -208,69 +204,31 @@ void PrimalEdgeNorms::UpdateEdgeSquaredNorms(ColIndex entering_col,
int stat_lower_bounded_norms = 0;
const Fractional factor = 2.0 / pivot;
#ifdef OMP
const int num_omp_threads = parameters_.num_omp_threads();
#else
const int num_omp_threads = 1;
#endif
if (num_omp_threads == 1) {
for (const ColIndex col : update_row.GetNonZeroPositions()) {
const Fractional coeff = update_row.GetCoefficient(col);
const Fractional scalar_product = compact_matrix_.ColumnScalarProduct(
col, direction_left_inverse_.values);
num_operations_ += compact_matrix_.column(col).num_entries().value();
for (const ColIndex col : update_row.GetNonZeroPositions()) {
const Fractional coeff = update_row.GetCoefficient(col);
const Fractional scalar_product = compact_matrix_.ColumnScalarProduct(
col, direction_left_inverse_.values);
num_operations_ += compact_matrix_.column(col).num_entries().value();
// Update the edge squared norm of this column. Note that the update
// formula used is important to maximize the precision. See an explanation
// in the dual context in Koberstein's PhD thesis, section 8.2.2.1.
edge_squared_norms_[col] +=
coeff * (coeff * leaving_squared_norm + factor * scalar_product);
// Update the edge squared norm of this column. Note that the update
// formula used is important to maximize the precision. See an explanation
// in the dual context in Koberstein's PhD thesis, section 8.2.2.1.
edge_squared_norms_[col] +=
coeff * (coeff * leaving_squared_norm + factor * scalar_product);
// Make sure it doesn't go under a known lower bound (TODO(user): ref?).
// This way norms are always >= 1.0 .
// TODO(user): precompute 1 / Square(pivot) or 1 / pivot? it will be
// slightly faster, but may introduce numerical issues. More generally,
// this test is only needed in a few cases, so is it worth it?
const Fractional lower_bound = 1.0 + Square(coeff / pivot);
if (edge_squared_norms_[col] < lower_bound) {
edge_squared_norms_[col] = lower_bound;
++stat_lower_bounded_norms;
}
// Make sure it doesn't go under a known lower bound (TODO(user): ref?).
// This way norms are always >= 1.0 .
// TODO(user): precompute 1 / Square(pivot) or 1 / pivot? it will be
// slightly faster, but may introduce numerical issues. More generally,
// this test is only needed in a few cases, so is it worth it?
const Fractional lower_bound = 1.0 + Square(coeff / pivot);
if (edge_squared_norms_[col] < lower_bound) {
edge_squared_norms_[col] = lower_bound;
++stat_lower_bounded_norms;
}
edge_squared_norms_[leaving_col] = leaving_squared_norm;
stats_.lower_bounded_norms.Add(stat_lower_bounded_norms);
} else {
#ifdef OMP
// In the multi-threaded case, perform the same computation as in the
// single-threaded case above.
//
// TODO(user): also update num_operations_.
std::vector<int> thread_local_stat_lower_bounded_norms(num_omp_threads, 0);
const std::vector<ColIndex>& relevant_rows =
update_row.GetNonZeroPositions();
const int parallel_loop_size = relevant_rows.size();
#pragma omp parallel for num_threads(num_omp_threads)
for (int i = 0; i < parallel_loop_size; i++) {
const ColIndex col(relevant_rows[i]);
const Fractional coeff = update_row.GetCoefficient(col);
const Fractional scalar_product = compact_matrix_.ColumnScalarProduct(
col, direction_left_inverse_.values);
edge_squared_norms_[col] +=
coeff * (coeff * leaving_squared_norm + factor * scalar_product);
const Fractional lower_bound = 1.0 + Square(coeff / pivot);
if (edge_squared_norms_[col] < lower_bound) {
edge_squared_norms_[col] = lower_bound;
++thread_local_stat_lower_bounded_norms[omp_get_thread_num()];
}
}
// end of omp parallel for
edge_squared_norms_[leaving_col] = leaving_squared_norm;
for (int i = 0; i < num_omp_threads; i++) {
stat_lower_bounded_norms += thread_local_stat_lower_bounded_norms[i];
}
stats_.lower_bounded_norms.Add(stat_lower_bounded_norms);
#endif // OMP
}
edge_squared_norms_[leaving_col] = leaving_squared_norm;
stats_.lower_bounded_norms.Add(stat_lower_bounded_norms);
}
void PrimalEdgeNorms::UpdateDevexWeights(

View File

@@ -13,10 +13,6 @@
#include "ortools/glop/update_row.h"
#ifdef OMP
#include <omp.h>
#endif
#include "ortools/lp_data/lp_utils.h"
namespace operations_research {
@@ -273,45 +269,19 @@ void UpdateRow::ComputeUpdatesColumnWise() {
const Fractional drop_tolerance = parameters_.drop_tolerance();
coefficient_.resize(num_cols, 0.0);
non_zero_position_list_.clear();
#ifdef OMP
const int num_omp_threads = parameters_.num_omp_threads();
if (num_omp_threads == 1) {
#endif
for (const ColIndex col : variables_info_.GetIsRelevantBitRow()) {
// Coefficient of the column right inverse on the 'leaving_row'.
const Fractional coeff =
matrix_.ColumnScalarProduct(col, unit_row_left_inverse_.values);
// Nothing to do if 'coeff' is (almost) zero which does happen due to
// sparsity. Note that it shouldn't be too bad to use a non-zero drop
// tolerance here because even if we introduce some precision issues, the
// quantities updated by this update row will eventually be recomputed.
if (std::abs(coeff) > drop_tolerance) {
non_zero_position_list_.push_back(col);
coefficient_[col] = coeff;
}
}
#ifdef OMP
} else {
// In the multi-threaded case, perform the same computation as in the
// single-threaded case above.
const DenseBitRow& is_relevant = variables_info_.GetIsRelevantBitRow();
const int parallel_loop_size = is_relevant.size().value();
#pragma omp parallel for num_threads(num_omp_threads)
for (int i = 0; i < parallel_loop_size; i++) {
const ColIndex col(i);
if (is_relevant.IsSet(col)) {
coefficient_[col] =
matrix_.ColumnScalarProduct(col, unit_row_left_inverse_.values);
}
}
// End of omp parallel for.
for (const ColIndex col : variables_info_.GetIsRelevantBitRow()) {
if (std::abs(coefficient_[col]) > drop_tolerance) {
non_zero_position_list_.push_back(col);
}
for (const ColIndex col : variables_info_.GetIsRelevantBitRow()) {
// Coefficient of the column right inverse on the 'leaving_row'.
const Fractional coeff =
matrix_.ColumnScalarProduct(col, unit_row_left_inverse_.values);
// Nothing to do if 'coeff' is (almost) zero which does happen due to
// sparsity. Note that it shouldn't be too bad to use a non-zero drop
// tolerance here because even if we introduce some precision issues, the
// quantities updated by this update row will eventually be recomputed.
if (std::abs(coeff) > drop_tolerance) {
non_zero_position_list_.push_back(col);
coefficient_[col] = coeff;
}
}
#endif // OMP
}
} // namespace glop