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
910namespace 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
401411void 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
440463Int 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 " ;
0 commit comments