Skip to content

Commit 33350fe

Browse files
committed
Warn about overflow
1 parent b55bf47 commit 33350fe

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "Status.h"
66
#include "ipm/hipo/auxiliary/Auxiliary.h"
77
#include "ipm/hipo/auxiliary/Log.h"
8+
#include "ipm/hipo/factorhighs/ReturnValues.h"
89

910
namespace hipo {
1011

@@ -33,7 +34,7 @@ static Int getASstructure(const HighsSparseMatrix& A, std::vector<Int>& ptr,
3334
Int mA = A.num_row_;
3435
Int nzA = A.numNz();
3536

36-
if (nA + nzA + mA > kHighsIInf) return kStatusOoM;
37+
if (nA + nzA + mA > kHighsIInf) return kStatusOverflow;
3738

3839
ptr.resize(nA + mA + 1);
3940
rows.resize(nA + nzA + mA);
@@ -195,6 +196,8 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
195196
// intersection of row with rows below finished.
196197

197198
// if the total number of nonzeros exceeds the maximum, return error
199+
if ((int64_t)ptrNE_[row] + (int64_t)nz_in_col >= kHighsIInf)
200+
return kStatusOverflow;
198201
if ((int64_t)ptrNE_[row] + (int64_t)nz_in_col >= nz_limit)
199202
return kStatusOoM;
200203

@@ -395,7 +398,14 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
395398
S.print(log_, true);
396399
}
397400

398-
return status ? kStatusErrorAnalyse : kStatusOk;
401+
if (status == kRetIntOverflow)
402+
status = kStatusOverflow;
403+
else if (status)
404+
status = kStatusErrorAnalyse;
405+
else
406+
status = kStatusOk;
407+
408+
return status;
399409
}
400410

401411
void FactorHiGHSSolver::freeNEmemory() {
@@ -434,7 +444,20 @@ Int FactorHiGHSSolver::analyseNE(Symbolic& S, int64_t nz_limit) {
434444
S.print(log_, true);
435445
}
436446

437-
return status ? kStatusErrorAnalyse : kStatusOk;
447+
if (status == kRetIntOverflow)
448+
status = kStatusOverflow;
449+
else if (status)
450+
status = kStatusErrorAnalyse;
451+
else
452+
status = kStatusOk;
453+
454+
return status;
455+
}
456+
457+
static void warnOverflow(const LogHighs& log) {
458+
log.printw(
459+
"32-bit integer overflow occurred during the factorisation. Consider "
460+
"compiling HiGHS with 64-bit integers.\n");
438461
}
439462

440463
Int FactorHiGHSSolver::chooseNla() {
@@ -446,14 +469,22 @@ Int FactorHiGHSSolver::chooseNla() {
446469
Symbolic symb_AS{};
447470
bool failure_NE = false;
448471
bool failure_AS = false;
472+
bool overflow_NE = false;
473+
bool overflow_AS = false;
449474

450475
symb_NE.setMetisNo2hop(options_.metis_no2hop);
451476
symb_AS.setMetisNo2hop(options_.metis_no2hop);
452477

453478
Clock clock;
454479

455480
// Perform analyse phase of augmented system
456-
if (analyseAS(symb_AS)) failure_AS = true;
481+
if (Int status_AS = analyseAS(symb_AS)) {
482+
failure_AS = true;
483+
if (status_AS == kStatusOverflow) {
484+
log_.printDevInfo("AS overflow\n");
485+
overflow_AS = true;
486+
}
487+
}
457488

458489
// Perform analyse phase of normal equations
459490
if (model_.m() > kMinRowsForDensity &&
@@ -469,7 +500,11 @@ Int FactorHiGHSSolver::chooseNla() {
469500

470501
Int NE_status = analyseNE(symb_NE, NE_nz_limit);
471502
if (NE_status) failure_NE = true;
472-
if (NE_status == kStatusOoM) log_.printDevInfo("NE matrix is too large\n");
503+
if (NE_status == kStatusOverflow) {
504+
log_.printDevInfo("NE overflow\n");
505+
overflow_NE = true;
506+
} else if (NE_status == kStatusOoM)
507+
log_.printDevInfo("NE matrix is too large\n");
473508
}
474509

475510
Int status = kStatusOk;
@@ -491,6 +526,8 @@ Int FactorHiGHSSolver::chooseNla() {
491526
log_.print(
492527
"Large fill-in in factorisation. Consider setting the "
493528
"hipo_metis_no2hop option to true\n");
529+
530+
if (overflow_AS && overflow_NE) warnOverflow(log_);
494531
} else {
495532
// Total number of operations, given by dense flops and sparse indexing
496533
// operations, weighted with an empirical factor
@@ -539,21 +576,19 @@ Int FactorHiGHSSolver::setNla() {
539576

540577
switch (options_.nla) {
541578
case kOptionNlaAugmented: {
542-
if (analyseAS(S_)) {
579+
if (Int status = analyseAS(S_)) {
543580
log_.printe("AS requested, failed analyse phase\n");
581+
if (status == kStatusOverflow) warnOverflow(log_);
544582
return kStatusErrorAnalyse;
545583
}
546584
log_stream << textline("Newton system:") << "AS requested\n";
547585
break;
548586
}
549587

550588
case kOptionNlaNormEq: {
551-
Int status = analyseNE(S_);
552-
if (status == kStatusOoM) {
553-
log_.printe("NE requested, matrix is too large\n");
554-
return kStatusOoM;
555-
} else if (status) {
589+
if (Int status = analyseNE(S_)) {
556590
log_.printe("NE requested, failed analyse phase\n");
591+
if (status == kStatusOverflow) warnOverflow(log_);
557592
return kStatusErrorAnalyse;
558593
}
559594
log_stream << textline("Newton system:") << "NE requested\n";

highs/ipm/hipo/ipm/Status.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ enum Status {
2626
kStatusFailed,
2727
kStatusError,
2828
kStatusOoM,
29+
kStatusOverflow,
2930
kStatusErrorAnalyse,
3031
kStatusErrorFactorise,
3132
kStatusErrorSolve,
@@ -67,6 +68,7 @@ inline std::string statusString(Status status) {
6768
{kStatusImprecise, "imprecise"},
6869
{kStatusError, "internal error"},
6970
{kStatusOoM, "out of memory"},
71+
{kStatusOverflow, "Integer overflow"},
7072
{kStatusErrorAnalyse, "error in analyse phase"},
7173
{kStatusErrorFactorise, "error in factorise phase"},
7274
{kStatusErrorSolve, "error in solve phase"},

0 commit comments

Comments
 (0)