Skip to content

Commit bb3b262

Browse files
authored
Merge pull request #2632 from ERGO-Code/better-ipx-logging
Better IPX logging
2 parents 274a8fd + 479ad74 commit bb3b262

File tree

14 files changed

+57
-46
lines changed

14 files changed

+57
-46
lines changed

highs/ipm/IpxWrapper.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ HighsStatus solveLpIpx(const HighsOptions& options, HighsTimer& timer,
6363
resetModelStatusAndHighsInfo(model_status, highs_info);
6464
// Create the LpSolver instance
6565
ipx::LpSolver lps;
66+
// Use the current HiGHS time as an offset for the lps.control_
67+
// elapsed time
68+
lps.setTimerOffset(timer.read());
69+
6670
// Set IPX parameters
6771
//
6872
// Cannot set internal IPX parameters directly since they are
@@ -125,8 +129,9 @@ HighsStatus solveLpIpx(const HighsOptions& options, HighsTimer& timer,
125129

126130
parameters.analyse_basis_data =
127131
kHighsAnalysisLevelNlaData & options.highs_analysis_level;
128-
// Determine the run time allowed for IPX
129-
parameters.time_limit = options.time_limit - timer.read();
132+
// Now that the lps.control_ elapsed time includes the HiGHS time,
133+
// can use the HiGHS time limit
134+
parameters.time_limit = options.time_limit;
130135
parameters.ipm_maxiter =
131136
options.ipm_iteration_limit - highs_info.ipm_iteration_count;
132137
// Determine if crossover is to be run or not
@@ -458,6 +463,10 @@ HighsStatus solveLpHipo(const HighsOptions& options, HighsTimer& timer,
458463

459464
// Create solver instance
460465
hipo::Solver hipo{};
466+
// This creates ipx::LpSolver ipx_lps_, in case HiPO has to switch
467+
// to IPX, so use the current HiGHS time as an offset for the
468+
// ipx_lps.control_ elapsed time
469+
hipo.setIpxTimerOffset(timer.read());
461470

462471
hipo::Options hipo_options{};
463472

@@ -504,7 +513,7 @@ HighsStatus solveLpHipo(const HighsOptions& options, HighsTimer& timer,
504513

505514
// Potentially control if ipx is used for refinement and if it is displayed
506515
// hipo_options.refine_with_ipx = true;
507-
// hipo_options.display_ipx = true;
516+
hipo_options.display_ipx = true;
508517

509518
// if option parallel is on, it can be refined by option hipo_parallel_type
510519
if (options.parallel == kHighsOnString) {
@@ -1591,4 +1600,4 @@ HighsStatus reportHipoCrossoverStatus(const HighsOptions& options,
15911600
}
15921601
return HighsStatus::kError;
15931602
}
1594-
#endif
1603+
#endif

highs/ipm/hipo/ipm/Solver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ bool Solver::prepareIpx() {
187187
ipx_param.ipm_feasibility_tol = options_.feasibility_tol;
188188
ipx_param.ipm_optimality_tol = options_.optimality_tol;
189189
ipx_param.start_crossover_tol = options_.crossover_tol;
190-
ipx_param.time_limit = options_.time_limit - control_.elapsed();
190+
ipx_param.time_limit = options_.time_limit;
191191
ipx_param.ipm_maxiter = options_.max_iter - iter_;
192192
ipx_lps_.SetParameters(ipx_param);
193193

@@ -1590,4 +1590,4 @@ bool Solver::solved() const { return statusIsSolved(); }
15901590
bool Solver::stopped() const { return statusIsStopped(); }
15911591
bool Solver::failed() const { return statusIsFailed(); }
15921592

1593-
} // namespace hipo
1593+
} // namespace hipo

highs/ipm/hipo/ipm/Solver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ class Solver {
121121
bool stopped() const;
122122
bool failed() const;
123123

124+
// Set the IPX timer offset
125+
void setIpxTimerOffset(const double offset) { this->ipx_lps_.setTimerOffset(offset); }
126+
124127
private:
125128
// Functions to run the various stages of the ipm
126129
void runIpm();

highs/ipm/ipx/basis.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Int Basis::Factorize() {
132132
h_logging_stream <<
133133
" Start factorization " << Format(num_factorizations_+1, 3) <<
134134
": nonzeros in basis = " << Format(basis_num_nz, 9) <<
135-
Format("", 14) << Fixed(control_.Elapsed(), 6, 0) << "s\n";
135+
Format("", 14) << time(control_.Elapsed()) << "\n";
136136
control_.hIntervalLog(h_logging_stream);
137137

138138
Int err = 0; // return code
@@ -165,7 +165,7 @@ Int Basis::Factorize() {
165165
h_logging_stream <<
166166
" Finish factorization " << Format(num_factorizations_, 3) <<
167167
": fill factor = " << Fixed(lu_->fill_factor(), 6, 2) <<
168-
Format("", 23) << Fixed(control_.Elapsed(), 6, 0) << "s\n";
168+
Format("", 23) << time(control_.Elapsed()) << "\n";
169169
control_.hIntervalLog(h_logging_stream);
170170
return err;
171171
}
@@ -933,7 +933,7 @@ void Basis::PivotFixedVariablesOutOfBasis(const double* colweights, Info* info){
933933
h_logging_stream.str(std::string());
934934
h_logging_stream << Format(remaining.size(), 9) <<
935935
" fixed variables remaining" << Format("", 38) <<
936-
Fixed(control_.Elapsed(), 6, 0) << "s\n";
936+
time(control_.Elapsed()) << "\n";
937937
control_.hIntervalLog(h_logging_stream);
938938
}
939939
control_.Debug()

highs/ipm/ipx/control.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Control::Control() {
1313
Int Control::InterruptCheck(const Int ipm_iteration_count) const {
1414
HighsTaskExecutor::getThisWorkerDeque()->checkInterrupt();
1515
if (parameters_.time_limit >= 0.0 &&
16-
parameters_.time_limit < timer_.Elapsed())
16+
parameters_.time_limit < this->Elapsed())
1717
return IPX_ERROR_time_interrupt;
1818
// The pointer callback_ should not be null, since that indicates
1919
// that it's not been set
@@ -38,7 +38,8 @@ void Control::hLog(std::string str) const {
3838
} else {
3939
output_ << str;
4040
}
41-
41+
// Reset interval-based logging since something has been logged
42+
interval_.Reset();
4243
}
4344

4445
void Control::hLog(std::stringstream& logging) const {
@@ -50,9 +51,12 @@ void Control::hLog(std::stringstream& logging) const {
5051
output_ << logging.str();
5152
}
5253
logging.str(std::string());
54+
// Reset interval-based logging since something has been logged
55+
interval_.Reset();
5356
}
5457

5558
void Control::hIntervalLog(std::stringstream& logging) const {
59+
double interval_elapsed = interval_.Elapsed();
5660
if (parameters_.print_interval >= 0.0 &&
5761
interval_.Elapsed() >= parameters_.print_interval) {
5862
interval_.Reset();
@@ -79,7 +83,7 @@ void Control::ResetPrintInterval() const {
7983
}
8084

8185
double Control::Elapsed() const {
82-
return timer_.Elapsed();
86+
return timer_.offset_ + timer_.Elapsed();
8387
}
8488

8589
const Parameters& Control::parameters() const {

highs/ipm/ipx/control.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class Control {
9292
double centringAlphaScaling() const{return parameters_.centring_alpha_scaling; }
9393
ipxint badProductsTolerance() const{return parameters_.bad_products_tolerance; }
9494
bool timelessLog() const{return parameters_.timeless_log; }
95+
void setTimerOffset(const double offset) { this->timer_.offset_ = offset; }
96+
9597

9698
const Parameters& parameters() const;
9799
void parameters(const Parameters& new_parameters);
@@ -137,6 +139,7 @@ inline std::string sci2(double d) { return Scientific(d,0,2); }
137139
inline std::string sci8(double d) { return Scientific(d,0,8); }
138140
inline std::string fix2(double d) { return Fixed(d,0,2); }
139141
inline std::string fix8(double d) { return Fixed(d,0,8); }
142+
inline std::string time(double d) { return Fixed(d,8,1); }
140143

141144
// Formats @text into a line of fixed width and indentation.
142145
// This is used to print messages like

highs/ipm/ipx/ipm.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -828,9 +828,8 @@ void IPM::PrintHeader() {
828828
<< " " << Format("pinf", 9)
829829
<< " " << Format("dinf", 9)
830830
<< " " << Format("gap", 8);
831-
// h_logging_stream << " " << Format("mu", 8);
832831
if (!control_.timelessLog())
833-
h_logging_stream << " " << Format("time", 7);
832+
h_logging_stream << " " << Format("time", 7);
834833
control_.hLog(h_logging_stream);
835834
control_.Debug()
836835
<< " " << Format("stepsizes", 9)
@@ -868,7 +867,7 @@ void IPM::PrintOutput() {
868867
<< " " << Scientific(logging_gap, 8, 2);
869868
// h_logging_stream << " " << Scientific(iterate_->mu(), 8, 2);
870869
if (!control_.timelessLog())
871-
h_logging_stream << " " << Fixed(control_.Elapsed(), 6, 0) << "s";
870+
h_logging_stream << " " << time(control_.Elapsed());
872871
control_.hLog(h_logging_stream);
873872
control_.Debug()
874873
<< " " << Fixed(step_primal_, 4, 2) << " " << Fixed(step_dual_, 4, 2)

highs/ipm/ipx/ipm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class IPM {
3737

3838
Int maxiter() const { return maxiter_; }
3939
void maxiter(Int i) { maxiter_ = i; }
40+
void PrintHeader();
4041

4142
private:
4243
struct Step;
@@ -67,7 +68,6 @@ class IPM {
6768
void SolveNewtonSystem(const double* rb, const double* rc,
6869
const double* rl, const double* ru,
6970
const double* sl, const double* su, Step& lhs);
70-
void PrintHeader();
7171
void PrintOutput();
7272

7373
const Control& control_;

highs/ipm/ipx/ipx_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct Parameters : public ipx_parameters {
2121
Parameters() {
2222
display = 1;
2323
logfile = nullptr;
24-
print_interval = 5.0;
24+
print_interval = 60.0;
2525
analyse_basis_data = false;
2626
time_limit = -1.0;
2727
dualize = -1;

highs/ipm/ipx/lp_solver.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ void LpSolver::RunIPM() {
394394
info_.centring_success = false;
395395

396396
if (x_start_.size() != 0) {
397-
control_.hLog(" Using starting point provided by user. Skipping initial iterations.\n");
397+
control_.hLog(" Using starting point provided by user. Skipping initial iterations.\n");
398398
iterate_->Initialize(x_start_, xl_start_, xu_start_,
399399
y_start_, zl_start_, zu_start_);
400400
}
@@ -558,6 +558,7 @@ void LpSolver::BuildStartingBasis() {
558558
void LpSolver::RunMainIPM(IPM& ipm) {
559559
KKTSolverBasis kkt(control_, *basis_);
560560
Timer timer;
561+
ipm.PrintHeader();
561562
ipm.maxiter(control_.ipm_maxiter());
562563
ipm.Driver(&kkt, iterate_.get(), &info_);
563564
info_.time_ipm2 = timer.Elapsed();

0 commit comments

Comments
 (0)