From f6b18c3a5cbd2678cfa18bcc2d48464ac3920498 Mon Sep 17 00:00:00 2001 From: Laurent Perron Date: Mon, 4 Dec 2023 13:42:21 +0100 Subject: [PATCH] fix crash in glop --- ortools/glop/lu_factorization.cc | 3 +++ ortools/glop/revised_simplex.cc | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/ortools/glop/lu_factorization.cc b/ortools/glop/lu_factorization.cc index 4eb7bae45a..c71dd312fc 100644 --- a/ortools/glop/lu_factorization.cc +++ b/ortools/glop/lu_factorization.cc @@ -64,6 +64,9 @@ Status LuFactorization::ComputeFactorization( stats_.lu_fill_in.Add(GetFillInPercentage(matrix)); stats_.basis_num_entries.Add(matrix.num_entries().value()); }); + + // TODO(user): This might fail on badly scaled matrices. + // I still prefer to keep it as a DCHECK for tests though. DCHECK(CheckFactorization(matrix, Fractional(1e-6))); return Status::OK(); } diff --git a/ortools/glop/revised_simplex.cc b/ortools/glop/revised_simplex.cc index 030ba17f05..a8d302ccaa 100644 --- a/ortools/glop/revised_simplex.cc +++ b/ortools/glop/revised_simplex.cc @@ -3304,6 +3304,17 @@ Status RevisedSimplex::DualMinimize(bool feasibility_phase, } } + // This is to avoid crashes below. It seems to happen rarely on a few miplib + // problem like rmine11.pb.gz in multithread. + // + // TODO(user): Try to recover instead. + if (std::abs(direction_[leaving_row]) <= 1e-20) { + const std::string error_message = absl::StrCat( + "trying to pivot with number too small: ", direction_[leaving_row]); + SOLVER_LOG(logger_, error_message); + return Status(Status::ERROR_LU, error_message); + } + // This test takes place after the check for optimality/feasibility because // when running with 0 iterations, we still want to report // ProblemStatus::OPTIMAL or ProblemStatus::PRIMAL_FEASIBLE if it is the