From c54f91e3d44df81826bea6f64207d8dcd59e00a7 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 7 Feb 2024 10:08:10 +0100 Subject: [PATCH 01/68] Use quad precision to update row activities. This fixes assertion failures on neos4. --- src/mip/HighsDomain.cpp | 178 +++++++++++----------------------------- 1 file changed, 46 insertions(+), 132 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 77ce15344c..8f271055d6 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -444,6 +444,20 @@ void HighsDomain::CutpoolPropagation::markPropagateCut(HighsInt cut) { } } +HighsCDouble computeDelta(HighsInt row, double val, double oldbound, + double newbound, double inf, + std::vector& numinfs) { + if (oldbound == inf) { + --numinfs[row]; + return HighsCDouble(newbound) * val; + } else if (newbound == inf) { + ++numinfs[row]; + return -HighsCDouble(oldbound) * val; + } else { + return (HighsCDouble(newbound) - HighsCDouble(oldbound)) * val; + } +} + void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, double oldbound, double newbound) { @@ -461,17 +475,8 @@ void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, cutpool->getMatrix().forEachPositiveColumnEntry( col, [&](HighsInt row, double val) { assert(val > 0); - double deltamin; - - if (oldbound == -kHighsInf) { - --activitycutsinf_[row]; - deltamin = newbound * val; - } else if (newbound == -kHighsInf) { - ++activitycutsinf_[row]; - deltamin = -oldbound * val; - } else { - deltamin = (newbound - oldbound) * val; - } + HighsCDouble deltamin = computeDelta(row, val, oldbound, newbound, + -kHighsInf, activitycutsinf_); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -504,18 +509,8 @@ void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, cutpool->getMatrix().forEachPositiveColumnEntry( col, [&](HighsInt row, double val) { assert(val > 0); - double deltamin; - - if (oldbound == -kHighsInf) { - --activitycutsinf_[row]; - deltamin = newbound * val; - } else if (newbound == -kHighsInf) { - ++activitycutsinf_[row]; - deltamin = -oldbound * val; - } else { - deltamin = (newbound - oldbound) * val; - } - activitycuts_[row] += deltamin; + activitycuts_[row] += computeDelta(row, val, oldbound, newbound, + -kHighsInf, activitycutsinf_); if (domain->infeasible_reason.index == row) return false; @@ -541,17 +536,8 @@ void HighsDomain::CutpoolPropagation::updateActivityUbChange(HighsInt col, cutpool->getMatrix().forEachNegativeColumnEntry( col, [&](HighsInt row, double val) { assert(val < 0); - double deltamin; - - if (oldbound == kHighsInf) { - --activitycutsinf_[row]; - deltamin = newbound * val; - } else if (newbound == kHighsInf) { - ++activitycutsinf_[row]; - deltamin = -oldbound * val; - } else { - deltamin = (newbound - oldbound) * val; - } + HighsCDouble deltamin = computeDelta(row, val, oldbound, newbound, + kHighsInf, activitycutsinf_); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -582,18 +568,8 @@ void HighsDomain::CutpoolPropagation::updateActivityUbChange(HighsInt col, cutpool->getMatrix().forEachNegativeColumnEntry( col, [&](HighsInt row, double val) { assert(val < 0); - double deltamin; - - if (oldbound == kHighsInf) { - --activitycutsinf_[row]; - deltamin = newbound * val; - } else if (newbound == kHighsInf) { - ++activitycutsinf_[row]; - deltamin = -oldbound * val; - } else { - deltamin = (newbound - oldbound) * val; - } - activitycuts_[row] += deltamin; + activitycuts_[row] += computeDelta(row, val, oldbound, newbound, + kHighsInf, activitycutsinf_); if (domain->infeasible_reason.index == row) return false; @@ -1567,16 +1543,9 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - double deltamin; - if (oldbound == -kHighsInf) { - --activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == -kHighsInf) { - ++activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamin = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } + HighsCDouble deltamin = + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, -kHighsInf, activitymininf_); activitymin_[mip->a_matrix_.index_[i]] += deltamin; #ifndef NDEBUG @@ -1618,16 +1587,9 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, mip->row_upper_[mip->a_matrix_.index_[i]] != kHighsInf) markPropagate(mip->a_matrix_.index_[i]); } else { - double deltamax; - if (oldbound == -kHighsInf) { - --activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == -kHighsInf) { - ++activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamax = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } + HighsCDouble deltamax = + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, -kHighsInf, activitymaxinf_); activitymax_[mip->a_matrix_.index_[i]] += deltamax; #ifndef NDEBUG @@ -1684,29 +1646,13 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, std::swap(oldbound, newbound); for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - double deltamin; - if (oldbound == -kHighsInf) { - --activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == -kHighsInf) { - ++activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamin = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } - activitymin_[mip->a_matrix_.index_[i]] += deltamin; + activitymin_[mip->a_matrix_.index_[i]] += + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, -kHighsInf, activitymininf_); } else { - double deltamax; - if (oldbound == -kHighsInf) { - --activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == -kHighsInf) { - ++activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamax = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } - activitymax_[mip->a_matrix_.index_[i]] += deltamax; + activitymax_[mip->a_matrix_.index_[i]] += + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, -kHighsInf, activitymaxinf_); } } @@ -1736,16 +1682,9 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - double deltamax; - if (oldbound == kHighsInf) { - --activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == kHighsInf) { - ++activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamax = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } + HighsCDouble deltamax = + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, kHighsInf, activitymaxinf_); activitymax_[mip->a_matrix_.index_[i]] += deltamax; #ifndef NDEBUG @@ -1790,17 +1729,9 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, // propagateinds_.push_back(mip->a_matrix_.index_[i]); } } else { - double deltamin; - if (oldbound == kHighsInf) { - --activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == kHighsInf) { - ++activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamin = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } - + HighsCDouble deltamin = + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, kHighsInf, activitymininf_); activitymin_[mip->a_matrix_.index_[i]] += deltamin; #ifndef NDEBUG @@ -1860,30 +1791,13 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, std::swap(oldbound, newbound); for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - double deltamax; - if (oldbound == kHighsInf) { - --activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == kHighsInf) { - ++activitymaxinf_[mip->a_matrix_.index_[i]]; - deltamax = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamax = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } - activitymax_[mip->a_matrix_.index_[i]] += deltamax; + activitymax_[mip->a_matrix_.index_[i]] += + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, kHighsInf, activitymaxinf_); } else { - double deltamin; - if (oldbound == kHighsInf) { - --activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = newbound * mip->a_matrix_.value_[i]; - } else if (newbound == kHighsInf) { - ++activitymininf_[mip->a_matrix_.index_[i]]; - deltamin = -oldbound * mip->a_matrix_.value_[i]; - } else { - deltamin = (newbound - oldbound) * mip->a_matrix_.value_[i]; - } - - activitymin_[mip->a_matrix_.index_[i]] += deltamin; + activitymin_[mip->a_matrix_.index_[i]] += + computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], + oldbound, newbound, kHighsInf, activitymininf_); } } From 3bdff2bd9305c3209a42f270f5e92fa431dfb37d Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 7 Feb 2024 10:50:28 +0100 Subject: [PATCH 02/68] Move code --- src/mip/HighsDomain.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 8f271055d6..75b155f4f9 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -46,6 +46,20 @@ static double activityContributionMax(double coef, const double& lb, } } +static HighsCDouble computeDelta(HighsInt row, double val, double oldbound, + double newbound, double inf, + std::vector& numinfs) { + if (oldbound == inf) { + --numinfs[row]; + return HighsCDouble(newbound) * val; + } else if (newbound == inf) { + ++numinfs[row]; + return -HighsCDouble(oldbound) * val; + } else { + return (HighsCDouble(newbound) - HighsCDouble(oldbound)) * val; + } +} + HighsDomain::HighsDomain(HighsMipSolver& mipsolver) : mipsolver(&mipsolver) { col_lower_ = mipsolver.model_->col_lower_; col_upper_ = mipsolver.model_->col_upper_; @@ -444,20 +458,6 @@ void HighsDomain::CutpoolPropagation::markPropagateCut(HighsInt cut) { } } -HighsCDouble computeDelta(HighsInt row, double val, double oldbound, - double newbound, double inf, - std::vector& numinfs) { - if (oldbound == inf) { - --numinfs[row]; - return HighsCDouble(newbound) * val; - } else if (newbound == inf) { - ++numinfs[row]; - return -HighsCDouble(oldbound) * val; - } else { - return (HighsCDouble(newbound) - HighsCDouble(oldbound)) * val; - } -} - void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, double oldbound, double newbound) { From f53ecbac303b65f1fb9873152d8a0170910bd23b Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 29 May 2024 21:46:11 +0200 Subject: [PATCH 03/68] Minor changes --- src/mip/HighsDomain.cpp | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 3b611b6b91..e037566dfc 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -1263,7 +1263,6 @@ void HighsDomain::computeMinActivity(HighsInt start, HighsInt end, activitymin += contributionmin; } - activitymin.renormalize(); } else { activitymin = 0.0; ninfmin = 0; @@ -1281,9 +1280,8 @@ void HighsDomain::computeMinActivity(HighsInt start, HighsInt end, else activitymin += contributionmin; } - - activitymin.renormalize(); } + activitymin.renormalize(); } void HighsDomain::computeMaxActivity(HighsInt start, HighsInt end, @@ -1309,8 +1307,6 @@ void HighsDomain::computeMaxActivity(HighsInt start, HighsInt end, else activitymax += contributionmin; } - - activitymax.renormalize(); } else { activitymax = 0.0; ninfmax = 0; @@ -1328,9 +1324,8 @@ void HighsDomain::computeMaxActivity(HighsInt start, HighsInt end, else activitymax += contributionmin; } - - activitymax.renormalize(); } + activitymax.renormalize(); } double HighsDomain::adjustedUb(HighsInt col, HighsCDouble boundVal, @@ -1339,12 +1334,9 @@ double HighsDomain::adjustedUb(HighsInt col, HighsCDouble boundVal, if (mipsolver->variableType(col) != HighsVarType::kContinuous) { bound = std::floor(double(boundVal + mipsolver->mipdata_->feastol)); - if (bound < col_upper_[col] && - col_upper_[col] - bound > - 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound)) - accept = true; - else - accept = false; + accept = bound < col_upper_[col] && + col_upper_[col] - bound > + 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound); } else { if (std::fabs(double(boundVal) - col_lower_[col]) <= mipsolver->mipdata_->epsilon) @@ -1374,12 +1366,9 @@ double HighsDomain::adjustedLb(HighsInt col, HighsCDouble boundVal, if (mipsolver->variableType(col) != HighsVarType::kContinuous) { bound = std::ceil(double(boundVal - mipsolver->mipdata_->feastol)); - if (bound > col_lower_[col] && - bound - col_lower_[col] > - 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound)) - accept = true; - else - accept = false; + accept = bound > col_lower_[col] && + bound - col_lower_[col] > + 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound); } else { if (std::fabs(col_upper_[col] - double(boundVal)) <= mipsolver->mipdata_->epsilon) From c57d455fc0cb7d847cb6186083825e9af3a16bb0 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 29 May 2024 22:01:59 +0200 Subject: [PATCH 04/68] Minor stuff --- src/mip/HighsDomain.cpp | 110 +++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 59 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 8f084fe1f0..89385a09b3 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -46,6 +46,14 @@ static double activityContributionMax(double coef, const double& lb, } } +static inline double boundRange(double upper_bound, double lower_bound, + double tolerance, HighsVarType var_type) { + double range = upper_bound - lower_bound; + return range - (var_type == HighsVarType::kContinuous + ? std::max(0.3 * range, 1000.0 * tolerance) + : tolerance); +} + HighsDomain::HighsDomain(HighsMipSolver& mipsolver) : mipsolver(&mipsolver) { col_lower_ = mipsolver.model_->col_lower_; col_upper_ = mipsolver.model_->col_upper_; @@ -369,14 +377,11 @@ void HighsDomain::CutpoolPropagation::recomputeCapacityThreshold(HighsInt cut) { if (domain->col_upper_[arindex[i]] == domain->col_lower_[arindex[i]]) continue; - double boundRange = - domain->col_upper_[arindex[i]] - domain->col_lower_[arindex[i]]; - - boundRange -= domain->variableType(arindex[i]) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - - double threshold = std::fabs(arvalue[i]) * boundRange; + double threshold = + std::fabs(arvalue[i]) * boundRange(domain->col_upper_[arindex[i]], + domain->col_lower_[arindex[i]], + domain->feastol(), + domain->variableType(arindex[i])); capacityThreshold_[cut] = std::max({capacityThreshold_[cut], threshold, domain->feastol()}); @@ -780,12 +785,11 @@ void HighsDomain::ObjectivePropagation::recomputeCapacityThreshold() { for (HighsInt i = partitionStarts[numPartitions]; i < numObjNzs; ++i) { HighsInt col = objNonzeros[i]; - double boundRange = (domain->col_upper_[col] - domain->col_lower_[col]); - boundRange -= domain->variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - capacityThreshold = - std::max(capacityThreshold, std::fabs(cost[col]) * boundRange); + capacityThreshold = std::max( + capacityThreshold, + std::fabs(cost[col]) * + boundRange(domain->col_upper_[col], domain->col_lower_[col], + domain->feastol(), domain->variableType(col))); } } @@ -793,11 +797,11 @@ void HighsDomain::ObjectivePropagation::updateActivityLbChange( HighsInt col, double oldbound, double newbound) { if (cost[col] <= 0.0) { if (cost[col] != 0.0 && newbound < oldbound) { - double boundRange = domain->col_upper_[col] - newbound; - boundRange -= domain->variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - capacityThreshold = std::max(capacityThreshold, -cost[col] * boundRange); + capacityThreshold = + std::max(capacityThreshold, + -cost[col] * boundRange(domain->col_upper_[col], newbound, + domain->feastol(), + domain->variableType(col))); isPropagated = false; } debugCheckObjectiveLower(); @@ -821,11 +825,11 @@ void HighsDomain::ObjectivePropagation::updateActivityLbChange( debugCheckObjectiveLower(); if (newbound < oldbound) { - double boundRange = (domain->col_upper_[col] - domain->col_lower_[col]); - boundRange -= domain->variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - capacityThreshold = std::max(capacityThreshold, cost[col] * boundRange); + capacityThreshold = std::max( + capacityThreshold, + cost[col] * boundRange(domain->col_upper_[col], + domain->col_lower_[col], domain->feastol(), + domain->variableType(col))); } else if (numInfObjLower == 0 && objectiveLower > domain->mipsolver->mipdata_->upper_limit) { domain->infeasible_ = true; @@ -914,11 +918,10 @@ void HighsDomain::ObjectivePropagation::updateActivityUbChange( HighsInt col, double oldbound, double newbound) { if (cost[col] >= 0.0) { if (cost[col] != 0.0 && newbound > oldbound) { - double boundRange = newbound - domain->col_lower_[col]; - boundRange -= domain->variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - capacityThreshold = std::max(capacityThreshold, cost[col] * boundRange); + capacityThreshold = std::max( + capacityThreshold, + cost[col] * boundRange(newbound, domain->col_lower_[col], + domain->feastol(), domain->variableType(col))); isPropagated = false; } debugCheckObjectiveLower(); @@ -942,11 +945,11 @@ void HighsDomain::ObjectivePropagation::updateActivityUbChange( debugCheckObjectiveLower(); if (newbound > oldbound) { - double boundRange = (domain->col_upper_[col] - domain->col_lower_[col]); - boundRange -= domain->variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * domain->feastol()) - : domain->feastol(); - capacityThreshold = std::max(capacityThreshold, -cost[col] * boundRange); + capacityThreshold = std::max( + capacityThreshold, + -cost[col] * boundRange(domain->col_upper_[col], + domain->col_lower_[col], domain->feastol(), + domain->variableType(col))); } else if (numInfObjLower == 0 && objectiveLower > domain->mipsolver->mipdata_->upper_limit) { domain->infeasible_ = true; @@ -1362,7 +1365,7 @@ double HighsDomain::adjustedUb(HighsInt col, HighsCDouble boundVal, double bound; if (mipsolver->variableType(col) != HighsVarType::kContinuous) { - bound = std::floor(double(boundVal + mipsolver->mipdata_->feastol)); + bound = static_cast(floor(boundVal + mipsolver->mipdata_->feastol)); if (bound < col_upper_[col] && col_upper_[col] - bound > 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound)) @@ -1397,7 +1400,7 @@ double HighsDomain::adjustedLb(HighsInt col, HighsCDouble boundVal, double bound; if (mipsolver->variableType(col) != HighsVarType::kContinuous) { - bound = std::ceil(double(boundVal - mipsolver->mipdata_->feastol)); + bound = static_cast(ceil(boundVal - mipsolver->mipdata_->feastol)); if (bound > col_lower_[col] && bound - col_lower_[col] > 1000.0 * mipsolver->mipdata_->feastol * std::fabs(bound)) @@ -1517,14 +1520,10 @@ HighsInt HighsDomain::propagateRowLower(const HighsInt* Rindex, void HighsDomain::updateThresholdLbChange(HighsInt col, double newbound, double val, double& threshold) { if (newbound != col_upper_[col]) { - double boundRange = (col_upper_[col] - newbound); - - boundRange -= - variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * mipsolver->mipdata_->feastol) - : mipsolver->mipdata_->feastol; - - double thresholdNew = std::fabs(val) * boundRange; + double thresholdNew = + std::fabs(val) * boundRange(col_upper_[col], newbound, + mipsolver->mipdata_->feastol, + variableType(col)); // the new threshold is now the maximum of the new threshold and the current // one @@ -1536,14 +1535,10 @@ void HighsDomain::updateThresholdLbChange(HighsInt col, double newbound, void HighsDomain::updateThresholdUbChange(HighsInt col, double newbound, double val, double& threshold) { if (newbound != col_lower_[col]) { - double boundRange = (newbound - col_lower_[col]); - - boundRange -= - variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * mipsolver->mipdata_->feastol) - : mipsolver->mipdata_->feastol; - - double thresholdNew = std::fabs(val) * boundRange; + double thresholdNew = + std::fabs(val) * boundRange(newbound, col_lower_[col], + mipsolver->mipdata_->feastol, + variableType(col)); // the new threshold is now the maximum of the new threshold and the current // one @@ -1908,13 +1903,9 @@ void HighsDomain::recomputeCapacityThreshold(HighsInt row) { if (col_upper_[col] == col_lower_[col]) continue; - double boundRange = col_upper_[col] - col_lower_[col]; - - boundRange -= variableType(col) == HighsVarType::kContinuous - ? std::max(0.3 * boundRange, 1000.0 * feastol()) - : feastol(); - - double threshold = std::fabs(mipsolver->mipdata_->ARvalue_[i]) * boundRange; + double threshold = std::fabs(mipsolver->mipdata_->ARvalue_[i]) * + boundRange(col_upper_[col], col_lower_[col], feastol(), + variableType(col)); capacityThreshold_[row] = std::max({capacityThreshold_[row], threshold, feastol()}); @@ -3037,6 +3028,7 @@ bool HighsDomain::ConflictSet::resolveLinearGeq(HighsCDouble M, double Mupper, relaxUb = std::floor(relaxUb); if (relaxUb - ub <= localdom.feastol()) continue; + locdomchg.domchg.boundval = relaxUb; if (relaxUb - gub >= -localdom.mipsolver->mipdata_->epsilon) { From ea24d489de5baa443fc17466f568330a41b9345f Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 29 May 2024 22:12:39 +0200 Subject: [PATCH 05/68] Revert switch to quad precision; need to qualify --- src/mip/HighsDomain.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index ec788c1681..615f387327 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -46,17 +46,17 @@ static double activityContributionMax(double coef, const double& lb, } } -static HighsCDouble computeDelta(HighsInt row, double val, double oldbound, - double newbound, double inf, - std::vector& numinfs) { +static double computeDelta(HighsInt row, double val, double oldbound, + double newbound, double inf, + std::vector& numinfs) { if (oldbound == inf) { --numinfs[row]; - return HighsCDouble(newbound) * val; + return newbound * val; } else if (newbound == inf) { ++numinfs[row]; - return -HighsCDouble(oldbound) * val; + return -oldbound * val; } else { - return (HighsCDouble(newbound) - HighsCDouble(oldbound)) * val; + return (newbound - oldbound) * val; } } From e7ff875867e1e7f3fd71abea048a8563ac039322 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 31 May 2024 08:58:56 +0200 Subject: [PATCH 06/68] Use double --- src/mip/HighsDomain.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 615f387327..f91d5c52d5 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -480,8 +480,8 @@ void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, cutpool->getMatrix().forEachPositiveColumnEntry( col, [&](HighsInt row, double val) { assert(val > 0); - HighsCDouble deltamin = computeDelta(row, val, oldbound, newbound, - -kHighsInf, activitycutsinf_); + double deltamin = computeDelta(row, val, oldbound, newbound, -kHighsInf, + activitycutsinf_); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -541,8 +541,8 @@ void HighsDomain::CutpoolPropagation::updateActivityUbChange(HighsInt col, cutpool->getMatrix().forEachNegativeColumnEntry( col, [&](HighsInt row, double val) { assert(val < 0); - HighsCDouble deltamin = computeDelta(row, val, oldbound, newbound, - kHighsInf, activitycutsinf_); + double deltamin = computeDelta(row, val, oldbound, newbound, kHighsInf, + activitycutsinf_); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -1527,7 +1527,7 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - HighsCDouble deltamin = + double deltamin = computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], oldbound, newbound, -kHighsInf, activitymininf_); activitymin_[mip->a_matrix_.index_[i]] += deltamin; @@ -1571,7 +1571,7 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, mip->row_upper_[mip->a_matrix_.index_[i]] != kHighsInf) markPropagate(mip->a_matrix_.index_[i]); } else { - HighsCDouble deltamax = + double deltamax = computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], oldbound, newbound, -kHighsInf, activitymaxinf_); activitymax_[mip->a_matrix_.index_[i]] += deltamax; @@ -1666,7 +1666,7 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { - HighsCDouble deltamax = + double deltamax = computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], oldbound, newbound, kHighsInf, activitymaxinf_); activitymax_[mip->a_matrix_.index_[i]] += deltamax; @@ -1713,7 +1713,7 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, // propagateinds_.push_back(mip->a_matrix_.index_[i]); } } else { - HighsCDouble deltamin = + double deltamin = computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], oldbound, newbound, kHighsInf, activitymininf_); activitymin_[mip->a_matrix_.index_[i]] += deltamin; From acfe87c726d3985d706e1c184a952e97143544d7 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 31 May 2024 09:10:20 +0200 Subject: [PATCH 07/68] Add a comment regarding todos --- src/mip/HighsDomain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index f91d5c52d5..611cdcbc53 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -49,6 +49,8 @@ static double activityContributionMax(double coef, const double& lb, static double computeDelta(HighsInt row, double val, double oldbound, double newbound, double inf, std::vector& numinfs) { + // if bounds are huge, HighsCDouble should be used when computing bound + // differences. todo: qualify usage of HighsCDouble in this function. if (oldbound == inf) { --numinfs[row]; return newbound * val; From 855e0ffd5d6f3beca825422115bd0aad170e9653 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 31 May 2024 09:36:28 +0200 Subject: [PATCH 08/68] Fix typo --- src/mip/HighsDomain.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index 611cdcbc53..a88857fb8c 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -2076,13 +2076,13 @@ void HighsDomain::setDomainChangeStack( if (k == stacksize) return; // For redundant branching bound changes we need to be more careful due to - // symmetry handling. If these boundchanges are redundant simply because the - // corresponding subtree was enumerated and hence the global bound updated, - // then we still need to keep their status as branching variables for - // computing correct stabilizers. - // They can, however, be safely dropped if they are either strictly - // redundant in the global domain, or if there is already a local bound - // change that makes the branching change redundant. + // symmetry handling. If these bound changes are redundant simply because + // the corresponding subtree was enumerated and hence the global bound + // updated, then we still need to keep their status as branching variables + // for computing correct stabilizers. They can, however, be safely dropped + // if they are either strictly redundant in the global domain, or if there + // is already a local bound change that makes the branching change + // redundant. if (domchgstack[k].boundtype == HighsBoundType::kLower) { if (domchgstack[k].boundval <= col_lower_[domchgstack[k].column]) { if (domchgstack[k].boundval < col_lower_[domchgstack[k].column]) From 57b37594c580f75b4e3cd56cc101eb615d038e59 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 31 May 2024 09:54:19 +0200 Subject: [PATCH 09/68] Fix some typos along the way --- extern/zstr/strict_fstream.hpp | 2 +- src/ipm/ipx/crossover.h | 2 +- src/ipm/ipx/forrest_tomlin.h | 2 +- src/ipm/ipx/indexed_vector.h | 2 +- src/ipm/ipx/iterate.cc | 2 +- src/ipm/ipx/iterate.h | 4 ++-- src/ipm/ipx/lu_factorization.h | 2 +- src/ipm/ipx/lu_update.h | 2 +- src/ipm/ipx/sparse_utils.h | 2 +- src/lp_data/HighsInterface.cpp | 4 ++-- src/lp_data/HighsSolve.cpp | 2 +- src/mip/HighsModkSeparator.h | 2 +- src/pdlp/cupdlp/cupdlp_defs.h | 2 +- src/simplex/SimplexStruct.h | 2 +- src/util/HighsCDouble.h | 4 ++-- 15 files changed, 18 insertions(+), 18 deletions(-) diff --git a/extern/zstr/strict_fstream.hpp b/extern/zstr/strict_fstream.hpp index 7d03ea6648..b93acfd6a9 100644 --- a/extern/zstr/strict_fstream.hpp +++ b/extern/zstr/strict_fstream.hpp @@ -17,7 +17,7 @@ namespace strict_fstream { -// Help people out a bit, it seems like this is a common recommenation since +// Help people out a bit, it seems like this is a common recommendation since // musl breaks all over the place. #if defined(__NEED_size_t) && !defined(__MUSL__) #warning "It seems to be recommended to patch in a define for __MUSL__ if you use musl globally: https://www.openwall.com/lists/musl/2013/02/10/5" diff --git a/src/ipm/ipx/crossover.h b/src/ipm/ipx/crossover.h index 3587014353..7e16b00eb1 100644 --- a/src/ipm/ipx/crossover.h +++ b/src/ipm/ipx/crossover.h @@ -44,7 +44,7 @@ class Crossover { // as long as the Crossover object is used. Crossover(const Control& control); - // First runs the dual push phase; if this was succesful, then runs the + // First runs the dual push phase; if this was successful, then runs the // primal push phase. // // weights: Must either be NULL or an array of size n+m. diff --git a/src/ipm/ipx/forrest_tomlin.h b/src/ipm/ipx/forrest_tomlin.h index 32c373080b..dc60bfd6ab 100644 --- a/src/ipm/ipx/forrest_tomlin.h +++ b/src/ipm/ipx/forrest_tomlin.h @@ -11,7 +11,7 @@ namespace ipx { // Generic implementation of the Forrest-Tomlin update [1] that can be used with // any LU factorization. The implementation does not exploit hypersparsity, -// which exludes its use for such problems. For non-hypersparse problems the +// which excludes its use for such problems. For non-hypersparse problems the // implementation is better suited than BASICLU, however, because it stores L // and U in compressed form with permuted indices; hence solving triangular // systems with a dense rhs/lhs accesses memory contiguously. BASICLU could not diff --git a/src/ipm/ipx/indexed_vector.h b/src/ipm/ipx/indexed_vector.h index 6ad46af292..07a0864be1 100644 --- a/src/ipm/ipx/indexed_vector.h +++ b/src/ipm/ipx/indexed_vector.h @@ -24,7 +24,7 @@ namespace ipx { // otherwise. // // When modifying the vector changes its pattern (e.g. by writing to v[i] for an -// arbitray index i), you have to invalidate the pattern or provide the new one. +// arbitrary index i), you have to invalidate the pattern or provide the new one. class IndexedVector { public: diff --git a/src/ipm/ipx/iterate.cc b/src/ipm/ipx/iterate.cc index 755e143f8f..c407eb3de4 100644 --- a/src/ipm/ipx/iterate.cc +++ b/src/ipm/ipx/iterate.cc @@ -279,7 +279,7 @@ void Iterate::Postprocess() { // For fixed variables compute xl[j] and xu[j] from x[j]. If the lower and // upper bound are equal, set zl[j] or zu[j] such that the variable is dual - // feasibile. Otherwise leave them zero. + // feasible. Otherwise leave them zero. for (Int j = 0; j < n+m; j++) { if (StateOf(j) == State::fixed) { xl_[j] = x_[j] - lb[j]; diff --git a/src/ipm/ipx/iterate.h b/src/ipm/ipx/iterate.h index 53b05cce37..0f1ce529d4 100644 --- a/src/ipm/ipx/iterate.h +++ b/src/ipm/ipx/iterate.h @@ -77,7 +77,7 @@ class Iterate { double zl(Int j) const { return zl_[j]; } double zu(Int j) const { return zu_[j]; } - // Returns const rerefences to the residual vectors + // Returns const references to the residual vectors // rb = b-AI*x, // rl = lb-x+xl, // ru = ub-x-xu, @@ -155,7 +155,7 @@ class Iterate { double presidual() const; double dresidual() const; - // copmlementarity() returns the sum of the pairwise complementarity + // complementarity() returns the sum of the pairwise complementarity // products xl[j]*zl[j] and xu[j]*zu[j] from all barrier terms. mu() // returns the average, mu_min() the minimum and mu_max() the maximum. double complementarity() const; diff --git a/src/ipm/ipx/lu_factorization.h b/src/ipm/ipx/lu_factorization.h index 6effb8b094..5bc4340678 100644 --- a/src/ipm/ipx/lu_factorization.h +++ b/src/ipm/ipx/lu_factorization.h @@ -38,7 +38,7 @@ class LuFactorization { // kLuDependencyTol as absolute pivot tolerance and to // remove columns from the active submatrix // immediately when all entries became smaller than - // the abolute pivot tolerance. Need not be supported + // the absolute pivot tolerance. Need not be supported // by the implementation. // @L, @U: return the matrix factors with sorted indices. The objects are // resized as necessary. diff --git a/src/ipm/ipx/lu_update.h b/src/ipm/ipx/lu_update.h index 2ef13e0228..299ec4d8c0 100644 --- a/src/ipm/ipx/lu_update.h +++ b/src/ipm/ipx/lu_update.h @@ -25,7 +25,7 @@ class LuUpdate { // kLuDependencyTol as absolute pivot tolerance and to // remove columns from the active submatrix // immediately when all entries became smaller than - // the abolute pivot tolerance. Need not be supported + // the absolute pivot tolerance. Need not be supported // by the implementation. // // Factorize() cannot fail other than for out of memory, in which case diff --git a/src/ipm/ipx/sparse_utils.h b/src/ipm/ipx/sparse_utils.h index 54bdbc782c..db45600ef7 100644 --- a/src/ipm/ipx/sparse_utils.h +++ b/src/ipm/ipx/sparse_utils.h @@ -16,7 +16,7 @@ namespace ipx { // have previously been unmarked; they are marked now and newtop // is returned. // @marked, @marker Node i is "marked" iff @marked[i] == @marker. -// @work worksapce of size # rows of A. +// @work workspace of size # rows of A. // // The code has been copied and adapted from cs_dfs.c, included in the CSPARSE // package [1]. diff --git a/src/lp_data/HighsInterface.cpp b/src/lp_data/HighsInterface.cpp index 7f7a201f99..d5ffd342a0 100644 --- a/src/lp_data/HighsInterface.cpp +++ b/src/lp_data/HighsInterface.cpp @@ -2198,7 +2198,7 @@ void Highs::formIllConditioningLp0(HighsLp& ill_conditioning_lp, ill_conditioning_matrix.value_.push_back(1.0); ill_conditioning_matrix.start_.push_back( HighsInt(ill_conditioning_matrix.index_.size())); - // Subracting x_- with cost 1 + // Subtracting x_- with cost 1 ill_conditioning_lp.col_cost_.push_back(1); ill_conditioning_lp.col_lower_.push_back(0); ill_conditioning_lp.col_upper_.push_back(kHighsInf); @@ -2312,7 +2312,7 @@ void Highs::formIllConditioningLp1(HighsLp& ill_conditioning_lp, } assert(ill_conditioning_lp.num_col_ == incumbent_num_row); if (constraint) { - // Add the identiy matrix for constraint y - u + w = 0 + // Add the identity matrix for constraint y - u + w = 0 for (HighsInt iRow = 0; iRow < incumbent_num_row; iRow++) { ill_conditioning_matrix.index_.push_back(iRow); ill_conditioning_matrix.value_.push_back(1.0); diff --git a/src/lp_data/HighsSolve.cpp b/src/lp_data/HighsSolve.cpp index 29377e7fec..d839bfb88d 100644 --- a/src/lp_data/HighsSolve.cpp +++ b/src/lp_data/HighsSolve.cpp @@ -254,7 +254,7 @@ HighsStatus solveUnconstrainedLp(const HighsOptions& options, const HighsLp& lp, if (lp.num_row_ > 0) { // Assign primal, dual and basis status for rows, checking for - // infeasiblility + // infeasibility for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) { double primal_infeasibility = 0; double lower = lp.row_lower_[iRow]; diff --git a/src/mip/HighsModkSeparator.h b/src/mip/HighsModkSeparator.h index e7c2c9005f..8e6eb88bac 100644 --- a/src/mip/HighsModkSeparator.h +++ b/src/mip/HighsModkSeparator.h @@ -20,7 +20,7 @@ * cut. * * If a row contains continuous variables that sit at zero after bound - * substitution, then those rows are included in the congurence system, as the + * substitution, then those rows are included in the congruence system, as the * presence of such variables does not reduce the cuts violation when applying * the MIR procedure. In order to handle their presence the row must simply be * scaled, such that all integer variables that have a non-zero solution value diff --git a/src/pdlp/cupdlp/cupdlp_defs.h b/src/pdlp/cupdlp/cupdlp_defs.h index bdc4257a73..068c150935 100644 --- a/src/pdlp/cupdlp/cupdlp_defs.h +++ b/src/pdlp/cupdlp/cupdlp_defs.h @@ -154,7 +154,7 @@ struct CUPDLP_CSC_MATRIX { cupdlp_int *colMatIdx; cupdlp_float *colMatElem; - // Used to aviod implementing NormInf on cuda + // Used to avoid implementing NormInf on cuda cupdlp_float MatElemNormInf; #ifndef CUPDLP_CPU // Pointers to GPU vectors diff --git a/src/simplex/SimplexStruct.h b/src/simplex/SimplexStruct.h index e29ce4e1ee..eb49c8ca96 100644 --- a/src/simplex/SimplexStruct.h +++ b/src/simplex/SimplexStruct.h @@ -25,7 +25,7 @@ struct SimplexBasis { // The basis for the simplex method consists of basicIndex, // nonbasicFlag and nonbasicMove. If HighsSimplexStatus has_basis // is true then it is assumed that basicIndex_ and nonbasicFlag_ are - // self-consistent and correpond to the dimensions of an associated + // self-consistent and correspond to the dimensions of an associated // HighsLp, but the basis matrix B is not necessarily nonsingular. std::vector basicIndex_; std::vector nonbasicFlag_; diff --git a/src/util/HighsCDouble.h b/src/util/HighsCDouble.h index 11cc8460d7..b02622d162 100644 --- a/src/util/HighsCDouble.h +++ b/src/util/HighsCDouble.h @@ -32,7 +32,7 @@ class HighsCDouble { // Proceedings of. 2005. /// performs an exact transformation such that x + y = a + b - /// and x = double(a + b). The operation uses 6 flops (addition/substraction). + /// and x = double(a + b). The operation uses 6 flops (addition/subtraction). static void two_sum(double& x, double& y, double a, double b) { x = a + b; double z = x - a; @@ -50,7 +50,7 @@ class HighsCDouble { /// performs an exact transformation such that x + y = a * b /// and x = double(a * b). The operation uses 10 flops for - /// addition/substraction and 7 flops for multiplication. + /// addition/subtraction and 7 flops for multiplication. static void two_product(double& x, double& y, double a, double b) { x = a * b; double a1, a2, b1, b2; From 4b7963fc5a989183b33aacde0553fcdc9846c971 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 31 May 2024 10:32:45 +0200 Subject: [PATCH 10/68] No need to pass entire vector --- src/mip/HighsDomain.cpp | 57 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index a88857fb8c..a00e8784c0 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -46,16 +46,15 @@ static double activityContributionMax(double coef, const double& lb, } } -static double computeDelta(HighsInt row, double val, double oldbound, - double newbound, double inf, - std::vector& numinfs) { +static double computeDelta(double val, double oldbound, double newbound, + double inf, HighsInt& numinfs) { // if bounds are huge, HighsCDouble should be used when computing bound // differences. todo: qualify usage of HighsCDouble in this function. if (oldbound == inf) { - --numinfs[row]; + --numinfs; return newbound * val; } else if (newbound == inf) { - ++numinfs[row]; + ++numinfs; return -oldbound * val; } else { return (newbound - oldbound) * val; @@ -482,8 +481,8 @@ void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, cutpool->getMatrix().forEachPositiveColumnEntry( col, [&](HighsInt row, double val) { assert(val > 0); - double deltamin = computeDelta(row, val, oldbound, newbound, -kHighsInf, - activitycutsinf_); + double deltamin = computeDelta(val, oldbound, newbound, -kHighsInf, + activitycutsinf_[row]); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -516,8 +515,8 @@ void HighsDomain::CutpoolPropagation::updateActivityLbChange(HighsInt col, cutpool->getMatrix().forEachPositiveColumnEntry( col, [&](HighsInt row, double val) { assert(val > 0); - activitycuts_[row] += computeDelta(row, val, oldbound, newbound, - -kHighsInf, activitycutsinf_); + activitycuts_[row] += computeDelta(val, oldbound, newbound, + -kHighsInf, activitycutsinf_[row]); if (domain->infeasible_reason.index == row) return false; @@ -543,8 +542,8 @@ void HighsDomain::CutpoolPropagation::updateActivityUbChange(HighsInt col, cutpool->getMatrix().forEachNegativeColumnEntry( col, [&](HighsInt row, double val) { assert(val < 0); - double deltamin = computeDelta(row, val, oldbound, newbound, kHighsInf, - activitycutsinf_); + double deltamin = computeDelta(val, oldbound, newbound, kHighsInf, + activitycutsinf_[row]); activitycuts_[row] += deltamin; if (deltamin <= 0) { @@ -575,8 +574,8 @@ void HighsDomain::CutpoolPropagation::updateActivityUbChange(HighsInt col, cutpool->getMatrix().forEachNegativeColumnEntry( col, [&](HighsInt row, double val) { assert(val < 0); - activitycuts_[row] += computeDelta(row, val, oldbound, newbound, - kHighsInf, activitycutsinf_); + activitycuts_[row] += computeDelta(val, oldbound, newbound, kHighsInf, + activitycutsinf_[row]); if (domain->infeasible_reason.index == row) return false; @@ -1530,8 +1529,8 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { double deltamin = - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, -kHighsInf, activitymininf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, -kHighsInf, + activitymininf_[mip->a_matrix_.index_[i]]); activitymin_[mip->a_matrix_.index_[i]] += deltamin; #ifndef NDEBUG @@ -1574,8 +1573,8 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, markPropagate(mip->a_matrix_.index_[i]); } else { double deltamax = - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, -kHighsInf, activitymaxinf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, -kHighsInf, + activitymaxinf_[mip->a_matrix_.index_[i]]); activitymax_[mip->a_matrix_.index_[i]] += deltamax; #ifndef NDEBUG @@ -1633,12 +1632,12 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { activitymin_[mip->a_matrix_.index_[i]] += - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, -kHighsInf, activitymininf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, + -kHighsInf, activitymininf_[mip->a_matrix_.index_[i]]); } else { activitymax_[mip->a_matrix_.index_[i]] += - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, -kHighsInf, activitymaxinf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, + -kHighsInf, activitymaxinf_[mip->a_matrix_.index_[i]]); } } @@ -1669,8 +1668,8 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { double deltamax = - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, kHighsInf, activitymaxinf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, kHighsInf, + activitymaxinf_[mip->a_matrix_.index_[i]]); activitymax_[mip->a_matrix_.index_[i]] += deltamax; #ifndef NDEBUG @@ -1716,8 +1715,8 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, } } else { double deltamin = - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, kHighsInf, activitymininf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, kHighsInf, + activitymininf_[mip->a_matrix_.index_[i]]); activitymin_[mip->a_matrix_.index_[i]] += deltamin; #ifndef NDEBUG @@ -1778,12 +1777,12 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound, for (HighsInt i = start; i != end; ++i) { if (mip->a_matrix_.value_[i] > 0) { activitymax_[mip->a_matrix_.index_[i]] += - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, kHighsInf, activitymaxinf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, + kHighsInf, activitymaxinf_[mip->a_matrix_.index_[i]]); } else { activitymin_[mip->a_matrix_.index_[i]] += - computeDelta(mip->a_matrix_.index_[i], mip->a_matrix_.value_[i], - oldbound, newbound, kHighsInf, activitymininf_); + computeDelta(mip->a_matrix_.value_[i], oldbound, newbound, + kHighsInf, activitymininf_[mip->a_matrix_.index_[i]]); } } From 7af6df9805e138f144f3ab98691006dbf74861ca Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Tue, 11 Jun 2024 10:30:06 +0200 Subject: [PATCH 11/68] fix declaration of highsCompilationDate() - move back to original position - there is no implementation for HiGHS::highsCompilationDate(), but only for highsCompilationDate() --- src/Highs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Highs.h b/src/Highs.h index 94d6193cf3..ade7bcad70 100644 --- a/src/Highs.h +++ b/src/Highs.h @@ -37,6 +37,7 @@ HighsInt highsVersionMajor(); HighsInt highsVersionMinor(); HighsInt highsVersionPatch(); const char* highsGithash(); +const char* highsCompilationDate(); /** * @brief Class to set parameters and run HiGHS @@ -1216,7 +1217,6 @@ class Highs { * @brief Return compilation date */ std::string compilationDate() const { return "deprecated"; } - const char* highsCompilationDate(); HighsStatus setLogCallback(void (*user_log_callback)(HighsLogType, const char*, void*), From 57d84897617aaf899f1ecb9ce5f8dfbfba4acdd4 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Tue, 11 Jun 2024 10:31:09 +0200 Subject: [PATCH 12/68] make new local functions static - fixes missing-declaration warning --- src/lp_data/Highs.cpp | 12 ++++++------ src/qpsolver/a_quass.cpp | 2 +- src/qpsolver/quass.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lp_data/Highs.cpp b/src/lp_data/Highs.cpp index a2f6cd517d..fa600bba14 100644 --- a/src/lp_data/Highs.cpp +++ b/src/lp_data/Highs.cpp @@ -2320,12 +2320,12 @@ HighsStatus Highs::changeColsIntegrality(const HighsInt from_col, return returnFromHighs(return_status); } -HighsStatus analyseSetCreateError(HighsLogOptions log_options, - const std::string method, - const HighsInt create_error, - const bool ordered, - const HighsInt num_set_entries, - const HighsInt dimension) { +static HighsStatus analyseSetCreateError(HighsLogOptions log_options, + const std::string method, + const HighsInt create_error, + const bool ordered, + const HighsInt num_set_entries, + const HighsInt dimension) { if (create_error == kIndexCollectionCreateIllegalSetSize) { highsLogUser(log_options, HighsLogType::kError, "Set supplied to Highs::%s has illegal size of %d\n", diff --git a/src/qpsolver/a_quass.cpp b/src/qpsolver/a_quass.cpp index a2fda85ff5..a8e2583b12 100644 --- a/src/qpsolver/a_quass.cpp +++ b/src/qpsolver/a_quass.cpp @@ -4,7 +4,7 @@ #include "qpsolver/feasibility_highs.hpp" #include "qpsolver/feasibility_bounded.hpp" -QpAsmStatus quass2highs(Instance& instance, +static QpAsmStatus quass2highs(Instance& instance, Settings& settings, Statistics& stats, QpModelStatus& qp_model_status, diff --git a/src/qpsolver/quass.cpp b/src/qpsolver/quass.cpp index cbff174e58..2b0f825e69 100644 --- a/src/qpsolver/quass.cpp +++ b/src/qpsolver/quass.cpp @@ -266,12 +266,12 @@ static double compute_dual_violation(Instance& instance, QpVector& primal, QpVec } #endif -bool check_reinvert_due(Basis& basis) { +static bool check_reinvert_due(Basis& basis) { // reinvert can be triggered by basis return basis.getreinversionhint(); } -void reinvert(Basis& basis, CholeskyFactor& factor, Gradient& grad, ReducedCosts& rc, ReducedGradient& rg, std::unique_ptr& pricing) { +static void reinvert(Basis& basis, CholeskyFactor& factor, Gradient& grad, ReducedCosts& rc, ReducedGradient& rg, std::unique_ptr& pricing) { basis.rebuild(); factor.recompute(); grad.recompute(); From cb8525c766b6d6d32dc2a056beccd441a61fea90 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Tue, 11 Jun 2024 10:31:53 +0200 Subject: [PATCH 13/68] put back first line of comment header --- src/lp_data/HighsCallbackStruct.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lp_data/HighsCallbackStruct.h b/src/lp_data/HighsCallbackStruct.h index 4553707f61..237eb30c74 100644 --- a/src/lp_data/HighsCallbackStruct.h +++ b/src/lp_data/HighsCallbackStruct.h @@ -1,3 +1,4 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* This file is part of the HiGHS linear optimization suite */ /* */ From 1de0ff66945bcfabb33ef335a0619e7b67794fae Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Tue, 11 Jun 2024 10:32:09 +0200 Subject: [PATCH 14/68] fix comparison of mixed types --- src/qpsolver/feasibility_bounded.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qpsolver/feasibility_bounded.hpp b/src/qpsolver/feasibility_bounded.hpp index e2c345f181..4a92c813e1 100644 --- a/src/qpsolver/feasibility_bounded.hpp +++ b/src/qpsolver/feasibility_bounded.hpp @@ -18,8 +18,8 @@ static void computeStartingPointBounded(Instance& instance, L.resize(instance.num_var * instance.num_var); // compute cholesky factorization of Q - for (size_t col = 0; col < instance.num_var; col++) { - for (size_t idx = instance.Q.mat.start[col]; idx < instance.Q.mat.start[col+1]; idx++) { + for (size_t col = 0; col < (size_t)instance.num_var; col++) { + for (size_t idx = instance.Q.mat.start[col]; idx < (size_t)instance.Q.mat.start[col+1]; idx++) { double sum = 0; size_t row = instance.Q.mat.index[idx]; if (row == col) { From 0bd9271e8c9af768d6576e8feeffec00688fe56c Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Tue, 11 Jun 2024 10:32:43 +0200 Subject: [PATCH 15/68] fix order of initializers in constructor - align to declaration order --- src/qpsolver/runtime.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qpsolver/runtime.hpp b/src/qpsolver/runtime.hpp index 4630f8fdff..5c9c199a9a 100644 --- a/src/qpsolver/runtime.hpp +++ b/src/qpsolver/runtime.hpp @@ -26,13 +26,13 @@ struct Runtime { Runtime(Instance& inst, Statistics& stats) : instance(inst), + statistics(stats), primal(QpVector(instance.num_var)), rowactivity(QpVector(instance.num_con)), dualvar(instance.num_var), dualcon(instance.num_con), status_var(instance.num_var), - status_con(instance.num_con), - statistics(stats) {} + status_con(instance.num_con) {} }; #endif From f7fe336be7d138d2209d0ffd2b521d0f3831e455 Mon Sep 17 00:00:00 2001 From: Jens Diewald Date: Tue, 11 Jun 2024 21:24:16 +0200 Subject: [PATCH 16/68] Correctly Report Invalid Row Names Otherwise, HiGHS may silently not write an MPS file when it runs into invalid row names and still return kOK. --- src/io/HMPSIO.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/HMPSIO.cpp b/src/io/HMPSIO.cpp index 69e906b66e..b6037d3624 100644 --- a/src/io/HMPSIO.cpp +++ b/src/io/HMPSIO.cpp @@ -564,7 +564,7 @@ HighsStatus writeModelAsMps(const HighsOptions& options, HighsStatus row_name_status = normaliseNames(options.log_options, "row", lp.num_row_, local_row_names, max_row_name_length); - if (row_name_status == HighsStatus::kError) return col_name_status; + if (row_name_status == HighsStatus::kError) return row_name_status; warning_found = row_name_status == HighsStatus::kWarning || warning_found; HighsInt max_name_length = std::max(max_col_name_length, max_row_name_length); From 57214c9a79366ebcd7c35b3879614b6a4af742b6 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 12 Jun 2024 10:42:24 +0200 Subject: [PATCH 17/68] Minor changes --- src/presolve/HPresolve.cpp | 131 ++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 67 deletions(-) diff --git a/src/presolve/HPresolve.cpp b/src/presolve/HPresolve.cpp index b25b87af00..f2d549e865 100644 --- a/src/presolve/HPresolve.cpp +++ b/src/presolve/HPresolve.cpp @@ -1456,77 +1456,75 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) { for (const auto& binvar : binaries) { HighsInt i = std::get<3>(binvar); - if (cliquetable.getSubstitution(i) != nullptr) continue; - - if (domain.isBinary(i)) { - // when a large percentage of columns have been deleted, stop this round - // of probing - // if (numDel > std::max(model->num_col_ * 0.2, 1000.)) break; - if (numDel > - std::max(1000., (model->num_row_ + model->num_col_) * 0.05)) { - probingEarlyAbort = true; - break; - } + if (cliquetable.getSubstitution(i) != nullptr || !domain.isBinary(i)) + continue; - // break in case of too many new implications to not spent ages in - // probing - if (cliquetable.isFull() || - cliquetable.numCliques() - numCliquesStart > - std::max(HighsInt{1000000}, 2 * numNonzeros()) || - implications.getNumImplications() - numImplicsStart > - std::max(HighsInt{1000000}, 2 * numNonzeros())) - break; + // when a large percentage of columns have been deleted, stop this round + // of probing + // if (numDel > std::max(model->num_col_ * 0.2, 1000.)) break; + probingEarlyAbort = + numDel > + std::max(HighsInt{1000}, (model->num_row_ + model->num_col_) / 20); + if (probingEarlyAbort) break; + + // break in case of too many new implications to not spent ages in + // probing + if (cliquetable.isFull() || + cliquetable.numCliques() - numCliquesStart > + std::max(HighsInt{1000000}, 2 * numNonzeros()) || + implications.getNumImplications() - numImplicsStart > + std::max(HighsInt{1000000}, 2 * numNonzeros())) + break; - // if (numProbed % 10 == 0) - // printf( - // "numprobed=%d numDel=%d newcliques=%d " - // "numNeighbourhoodQueries=%ld " - // "splayContingent=%ld\n", - // numProbed, numDel, cliquetable.numCliques() - numCliquesStart, - // cliquetable.numNeighbourhoodQueries, splayContingent); - if (cliquetable.numNeighbourhoodQueries > splayContingent) break; - - if (probingContingent - numProbed < 0) break; - - HighsInt numBoundChgs = 0; - HighsInt numNewCliques = -cliquetable.numCliques(); - if (!implications.runProbing(i, numBoundChgs)) continue; - probingContingent += numBoundChgs; - numNewCliques += cliquetable.numCliques(); - numNewCliques = std::max(numNewCliques, HighsInt{0}); - while (domain.getChangedCols().size() != numChangedCols) { - if (domain.isFixed(domain.getChangedCols()[numChangedCols++])) - ++probingNumDelCol; - } - HighsInt newNumDel = probingNumDelCol - numDelStart + - implications.substitutions.size() + - cliquetable.getSubstitutions().size(); - - if (newNumDel > numDel) { - probingContingent += numDel; - if (!mipsolver->submip) { - splayContingent += 100 * (newNumDel + numDelStart); - splayContingent += 1000 * numNewCliques; - } - numDel = newNumDel; - numFail = 0; - } else if (mipsolver->submip || numNewCliques == 0) { - splayContingent -= 100 * numFail; - ++numFail; - } else { + // if (numProbed % 10 == 0) + // printf( + // "numprobed=%d numDel=%d newcliques=%d " + // "numNeighbourhoodQueries=%ld " + // "splayContingent=%ld\n", + // numProbed, numDel, cliquetable.numCliques() - numCliquesStart, + // cliquetable.numNeighbourhoodQueries, splayContingent); + if (cliquetable.numNeighbourhoodQueries > splayContingent) break; + + if (probingContingent - numProbed < 0) break; + + HighsInt numBoundChgs = 0; + HighsInt numNewCliques = -cliquetable.numCliques(); + if (!implications.runProbing(i, numBoundChgs)) continue; + probingContingent += numBoundChgs; + numNewCliques += cliquetable.numCliques(); + numNewCliques = std::max(numNewCliques, HighsInt{0}); + while (domain.getChangedCols().size() != numChangedCols) { + if (domain.isFixed(domain.getChangedCols()[numChangedCols++])) + ++probingNumDelCol; + } + HighsInt newNumDel = probingNumDelCol - numDelStart + + implications.substitutions.size() + + cliquetable.getSubstitutions().size(); + + if (newNumDel > numDel) { + probingContingent += numDel; + if (!mipsolver->submip) { + splayContingent += 100 * (newNumDel + numDelStart); splayContingent += 1000 * numNewCliques; - numFail = 0; } + numDel = newNumDel; + numFail = 0; + } else if (mipsolver->submip || numNewCliques == 0) { + splayContingent -= 100 * numFail; + ++numFail; + } else { + splayContingent += 1000 * numNewCliques; + numFail = 0; + } - ++numProbed; - numProbes[i] += 1; + ++numProbed; + numProbes[i] += 1; - // printf("nprobed: %" HIGHSINT_FORMAT ", numCliques: %" HIGHSINT_FORMAT - // "\n", nprobed, - // cliquetable.numCliques()); - if (domain.infeasible()) { - return Result::kPrimalInfeasible; - } + // printf("nprobed: %" HIGHSINT_FORMAT ", numCliques: %" HIGHSINT_FORMAT + // "\n", nprobed, + // cliquetable.numCliques()); + if (domain.infeasible()) { + return Result::kPrimalInfeasible; } } @@ -5195,8 +5193,7 @@ HighsInt HPresolve::strengthenInequalities() { // do not run on very dense rows as this could get expensive if (rowsize[row] > - std::max(HighsInt{1000}, - HighsInt(0.05 * (model->num_col_ - numDeletedCols)))) + std::max(HighsInt{1000}, (model->num_col_ - numDeletedCols) / 20)) continue; // printf("strengthening knapsack of %" HIGHSINT_FORMAT " vars\n", From 347bde41d79a12cbfb8f464a96751156b16c4a2d Mon Sep 17 00:00:00 2001 From: JAJHall Date: Wed, 12 Jun 2024 12:35:07 +0100 Subject: [PATCH 18/68] Fixed obvious omission in docs/src/guide/basic.md --- docs/src/guide/basic.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/src/guide/basic.md b/docs/src/guide/basic.md index 764b99ecd4..30a4b9dcba 100644 --- a/docs/src/guide/basic.md +++ b/docs/src/guide/basic.md @@ -20,14 +20,16 @@ and [classes](@ref classes-overview), and are referred to below. #### [Enums](@id guide-basic-enums) -Enums are scalar identifier types that can take only a limited range of values.???? - -#### The -advantage using these classes is that many fewer parameters are -needed when passing data to and from HiGHS. However, the use of -classes is not necessary for the basic use of `highspy`. As with the -`C` and `Fortran` interfaces, there are equivalent methods that use -simple scalars and vectors of data. +Enums are scalar identifier types that can take only a limited range of values. + +#### [Classes](@id guide-basic-classes) The advantage of using the +native `C++` classes in HiGHS is that many fewer parameters are needed +when passing data to and from HiGHS. The binding of the data members +of these classes to `highspy` structures allows them to be used when +calling HiGHS from Python, although they are not necessary for the +basic use of `highspy`. As with the `C` and `Fortran` interfaces, +there are equivalent methods that use simple scalars and vectors of +data. ## Defining a model From fee790daef90aa2a7ac650bd18b75037323f6f50 Mon Sep 17 00:00:00 2001 From: JAJHall Date: Wed, 12 Jun 2024 13:34:16 +0100 Subject: [PATCH 19/68] Moved const char* highsCompilationDate() below Highs class definition and updated unit test HighsVersion --- check/TestHighsVersion.cpp | 26 ++++++++++++++++++++++---- src/Highs.h | 9 +++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/check/TestHighsVersion.cpp b/check/TestHighsVersion.cpp index 6a133d1a03..0d41016f5b 100644 --- a/check/TestHighsVersion.cpp +++ b/check/TestHighsVersion.cpp @@ -13,6 +13,8 @@ TEST_CASE("HighsVersion", "[highs_version]") { const HighsInt major = highsVersionMajor(); const HighsInt minor = highsVersionMinor(); const HighsInt patch = highsVersionPatch(); + const std::string compilation = highsCompilationDate(); + const std::string githash = std::string(highsGithash()); std::stringstream ss; ss << major << "." << minor << "." << patch; std::string local_version = ss.str(); @@ -21,15 +23,31 @@ TEST_CASE("HighsVersion", "[highs_version]") { printf("HiGHS major version %d\n", int(major)); printf("HiGHS minor version %d\n", int(minor)); printf("HiGHS patch version %d\n", int(patch)); - printf("HiGHS githash: %s\n", highsGithash()); - // Compilation date is deprecated. - // printf("HiGHS compilation date: %s\n", highsCompilationDate()); + printf("HiGHS githash: %s\n", githash.c_str()); + // Compilation date is deprecated, but make sure that the + // deprecated method is still tested. + printf("HiGHS compilation date: %s\n", compilation.c_str()); printf("HiGHS local version: %s\n", local_version.c_str()); } REQUIRE(major == HIGHS_VERSION_MAJOR); REQUIRE(minor == HIGHS_VERSION_MINOR); REQUIRE(patch == HIGHS_VERSION_PATCH); - REQUIRE(local_version == version); + REQUIRE(githash == std::string(HIGHS_GITHASH)); + REQUIRE(version == local_version); + // Check that the corresponding methods + Highs highs; + const std::string version0 = highs.version(); + REQUIRE(version0 == version); + const HighsInt major0 = highs.versionMajor(); + REQUIRE(major0 == major); + const HighsInt minor0 = highs.versionMinor(); + REQUIRE(minor0 == minor); + const HighsInt patch0 = highs.versionPatch(); + REQUIRE(patch0 == patch); + const std::string githash0 = highs.githash(); + REQUIRE(githash0 == githash); + const std::string compilation0 = highs.compilationDate(); + REQUIRE(compilation == compilation); } TEST_CASE("sizeof-highs-int", "[highs_version]") { diff --git a/src/Highs.h b/src/Highs.h index ade7bcad70..7b3c08ca26 100644 --- a/src/Highs.h +++ b/src/Highs.h @@ -37,7 +37,6 @@ HighsInt highsVersionMajor(); HighsInt highsVersionMinor(); HighsInt highsVersionPatch(); const char* highsGithash(); -const char* highsCompilationDate(); /** * @brief Class to set parameters and run HiGHS @@ -1213,9 +1212,6 @@ class Highs { // Start of deprecated methods - /** - * @brief Return compilation date - */ std::string compilationDate() const { return "deprecated"; } HighsStatus setLogCallback(void (*user_log_callback)(HighsLogType, @@ -1525,4 +1521,9 @@ class Highs { const double ill_conditioning_bound); bool infeasibleBoundsOk(); }; + +// Start of deprecated methods not in the Highs class + +const char* highsCompilationDate(); + #endif From b8db77f3cf18db56f9d7c8ff5289c90dd46cab82 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:00:41 +0300 Subject: [PATCH 20/68] fortran fix macos --- .github/workflows/test-fortran-macos.yml | 46 +++++++++++++++++++++++ .github/workflows/test-fortran-ubuntu.yml | 2 +- CMakeLists.txt | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test-fortran-macos.yml diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml new file mode 100644 index 0000000000..82d9aa7cd3 --- /dev/null +++ b/.github/workflows/test-fortran-macos.yml @@ -0,0 +1,46 @@ +name: test-fortran-macos + +on: [push, pull_request] + +jobs: + fast_build_release: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest] + # toolchain: + # - {compiler: gcc, version: 13} + # # - {compiler: intel, version: '2023.2'} + # # - {compiler: nvidia-hpc, version: '23.11'} + # include: + # - os: ubuntu-latest + # toolchain: {compiler: gcc, version: 12} + + steps: + - uses: actions/checkout@v4 + + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + # with: + # compiler: ${{ matrix.toolchain.compiler }} + # version: ${{ matrix.toolchain.version }} + + - name: Create Build Environment + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Configure CMake + shell: bash + working-directory: ${{runner.workspace}}/build + run: cmake $GITHUB_WORKSPACE -DFORTRAN=ON + + - name: Build + shell: bash + working-directory: ${{runner.workspace}}/build + run: cmake --build . --parallel + + - name: Test + shell: bash + working-directory: ${{runner.workspace}}/build + run: | + ls + ./bin/fortrantest diff --git a/.github/workflows/test-fortran-ubuntu.yml b/.github/workflows/test-fortran-ubuntu.yml index 937f51b12c..7030087313 100644 --- a/.github/workflows/test-fortran-ubuntu.yml +++ b/.github/workflows/test-fortran-ubuntu.yml @@ -1,4 +1,4 @@ -name: test-fortran +name: test-fortran-ubuntu on: [push, pull_request] diff --git a/CMakeLists.txt b/CMakeLists.txt index 68e24246eb..ccaa64107a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ if (BUILD_CXX) "but it is not supported by the compiler. The check failed with this output:\n" "${check_ipo_support_output}") endif() - elseif(NOT ipo_supported) + elseif(NOT ipo_supported OR APPLE) message(STATUS "IPO / LTO: disabled because it is not supported") elseif(NOT BUILD_SHARED_LIBS) # For a static library, we can't be sure whether the final linking will From 077aaf7ee7b16a5d51b966325e26541d28920e60 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:12:17 +0300 Subject: [PATCH 21/68] macos fortran test workflow --- .github/workflows/test-fortran-macos.yml | 10 +++++----- cmake/README.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 82d9aa7cd3..b6ffc2ff6a 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -8,8 +8,8 @@ jobs: strategy: matrix: os: [macos-latest] - # toolchain: - # - {compiler: gcc, version: 13} + toolchain: + - {compiler: gcc, version: 13} # # - {compiler: intel, version: '2023.2'} # # - {compiler: nvidia-hpc, version: '23.11'} # include: @@ -21,9 +21,9 @@ jobs: - uses: fortran-lang/setup-fortran@v1 id: setup-fortran - # with: - # compiler: ${{ matrix.toolchain.compiler }} - # version: ${{ matrix.toolchain.version }} + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build diff --git a/cmake/README.md b/cmake/README.md index 4cb04ac682..5a24107a5a 100644 --- a/cmake/README.md +++ b/cmake/README.md @@ -3,7 +3,7 @@ | OS | C++ | Fortran | Python | CSharp Example | .NET | |:-------- | :---: | :------: | :----: | :----: | :----: | | Linux | [![Status][linux_cpp_svg]][linux_cpp_link] | [![Status][linux_fortran_svg]][linux_fortran_link] | [![Status][linux_python_svg]][linux_python_link] | *(1)* | [![Status][linux_dotnet_svg]][linux_dotnet_link] | -| MacOS | [![Status][macos_cpp_svg]][macos_cpp_link] | *(2)* | [![Status][macos_python_svg]][macos_python_link] | *(1)* |[![Status][macos_dotnet_svg]][macos_dotnet_link] | +| MacOS | [![Status][macos_cpp_svg]][macos_cpp_link] | [![Status][macos_fortran_svg]][macos_fortran_link] | [![Status][macos_python_svg]][macos_python_link] | *(1)* |[![Status][macos_dotnet_svg]][macos_dotnet_link] | | Windows | [![Status][windows_cpp_svg]][windows_cpp_link] | *(2)* | [![Status][windows_python_svg]][windows_python_link] | [![Status][windows_csharp_svg]][windows_csharp_link] | [![Status][windows_dotnet_svg]][windows_dotnet_link] | [linux_cpp_svg]: https://github.com/ERGO-Code/HiGHS/actions/workflows/cmake-linux-cpp.yml/badge.svg From 112d82c82a5b0a1294967236d41f264438edb00b Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:17:46 +0300 Subject: [PATCH 22/68] gfortran on macos test server try homebrew --- .github/workflows/test-fortran-macos.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index b6ffc2ff6a..d4e9ceec75 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -8,8 +8,8 @@ jobs: strategy: matrix: os: [macos-latest] - toolchain: - - {compiler: gcc, version: 13} + # toolchain: + # - {compiler: gcc, version: 13} # # - {compiler: intel, version: '2023.2'} # # - {compiler: nvidia-hpc, version: '23.11'} # include: @@ -19,11 +19,14 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: fortran-lang/setup-fortran@v1 - id: setup-fortran - with: - compiler: ${{ matrix.toolchain.compiler }} - version: ${{ matrix.toolchain.version }} + # - uses: fortran-lang/setup-fortran@v1 + # id: setup-fortran + # with: + # compiler: ${{ matrix.toolchain.compiler }} + # version: ${{ matrix.toolchain.version }} + + - name: Install GFortran + run: brew install gfortran - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build From 464691f9a530b58953902bfdbe731aaff05380d1 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:24:13 +0300 Subject: [PATCH 23/68] clean up workflow --- .github/workflows/test-fortran-macos.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index d4e9ceec75..074e8ac4d5 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -8,23 +8,10 @@ jobs: strategy: matrix: os: [macos-latest] - # toolchain: - # - {compiler: gcc, version: 13} - # # - {compiler: intel, version: '2023.2'} - # # - {compiler: nvidia-hpc, version: '23.11'} - # include: - # - os: ubuntu-latest - # toolchain: {compiler: gcc, version: 12} steps: - uses: actions/checkout@v4 - # - uses: fortran-lang/setup-fortran@v1 - # id: setup-fortran - # with: - # compiler: ${{ matrix.toolchain.compiler }} - # version: ${{ matrix.toolchain.version }} - - name: Install GFortran run: brew install gfortran From d0f45ccd375e64e1030369e68846b5c4673725d1 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:37:42 +0300 Subject: [PATCH 24/68] iteration count 80bau3b macos --- check/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index 0367e593be..cd8a1080e9 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -173,7 +173,7 @@ if (NOT FAST_BUILD OR ALL_TESTS) set(successMacArmInstances "25fv47\;3103\; 5.5018458883\;" - "80bau3b\;3705\; 9.8722419241\;" + "80bau3b\;3686\; 9.8722419241\;" "adlittle\;74\; 2.2549496316\;" "afiro\;22\;-4.6475314286\;" "etamacro\;531\;-7.5571523330\;" From 3fbe0ccf3eccf38667d791dcab6c88dad7f86515 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:50:33 +0300 Subject: [PATCH 25/68] other runner for linux --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4908e82a5e..4d6c14f7b2 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -7,7 +7,7 @@ on: types: [opened, synchronize, reopened] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@latest From f761e9afc3a687b5bd9b92ece53ed6dcc98b9456 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:53:38 +0300 Subject: [PATCH 26/68] disable IPO on macos only if fortran is ON --- CMakeLists.txt | 2 +- check/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccaa64107a..a861f4088f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ if (BUILD_CXX) "but it is not supported by the compiler. The check failed with this output:\n" "${check_ipo_support_output}") endif() - elseif(NOT ipo_supported OR APPLE) + elseif(NOT ipo_supported OR (APPLE AND FORTRAN)) message(STATUS "IPO / LTO: disabled because it is not supported") elseif(NOT BUILD_SHARED_LIBS) # For a static library, we can't be sure whether the final linking will diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index cd8a1080e9..0367e593be 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -173,7 +173,7 @@ if (NOT FAST_BUILD OR ALL_TESTS) set(successMacArmInstances "25fv47\;3103\; 5.5018458883\;" - "80bau3b\;3686\; 9.8722419241\;" + "80bau3b\;3705\; 9.8722419241\;" "adlittle\;74\; 2.2549496316\;" "afiro\;22\;-4.6475314286\;" "etamacro\;531\;-7.5571523330\;" From 0a0692c8c660bfc0299f5b17bd3a65366b127680 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Wed, 12 Jun 2024 22:58:06 +0300 Subject: [PATCH 27/68] docs fail was not the other runner --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4d6c14f7b2..4908e82a5e 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -7,7 +7,7 @@ on: types: [opened, synchronize, reopened] jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@latest From b1b3306b41e1bfe242c8a5b366ec725c560414e5 Mon Sep 17 00:00:00 2001 From: Julian Hall Date: Wed, 12 Jun 2024 23:03:52 +0100 Subject: [PATCH 28/68] Update basic.md Fixed error spotted by @odow --- docs/src/guide/basic.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/guide/basic.md b/docs/src/guide/basic.md index 30a4b9dcba..1b674a84a6 100644 --- a/docs/src/guide/basic.md +++ b/docs/src/guide/basic.md @@ -22,8 +22,9 @@ and [classes](@ref classes-overview), and are referred to below. Enums are scalar identifier types that can take only a limited range of values. -#### [Classes](@id guide-basic-classes) The advantage of using the -native `C++` classes in HiGHS is that many fewer parameters are needed +#### [Classes](@id guide-basic-classes) + +The advantage of using the native `C++` classes in HiGHS is that many fewer parameters are needed when passing data to and from HiGHS. The binding of the data members of these classes to `highspy` structures allows them to be used when calling HiGHS from Python, although they are not necessary for the From c5ba1cd413aeff2a90381b5f6e33680d80f910d0 Mon Sep 17 00:00:00 2001 From: JAJHall Date: Fri, 14 Jun 2024 11:02:22 +0100 Subject: [PATCH 29/68] Minor correction in docs --- docs/src/interfaces/python/example-py.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/interfaces/python/example-py.md b/docs/src/interfaces/python/example-py.md index 9fe1989be8..d75c67dd9e 100644 --- a/docs/src/interfaces/python/example-py.md +++ b/docs/src/interfaces/python/example-py.md @@ -210,7 +210,7 @@ print('Basis validity = ', h.basisValidityToString(info.basis_validity)) * `changeColCost` * `changeColBounds` * `changeRowBounds` - * `changeColsCosts` + * `changeColsCost` * `changeColsBounds` * `changeRowsBounds` * `changeCoeff` From eae4eded0501c68ae3041a5df273b2c3a21953e1 Mon Sep 17 00:00:00 2001 From: JAJHall Date: Mon, 17 Jun 2024 22:13:34 +0100 Subject: [PATCH 30/68] Now passing nullptr to writeModelBoundSolution if lp.integrality_.size() = 0 --- src/lp_data/HighsModelUtils.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lp_data/HighsModelUtils.cpp b/src/lp_data/HighsModelUtils.cpp index cc48527032..1e878740b0 100644 --- a/src/lp_data/HighsModelUtils.cpp +++ b/src/lp_data/HighsModelUtils.cpp @@ -398,10 +398,12 @@ void writeSolutionFile(FILE* file, const HighsOptions& options, if (style == kSolutionStyleOldRaw) { writeOldRawSolution(file, lp, basis, solution); } else if (style == kSolutionStylePretty) { - writeModelBoundSolution( - file, true, lp.num_col_, lp.col_lower_, lp.col_upper_, lp.col_names_, - have_primal, solution.col_value, have_dual, solution.col_dual, - have_basis, basis.col_status, lp.integrality_.data()); + const HighsVarType* integrality = + lp.integrality_.size() > 0 ? lp.integrality_.data() : nullptr; + writeModelBoundSolution(file, true, lp.num_col_, lp.col_lower_, + lp.col_upper_, lp.col_names_, have_primal, + solution.col_value, have_dual, solution.col_dual, + have_basis, basis.col_status, integrality); writeModelBoundSolution(file, false, lp.num_row_, lp.row_lower_, lp.row_upper_, lp.row_names_, have_primal, solution.row_value, have_dual, solution.row_dual, From 4cd4c8995512b6383723bd1959277f90ca70d582 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 19 Jun 2024 09:54:45 +0200 Subject: [PATCH 31/68] Add constructor to make VS happy --- src/io/HighsIO.h | 19 +- src/lp_data/HighsOptions.h | 122 +++++++++++ src/presolve/ICrash.h | 8 +- src/simplex/HEkk.h | 68 ++++-- src/simplex/HighsSimplexAnalysis.h | 322 ++++++++++++++++++++--------- 5 files changed, 418 insertions(+), 121 deletions(-) diff --git a/src/io/HighsIO.h b/src/io/HighsIO.h index 7dd398d86d..cf041d5baa 100644 --- a/src/io/HighsIO.h +++ b/src/io/HighsIO.h @@ -18,7 +18,7 @@ #include #include "lp_data/HighsCallback.h" -//#include "util/HighsInt.h" +// #include "util/HighsInt.h" class HighsOptions; @@ -45,14 +45,23 @@ struct HighsLogOptions { bool* output_flag; bool* log_to_console; HighsInt* log_dev_level; - void (*user_log_callback)(HighsLogType, const char*, void*) = nullptr; - void* user_log_callback_data = nullptr; + void (*user_log_callback)(HighsLogType, const char*, void*); + void* user_log_callback_data; std::function user_callback; - void* user_callback_data = nullptr; - bool user_callback_active = false; + void* user_callback_data; + bool user_callback_active; void clear(); + HighsLogOptions() + : log_stream(nullptr), + output_flag(nullptr), + log_to_console(nullptr), + log_dev_level(nullptr), + user_log_callback(nullptr), + user_log_callback_data(nullptr), + user_callback_data(nullptr), + user_callback_active(false){}; }; /** diff --git a/src/lp_data/HighsOptions.h b/src/lp_data/HighsOptions.h index 38be9b59ae..879ed8e60e 100644 --- a/src/lp_data/HighsOptions.h +++ b/src/lp_data/HighsOptions.h @@ -424,6 +424,128 @@ struct HighsOptionsStruct { // Logging callback identifiers HighsLogOptions log_options; virtual ~HighsOptionsStruct() {} + + HighsOptionsStruct() + : presolve(""), + solver(""), + parallel(""), + run_crossover(""), + time_limit(0.0), + solution_file(""), + write_model_file(""), + random_seed(0), + ranging(""), + infinite_cost(0.0), + infinite_bound(0.0), + small_matrix_value(0.0), + large_matrix_value(0.0), + primal_feasibility_tolerance(0.0), + dual_feasibility_tolerance(0.0), + ipm_optimality_tolerance(0.0), + objective_bound(0.0), + objective_target(0.0), + threads(0), + user_bound_scale(0), + user_cost_scale(0), + highs_debug_level(0), + highs_analysis_level(0), + simplex_strategy(0), + simplex_scale_strategy(0), + simplex_crash_strategy(0), + simplex_dual_edge_weight_strategy(0), + simplex_primal_edge_weight_strategy(0), + simplex_iteration_limit(0), + simplex_update_limit(0), + simplex_min_concurrency(0), + simplex_max_concurrency(0), + log_file(""), + write_model_to_file(false), + write_solution_to_file(false), + write_solution_style(0), + glpsol_cost_row_location(0), + output_flag(false), + log_to_console(false), + ipm_iteration_limit(0), + pdlp_native_termination(false), + pdlp_scaling(false), + pdlp_iteration_limit(0), + pdlp_e_restart_method(0), + pdlp_d_gap_tol(0.0), + qp_iteration_limit(0), + qp_nullspace_limit(0), + log_dev_level(0), + log_githash(false), + solve_relaxation(false), + allow_unbounded_or_infeasible(false), + use_implied_bounds_from_presolve(false), + lp_presolve_requires_basis_postsolve(false), + mps_parser_type_free(false), + keep_n_rows(0), + cost_scale_factor(0), + allowed_matrix_scale_factor(0), + allowed_cost_scale_factor(0), + ipx_dualize_strategy(0), + simplex_dualize_strategy(0), + simplex_permute_strategy(0), + max_dual_simplex_cleanup_level(0), + max_dual_simplex_phase1_cleanup_level(0), + simplex_price_strategy(0), + simplex_unscaled_solution_strategy(0), + presolve_reduction_limit(0), + restart_presolve_reduction_limit(0), + presolve_substitution_maxfillin(0), + presolve_rule_off(0), + presolve_rule_logging(false), + simplex_initial_condition_check(false), + no_unnecessary_rebuild_refactor(false), + simplex_initial_condition_tolerance(0.0), + rebuild_refactor_solution_error_tolerance(0.0), + dual_steepest_edge_weight_error_tolerance(0.0), + dual_steepest_edge_weight_log_error_threshold(0.0), + dual_simplex_cost_perturbation_multiplier(0.0), + primal_simplex_bound_perturbation_multiplier(0.0), + dual_simplex_pivot_growth_tolerance(0.0), + presolve_pivot_threshold(0.0), + factor_pivot_threshold(0.0), + factor_pivot_tolerance(0.0), + start_crossover_tolerance(0.0), + less_infeasible_DSE_check(false), + less_infeasible_DSE_choose_row(false), + use_original_HFactor_logic(false), + run_centring(false), + max_centring_steps(0), + centring_ratio_tolerance(0.0), + icrash(false), + icrash_dualize(false), + icrash_strategy(""), + icrash_starting_weight(0.0), + icrash_iterations(0), + icrash_approx_iter(0), + icrash_exact(false), + icrash_breakpoints(false), + mip_detect_symmetry(false), + mip_allow_restart(false), + mip_max_nodes(0), + mip_max_stall_nodes(0), + mip_max_leaves(0), + mip_max_improving_sols(0), + mip_lp_age_limit(0), + mip_pool_age_limit(0), + mip_pool_soft_limit(0), + mip_pscost_minreliable(0), + mip_min_cliquetable_entries_for_parallelism(0), + mip_report_level(0), + mip_feasibility_tolerance(0.0), + mip_rel_gap(0.0), + mip_abs_gap(0.0), + mip_heuristic_effort(0.0), + mip_min_logging_interval(0.0), +#ifdef HIGHS_DEBUGSOL + mip_debug_solution_file(""), +#endif + mip_improving_solution_save(false), + mip_improving_solution_report_sparse(false), + mip_improving_solution_file(""){}; }; // For now, but later change so HiGHS properties are string based so that new diff --git a/src/presolve/ICrash.h b/src/presolve/ICrash.h index 9484b61535..dfe3d40bc7 100644 --- a/src/presolve/ICrash.h +++ b/src/presolve/ICrash.h @@ -85,7 +85,13 @@ struct Quadratic { double mu; std::vector lambda; - Quadratic(HighsLp lp_, ICrashOptions options_) : lp(lp_), options(options_) {} + Quadratic(HighsLp lp_, ICrashOptions options_) + : lp(lp_), + options(options_), + lp_objective(0.0), + quadratic_objective(0.0), + residual_norm_2(0.0), + mu(0.0) {} }; // Functions: Call. diff --git a/src/simplex/HEkk.h b/src/simplex/HEkk.h index c91aba199a..24baeb6338 100644 --- a/src/simplex/HEkk.h +++ b/src/simplex/HEkk.h @@ -25,7 +25,41 @@ class HighsLpSolverObject; class HEkk { public: - HEkk() {} + HEkk() + : callback_(nullptr), + options_(nullptr), + timer_(nullptr), + lp_name_(""), + model_status_(HighsModelStatus::kNotset), + simplex_in_scaled_space_(false), + cost_scale_(1.0), + cost_perturbation_base_(0.0), + cost_perturbation_max_abs_cost_(0.0), + iteration_count_(0), + dual_simplex_cleanup_level_(0), + dual_simplex_phase1_cleanup_level_(0), + previous_iteration_cycling_detected(-kHighsInf), + solve_bailout_(false), + called_return_from_solve_(false), + exit_algorithm_(SimplexAlgorithm::kNone), + return_primal_solution_status_(0), + return_dual_solution_status_(0), + original_num_col_(0), + original_num_row_(0), + original_num_nz_(0), + original_offset_(0.0), + edge_weight_error_(0.0), + build_synthetic_tick_(0.0), + total_synthetic_tick_(0.0), + debug_solve_call_num_(0), + debug_basis_id_(0), + time_report_(false), + debug_initial_build_synthetic_tick_(0), + debug_solve_report_(false), + debug_iteration_report_(false), + debug_basis_report_(false), + debug_dual_feasible(false), + debug_max_relative_dual_steepest_edge_weight_error(0) {} /** * @brief Interface to simplex solvers */ @@ -155,14 +189,14 @@ class HEkk { HSimplexNla simplex_nla_; HotStart hot_start_; - double cost_scale_ = 1; + double cost_scale_; double cost_perturbation_base_; double cost_perturbation_max_abs_cost_; - HighsInt iteration_count_ = 0; - HighsInt dual_simplex_cleanup_level_ = 0; - HighsInt dual_simplex_phase1_cleanup_level_ = 0; + HighsInt iteration_count_; + HighsInt dual_simplex_cleanup_level_; + HighsInt dual_simplex_phase1_cleanup_level_; - HighsInt previous_iteration_cycling_detected = -kHighsIInf; + HighsInt previous_iteration_cycling_detected; bool solve_bailout_; bool called_return_from_solve_; @@ -197,17 +231,17 @@ class HEkk { double edge_weight_error_; - double build_synthetic_tick_ = 0; - double total_synthetic_tick_ = 0; - HighsInt debug_solve_call_num_ = 0; - HighsInt debug_basis_id_ = 0; - bool time_report_ = false; - HighsInt debug_initial_build_synthetic_tick_ = 0; - bool debug_solve_report_ = false; - bool debug_iteration_report_ = false; - bool debug_basis_report_ = false; - bool debug_dual_feasible = false; - double debug_max_relative_dual_steepest_edge_weight_error = 0; + double build_synthetic_tick_; + double total_synthetic_tick_; + HighsInt debug_solve_call_num_; + HighsInt debug_basis_id_; + bool time_report_; + HighsInt debug_initial_build_synthetic_tick_; + bool debug_solve_report_; + bool debug_iteration_report_; + bool debug_basis_report_; + bool debug_dual_feasible; + double debug_max_relative_dual_steepest_edge_weight_error; std::vector bad_basis_change_; diff --git a/src/simplex/HighsSimplexAnalysis.h b/src/simplex/HighsSimplexAnalysis.h index 20d1e14e2d..7ac3035d41 100644 --- a/src/simplex/HighsSimplexAnalysis.h +++ b/src/simplex/HighsSimplexAnalysis.h @@ -58,7 +58,133 @@ const HighsLogType kIterationReportLogType = HighsLogType::kVerbose; */ class HighsSimplexAnalysis { public: - HighsSimplexAnalysis() {} + HighsSimplexAnalysis() + : timer_(nullptr), + pointer_serial_factor_clocks(nullptr), + numRow(0), + numCol(0), + numTot(0), + model_name_(""), + lp_name_(""), + analyse_lp_data(false), + analyse_simplex_summary_data(false), + analyse_simplex_runtime_data(false), + analyse_simplex_time(false), + analyse_factor_data(false), + analyse_factor_time(false), + analyse_simplex_data(false), + simplex_strategy(0), + edge_weight_mode(EdgeWeightMode::kSteepestEdge), + solve_phase(0), + simplex_iteration_count(0), + devex_iteration_count(0), + pivotal_row_index(0), + leaving_variable(0), + entering_variable(0), + rebuild_reason(0), + rebuild_reason_string(""), + reduced_rhs_value(0.0), + reduced_cost_value(0.0), + edge_weight(0.0), + edge_weight_error(0.0), + primal_delta(0.0), + primal_step(0.0), + dual_step(0.0), + pivot_value_from_column(0.0), + pivot_value_from_row(0.0), + factor_pivot_threshold(0.0), + numerical_trouble(0.0), + objective_value(0.0), + num_primal_infeasibility(0), + num_dual_infeasibility(0), + sum_primal_infeasibility(0.0), + sum_dual_infeasibility(0.0), + num_dual_phase_1_lp_dual_infeasibility(0), + max_dual_phase_1_lp_dual_infeasibility(0.0), + sum_dual_phase_1_lp_dual_infeasibility(0.0), + num_devex_framework(0), + col_aq_density(0.0), + row_ep_density(0.0), + row_ap_density(0.0), + row_DSE_density(0.0), + col_steepest_edge_density(0.0), + col_basic_feasibility_change_density(0.0), + row_basic_feasibility_change_density(0.0), + col_BFRT_density(0.0), + primal_col_density(0.0), + dual_col_density(0.0), + num_costly_DSE_iteration(0), + costly_DSE_measure(0.0), + multi_iteration_count(0), + multi_chosen(0), + multi_finished(0), + min_concurrency(0), + num_concurrency(0), + max_concurrency(0), + num_col_price(0), + num_row_price(0), + num_row_price_with_switch(0), + num_primal_cycling_detections(0), + num_dual_cycling_detections(0), + num_quad_chuzc(0), + num_heap_chuzc(0), + sum_quad_chuzc_size(0.0), + sum_heap_chuzc_size(0.0), + max_quad_chuzc_size(0), + max_heap_chuzc_size(0), + num_improve_choose_column_row_call(0), + num_remove_pivot_from_pack(0), + num_correct_dual_primal_flip(0), + min_correct_dual_primal_flip_dual_infeasibility(kHighsInf), + max_correct_dual_primal_flip(0.0), + num_correct_dual_cost_shift(0), + max_correct_dual_cost_shift_dual_infeasibility(0.0), + max_correct_dual_cost_shift(0.0), + net_num_single_cost_shift(0), + num_single_cost_shift(0), + max_single_cost_shift(0.0), + sum_single_cost_shift(0.0), + num_dual_steepest_edge_weight_check(0), + num_dual_steepest_edge_weight_reject(0), + num_wrong_low_dual_steepest_edge_weight(0), + num_wrong_high_dual_steepest_edge_weight(0), + average_frequency_low_dual_steepest_edge_weight(0.0), + average_frequency_high_dual_steepest_edge_weight(0.0), + average_log_low_dual_steepest_edge_weight_error(0.0), + average_log_high_dual_steepest_edge_weight_error(0.0), + max_average_frequency_low_dual_steepest_edge_weight(0.0), + max_average_frequency_high_dual_steepest_edge_weight(0.0), + max_sum_average_frequency_extreme_dual_steepest_edge_weight(0.0), + max_average_log_low_dual_steepest_edge_weight_error(0.0), + max_average_log_high_dual_steepest_edge_weight_error(0.0), + max_sum_average_log_extreme_dual_steepest_edge_weight_error(0.0), + num_invert_report_since_last_header(-1), + num_iteration_report_since_last_header(-1), + last_user_log_time(-kHighsInf), + delta_user_log_time(1e0), + average_concurrency(0.0), + average_fraction_of_possible_minor_iterations_performed(0.0), + sum_multi_chosen(0), + sum_multi_finished(0), + num_invert(0), + num_kernel(0), + num_major_kernel(0), + max_kernel_dim(0.0), + sum_kernel_dim(0.0), + running_average_kernel_dim(0.0), + sum_invert_fill_factor(0.0), + sum_kernel_fill_factor(0.0), + sum_major_kernel_fill_factor(0.0), + running_average_invert_fill_factor(1.0), + running_average_kernel_fill_factor(1.0), + running_average_major_kernel_fill_factor(1.0), + AnIterIt0(0), + AnIterPrevIt(0), + AnIterTraceNumRec(0), + AnIterTraceIterDl(0), + AnIterNumInvert{}, + AnIterNumEdWtIt{} {} + // Pointer to timer HighsTimer* timer_; @@ -162,38 +288,38 @@ class HighsSimplexAnalysis { // double dual_steepest_edge_weight_log_error_threshold; // Local copies of simplex data for reporting - HighsInt simplex_strategy = 0; - EdgeWeightMode edge_weight_mode = EdgeWeightMode::kSteepestEdge; - HighsInt solve_phase = 0; - HighsInt simplex_iteration_count = 0; - HighsInt devex_iteration_count = 0; - HighsInt pivotal_row_index = 0; - HighsInt leaving_variable = 0; - HighsInt entering_variable = 0; - HighsInt rebuild_reason = 0; - std::string rebuild_reason_string = ""; - double reduced_rhs_value = 0; - double reduced_cost_value = 0; - double edge_weight = 0; - double edge_weight_error = 0; - double primal_delta = 0; - double primal_step = 0; - double dual_step = 0; - double pivot_value_from_column = 0; - double pivot_value_from_row = 0; - double factor_pivot_threshold = 0; - double numerical_trouble = 0; - double objective_value = 0; - HighsInt num_primal_infeasibility = 0; - HighsInt num_dual_infeasibility = 0; - double sum_primal_infeasibility = 0; - double sum_dual_infeasibility = 0; + HighsInt simplex_strategy; + EdgeWeightMode edge_weight_mode; + HighsInt solve_phase; + HighsInt simplex_iteration_count; + HighsInt devex_iteration_count; + HighsInt pivotal_row_index; + HighsInt leaving_variable; + HighsInt entering_variable; + HighsInt rebuild_reason; + std::string rebuild_reason_string; + double reduced_rhs_value; + double reduced_cost_value; + double edge_weight; + double edge_weight_error; + double primal_delta; + double primal_step; + double dual_step; + double pivot_value_from_column; + double pivot_value_from_row; + double factor_pivot_threshold; + double numerical_trouble; + double objective_value; + HighsInt num_primal_infeasibility; + HighsInt num_dual_infeasibility; + double sum_primal_infeasibility; + double sum_dual_infeasibility; // This triple is an original infeasibility record, so it includes max, // but it's only used for reporting - HighsInt num_dual_phase_1_lp_dual_infeasibility = 0; - double max_dual_phase_1_lp_dual_infeasibility = 0; - double sum_dual_phase_1_lp_dual_infeasibility = 0; - HighsInt num_devex_framework = 0; + HighsInt num_dual_phase_1_lp_dual_infeasibility; + double max_dual_phase_1_lp_dual_infeasibility; + double sum_dual_phase_1_lp_dual_infeasibility; + HighsInt num_devex_framework; double col_aq_density; double row_ep_density; double row_ap_density; @@ -208,21 +334,21 @@ class HighsSimplexAnalysis { double costly_DSE_measure; // Local copies of parallel simplex data for reporting - HighsInt multi_iteration_count = 0; - HighsInt multi_chosen = 0; - HighsInt multi_finished = 0; - HighsInt min_concurrency = 0; - HighsInt num_concurrency = 0; - HighsInt max_concurrency = 0; + HighsInt multi_iteration_count; + HighsInt multi_chosen; + HighsInt multi_finished; + HighsInt min_concurrency; + HighsInt num_concurrency; + HighsInt max_concurrency; // Unused // HighsInt multi_num = 0; // Useless // double basis_condition = 0; // Maybe useful // Records of how pivotal row PRICE was done - HighsInt num_col_price = 0; - HighsInt num_row_price = 0; - HighsInt num_row_price_with_switch = 0; + HighsInt num_col_price; + HighsInt num_row_price; + HighsInt num_row_price_with_switch; HighsValueDistribution before_ftran_upper_sparse_density; HighsValueDistribution ftran_upper_sparse_density; @@ -235,29 +361,29 @@ class HighsSimplexAnalysis { HighsValueDistribution cleanup_dual_step_distribution; HighsValueDistribution cleanup_primal_change_distribution; - HighsInt num_primal_cycling_detections = 0; - HighsInt num_dual_cycling_detections = 0; - - HighsInt num_quad_chuzc = 0; - HighsInt num_heap_chuzc = 0; - double sum_quad_chuzc_size = 0; - double sum_heap_chuzc_size = 0; - HighsInt max_quad_chuzc_size = 0; - HighsInt max_heap_chuzc_size = 0; - - HighsInt num_improve_choose_column_row_call = 0; - HighsInt num_remove_pivot_from_pack = 0; - - HighsInt num_correct_dual_primal_flip = 0; - double min_correct_dual_primal_flip_dual_infeasibility = kHighsInf; - double max_correct_dual_primal_flip = 0; - HighsInt num_correct_dual_cost_shift = 0; - double max_correct_dual_cost_shift_dual_infeasibility = 0; - double max_correct_dual_cost_shift = 0; - HighsInt net_num_single_cost_shift = 0; - HighsInt num_single_cost_shift = 0; - double max_single_cost_shift = 0; - double sum_single_cost_shift = 0; + HighsInt num_primal_cycling_detections; + HighsInt num_dual_cycling_detections; + + HighsInt num_quad_chuzc; + HighsInt num_heap_chuzc; + double sum_quad_chuzc_size; + double sum_heap_chuzc_size; + HighsInt max_quad_chuzc_size; + HighsInt max_heap_chuzc_size; + + HighsInt num_improve_choose_column_row_call; + HighsInt num_remove_pivot_from_pack; + + HighsInt num_correct_dual_primal_flip; + double min_correct_dual_primal_flip_dual_infeasibility; + double max_correct_dual_primal_flip; + HighsInt num_correct_dual_cost_shift; + double max_correct_dual_cost_shift_dual_infeasibility; + double max_correct_dual_cost_shift; + HighsInt net_num_single_cost_shift; + HighsInt num_single_cost_shift; + double max_single_cost_shift; + double sum_single_cost_shift; // Tolerances for analysis of TRAN stages - could be needed for // control if this is ever used again! @@ -290,46 +416,46 @@ class HighsSimplexAnalysis { // double AnIterCostlyDseFq; //!< Frequency of iterations when DSE is costly // double AnIterCostlyDseMeasure; - HighsInt num_dual_steepest_edge_weight_check = 0; - HighsInt num_dual_steepest_edge_weight_reject = 0; - HighsInt num_wrong_low_dual_steepest_edge_weight = 0; - HighsInt num_wrong_high_dual_steepest_edge_weight = 0; - double average_frequency_low_dual_steepest_edge_weight = 0; - double average_frequency_high_dual_steepest_edge_weight = 0; - double average_log_low_dual_steepest_edge_weight_error = 0; - double average_log_high_dual_steepest_edge_weight_error = 0; - double max_average_frequency_low_dual_steepest_edge_weight = 0; - double max_average_frequency_high_dual_steepest_edge_weight = 0; - double max_sum_average_frequency_extreme_dual_steepest_edge_weight = 0; - double max_average_log_low_dual_steepest_edge_weight_error = 0; - double max_average_log_high_dual_steepest_edge_weight_error = 0; - double max_sum_average_log_extreme_dual_steepest_edge_weight_error = 0; - - HighsInt num_invert_report_since_last_header = -1; - HighsInt num_iteration_report_since_last_header = -1; - double last_user_log_time = -kHighsInf; - double delta_user_log_time = 1e0; + HighsInt num_dual_steepest_edge_weight_check; + HighsInt num_dual_steepest_edge_weight_reject; + HighsInt num_wrong_low_dual_steepest_edge_weight; + HighsInt num_wrong_high_dual_steepest_edge_weight; + double average_frequency_low_dual_steepest_edge_weight; + double average_frequency_high_dual_steepest_edge_weight; + double average_log_low_dual_steepest_edge_weight_error; + double average_log_high_dual_steepest_edge_weight_error; + double max_average_frequency_low_dual_steepest_edge_weight; + double max_average_frequency_high_dual_steepest_edge_weight; + double max_sum_average_frequency_extreme_dual_steepest_edge_weight; + double max_average_log_low_dual_steepest_edge_weight_error; + double max_average_log_high_dual_steepest_edge_weight_error; + double max_sum_average_log_extreme_dual_steepest_edge_weight_error; + + HighsInt num_invert_report_since_last_header; + HighsInt num_iteration_report_since_last_header; + double last_user_log_time; + double delta_user_log_time; double average_concurrency; double average_fraction_of_possible_minor_iterations_performed; - HighsInt sum_multi_chosen = 0; - HighsInt sum_multi_finished = 0; + HighsInt sum_multi_chosen; + HighsInt sum_multi_finished; // Analysis of INVERT form - HighsInt num_invert = 0; - HighsInt num_kernel = 0; - HighsInt num_major_kernel = 0; - double max_kernel_dim = 0; - double sum_kernel_dim = 0; - double running_average_kernel_dim = 0; - double sum_invert_fill_factor = 0; - double sum_kernel_fill_factor = 0; - double sum_major_kernel_fill_factor = 0; - double running_average_invert_fill_factor = 1; - double running_average_kernel_fill_factor = 1; - double running_average_major_kernel_fill_factor = 1; - - HighsInt AnIterIt0 = 0; + HighsInt num_invert; + HighsInt num_kernel; + HighsInt num_major_kernel; + double max_kernel_dim; + double sum_kernel_dim; + double running_average_kernel_dim; + double sum_invert_fill_factor; + double sum_kernel_fill_factor; + double sum_major_kernel_fill_factor; + double running_average_invert_fill_factor; + double running_average_kernel_fill_factor; + double running_average_major_kernel_fill_factor; + + HighsInt AnIterIt0; HighsInt AnIterPrevIt; // Major operation analysis struct From 8b10c1745cc5144e506612f6557507372f26ad28 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 19 Jun 2024 09:59:14 +0200 Subject: [PATCH 32/68] Minor changes --- src/io/HighsIO.h | 2 +- src/simplex/HighsSimplexAnalysis.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/io/HighsIO.h b/src/io/HighsIO.h index cf041d5baa..adead90c24 100644 --- a/src/io/HighsIO.h +++ b/src/io/HighsIO.h @@ -18,7 +18,7 @@ #include #include "lp_data/HighsCallback.h" -// #include "util/HighsInt.h" +//#include "util/HighsInt.h" class HighsOptions; diff --git a/src/simplex/HighsSimplexAnalysis.h b/src/simplex/HighsSimplexAnalysis.h index 7ac3035d41..93b88bcc93 100644 --- a/src/simplex/HighsSimplexAnalysis.h +++ b/src/simplex/HighsSimplexAnalysis.h @@ -182,6 +182,7 @@ class HighsSimplexAnalysis { AnIterPrevIt(0), AnIterTraceNumRec(0), AnIterTraceIterDl(0), + AnIterTrace{}, AnIterNumInvert{}, AnIterNumEdWtIt{} {} From dc93a4f4125b954f39a3f58a315cdf89dffc270d Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 19 Jun 2024 10:19:51 +0200 Subject: [PATCH 33/68] Add missing initializations --- src/mip/HighsDomain.h | 1 + src/mip/HighsSearch.h | 1 + src/simplex/HighsSimplexAnalysis.h | 1 + src/util/HighsMatrixSlice.h | 10 ++++++---- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mip/HighsDomain.h b/src/mip/HighsDomain.h index fb09c99164..40968d0266 100644 --- a/src/mip/HighsDomain.h +++ b/src/mip/HighsDomain.h @@ -358,6 +358,7 @@ class HighsDomain { conflictPoolPropagation(other.conflictPoolPropagation), infeasible_(other.infeasible_), infeasible_reason(other.infeasible_reason), + infeasible_pos(0), colLowerPos_(other.colLowerPos_), colUpperPos_(other.colUpperPos_), branchPos_(other.branchPos_), diff --git a/src/mip/HighsSearch.h b/src/mip/HighsSearch.h index ccea0a26ef..c9c665e21a 100644 --- a/src/mip/HighsSearch.h +++ b/src/mip/HighsSearch.h @@ -96,6 +96,7 @@ class HighsSearch { std::shared_ptr stabilizerOrbits = nullptr) : lower_bound(parentlb), estimate(parentestimate), + branching_point(0.0), lp_objective(-kHighsInf), other_child_lb(parentlb), nodeBasis(std::move(parentBasis)), diff --git a/src/simplex/HighsSimplexAnalysis.h b/src/simplex/HighsSimplexAnalysis.h index 93b88bcc93..b12dd1c134 100644 --- a/src/simplex/HighsSimplexAnalysis.h +++ b/src/simplex/HighsSimplexAnalysis.h @@ -180,6 +180,7 @@ class HighsSimplexAnalysis { running_average_major_kernel_fill_factor(1.0), AnIterIt0(0), AnIterPrevIt(0), + AnIterOp{}, AnIterTraceNumRec(0), AnIterTraceIterDl(0), AnIterTrace{}, diff --git a/src/util/HighsMatrixSlice.h b/src/util/HighsMatrixSlice.h index 6c71253672..3da09ce402 100644 --- a/src/util/HighsMatrixSlice.h +++ b/src/util/HighsMatrixSlice.h @@ -196,7 +196,7 @@ class HighsMatrixSlice { using pointer = const HighsSliceNonzero*; using reference = const HighsSliceNonzero&; - iterator(HighsInt node) : currentNode(node) {} + iterator(HighsInt node) : pos_(), nodeNext(nullptr), currentNode(node) {} iterator(const HighsInt* nodeIndex, const double* nodeValue, const HighsInt* nodeNext, HighsInt node) : pos_(node == -1 ? nullptr : nodeIndex + node, @@ -276,7 +276,8 @@ class HighsMatrixSlice { using pointer = const HighsSliceNonzero*; using reference = const HighsSliceNonzero&; - iterator(HighsInt node) : currentNode(node) {} + iterator(HighsInt node) + : pos_(), nodeLeft(nullptr), nodeRight(nullptr), currentNode(node) {} iterator(const HighsInt* nodeIndex, const double* nodeValue, const HighsInt* nodeLeft, const HighsInt* nodeRight, HighsInt node) : pos_(nodeIndex + node, nodeValue + node), @@ -374,7 +375,8 @@ class HighsMatrixSlice { using pointer = const HighsSliceNonzero*; using reference = const HighsSliceNonzero&; - iterator(HighsInt node) : currentNode(node) {} + iterator(HighsInt node) + : pos_(), nodeLeft(nullptr), nodeRight(nullptr), currentNode(node) {} iterator(const HighsInt* nodeIndex, const double* nodeValue, const HighsInt* nodeLeft, const HighsInt* nodeRight, HighsInt node) : pos_(nodeIndex, nodeValue), @@ -477,7 +479,7 @@ class HighsMatrixSlice { using pointer = const HighsSliceNonzero*; using reference = const HighsSliceNonzero&; - iterator(const HighsInt* node) : node(node) {} + iterator(const HighsInt* node) : pos_(), node(node), currentNode(0) {} iterator(const HighsInt* nodeIndex, const double* nodeValue, const HighsInt* node) : pos_(nodeIndex, nodeValue), node(node), currentNode(0) {} From 337e8a3f8581fcd60cfb1bd8114e757722c2036b Mon Sep 17 00:00:00 2001 From: JAJHall Date: Wed, 19 Jun 2024 18:25:30 +0100 Subject: [PATCH 34/68] Updated documentation --- docs/src/options/definitions.md | 12 ++++++++++++ docs/src/structures/enums.md | 2 ++ src/lp_data/HighsOptions.h | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/src/options/definitions.md b/docs/src/options/definitions.md index ba3988e850..2505c4d3c3 100644 --- a/docs/src/options/definitions.md +++ b/docs/src/options/definitions.md @@ -341,3 +341,15 @@ - Range: [1e-12, inf] - Default: 0.0001 +## qp\_iteration\_limit +- Iteration limit for QP solver +- Type: integer +- Range: {0, 2147483647} +- Default: 2147483647 + +## qp\_nullspace\_limit +- Nullspace limit for QP solver +- Type: integer +- Range: {0, 2147483647} +- Default: 4000 + diff --git a/docs/src/structures/enums.md b/docs/src/structures/enums.md index af9601b7c2..7975e41fb0 100644 --- a/docs/src/structures/enums.md +++ b/docs/src/structures/enums.md @@ -73,6 +73,8 @@ This defines the status of the model after a call to `run` * `kTimeLimit`: The run time limit has been reached * `kIterationLimit`: The iteration limit has been reached * `kSolutionLimit`: The MIP solver has reached the limit on the number of LPs solved + * `kInterrupt`: The solver has been interrupted by the user + * `kMemoryLimit`: The solver has been unable to allocate sufficient memory * `kUnknown`: The model status is unknown ## HighsBasisStatus diff --git a/src/lp_data/HighsOptions.h b/src/lp_data/HighsOptions.h index 38be9b59ae..e3f0bacf6b 100644 --- a/src/lp_data/HighsOptions.h +++ b/src/lp_data/HighsOptions.h @@ -817,7 +817,7 @@ class HighsOptions : public HighsOptionsStruct { record_string = new OptionRecordString( "mip_improving_solution_file", "File for reporting improving MIP solutions: not reported for an empty " - "string \"\"", + "string \\\"\\\"", advanced, &mip_improving_solution_file, kHighsFilenameDefault); records.push_back(record_string); From 105fdee064ccb9d4b6dfb5e8d910e2fe7f58da5e Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 19 Jun 2024 21:17:05 +0200 Subject: [PATCH 35/68] Fix typo --- src/simplex/HEkk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplex/HEkk.h b/src/simplex/HEkk.h index 24baeb6338..6384e22c10 100644 --- a/src/simplex/HEkk.h +++ b/src/simplex/HEkk.h @@ -38,7 +38,7 @@ class HEkk { iteration_count_(0), dual_simplex_cleanup_level_(0), dual_simplex_phase1_cleanup_level_(0), - previous_iteration_cycling_detected(-kHighsInf), + previous_iteration_cycling_detected(-kHighsIInf), solve_bailout_(false), called_return_from_solve_(false), exit_algorithm_(SimplexAlgorithm::kNone), From 093a696e8e40cb51c7217a960e02fa2bcd0cc890 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 21 Jun 2024 09:58:05 +0200 Subject: [PATCH 36/68] Fix initialization --- src/mip/HighsDomain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mip/HighsDomain.h b/src/mip/HighsDomain.h index 40968d0266..57ff4fe45c 100644 --- a/src/mip/HighsDomain.h +++ b/src/mip/HighsDomain.h @@ -358,7 +358,7 @@ class HighsDomain { conflictPoolPropagation(other.conflictPoolPropagation), infeasible_(other.infeasible_), infeasible_reason(other.infeasible_reason), - infeasible_pos(0), + infeasible_pos(other.infeasible_pos), colLowerPos_(other.colLowerPos_), colUpperPos_(other.colUpperPos_), branchPos_(other.branchPos_), From 032b4990a951f21248e3e74d7da5d5a4b5f994c5 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 21 Jun 2024 15:01:02 +0200 Subject: [PATCH 37/68] Add constructor in HFactor.h and other minor things --- src/mip/HighsCliqueTable.cpp | 2 +- src/qpsolver/steepestedgepricing.hpp | 3 +-- src/simplex/HEkkDualRow.cpp | 8 ++++---- src/util/HFactor.h | 29 ++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/mip/HighsCliqueTable.cpp b/src/mip/HighsCliqueTable.cpp index 9a51cda7f9..123a479158 100644 --- a/src/mip/HighsCliqueTable.cpp +++ b/src/mip/HighsCliqueTable.cpp @@ -189,7 +189,7 @@ void HighsCliqueTable::bronKerboschRecurse(BronKerboschData& data, if (data.stop()) return; double pivweight = -1.0; - CliqueVar pivot; + CliqueVar pivot{0, 0}; for (HighsInt i = 0; i != Xlen; ++i) { if (X[i].weight(data.sol) > pivweight) { diff --git a/src/qpsolver/steepestedgepricing.hpp b/src/qpsolver/steepestedgepricing.hpp index 0002bd6e13..0a216394ee 100644 --- a/src/qpsolver/steepestedgepricing.hpp +++ b/src/qpsolver/steepestedgepricing.hpp @@ -91,7 +91,6 @@ class SteepestEdgePricing : public Pricing { std::vector correct_weights; std::vector incorrect_weights; - bool ret = true; for (int i=0; isimplexTimerStart(Chuzc4bClock); - HighsInt breakIndex; - HighsInt breakGroup; - HighsInt alt_breakIndex; - HighsInt alt_breakGroup; + HighsInt breakIndex = -1; + HighsInt breakGroup = -1; + HighsInt alt_breakIndex = -1; + HighsInt alt_breakGroup = -1; if (use_quad_sort) chooseFinalLargeAlpha(breakIndex, breakGroup, workCount, workData, workGroup); diff --git a/src/util/HFactor.h b/src/util/HFactor.h index a846c9c528..f4057b88ee 100644 --- a/src/util/HFactor.h +++ b/src/util/HFactor.h @@ -105,6 +105,35 @@ struct InvertibleRepresentation { */ class HFactor { public: + HFactor() + : build_realTick(0.0), + build_synthetic_tick(0.0), + rank_deficiency(0), + basis_matrix_num_el(0), + invert_num_el(0), + kernel_dim(0), + kernel_num_el(0), + num_row(0), + num_col(0), + num_basic(0), + a_matrix_valid(false), + a_start(nullptr), + a_index(nullptr), + a_value(nullptr), + basic_index(nullptr), + pivot_threshold(0.0), + pivot_tolerance(0.0), + highs_debug_level(0), + time_limit_(0.0), + use_original_HFactor_logic(false), + debug_report_(false), + basis_matrix_limit_size(0), + update_method(0), + build_timer_(nullptr), + nwork(0), + u_merit_x(0), + u_total_x(0){}; + /** * @brief Copy problem size and pointers of constraint matrix, and set * up space for INVERT From 4418ec5f810dec57bbeef366a85c8cb96b608ca2 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 21 Jun 2024 15:05:01 +0200 Subject: [PATCH 38/68] Make compiler happy --- src/simplex/HEkkDual.cpp | 2 +- src/simplex/HEkkPrimal.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simplex/HEkkDual.cpp b/src/simplex/HEkkDual.cpp index 30d42a96a2..6a6ca9d13e 100644 --- a/src/simplex/HEkkDual.cpp +++ b/src/simplex/HEkkDual.cpp @@ -1063,7 +1063,7 @@ void HEkkDual::rebuild() { // Note that computePrimalObjectiveValue sets // has_primal_objective_value const bool check_updated_objective_value = status.has_dual_objective_value; - double previous_dual_objective_value; + double previous_dual_objective_value = -kHighsInf; if (check_updated_objective_value) { // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, // "Before computeDual"); diff --git a/src/simplex/HEkkPrimal.cpp b/src/simplex/HEkkPrimal.cpp index 8c9787cee4..9a258ad90e 100644 --- a/src/simplex/HEkkPrimal.cpp +++ b/src/simplex/HEkkPrimal.cpp @@ -697,7 +697,7 @@ void HEkkPrimal::rebuild() { // basic variables, and baseValue only corresponds to the new // ordering once computePrimal has been called const bool check_updated_objective_value = status.has_primal_objective_value; - double previous_primal_objective_value; + double previous_primal_objective_value = -kHighsInf; if (check_updated_objective_value) { // debugUpdatedObjectiveValue(ekk_instance_, algorithm, solve_phase, // "Before INVERT"); From b831faa63810ce9b0bff2a5b406e96e69e5ac824 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 21 Jun 2024 15:09:24 +0200 Subject: [PATCH 39/68] WIP --- src/util/HFactor.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/util/HFactor.h b/src/util/HFactor.h index f4057b88ee..d06a79af67 100644 --- a/src/util/HFactor.h +++ b/src/util/HFactor.h @@ -333,10 +333,10 @@ class HFactor { RefactorInfo refactor_info_; // Properties of data held in HFactor.h - HighsInt basis_matrix_num_el = 0; - HighsInt invert_num_el = 0; - HighsInt kernel_dim = 0; - HighsInt kernel_num_el = 0; + HighsInt basis_matrix_num_el; + HighsInt invert_num_el; + HighsInt kernel_dim; + HighsInt kernel_num_el; /** * Data of the factor @@ -368,7 +368,7 @@ class HFactor { HighsLogOptions log_options; bool use_original_HFactor_logic; - bool debug_report_ = false; + bool debug_report_; HighsInt basis_matrix_limit_size; HighsInt update_method; From 38578b2c40a9059cdd709fc0315fe687f97186fa Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 21 Jun 2024 15:19:56 +0200 Subject: [PATCH 40/68] Fix two warnings --- src/qpsolver/a_quass.cpp | 2 +- src/simplex/HEkkDualRow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qpsolver/a_quass.cpp b/src/qpsolver/a_quass.cpp index a8e2583b12..b62d22ebc9 100644 --- a/src/qpsolver/a_quass.cpp +++ b/src/qpsolver/a_quass.cpp @@ -157,7 +157,7 @@ QpAsmStatus solveqp(Instance& instance, } // solve - QpAsmStatus status = solveqp_actual(instance, settings, startinfo, stats, qp_model_status, qp_solution, qp_timer); + solveqp_actual(instance, settings, startinfo, stats, qp_model_status, qp_solution, qp_timer); // undo perturbation and resolve diff --git a/src/simplex/HEkkDualRow.cpp b/src/simplex/HEkkDualRow.cpp index 11813c6ab3..6f0e00bc6c 100644 --- a/src/simplex/HEkkDualRow.cpp +++ b/src/simplex/HEkkDualRow.cpp @@ -186,7 +186,7 @@ HighsInt HEkkDualRow::chooseFinal() { alt_workCount = workCount; } analysis->simplexTimerStart(Chuzc4Clock); - bool choose_ok; + bool choose_ok = false; if (use_quad_sort) { // Use the O(n^2) quadratic sort for the candidates analysis->simplexTimerStart(Chuzc4a0Clock); From 71fc39ea9f710d40f46000d4e5348635d1a6b49a Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 24 Jun 2024 10:26:07 +0200 Subject: [PATCH 41/68] Unreferenced parameters --- src/mip/HighsDebugSol.h | 49 ++++++++++++++++++----------------------- src/mip/HighsGFkSolve.h | 2 +- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/mip/HighsDebugSol.h b/src/mip/HighsDebugSol.h index 9c8852ad9b..ddce632c45 100644 --- a/src/mip/HighsDebugSol.h +++ b/src/mip/HighsDebugSol.h @@ -88,54 +88,47 @@ struct HighsDebugSol { #else struct HighsDebugSol { - HighsDebugSol(HighsMipSolver& mipsolver) {} + HighsDebugSol(HighsMipSolver&) {} void newIncumbentFound() const {} void activate() const {} - void shrink(const std::vector& newColIndex) const {} + void shrink(const std::vector&) const {} - void registerDomain(const HighsDomain& domain) const {} + void registerDomain(const HighsDomain&) const {} - void boundChangeAdded(const HighsDomain& domain, - const HighsDomainChange& domchg, - bool branching = false) const {} + void boundChangeAdded(const HighsDomain&, const HighsDomainChange&, + bool = false) const {} - void boundChangeRemoved(const HighsDomain& domain, - const HighsDomainChange& domchg) const {} + void boundChangeRemoved(const HighsDomain&, const HighsDomainChange&) const {} - void resetDomain(const HighsDomain& domain) const {} + void resetDomain(const HighsDomain&) const {} - void nodePruned(const HighsDomain& localdomain) const {} + void nodePruned(const HighsDomain&) const {} - void checkCut(const HighsInt* Rindex, const double* Rvalue, HighsInt Rlen, - double rhs) const {} + void checkCut(const HighsInt*, const double*, HighsInt, double) const {} - void checkRow(const HighsInt* Rindex, const double* Rvalue, HighsInt Rlen, - double Rlower, double Rupper) const {} + void checkRow(const HighsInt*, const double*, HighsInt, double, + double) const {} - void checkRowAggregation(const HighsLp& lp, const HighsInt* Rindex, - const double* Rvalue, HighsInt Rlen) const {} + void checkRowAggregation(const HighsLp&, const HighsInt*, const double*, + HighsInt) const {} - void checkClique(const HighsCliqueTable::CliqueVar* clq, - HighsInt clqlen) const {} + void checkClique(const HighsCliqueTable::CliqueVar*, HighsInt) const {} - void checkVub(HighsInt col, HighsInt vubcol, double vubcoef, - double vubconstant) const {} + void checkVub(HighsInt, HighsInt, double, double) const {} - void checkVlb(HighsInt col, HighsInt vlbcol, double vlbcoef, - double vlbconstant) const {} + void checkVlb(HighsInt, HighsInt, double, double) const {} void checkConflictReasonFrontier( - const std::set& reasonSideFrontier, - const std::vector& domchgstack) const {} + const std::set&, + const std::vector&) const {} void checkConflictReconvergenceFrontier( - const std::set& - reconvergenceFrontier, - const HighsDomain::ConflictSet::LocalDomChg& reconvDomchgPos, - const std::vector& domchgstack) const {} + const std::set&, + const HighsDomain::ConflictSet::LocalDomChg&, + const std::vector&) const {} }; #endif diff --git a/src/mip/HighsGFkSolve.h b/src/mip/HighsGFkSolve.h index 7cfd5a52e2..75519459de 100644 --- a/src/mip/HighsGFkSolve.h +++ b/src/mip/HighsGFkSolve.h @@ -39,7 +39,7 @@ struct HighsGFk; template <> struct HighsGFk<2> { static constexpr unsigned int powk(unsigned int a) { return a * a; } - static constexpr unsigned int inverse(unsigned int a) { return 1; } + static constexpr unsigned int inverse(unsigned int) { return 1; } }; template <> From 358f90e6567f19b2db3d3f6890475af350de75f9 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 24 Jun 2024 14:01:08 +0200 Subject: [PATCH 42/68] Initialize member variables in HighsMipSolverData --- src/mip/HighsMipSolverData.h | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/mip/HighsMipSolverData.h b/src/mip/HighsMipSolverData.h index 07a17e23f6..cbf697fcfc 100644 --- a/src/mip/HighsMipSolverData.h +++ b/src/mip/HighsMipSolverData.h @@ -128,6 +128,46 @@ struct HighsMipSolverData { implications(mipsolver), heuristics(mipsolver), objectiveFunction(mipsolver), + presolve_status(HighsPresolveStatus::kNotSet), + cliquesExtracted(false), + rowMatrixSet(false), + analyticCenterComputed(false), + analyticCenterStatus(HighsModelStatus::kNotset), + detectSymmetries(false), + numRestarts(0), + numRestartsRoot(0), + numCliqueEntriesAfterPresolve(0), + numCliqueEntriesAfterFirstPresolve(0), + feastol(0.0), + epsilon(0.0), + heuristic_effort(0.0), + dispfreq(0), + firstlpsolobj(-kHighsInf), + rootlpsolobj(-kHighsInf), + numintegercols(0), + maxTreeSizeLog2(0), + pruned_treeweight(0), + avgrootlpiters(0.0), + last_disptime(0.0), + firstrootlpiters(0), + num_nodes(0), + num_leaves(0), + num_leaves_before_run(0), + num_nodes_before_run(0), + total_lp_iterations(0), + heuristic_lp_iterations(0), + sepa_lp_iterations(0), + sb_lp_iterations(0), + total_lp_iterations_before_run(0), + heuristic_lp_iterations_before_run(0), + sepa_lp_iterations_before_run(0), + sb_lp_iterations_before_run(0), + num_disp_lines(0), + numImprovingSols(0), + lower_bound(-kHighsInf), + upper_bound(kHighsInf), + upper_limit(kHighsInf), + optimality_limit(kHighsInf), debugSolution(mipsolver) { domain.addCutpool(cutpool); domain.addConflictPool(conflictPool); From 61c1a1bc4be3bdd9edeaf71be7ce0005b235b43e Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 24 Jun 2024 14:35:30 +0200 Subject: [PATCH 43/68] Two more warnings fixed --- src/mip/HighsCliqueTable.cpp | 10 ++++++---- src/parallel/HighsMutex.h | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/mip/HighsCliqueTable.cpp b/src/mip/HighsCliqueTable.cpp index 123a479158..54490e08e0 100644 --- a/src/mip/HighsCliqueTable.cpp +++ b/src/mip/HighsCliqueTable.cpp @@ -2021,8 +2021,9 @@ void HighsCliqueTable::runCliqueMerging(HighsDomain& globaldomain, std::remove_if(clique.begin(), clique.end(), [&](CliqueVar v) { return globaldomain.isFixed(v.col) && - int(globaldomain.col_lower_[v.col]) == - (1 - v.val); + static_cast( + globaldomain.col_lower_[v.col]) == + static_cast(1 - v.val); }), clique.end()); } @@ -2190,8 +2191,9 @@ void HighsCliqueTable::runCliqueMerging(HighsDomain& globaldomain) { std::remove_if(extensionvars.begin(), extensionvars.end(), [&](CliqueVar v) { return globaldomain.isFixed(v.col) && - int(globaldomain.col_lower_[v.col]) == - (1 - v.val); + static_cast( + globaldomain.col_lower_[v.col]) == + static_cast(1 - v.val); }), extensionvars.end()); diff --git a/src/parallel/HighsMutex.h b/src/parallel/HighsMutex.h index cd39788ace..34d8b95541 100644 --- a/src/parallel/HighsMutex.h +++ b/src/parallel/HighsMutex.h @@ -114,7 +114,8 @@ class HighsMutex { } void unlock() { - unsigned int prevState = state.fetch_add(-1, std::memory_order_release); + unsigned int prevState = state.fetch_add( + std::numeric_limits::max(), std::memory_order_release); if (prevState != 1) { unsigned int notifyWorkerId = (prevState >> 1) - 1; From 397e0266c075d5fe4e20e897a54fccee92244df2 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 24 Jun 2024 15:09:14 +0200 Subject: [PATCH 44/68] Two minor changes --- src/io/HMpsFF.cpp | 6 +++--- src/lp_data/HighsModelUtils.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/io/HMpsFF.cpp b/src/io/HMpsFF.cpp index cf18f204d5..14f0bf5dc0 100644 --- a/src/io/HMpsFF.cpp +++ b/src/io/HMpsFF.cpp @@ -2036,12 +2036,12 @@ double HMpsFF::getValue(const std::string& word, bool& is_nan, const HighsInt id) const { // Lambda to replace any d or D by E auto dD2e = [&](std::string& word) { - HighsInt ix = word.find("D"); - if (ix >= 0) { + size_t ix = word.find("D"); + if (ix != std::string::npos) { word.replace(ix, 1, "E"); } else { ix = word.find("d"); - if (ix >= 0) word.replace(ix, 1, "E"); + if (ix != std::string::npos) word.replace(ix, 1, "E"); } }; diff --git a/src/lp_data/HighsModelUtils.cpp b/src/lp_data/HighsModelUtils.cpp index 1e878740b0..6a60010282 100644 --- a/src/lp_data/HighsModelUtils.cpp +++ b/src/lp_data/HighsModelUtils.cpp @@ -319,8 +319,8 @@ bool hasNamesWithSpaces(const HighsLogOptions& log_options, const std::vector& names) { HighsInt num_names_with_spaces = 0; for (HighsInt ix = 0; ix < num_name; ix++) { - HighsInt space_pos = names[ix].find(" "); - if (space_pos >= 0) { + size_t space_pos = names[ix].find(" "); + if (space_pos != std::string::npos) { if (num_names_with_spaces == 0) { highsLogDev( log_options, HighsLogType::kInfo, From f9e8c3e2f97aefb10f120b6e6d84e8206e1f791f Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 25 Jun 2024 09:42:25 +0200 Subject: [PATCH 45/68] Fix output "generators" -> "generator(s)" --- src/mip/HighsMipSolverData.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mip/HighsMipSolverData.cpp b/src/mip/HighsMipSolverData.cpp index 4070dfb021..1d926134ab 100644 --- a/src/mip/HighsMipSolverData.cpp +++ b/src/mip/HighsMipSolverData.cpp @@ -183,17 +183,17 @@ void HighsMipSolverData::finishSymmetryDetection( "No symmetry present\n\n"); } else if (symmetries.orbitopes.size() == 0) { highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kInfo, - "Found %" HIGHSINT_FORMAT " generators\n\n", + "Found %" HIGHSINT_FORMAT " generator(s)\n\n", symmetries.numGenerators); } else { if (symmetries.numPerms != 0) { - highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kInfo, - "Found %" HIGHSINT_FORMAT " generators and %" HIGHSINT_FORMAT - " full orbitope(s) acting on %" HIGHSINT_FORMAT - " columns\n\n", - symmetries.numPerms, (HighsInt)symmetries.orbitopes.size(), - (HighsInt)symmetries.columnToOrbitope.size()); + highsLogUser( + mipsolver.options_mip_->log_options, HighsLogType::kInfo, + "Found %" HIGHSINT_FORMAT " generator(s) and %" HIGHSINT_FORMAT + " full orbitope(s) acting on %" HIGHSINT_FORMAT " columns\n\n", + symmetries.numPerms, (HighsInt)symmetries.orbitopes.size(), + (HighsInt)symmetries.columnToOrbitope.size()); } else { highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kInfo, "Found %" HIGHSINT_FORMAT From 7679e11a261aa4e6e40cb9d5222b9f81edca1990 Mon Sep 17 00:00:00 2001 From: jajhall Date: Sun, 30 Jun 2024 16:36:45 +0100 Subject: [PATCH 46/68] Moved pdlp_iteration_count back to where it was inserted, breaking the C API --- FEATURES.md | 42 +++++++------------------------ src/lp_data/HighsCallbackStruct.h | 2 +- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index 09784c9767..98dc828433 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -1,41 +1,17 @@ ## Build changes -### HiGHS on nixpkgs - -HiGHS now has a `flake.nix` to build the binary, allowing `nix` users to try it out - -### Python build update - -Highspy with setuptools from v1.7.0 only worked on Python 3.12 -For v1.7.0 we have dropped setuptools and switched to scikit-build-core - -### Windows versions - -Fixed version info of shared library -Added version info to executable - ## Code changes -Inserting `pdlp_iteration_count` into various structs (for v1.7.0) breaks the C API, so it has been moved to the end of those structs - -`setBasis` has been added to `highspy` - -`writePresolvedModel` has been added - -Saved MIP solution pool is populated when presolve reduces MIP to empty - -Compilation date has been removed improve build reproducibility. Methods to print compilation dates are deprecated - -Logging and error return when user-supplied solution or basis is rejected on vector dimensions - -Memory allocation errors in presolve are caught and `Highs::run()` returns `HighsStatus::kError` with `model_status_ = HighsModelStatus::kMemoryLimit` - -QP solver logging is now neater and quieter - -Any Hessian for the incumbent model is modified with zero entries when adding columns to the model, and rows/columns are removed when columns are deleted from the model. +The accessor function Highs_getCallbackDataOutItem in the C API means +that `pdlp_iteration_count` can be moved back to where it was inserted +into the `HighsCallbackDataOut` struct in v1.7.0, which broke the C +API. This fixes #1812 -Minor bug fix in MIP presolve +Some duplicate code has been eliminated from the MIP solver, and +modifications made to eliminate compiler warnings -QP solver will now hot start given a basis and solution +Declaration of the (deprecated) method `char* highsCompilationDate()` +has been corrected +Fixed bug when describing integrality status during the human-readable solution write diff --git a/src/lp_data/HighsCallbackStruct.h b/src/lp_data/HighsCallbackStruct.h index 237eb30c74..b76716d3eb 100644 --- a/src/lp_data/HighsCallbackStruct.h +++ b/src/lp_data/HighsCallbackStruct.h @@ -29,6 +29,7 @@ typedef struct { double running_time; HighsInt simplex_iteration_count; HighsInt ipm_iteration_count; + HighsInt pdlp_iteration_count; double objective_function_value; int64_t mip_node_count; double mip_primal_bound; @@ -43,7 +44,6 @@ typedef struct { double* cutpool_value; double* cutpool_lower; double* cutpool_upper; - HighsInt pdlp_iteration_count; } HighsCallbackDataOut; typedef struct { From 966bf4257e71d5759fe4511f21b43c01a0e604b5 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 09:50:33 +0200 Subject: [PATCH 47/68] Update CMakeLists.txt fortrantest linker language --- check/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index 0367e593be..96474eef14 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -3,6 +3,7 @@ include(CTest) if (FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY ${HIGHS_BINARY_DIR}/modules) add_executable(fortrantest TestFortranAPI.f90) + set_property(TARGET fortrantest PROPERTY LINKER_LANGUAGE Fortran) if (NOT FAST_BUILD) target_link_libraries(fortrantest libhighs FortranHighs) else() @@ -321,4 +322,4 @@ if (NOT FAST_BUILD OR ALL_TESTS) endforeach(setting) endforeach() -endif() \ No newline at end of file +endif() From 3e8f80a074456dff96cca45013ff2a01b00a69ea Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 10:49:54 +0200 Subject: [PATCH 48/68] Update CMakeLists.txt --- check/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index 96474eef14..2ee995d1f5 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -3,6 +3,7 @@ include(CTest) if (FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY ${HIGHS_BINARY_DIR}/modules) add_executable(fortrantest TestFortranAPI.f90) + set(CMAKE_Fortran_LINK_EXECUTABLE " -o ") set_property(TARGET fortrantest PROPERTY LINKER_LANGUAGE Fortran) if (NOT FAST_BUILD) target_link_libraries(fortrantest libhighs FortranHighs) From 86332df6b23c3eefe0bc264c19053c0c907ed5b3 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 10:59:40 +0200 Subject: [PATCH 49/68] Back --- check/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index 2ee995d1f5..dc01a76d93 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -3,8 +3,8 @@ include(CTest) if (FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY ${HIGHS_BINARY_DIR}/modules) add_executable(fortrantest TestFortranAPI.f90) - set(CMAKE_Fortran_LINK_EXECUTABLE " -o ") - set_property(TARGET fortrantest PROPERTY LINKER_LANGUAGE Fortran) + # set(CMAKE_Fortran_LINK_EXECUTABLE " -o ") + # set_property(TARGET fortrantest PROPERTY LINKER_LANGUAGE Fortran) if (NOT FAST_BUILD) target_link_libraries(fortrantest libhighs FortranHighs) else() From 627dcca35f59705d908f4871844ae61444f699a9 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:06:59 +0200 Subject: [PATCH 50/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 074e8ac4d5..6e444e5fb5 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -21,7 +21,9 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{runner.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DFORTRAN=ON + run: | + cmake --version + cmake $GITHUB_WORKSPACE -DFORTRAN=ON - name: Build shell: bash From f6fe663af64e19738ae21bd468bf4ec64ab22448 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:11:14 +0200 Subject: [PATCH 51/68] Versions --- .github/workflows/test-fortran-macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 6e444e5fb5..75854faf3f 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -23,6 +23,7 @@ jobs: working-directory: ${{runner.workspace}}/build run: | cmake --version + gfortran --version cmake $GITHUB_WORKSPACE -DFORTRAN=ON - name: Build From 9faed4f4cdab627e231622968f181f58c2d52468 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:12:51 +0200 Subject: [PATCH 52/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 75854faf3f..263e24414f 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -23,7 +23,7 @@ jobs: working-directory: ${{runner.workspace}}/build run: | cmake --version - gfortran --version + gfortran-11 --version cmake $GITHUB_WORKSPACE -DFORTRAN=ON - name: Build From ac81b2e4813972e574dd6a192a1fb26dcecc97ca Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:15:31 +0200 Subject: [PATCH 53/68] Symlink --- .github/workflows/test-fortran-macos.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 263e24414f..80759275fb 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -17,7 +17,17 @@ jobs: - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build - + + - name: Symlink gfortran (macOS) + run: | + # make sure gfortran is available + # https://github.com/actions/virtual-environments/issues/2524 + # https://github.com/cbg-ethz/dce/blob/master/.github/workflows/pkgdown.yaml + sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran + sudo mkdir /usr/local/gfortran + sudo ln -s /usr/local/Cellar/gcc@11/*/lib/gcc/11 /usr/local/gfortran/lib + gfortran --version + - name: Configure CMake shell: bash working-directory: ${{runner.workspace}}/build From 8dc135b92eb5401bf3fe24b4106869929654e305 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:23:34 +0200 Subject: [PATCH 54/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 80759275fb..834b2ee809 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -12,8 +12,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install GFortran - run: brew install gfortran + # - name: Install GFortran + # run: brew install gfortran - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build @@ -23,6 +23,9 @@ jobs: # make sure gfortran is available # https://github.com/actions/virtual-environments/issues/2524 # https://github.com/cbg-ethz/dce/blob/master/.github/workflows/pkgdown.yaml + gfortran-11 + gcc-11 + gcc sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran sudo mkdir /usr/local/gfortran sudo ln -s /usr/local/Cellar/gcc@11/*/lib/gcc/11 /usr/local/gfortran/lib From 53efec843f9695dd46b924281e522e76512c225a Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:25:33 +0200 Subject: [PATCH 55/68] Versions --- .github/workflows/test-fortran-macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 834b2ee809..8e7c1306f6 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -23,9 +23,9 @@ jobs: # make sure gfortran is available # https://github.com/actions/virtual-environments/issues/2524 # https://github.com/cbg-ethz/dce/blob/master/.github/workflows/pkgdown.yaml - gfortran-11 - gcc-11 - gcc + gfortran-11 --version + gcc-11 --version + gcc --version sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran sudo mkdir /usr/local/gfortran sudo ln -s /usr/local/Cellar/gcc@11/*/lib/gcc/11 /usr/local/gfortran/lib From dc24884975b8901233fed024488ecee095f927f6 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:31:47 +0200 Subject: [PATCH 56/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 8e7c1306f6..4da4f74e28 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -12,8 +12,8 @@ jobs: steps: - uses: actions/checkout@v4 - # - name: Install GFortran - # run: brew install gfortran + - name: Install GFortran + run: brew install gfortran gcc - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build From fdabd3dc6eb7a64aeaf9adf04df6bf355e353679 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:33:10 +0200 Subject: [PATCH 57/68] Es --- .github/workflows/test-fortran-macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 4da4f74e28..cf4620bbd1 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -26,6 +26,7 @@ jobs: gfortran-11 --version gcc-11 --version gcc --version + ls /usr/local/Cellar/gcc@11/*/lib/gcc/11 sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran sudo mkdir /usr/local/gfortran sudo ln -s /usr/local/Cellar/gcc@11/*/lib/gcc/11 /usr/local/gfortran/lib From a32db34072bab0ea51a0021b4e980e70cff21eea Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:38:27 +0200 Subject: [PATCH 58/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index cf4620bbd1..b8b6c92969 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -24,7 +24,8 @@ jobs: # https://github.com/actions/virtual-environments/issues/2524 # https://github.com/cbg-ethz/dce/blob/master/.github/workflows/pkgdown.yaml gfortran-11 --version - gcc-11 --version + gcc-11 --version + whereis gcc-11 gcc --version ls /usr/local/Cellar/gcc@11/*/lib/gcc/11 sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran From 8afad16d116e948d100652a9fe84e43c90b0f4cf Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:51:44 +0200 Subject: [PATCH 59/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 35 ++++++++++-------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index b8b6c92969..cca56c2177 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -4,34 +4,29 @@ on: [push, pull_request] jobs: fast_build_release: - runs-on: ${{ matrix.os }} + runs-on: macos-12 strategy: - matrix: - os: [macos-latest] + toolchain: + - {compiler: gcc, version: 13} steps: - uses: actions/checkout@v4 - - name: Install GFortran - run: brew install gfortran gcc + - uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: gcc + version: 13 + + - run: | + ${{ env.FC }} ... # environment vars FC, CC, and CXX are set + ${{ steps.setup-fortran.outputs.fc }} ... # outputs work too + + # - name: Install GFortran + # run: brew install gfortran gcc - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build - - - name: Symlink gfortran (macOS) - run: | - # make sure gfortran is available - # https://github.com/actions/virtual-environments/issues/2524 - # https://github.com/cbg-ethz/dce/blob/master/.github/workflows/pkgdown.yaml - gfortran-11 --version - gcc-11 --version - whereis gcc-11 - gcc --version - ls /usr/local/Cellar/gcc@11/*/lib/gcc/11 - sudo ln -s /usr/local/bin/gfortran-11 /usr/local/bin/gfortran - sudo mkdir /usr/local/gfortran - sudo ln -s /usr/local/Cellar/gcc@11/*/lib/gcc/11 /usr/local/gfortran/lib - gfortran --version - name: Configure CMake shell: bash From a2e870456a18ede66c8a7a60c2c9f566d95d47d8 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:53:15 +0200 Subject: [PATCH 60/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index cca56c2177..9e4a97ba2b 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -5,9 +5,7 @@ on: [push, pull_request] jobs: fast_build_release: runs-on: macos-12 - strategy: - toolchain: - - {compiler: gcc, version: 13} + steps: - uses: actions/checkout@v4 From fc06a3d4105785f40ba80273ebb3af751b8493b2 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:54:25 +0200 Subject: [PATCH 61/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 9e4a97ba2b..da260cc612 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -16,10 +16,6 @@ jobs: compiler: gcc version: 13 - - run: | - ${{ env.FC }} ... # environment vars FC, CC, and CXX are set - ${{ steps.setup-fortran.outputs.fc }} ... # outputs work too - # - name: Install GFortran # run: brew install gfortran gcc From 4c69faff2901c61cab3083d904ba8e86f4696e7e Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:58:10 +0200 Subject: [PATCH 62/68] Update CMakeLists.txt --- check/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/check/CMakeLists.txt b/check/CMakeLists.txt index dc01a76d93..366a4c5924 100644 --- a/check/CMakeLists.txt +++ b/check/CMakeLists.txt @@ -3,8 +3,6 @@ include(CTest) if (FORTRAN) set(CMAKE_Fortran_MODULE_DIRECTORY ${HIGHS_BINARY_DIR}/modules) add_executable(fortrantest TestFortranAPI.f90) - # set(CMAKE_Fortran_LINK_EXECUTABLE " -o ") - # set_property(TARGET fortrantest PROPERTY LINKER_LANGUAGE Fortran) if (NOT FAST_BUILD) target_link_libraries(fortrantest libhighs FortranHighs) else() From 9471b4b2668239eb663c40e9bc207b89de8626f9 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 11:58:39 +0200 Subject: [PATCH 63/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index da260cc612..7dc74351b6 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -10,11 +10,11 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: fortran-lang/setup-fortran@v1 + - uses: fortran-lang/setup-fortran@latest id: setup-fortran with: compiler: gcc - version: 13 + version: 11 # - name: Install GFortran # run: brew install gfortran gcc From f491ae63c89b02706b7bc4d3f3d6b1078d4e3083 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 12:34:47 +0200 Subject: [PATCH 64/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 7dc74351b6..7fb3f872ed 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: fortran-lang/setup-fortran@latest + - uses: fortran-lang/setup-fortran@1.6 id: setup-fortran with: compiler: gcc From cfbb54aec78fe6eadcbcf88e33dacfb5dbc320c8 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 12:35:59 +0200 Subject: [PATCH 65/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 7fb3f872ed..001cce2c60 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: fortran-lang/setup-fortran@1.6 + - uses: fortran-lang/setup-fortran@1 id: setup-fortran with: compiler: gcc From 7ca826e0a9253307a685e2449ceffb4f8ed9fd02 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 12:36:36 +0200 Subject: [PATCH 66/68] Update test-fortran-macos.yml --- .github/workflows/test-fortran-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-fortran-macos.yml b/.github/workflows/test-fortran-macos.yml index 001cce2c60..e90da71869 100644 --- a/.github/workflows/test-fortran-macos.yml +++ b/.github/workflows/test-fortran-macos.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: fortran-lang/setup-fortran@1 + - uses: fortran-lang/setup-fortran@v1.6 id: setup-fortran with: compiler: gcc From 9254a89d143bf5722bb91cd31a3e747699c47caf Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 13:09:11 +0200 Subject: [PATCH 67/68] Update FEATURES.md --- FEATURES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FEATURES.md b/FEATURES.md index 98dc828433..dd87925aef 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -1,5 +1,9 @@ ## Build changes +The python wrapper highspy is now available for aarch64 on manylinux + +This allows highs to be run through Python on AWS arm64 + ## Code changes The accessor function Highs_getCallbackDataOutItem in the C API means From 449e33c2587871e5660cdd6df1c32dad543bd1d0 Mon Sep 17 00:00:00 2001 From: galabovaa Date: Mon, 1 Jul 2024 13:18:29 +0200 Subject: [PATCH 68/68] Update FEATURES.md --- FEATURES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FEATURES.md b/FEATURES.md index dd87925aef..c587caf6ee 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -1,9 +1,10 @@ ## Build changes The python wrapper highspy is now available for aarch64 on manylinux - This allows highs to be run through Python on AWS arm64 +Bug fix for fortran on macOS + ## Code changes The accessor function Highs_getCallbackDataOutItem in the C API means