From fb8998673c4958bd05f3ef6cda4221098f9d56dd Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 28 Aug 2024 16:19:42 +0200 Subject: [PATCH 01/12] use std::array instead of C arrays if possible --- src/io/HMPSIO.cpp | 32 +++++++++++++++++++------------- src/io/HighsIO.cpp | 32 ++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/io/HMPSIO.cpp b/src/io/HMPSIO.cpp index b6037d3624..014f5716b1 100644 --- a/src/io/HMPSIO.cpp +++ b/src/io/HMPSIO.cpp @@ -78,21 +78,21 @@ FilereaderRetcode readMps( highsLogDev(log_options, HighsLogType::kInfo, "readMPS: Opened file OK\n"); // Input buffer const HighsInt lmax = 128; - char line[lmax]; - char flag[2] = {0, 0}; - double data[3]; + std::array line; + std::array flag = {0, 0}; + std::array data; HighsInt num_alien_entries = 0; HighsVarType integerCol = HighsVarType::kContinuous; // Load NAME - load_mpsLine(file, integerCol, lmax, line, flag, data); + load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), data.data()); highsLogDev(log_options, HighsLogType::kInfo, "readMPS: Read NAME OK\n"); // Load OBJSENSE or ROWS - load_mpsLine(file, integerCol, lmax, line, flag, data); + load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), data.data()); if (flag[0] == 'O') { // Found OBJSENSE - load_mpsLine(file, integerCol, lmax, line, flag, data); + load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), data.data()); std::string sense(&line[2], &line[2] + 3); // the sense must be "MAX" or "MIN" if (sense.compare("MAX") == 0) { @@ -105,7 +105,7 @@ FilereaderRetcode readMps( highsLogDev(log_options, HighsLogType::kInfo, "readMPS: Read OBJSENSE OK\n"); // Load ROWS - load_mpsLine(file, integerCol, lmax, line, flag, data); + load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), data.data()); } row_names.clear(); @@ -113,7 +113,8 @@ FilereaderRetcode readMps( vector rowType; map rowIndex; double objName = 0; - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { if (flag[0] == 'N' && (objName == 0 || keep_n_rows == kKeepNRowsDeleteRows)) { // N-row: take the first as the objective and possibly ignore any others @@ -149,7 +150,8 @@ FilereaderRetcode readMps( // line - field 5 non-empty. save_flag1 is used to deduce whether // the row name and value are from fields 5 and 6, or 3 and 4 HighsInt save_flag1 = 0; - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { HighsInt iRow = rowIndex[data[2]] - 1; std::string name = ""; if (iRow >= 0) name = row_names[iRow]; @@ -218,7 +220,8 @@ FilereaderRetcode readMps( num_alien_entries = 0; vector RHS(numRow, 0); save_flag1 = 0; - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { if (data[2] != objName) { HighsInt iRow = rowIndex[data[2]] - 1; if (iRow >= 0) { @@ -268,7 +271,8 @@ FilereaderRetcode readMps( rowUpper.resize(numRow); if (flag[0] == 'R') { save_flag1 = 0; - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { HighsInt iRow = rowIndex[data[2]] - 1; if (iRow >= 0) { if (rowType[iRow] == 'L' || (rowType[iRow] == 'E' && data[0] < 0)) { @@ -338,7 +342,8 @@ FilereaderRetcode readMps( colLower.assign(numCol, 0); colUpper.assign(numCol, kHighsInf); if (flag[0] == 'B') { - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { // Find the column index associated with the name "data[2]". If // the name is in colIndex then the value stored is the true // column index plus one. Otherwise 0 will be returned. @@ -389,7 +394,8 @@ FilereaderRetcode readMps( HighsInt previous_col = -1; bool has_diagonal = false; Qstart.clear(); - while (load_mpsLine(file, integerCol, lmax, line, flag, data)) { + while (load_mpsLine(file, integerCol, lmax, line.data(), flag.data(), + data.data())) { HighsInt iCol0 = colIndex[data[1]] - 1; std::string name0 = ""; if (iCol0 >= 0) name0 = col_names[iCol0]; diff --git a/src/io/HighsIO.cpp b/src/io/HighsIO.cpp index b32b5758a5..22763a09aa 100644 --- a/src/io/HighsIO.cpp +++ b/src/io/HighsIO.cpp @@ -131,27 +131,35 @@ void highsLogUser(const HighsLogOptions& log_options_, const HighsLogType type, if (flush_streams) fflush(stdout); } } else { - int len = 0; - char msgbuffer[kIoBufferSize] = {}; - if (prefix) - len = snprintf(msgbuffer, sizeof(msgbuffer), "%-9s", - HighsLogTypeTag[(int)type]); - if (len < (int)sizeof(msgbuffer)) - len += - vsnprintf(msgbuffer + len, sizeof(msgbuffer) - len, format, argptr); - if (len >= (int)sizeof(msgbuffer)) { + size_t len = 0; + std::array msgbuffer = {}; + if (prefix) { + int l = snprintf(msgbuffer.data(), msgbuffer.size(), "%-9s", + HighsLogTypeTag[(int)type]); + // assert that there are no encoding errors + assert(l >= 0); + len += static_cast(l); + } + if (len < msgbuffer.size()) { + int l = vsnprintf(msgbuffer.data() + len, msgbuffer.size() - len, format, + argptr); + // assert that there are no encoding errors + assert(l >= 0); + len += static_cast(l); + } + if (len >= msgbuffer.size()) { // Output was truncated: for now just ensure string is null-terminated - msgbuffer[sizeof(msgbuffer) - 1] = '\0'; + msgbuffer[msgbuffer.size() - 1] = '\0'; } if (log_options_.user_log_callback) { - log_options_.user_log_callback(type, msgbuffer, + log_options_.user_log_callback(type, msgbuffer.data(), log_options_.user_log_callback_data); } if (log_options_.user_callback_active) { assert(log_options_.user_callback); HighsCallbackDataOut data_out; data_out.log_type = int(type); - log_options_.user_callback(kCallbackLogging, msgbuffer, &data_out, + log_options_.user_callback(kCallbackLogging, msgbuffer.data(), &data_out, nullptr, log_options_.user_callback_data); } } From b1862c8900c697d575a46b7e9d3b531737fd7130 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 28 Aug 2024 16:34:43 +0200 Subject: [PATCH 02/12] Chaser --- src/io/HighsIO.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/io/HighsIO.cpp b/src/io/HighsIO.cpp index 22763a09aa..936b2db5c0 100644 --- a/src/io/HighsIO.cpp +++ b/src/io/HighsIO.cpp @@ -207,21 +207,22 @@ void highsLogDev(const HighsLogOptions& log_options_, const HighsLogType type, if (flush_streams) fflush(stdout); } } else { - int len; - char msgbuffer[kIoBufferSize] = {}; - len = vsnprintf(msgbuffer, sizeof(msgbuffer), format, argptr); - if (len >= (int)sizeof(msgbuffer)) { + std::array msgbuffer = {}; + int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr); + // assert that there are no encoding errors + assert(len >= 0); + if (static_cast(len) >= msgbuffer.size()) { // Output was truncated: for now just ensure string is null-terminated - msgbuffer[sizeof(msgbuffer) - 1] = '\0'; + msgbuffer[msgbuffer.size() - 1] = '\0'; } if (log_options_.user_log_callback) { - log_options_.user_log_callback(type, msgbuffer, + log_options_.user_log_callback(type, msgbuffer.data(), log_options_.user_log_callback_data); } else if (log_options_.user_callback_active) { assert(log_options_.user_callback); HighsCallbackDataOut data_out; data_out.log_type = int(type); - log_options_.user_callback(kCallbackLogging, msgbuffer, &data_out, + log_options_.user_callback(kCallbackLogging, msgbuffer.data(), &data_out, nullptr, log_options_.user_callback_data); } } @@ -269,16 +270,17 @@ void highsReportLogOptions(const HighsLogOptions& log_options_) { std::string highsFormatToString(const char* format, ...) { va_list argptr; va_start(argptr, format); - int len; - char msgbuffer[kIoBufferSize] = {}; - len = vsnprintf(msgbuffer, sizeof(msgbuffer), format, argptr); + std::array msgbuffer = {}; + int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr); + // assert that there are no encoding errors + assert(len >= 0); - if (len >= (int)sizeof(msgbuffer)) { + if (static_cast(len) >= msgbuffer.size()) { // Output was truncated: for now just ensure string is null-terminated - msgbuffer[sizeof(msgbuffer) - 1] = '\0'; + msgbuffer[msgbuffer.size() - 1] = '\0'; } va_end(argptr); - return std::string(msgbuffer); + return std::string(msgbuffer.data()); } const std::string highsBoolToString(const bool b, const HighsInt field_width) { From 2788fea3603d57947a62a15e4865ab9f3bb7f1b9 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 28 Aug 2024 20:00:56 +0200 Subject: [PATCH 03/12] Use std::array in other places --- src/mip/HighsDomain.cpp | 4 ++-- src/mip/HighsGFkSolve.h | 6 +++--- src/mip/HighsImplications.cpp | 18 ++++++++++-------- src/mip/HighsPathSeparator.cpp | 2 +- src/util/HighsHashTree.h | 4 ++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index eb38717812..e20ff5a19a 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -180,7 +180,7 @@ void HighsDomain::ConflictPoolPropagation::conflictAdded(HighsInt conflict) { } switch (numWatched) { case 0: { - std::pair latestActive[2]; + std::array, 2> latestActive; HighsInt numActive = 0; for (HighsInt i = start; i != end; ++i) { HighsInt pos = conflictEntries[i].boundtype == HighsBoundType::kLower @@ -306,7 +306,7 @@ void HighsDomain::ConflictPoolPropagation::propagateConflict( WatchedLiteral* watched = watchedLiterals_.data() + 2 * conflict; - HighsInt inactive[2]; + std::array inactive; HighsInt numInactive = 0; for (HighsInt i = start; i != end; ++i) { if (domain->isActive(entries[i])) continue; diff --git a/src/mip/HighsGFkSolve.h b/src/mip/HighsGFkSolve.h index 75519459de..d483d3bfda 100644 --- a/src/mip/HighsGFkSolve.h +++ b/src/mip/HighsGFkSolve.h @@ -317,7 +317,7 @@ class HighsGFkSolve { // check if a solution exists by scanning the linearly dependent rows for // nonzero right hand sides - bool hasSolution[kNumRhs]; + std::array hasSolution; HighsInt numRhsWithSolution = 0; for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) { hasSolution[rhsIndex] = true; @@ -341,7 +341,7 @@ class HighsGFkSolve { // now iterate a subset of the basic solutions. // When a column leaves the basis we do not allow it to enter again so that // we iterate at most one solution for each nonbasic column - std::vector solution[kNumRhs]; + std::array, kNumRhs> solution; for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) if (hasSolution[rhsIndex]) solution[rhsIndex].reserve(numCol); @@ -384,7 +384,7 @@ class HighsGFkSolve { for (HighsInt i = numFactorRows - 1; i >= 0; --i) { HighsInt row = factorRowPerm[i]; - unsigned int solval[kNumRhs]; + std::array solval; for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) { if (!hasSolution[rhsIndex]) continue; diff --git a/src/mip/HighsImplications.cpp b/src/mip/HighsImplications.cpp index 2c909d9f0d..e625669c22 100644 --- a/src/mip/HighsImplications.cpp +++ b/src/mip/HighsImplications.cpp @@ -79,7 +79,7 @@ bool HighsImplications::computeImplications(HighsInt col, bool val) { pdqsort(implics.begin(), binstart); - HighsCliqueTable::CliqueVar clique[2]; + std::array clique; clique[0] = HighsCliqueTable::CliqueVar(col, val); for (auto i = binstart; i != implics.end(); ++i) { @@ -88,7 +88,7 @@ bool HighsImplications::computeImplications(HighsInt col, bool val) { else clique[1] = HighsCliqueTable::CliqueVar(i->column, 1); - cliquetable.addClique(mipsolver, clique, 2); + cliquetable.addClique(mipsolver, clique.data(), 2); if (globaldomain.infeasible() || globaldomain.isFixed(col)) return true; } @@ -519,8 +519,8 @@ void HighsImplications::separateImpliedBounds( HighsCutPool& cutpool, double feastol) { HighsDomain& globaldomain = mipsolver.mipdata_->domain; - HighsInt inds[2]; - double vals[2]; + std::array inds; + std::array vals; double rhs; HighsInt numboundchgs = 0; @@ -586,7 +586,8 @@ void HighsImplications::separateImpliedBounds( if (infeas) { vals[0] = 1.0; inds[0] = col; - cutpool.addCut(mipsolver, inds, vals, 1, 0.0, false, true, false); + cutpool.addCut(mipsolver, inds.data(), vals.data(), 1, 0.0, false, true, + false); continue; } @@ -621,7 +622,7 @@ void HighsImplications::separateImpliedBounds( if (viol > feastol) { // printf("added implied bound cut to pool\n"); - cutpool.addCut(mipsolver, inds, vals, 2, rhs, + cutpool.addCut(mipsolver, inds.data(), vals.data(), 2, rhs, mipsolver.variableType(implics[i].column) != HighsVarType::kContinuous, false, false, false); @@ -637,7 +638,8 @@ void HighsImplications::separateImpliedBounds( if (infeas) { vals[0] = -1.0; inds[0] = col; - cutpool.addCut(mipsolver, inds, vals, 1, -1.0, false, true, false); + cutpool.addCut(mipsolver, inds.data(), vals.data(), 1, -1.0, false, + true, false); continue; } @@ -671,7 +673,7 @@ void HighsImplications::separateImpliedBounds( if (viol > feastol) { // printf("added implied bound cut to pool\n"); - cutpool.addCut(mipsolver, inds, vals, 2, rhs, + cutpool.addCut(mipsolver, inds.data(), vals.data(), 2, rhs, mipsolver.variableType(implics[i].column) != HighsVarType::kContinuous, false, false, false); diff --git a/src/mip/HighsPathSeparator.cpp b/src/mip/HighsPathSeparator.cpp index 83ab962a3d..0989bd098c 100644 --- a/src/mip/HighsPathSeparator.cpp +++ b/src/mip/HighsPathSeparator.cpp @@ -174,7 +174,7 @@ void HighsPathSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation, HighsInt currentPath[maxPathLen]; std::vector, std::vector>> aggregatedPath; - double scales[2]; + std::array scales; for (HighsInt i = 0; i != lp.num_row_; ++i) { switch (rowtype[i]) { case RowType::kUnusuable: diff --git a/src/util/HighsHashTree.h b/src/util/HighsHashTree.h index c42bc271e9..b33e470e43 100644 --- a/src/util/HighsHashTree.h +++ b/src/util/HighsHashTree.h @@ -113,8 +113,8 @@ class HighsHashTree { // to do a linear scan and key comparisons at all Occupation occupation; int size; - uint64_t hashes[capacity() + 1]; - Entry entries[capacity()]; + std::array hashes; + std::array entries; InnerLeaf() : occupation(0), size(0) { hashes[0] = 0; } From 455c007defe951b6b0d39aa122ffc4e552c94993 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Thu, 29 Aug 2024 10:37:22 +0200 Subject: [PATCH 04/12] Use std::next a little bit --- src/util/HighsHashTree.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/util/HighsHashTree.h b/src/util/HighsHashTree.h index b33e470e43..46557b8119 100644 --- a/src/util/HighsHashTree.h +++ b/src/util/HighsHashTree.h @@ -123,7 +123,8 @@ class HighsHashTree { assert(other.size <= capacity()); memcpy((void*)this, (void*)&other, (char*)&other.hashes[other.size + 1] - (char*)&other); - std::move(&other.entries[0], &other.entries[size], &entries[0]); + std::move(other.entries.begin(), std::next(other.entries.begin(), size), + entries.begin()); } int get_num_entries() const { return size; } @@ -190,7 +191,9 @@ class HighsHashTree { --size; if (pos < size) { - std::move(&entries[pos + 1], &entries[size + 1], &entries[pos]); + std::move(std::next(entries.begin(), pos + 1), + std::next(entries.begin(), size + 1), + std::next(entries.begin(), pos)); memmove(&hashes[pos], &hashes[pos + 1], sizeof(hashes[0]) * (size - pos)); if (get_first_chunk16(hashes[startPos]) != hashChunk) @@ -254,7 +257,9 @@ class HighsHashTree { void move_backward(const int& first, const int& last) { // move elements backwards - std::move_backward(&entries[first], &entries[last], &entries[last + 1]); + std::move_backward(std::next(entries.begin(), first), + std::next(entries.begin(), last), + std::next(entries.begin(), last + 1)); memmove(&hashes[first + 1], &hashes[first], sizeof(hashes[0]) * (last - first)); } From d69e295d35aa595c53bce4dd4814cae541ecfb39 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Fri, 30 Aug 2024 16:44:32 +0200 Subject: [PATCH 05/12] Make hashes an std::array --- src/util/HighsHashTree.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/util/HighsHashTree.h b/src/util/HighsHashTree.h index c42bc271e9..026f26195b 100644 --- a/src/util/HighsHashTree.h +++ b/src/util/HighsHashTree.h @@ -113,7 +113,7 @@ class HighsHashTree { // to do a linear scan and key comparisons at all Occupation occupation; int size; - uint64_t hashes[capacity() + 1]; + std::array hashes; Entry entries[capacity()]; InnerLeaf() : occupation(0), size(0) { hashes[0] = 0; } @@ -121,8 +121,10 @@ class HighsHashTree { template InnerLeaf(InnerLeaf&& other) { assert(other.size <= capacity()); - memcpy((void*)this, (void*)&other, - (char*)&other.hashes[other.size + 1] - (char*)&other); + occupation = other.occupation; + size = other.size; + std::copy(other.hashes.cbegin(), + std::next(other.hashes.cbegin(), size + 1), hashes.begin()); std::move(&other.entries[0], &other.entries[size], &entries[0]); } From 584069fb19f2f08050d038d49fea13b2a8274084 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 2 Sep 2024 08:45:45 +0200 Subject: [PATCH 06/12] Make entries an std::array --- src/util/HighsHashTree.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/util/HighsHashTree.h b/src/util/HighsHashTree.h index 026f26195b..c06bb96758 100644 --- a/src/util/HighsHashTree.h +++ b/src/util/HighsHashTree.h @@ -114,7 +114,7 @@ class HighsHashTree { Occupation occupation; int size; std::array hashes; - Entry entries[capacity()]; + std::array entries; InnerLeaf() : occupation(0), size(0) { hashes[0] = 0; } @@ -125,7 +125,8 @@ class HighsHashTree { size = other.size; std::copy(other.hashes.cbegin(), std::next(other.hashes.cbegin(), size + 1), hashes.begin()); - std::move(&other.entries[0], &other.entries[size], &entries[0]); + std::move(other.entries.begin(), std::next(other.entries.begin(), size), + entries.begin()); } int get_num_entries() const { return size; } @@ -192,7 +193,9 @@ class HighsHashTree { --size; if (pos < size) { - std::move(&entries[pos + 1], &entries[size + 1], &entries[pos]); + std::move(std::next(entries.begin(), pos + 1), + std::next(entries.begin(), size + 1), + std::next(entries.begin(), pos)); memmove(&hashes[pos], &hashes[pos + 1], sizeof(hashes[0]) * (size - pos)); if (get_first_chunk16(hashes[startPos]) != hashChunk) @@ -256,7 +259,9 @@ class HighsHashTree { void move_backward(const int& first, const int& last) { // move elements backwards - std::move_backward(&entries[first], &entries[last], &entries[last + 1]); + std::move_backward(std::next(entries.begin(), first), + std::next(entries.begin(), last), + std::next(entries.begin(), last + 1)); memmove(&hashes[first + 1], &hashes[first], sizeof(hashes[0]) * (last - first)); } From 6e32cb553e70a7bb05083585eef50602aff164c5 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Mon, 2 Sep 2024 10:09:34 +0200 Subject: [PATCH 07/12] Fix warning along the way --- src/mip/HighsDomain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mip/HighsDomain.cpp b/src/mip/HighsDomain.cpp index e20ff5a19a..3fb1950e79 100644 --- a/src/mip/HighsDomain.cpp +++ b/src/mip/HighsDomain.cpp @@ -276,7 +276,7 @@ void HighsDomain::ConflictPoolPropagation::updateActivityUbChange( HighsInt conflict = i >> 1; const HighsDomainChange& domchg = watchedLiterals_[i].domchg; - HighsInt numInactiveDelta = + uint8_t numInactiveDelta = (domchg.boundval < newbound) - (domchg.boundval < oldbound); if (numInactiveDelta != 0) { conflictFlag_[conflict] += numInactiveDelta; From ff778c65a780bfd67994aeb2c9764cef75a838d8 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 3 Sep 2024 11:39:00 +0200 Subject: [PATCH 08/12] Two minor changes --- src/io/FilereaderLp.cpp | 11 ++++++----- src/util/HighsHashTree.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/io/FilereaderLp.cpp b/src/io/FilereaderLp.cpp index 5de2163359..3e6ab1cad5 100644 --- a/src/io/FilereaderLp.cpp +++ b/src/io/FilereaderLp.cpp @@ -216,16 +216,17 @@ FilereaderRetcode FilereaderLp::readModelFromFile(const HighsOptions& options, void FilereaderLp::writeToFile(FILE* file, const char* format, ...) { va_list argptr; va_start(argptr, format); - char stringbuffer[LP_MAX_LINE_LENGTH + 1] = {}; + std::array stringbuffer = {}; HighsInt tokenlength = - vsnprintf(stringbuffer, sizeof stringbuffer, format, argptr); + vsnprintf(stringbuffer.data(), stringbuffer.size(), format, argptr); va_end(argptr); - if (this->linelength + tokenlength >= LP_MAX_LINE_LENGTH) { + if (static_cast(this->linelength + tokenlength) + 1 >= + stringbuffer.size()) { fprintf(file, "\n"); - fprintf(file, "%s", stringbuffer); + fprintf(file, "%s", stringbuffer.data()); this->linelength = tokenlength; } else { - fprintf(file, "%s", stringbuffer); + fprintf(file, "%s", stringbuffer.data()); this->linelength += tokenlength; } } diff --git a/src/util/HighsHashTree.h b/src/util/HighsHashTree.h index c06bb96758..abd9012bde 100644 --- a/src/util/HighsHashTree.h +++ b/src/util/HighsHashTree.h @@ -843,7 +843,7 @@ class HighsHashTree { hash, hashPos + 1, entry); } else { // there are many collisions, determine the exact sizes first - uint8_t sizes[InnerLeaf<4>::capacity() + 1] = {}; + std::array::capacity() + 1> sizes = {}; sizes[occupation.num_set_until(hashChunk) - 1] += 1; for (int i = 0; i < leaf->size; ++i) { int pos = From d772edf6dd42ed84832b38c868155620b1df6701 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 3 Sep 2024 12:43:53 +0200 Subject: [PATCH 09/12] No need to check for null termination --- src/io/FilereaderLp.cpp | 3 +-- src/io/HighsIO.cpp | 15 +-------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/io/FilereaderLp.cpp b/src/io/FilereaderLp.cpp index 3e6ab1cad5..8a9e0ba988 100644 --- a/src/io/FilereaderLp.cpp +++ b/src/io/FilereaderLp.cpp @@ -220,8 +220,7 @@ void FilereaderLp::writeToFile(FILE* file, const char* format, ...) { HighsInt tokenlength = vsnprintf(stringbuffer.data(), stringbuffer.size(), format, argptr); va_end(argptr); - if (static_cast(this->linelength + tokenlength) + 1 >= - stringbuffer.size()) { + if (this->linelength + tokenlength >= LP_MAX_LINE_LENGTH) { fprintf(file, "\n"); fprintf(file, "%s", stringbuffer.data()); this->linelength = tokenlength; diff --git a/src/io/HighsIO.cpp b/src/io/HighsIO.cpp index 936b2db5c0..c1e8ad4195 100644 --- a/src/io/HighsIO.cpp +++ b/src/io/HighsIO.cpp @@ -138,7 +138,7 @@ void highsLogUser(const HighsLogOptions& log_options_, const HighsLogType type, HighsLogTypeTag[(int)type]); // assert that there are no encoding errors assert(l >= 0); - len += static_cast(l); + len = static_cast(l); } if (len < msgbuffer.size()) { int l = vsnprintf(msgbuffer.data() + len, msgbuffer.size() - len, format, @@ -147,10 +147,6 @@ void highsLogUser(const HighsLogOptions& log_options_, const HighsLogType type, assert(l >= 0); len += static_cast(l); } - if (len >= msgbuffer.size()) { - // Output was truncated: for now just ensure string is null-terminated - msgbuffer[msgbuffer.size() - 1] = '\0'; - } if (log_options_.user_log_callback) { log_options_.user_log_callback(type, msgbuffer.data(), log_options_.user_log_callback_data); @@ -211,10 +207,6 @@ void highsLogDev(const HighsLogOptions& log_options_, const HighsLogType type, int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr); // assert that there are no encoding errors assert(len >= 0); - if (static_cast(len) >= msgbuffer.size()) { - // Output was truncated: for now just ensure string is null-terminated - msgbuffer[msgbuffer.size() - 1] = '\0'; - } if (log_options_.user_log_callback) { log_options_.user_log_callback(type, msgbuffer.data(), log_options_.user_log_callback_data); @@ -274,11 +266,6 @@ std::string highsFormatToString(const char* format, ...) { int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr); // assert that there are no encoding errors assert(len >= 0); - - if (static_cast(len) >= msgbuffer.size()) { - // Output was truncated: for now just ensure string is null-terminated - msgbuffer[msgbuffer.size() - 1] = '\0'; - } va_end(argptr); return std::string(msgbuffer.data()); } From cc3e870a05892bc7205f36a18cd31a5950e9d315 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 3 Sep 2024 15:15:11 +0200 Subject: [PATCH 10/12] Fix typo --- src/parallel/HighsSplitDeque.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parallel/HighsSplitDeque.h b/src/parallel/HighsSplitDeque.h index c4981f14ae..cdf3831953 100644 --- a/src/parallel/HighsSplitDeque.h +++ b/src/parallel/HighsSplitDeque.h @@ -176,7 +176,7 @@ class HighsSplitDeque { static_assert(sizeof(StealerData) <= 64, "sizeof(StealerData) exceeds cache line size"); static_assert(sizeof(WorkerBunkData) <= 64, - "sizeof(GlobalQueueData) exceeds cache line size"); + "sizeof(WorkerBunkData) exceeds cache line size"); alignas(64) OwnerData ownerData; alignas(64) std::atomic splitRequest; From b8a716f0e3f84fbdd8b9a7268aaed8c4a3fbfce0 Mon Sep 17 00:00:00 2001 From: jajhall Date: Wed, 4 Sep 2024 13:30:52 +0100 Subject: [PATCH 11/12] Formatted --- src/io/HighsIO.h | 2 +- src/lp_data/HighsSolve.cpp | 2 +- src/test/DevKkt.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/io/HighsIO.h b/src/io/HighsIO.h index b63d47141f..52bf156ff6 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/lp_data/HighsSolve.cpp b/src/lp_data/HighsSolve.cpp index d839bfb88d..b1a33476fb 100644 --- a/src/lp_data/HighsSolve.cpp +++ b/src/lp_data/HighsSolve.cpp @@ -127,7 +127,7 @@ HighsStatus solveLp(HighsLpSolverObject& solver_object, const string message) { return HighsStatus::kError; } } // options.run_crossover == kHighsOnString - } // unwelcome_ipx_status + } // unwelcome_ipx_status } else { // PDLP has been used, so check whether claim of optimality // satisfies the HiGHS criteria diff --git a/src/test/DevKkt.cpp b/src/test/DevKkt.cpp index de393f7bf1..47941d9fd6 100644 --- a/src/test/DevKkt.cpp +++ b/src/test/DevKkt.cpp @@ -261,8 +261,8 @@ void checkComplementarySlackness(const State& state, if (fabs(state.colDual[i]) > tol && fabs(state.colValue[i] - state.colUpper[i]) > tol) { if (dev_print) - std::cout << "Comp. slackness fail: " - << "l[" << i << "]=" << state.colLower[i] << ", x[" << i + std::cout << "Comp. slackness fail: " << "l[" << i + << "]=" << state.colLower[i] << ", x[" << i << "]=" << state.colValue[i] << ", z[" << i << "]=" << state.colDual[i] << std::endl; infeas = fabs(state.colDual[i]); From cd80bd5dc7495b1d51ef0e7338701465011f7d0a Mon Sep 17 00:00:00 2001 From: JAJHall Date: Mon, 9 Sep 2024 17:19:58 +0100 Subject: [PATCH 12/12] Formatted with Ubuntu clang-format version 14.0.0-1ubuntu1.1 --- src/lp_data/HighsSolve.cpp | 2 +- src/test/DevKkt.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lp_data/HighsSolve.cpp b/src/lp_data/HighsSolve.cpp index b1a33476fb..d839bfb88d 100644 --- a/src/lp_data/HighsSolve.cpp +++ b/src/lp_data/HighsSolve.cpp @@ -127,7 +127,7 @@ HighsStatus solveLp(HighsLpSolverObject& solver_object, const string message) { return HighsStatus::kError; } } // options.run_crossover == kHighsOnString - } // unwelcome_ipx_status + } // unwelcome_ipx_status } else { // PDLP has been used, so check whether claim of optimality // satisfies the HiGHS criteria diff --git a/src/test/DevKkt.cpp b/src/test/DevKkt.cpp index 47941d9fd6..de393f7bf1 100644 --- a/src/test/DevKkt.cpp +++ b/src/test/DevKkt.cpp @@ -261,8 +261,8 @@ void checkComplementarySlackness(const State& state, if (fabs(state.colDual[i]) > tol && fabs(state.colValue[i] - state.colUpper[i]) > tol) { if (dev_print) - std::cout << "Comp. slackness fail: " << "l[" << i - << "]=" << state.colLower[i] << ", x[" << i + std::cout << "Comp. slackness fail: " + << "l[" << i << "]=" << state.colLower[i] << ", x[" << i << "]=" << state.colValue[i] << ", z[" << i << "]=" << state.colDual[i] << std::endl; infeas = fabs(state.colDual[i]);