Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Gracefully fail for OOM (Out of Memory) in Presolve #1467

Open
wants to merge 9 commits into
base: latest
Choose a base branch
from
1 change: 1 addition & 0 deletions src/Highs.h
Expand Up @@ -23,6 +23,7 @@
#include "model/HighsModel.h"
#include "presolve/ICrash.h"
#include "presolve/PresolveComponent.h"
#include "util/HighsExceptions.h"

/**
* @brief Return the version
Expand Down
16 changes: 12 additions & 4 deletions src/presolve/HPresolve.cpp
Expand Up @@ -3685,10 +3685,18 @@ HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack,
// assert(non_fractional);
if (!non_fractional) return Result::kPrimalInfeasible;
}
postsolve_stack.fixedColAtLower(nonzero.index(),
model->col_lower_[nonzero.index()],
model->col_cost_[nonzero.index()],
getColumnVector(nonzero.index()));
try {
postsolve_stack.fixedColAtLower(
nonzero.index(), model->col_lower_[nonzero.index()],
model->col_cost_[nonzero.index()],
getColumnVector(nonzero.index()));
} catch (const DataStackOverflow& e) {
highsLogUser(options->log_options, HighsLogType::kError,
"Problem too large for Presolve, try without\n");
highsLogUser(options->log_options, HighsLogType::kInfo,
"Specific error raised:\n%s\n", e.what());
return Result::kPrimalInfeasible;
}
if (model->col_upper_[nonzero.index()] >
model->col_lower_[nonzero.index()])
changeColUpper(nonzero.index(),
Expand Down
15 changes: 13 additions & 2 deletions src/util/HighsDataStack.h
Expand Up @@ -16,9 +16,11 @@
#define UTIL_HIGHS_DATA_STACK_H_

#include <cstring>
#include <string>
#include <type_traits>
#include <vector>

#include "util/HighsExceptions.h"
#include "util/HighsInt.h"

#if __GNUG__ && __GNUC__ < 5 && !defined(__clang__)
Expand All @@ -37,8 +39,17 @@ class HighsDataStack {
template <typename T,
typename std::enable_if<IS_TRIVIALLY_COPYABLE(T), int>::type = 0>
void push(const T& r) {
std::size_t dataSize = data.size();
data.resize(dataSize + sizeof(T));
HighsInt dataSize = data.size();
HighsInt newSize = dataSize + sizeof(T);
try {
data.resize(newSize);
} catch (const std::length_error& e) {
throw DataStackOverflow(
"Failed to resize the vector. Requested new size: " +
std::to_string(newSize) + ". Size to add is " +
std::to_string(sizeof(T)) +
". Current size: " + std::to_string(data.size()) + ".");
}
std::memcpy(data.data() + dataSize, &r, sizeof(T));
}

Expand Down
8 changes: 8 additions & 0 deletions src/util/HighsExceptions.h
@@ -0,0 +1,8 @@
#pragma once
#include <stdexcept>

class DataStackOverflow : public std::runtime_error {
public:
explicit DataStackOverflow(const std::string& msg)
: std::runtime_error(msg) {}
};