Skip to content

Commit

Permalink
Merge pull request #1941 from ERGO-Code/fix-1930
Browse files Browse the repository at this point in the history
Only check for timeout if time_limit is finite, and don't consider timed logging if output_flag is false; formatted
  • Loading branch information
jajhall authored Oct 9, 2024
2 parents 3b0c798 + 70fdc01 commit 7406b5f
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 18 deletions.
10 changes: 8 additions & 2 deletions src/io/HMpsFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

namespace free_format_parser {

const bool kNoClockCalls = false;

FreeFormatParserReturnCode HMpsFF::loadProblem(
const HighsLogOptions& log_options, const std::string filename,
HighsModel& model) {
Expand Down Expand Up @@ -517,8 +519,12 @@ HMpsFF::Parsekey HMpsFF::parseDefault(const HighsLogOptions& log_options,

double getWallTime() {
using namespace std::chrono;
return duration_cast<duration<double> >(wall_clock::now().time_since_epoch())
.count();
const double wall_time = kNoClockCalls
? 0
: duration_cast<duration<double> >(
wall_clock::now().time_since_epoch())
.count();
return wall_time;
}

HMpsFF::Parsekey HMpsFF::parseObjsense(const HighsLogOptions& log_options,
Expand Down
1 change: 0 additions & 1 deletion src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4358,7 +4358,6 @@ HighsStatus Highs::returnFromRun(const HighsStatus run_return_status,
const bool solved_as_mip = !options_.solver.compare(kHighsChooseString) &&
model_.isMip() && !options_.solve_relaxation;
if (!solved_as_mip) reportSolvedLpQpStats();

return returnFromHighs(return_status);
}

Expand Down
5 changes: 3 additions & 2 deletions src/mip/HighsMipSolverData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1872,8 +1872,9 @@ bool HighsMipSolverData::checkLimits(int64_t nodeOffset) const {

// const double time = mipsolver.timer_.read(mipsolver.timer_.solve_clock);
// printf("checkLimits: time = %g\n", time);
if (mipsolver.timer_.read(mipsolver.timer_.solve_clock) >=
options.time_limit) {
if (options.time_limit < kHighsInf &&
mipsolver.timer_.read(mipsolver.timer_.solve_clock) >=
options.time_limit) {
if (mipsolver.modelstatus_ == HighsModelStatus::kNotset) {
highsLogDev(options.log_options, HighsLogType::kInfo,
"Reached time limit\n");
Expand Down
12 changes: 7 additions & 5 deletions src/presolve/HPresolve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4256,12 +4256,13 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
HighsInt numCol = model->num_col_ - numDeletedCols;
HighsInt numRow = model->num_row_ - numDeletedRows;
HighsInt numNonz = Avalue.size() - freeslots.size();
// Only read the run time if it's to be printed
const double run_time =
options->output_flag ? this->timer->read(run_clock) : 0;
#ifndef NDEBUG
std::string time_str =
" " + std::to_string(this->timer->read(run_clock)) + "s";
std::string time_str = " " + std::to_string(run_time) + "s";
#else
std::string time_str =
" " + std::to_string(int(this->timer->read(run_clock))) + "s";
std::string time_str = " " + std::to_string(int(run_time)) + "s";
#endif
highsLogUser(options->log_options, HighsLogType::kInfo,
"%" HIGHSINT_FORMAT " rows, %" HIGHSINT_FORMAT
Expand Down Expand Up @@ -4489,7 +4490,8 @@ HPresolve::Result HPresolve::checkLimits(HighsPostsolveStack& postsolve_stack) {
if ((numreductions & 1023u) == 0) {
assert(timer);
assert(run_clock >= 0);
if (timer->read(run_clock) >= options->time_limit) {
if (options->time_limit < kHighsInf &&
timer->read(run_clock) >= options->time_limit) {
return Result::kStopped;
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/qpsolver/feasibility_highs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@ static void computeStartingPointHighs(Instance& instance,

highs.setOptionValue("presolve", "on");

highs.setOptionValue("time_limit", settings.time_limit -
timer.readRunHighsClock());
const double use_time_limit = settings.time_limit < kHighsInf ?
settings.time_limit - timer.readRunHighsClock() :
kHighsInf;

highs.setOptionValue("time_limit", use_time_limit);

HighsLp lp;
lp.a_matrix_.index_ = instance.A.mat.index;
Expand Down
3 changes: 2 additions & 1 deletion src/simplex/HEkk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3458,7 +3458,8 @@ bool HEkk::bailout() {
model_status_ == HighsModelStatus::kIterationLimit ||
model_status_ == HighsModelStatus::kObjectiveBound ||
model_status_ == HighsModelStatus::kObjectiveTarget);
} else if (timer_->readRunHighsClock() > options_->time_limit) {
} else if (options_->time_limit < kHighsInf &&
timer_->readRunHighsClock() > options_->time_limit) {
solve_bailout_ = true;
model_status_ = HighsModelStatus::kTimeLimit;
} else if (iteration_count_ >= options_->simplex_iteration_limit) {
Expand Down
2 changes: 1 addition & 1 deletion src/simplex/HEkkDual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ void HEkkDual::reportRebuild(const HighsInt reason_for_rebuild) {
analysis->rebuild_reason = reason_for_rebuild;
analysis->rebuild_reason_string =
ekk_instance_.rebuildReason(reason_for_rebuild);
analysis->invertReport();
if (ekk_instance_.options_->output_flag) analysis->invertReport();
analysis->simplexTimerStop(ReportRebuildClock);
}

Expand Down
2 changes: 1 addition & 1 deletion src/simplex/HEkkPrimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2676,7 +2676,7 @@ void HEkkPrimal::reportRebuild(const HighsInt reason_for_rebuild) {
analysis->rebuild_reason = reason_for_rebuild;
analysis->rebuild_reason_string =
ekk_instance_.rebuildReason(reason_for_rebuild);
analysis->invertReport();
if (ekk_instance_.options_->output_flag) analysis->invertReport();
analysis->simplexTimerStop(ReportRebuildClock);
}

Expand Down
2 changes: 2 additions & 0 deletions src/simplex/HighsSimplexAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ void HighsSimplexAnalysis::iterationReport() {
iterationReport(false);
}

// Called externally - from HEkkPrimal/Dual::reportRebuild
void HighsSimplexAnalysis::invertReport() {
if (*log_options.log_dev_level) {
const bool header = (num_invert_report_since_last_header < 0) ||
Expand Down Expand Up @@ -373,6 +374,7 @@ void HighsSimplexAnalysis::invertReport(const bool header) {
if (!header) num_invert_report_since_last_header++;
}

// Called externally - from HEkk::returnFromSolve
void HighsSimplexAnalysis::userInvertReport(const bool force) {
if (last_user_log_time < 0) {
const bool header = true;
Expand Down
11 changes: 8 additions & 3 deletions src/util/HighsTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "util/HighsInt.h"

const bool kNoClockCalls = false;

/**
* @brief Clock record structure
*/
Expand Down Expand Up @@ -311,9 +313,12 @@ class HighsTimer {
*/
double getWallTime() {
using namespace std::chrono;
return duration_cast<duration<double> >(
wall_clock::now().time_since_epoch())
.count();
const double wall_time = kNoClockCalls
? 0
: duration_cast<duration<double> >(
wall_clock::now().time_since_epoch())
.count();
return wall_time;
}

virtual ~HighsTimer() = default;
Expand Down

0 comments on commit 7406b5f

Please sign in to comment.