Skip to content

Commit dc45be1

Browse files
committed
MAINT: Use exceptions to propagate errors
1 parent 49a27c5 commit dc45be1

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

src/presolve/HPresolve.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,11 +3817,22 @@ HPresolve::Result HPresolve::initialRowAndColPresolve(
38173817
// arrays are not initialized, also unset changedRowFlag so that the row will
38183818
// be added to the changed row vector when it is changed after it was
38193819
// processed
3820-
for (HighsInt row = 0; row != model->num_row_; ++row) {
3821-
if (rowDeleted[row]) continue;
3822-
HPRESOLVE_CHECKED_CALL(rowPresolve(postsolve_stack, row));
3823-
changedRowFlag[row] = false;
3824-
}
3820+
try {
3821+
for (HighsInt row = 0; row != model->num_row_; ++row) {
3822+
if (rowDeleted[row]) continue;
3823+
HPRESOLVE_CHECKED_CALL(rowPresolve(postsolve_stack, row));
3824+
changedRowFlag[row] = false;
3825+
}
3826+
} catch(const ProblemTooLargeException& e) {
3827+
std::cerr << "The problem is too large to be presolved with the current resources.\n";
3828+
std::cerr << "A problem occurred during execution: " << e.what() << std::endl;
3829+
std::cerr << "Model details: \n";
3830+
std::cerr << "Number of rows: " << model->num_row_ << "\n";
3831+
// Add additional model details as needed
3832+
// Once the necessary information is printed, you could decide whether to terminate or propagate the error further.
3833+
// Here we re-throw the error to allow higher level code to decide on next steps
3834+
throw;
3835+
}
38253836

38263837
// same for the columns
38273838
for (HighsInt col = 0; col != model->num_col_; ++col) {

src/presolve/HPresolve.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "util/HighsHash.h"
3333
#include "util/HighsLinearSumBounds.h"
3434
#include "util/HighsMatrixSlice.h"
35+
#include "util/HighsExceptions.h"
3536

3637
namespace presolve {
3738

src/presolve/HighsPostsolveStack.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <tuple>
2525
#include <vector>
2626

27+
#include "HighsExceptions.h"
2728
#include "lp_data/HConst.h"
2829
#include "lp_data/HStruct.h"
2930
#include "lp_data/HighsOptions.h"
@@ -367,6 +368,7 @@ class HighsPostsolveStack {
367368
template <typename ColStorageFormat>
368369
void fixedColAtLower(HighsInt col, double fixValue, double colCost,
369370
const HighsMatrixSlice<ColStorageFormat>& colVec) {
371+
try {
370372
assert(std::isfinite(fixValue));
371373
colValues.clear();
372374
for (const HighsSliceNonzero& colVal : colVec)
@@ -376,8 +378,12 @@ class HighsPostsolveStack {
376378
HighsBasisStatus::kLower});
377379
reductionValues.push(colValues);
378380
reductionAdded(ReductionType::kFixedCol);
381+
} catch(const DataStackOverflow& e) {
382+
std::cerr << "Memory allocation failed while processing fixedColAtLower: " << e.what() << std::endl;
383+
// Throw another exception.
384+
throw PresolveTooLarge("The problem cannot be pre-solved, either lower the size or try without presolve");
379385
}
380-
386+
}
381387
template <typename ColStorageFormat>
382388
void fixedColAtUpper(HighsInt col, double fixValue, double colCost,
383389
const HighsMatrixSlice<ColStorageFormat>& colVec) {

src/util/HighsDataStack.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include <cstring>
2121
#include <type_traits>
2222
#include <vector>
23+
#include <string>
2324

2425
#include "util/HighsInt.h"
26+
#include "util/HighsExceptions.h"
2527

2628
#if __GNUG__ && __GNUC__ < 5
2729
#define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
@@ -40,10 +42,18 @@ class HighsDataStack {
4042
typename std::enable_if<IS_TRIVIALLY_COPYABLE(T), int>::type = 0>
4143
void push(const T& r) {
4244
HighsInt dataSize = data.size();
43-
data.resize(dataSize + sizeof(T));
44-
std::memcpy(data.data() + dataSize, &r, sizeof(T));
45+
HighsInt newSize = dataSize + sizeof(T);
46+
try {
47+
data.resize(newSize);
48+
} catch (const std::length_error& e) {
49+
throw DataStackOverflow(
50+
"Failed to resize the vector. Requested new size: " +
51+
std::to_string(newSize) +
52+
". Size to add is "+std::to_string(sizeof(T))+"."+
53+
". Current size: " + std::to_string(data.size()) + ".");
4554
}
46-
55+
std::memcpy(data.data() + dataSize, &r, sizeof(T));
56+
}
4757
template <typename T,
4858
typename std::enable_if<IS_TRIVIALLY_COPYABLE(T), int>::type = 0>
4959
void pop(T& r) {

0 commit comments

Comments
 (0)