Skip to content

Commit

Permalink
Merge pull request #1909 from ERGO-Code/fix-1908
Browse files Browse the repository at this point in the history
Fix 1908
  • Loading branch information
jajhall committed Sep 9, 2024
2 parents f7be435 + cd80bd5 commit 0f31d20
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 73 deletions.
8 changes: 4 additions & 4 deletions src/io/FilereaderLp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,16 +216,16 @@ 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<char, LP_MAX_LINE_LENGTH + 1> 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) {
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;
}
}
Expand Down
32 changes: 19 additions & 13 deletions src/io/HMPSIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<char, lmax> line;
std::array<char, 2> flag = {0, 0};
std::array<double, 3> 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) {
Expand All @@ -105,15 +105,16 @@ 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();
col_names.clear();
vector<char> rowType;
map<double, int> 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
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -218,7 +220,8 @@ FilereaderRetcode readMps(
num_alien_entries = 0;
vector<double> 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) {
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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];
Expand Down
59 changes: 28 additions & 31 deletions src/io/HighsIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,31 @@ 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)) {
// Output was truncated: for now just ensure string is null-terminated
msgbuffer[sizeof(msgbuffer) - 1] = '\0';
size_t len = 0;
std::array<char, kIoBufferSize> 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<size_t>(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<size_t>(l);
}
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);
}
}
Expand Down Expand Up @@ -199,21 +203,18 @@ 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)) {
// Output was truncated: for now just ensure string is null-terminated
msgbuffer[sizeof(msgbuffer) - 1] = '\0';
}
std::array<char, kIoBufferSize> msgbuffer = {};
int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr);
// assert that there are no encoding errors
assert(len >= 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);
}
}
Expand Down Expand Up @@ -261,16 +262,12 @@ 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);

if (len >= (int)sizeof(msgbuffer)) {
// Output was truncated: for now just ensure string is null-terminated
msgbuffer[sizeof(msgbuffer) - 1] = '\0';
}
std::array<char, kIoBufferSize> msgbuffer = {};
int len = vsnprintf(msgbuffer.data(), msgbuffer.size(), format, argptr);
// assert that there are no encoding errors
assert(len >= 0);
va_end(argptr);
return std::string(msgbuffer);
return std::string(msgbuffer.data());
}

const std::string highsBoolToString(const bool b, const HighsInt field_width) {
Expand Down
2 changes: 1 addition & 1 deletion src/io/HighsIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <iostream>

#include "lp_data/HighsCallback.h"
//#include "util/HighsInt.h"
// #include "util/HighsInt.h"

class HighsOptions;

Expand Down
6 changes: 3 additions & 3 deletions src/mip/HighsDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void HighsDomain::ConflictPoolPropagation::conflictAdded(HighsInt conflict) {
}
switch (numWatched) {
case 0: {
std::pair<HighsInt, HighsInt> latestActive[2];
std::array<std::pair<HighsInt, HighsInt>, 2> latestActive;
HighsInt numActive = 0;
for (HighsInt i = start; i != end; ++i) {
HighsInt pos = conflictEntries[i].boundtype == HighsBoundType::kLower
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -306,7 +306,7 @@ void HighsDomain::ConflictPoolPropagation::propagateConflict(

WatchedLiteral* watched = watchedLiterals_.data() + 2 * conflict;

HighsInt inactive[2];
std::array<HighsInt, 2> inactive;
HighsInt numInactive = 0;
for (HighsInt i = start; i != end; ++i) {
if (domain->isActive(entries[i])) continue;
Expand Down
6 changes: 3 additions & 3 deletions src/mip/HighsGFkSolve.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool, kNumRhs> hasSolution;
HighsInt numRhsWithSolution = 0;
for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) {
hasSolution[rhsIndex] = true;
Expand All @@ -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<SolutionEntry> solution[kNumRhs];
std::array<std::vector<SolutionEntry>, kNumRhs> solution;
for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex)
if (hasSolution[rhsIndex]) solution[rhsIndex].reserve(numCol);

Expand Down Expand Up @@ -384,7 +384,7 @@ class HighsGFkSolve {
for (HighsInt i = numFactorRows - 1; i >= 0; --i) {
HighsInt row = factorRowPerm[i];

unsigned int solval[kNumRhs];
std::array<unsigned int, kNumRhs> solval;

for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) {
if (!hasSolution[rhsIndex]) continue;
Expand Down
18 changes: 10 additions & 8 deletions src/mip/HighsImplications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ bool HighsImplications::computeImplications(HighsInt col, bool val) {

pdqsort(implics.begin(), binstart);

HighsCliqueTable::CliqueVar clique[2];
std::array<HighsCliqueTable::CliqueVar, 2> clique;
clique[0] = HighsCliqueTable::CliqueVar(col, val);

for (auto i = binstart; i != implics.end(); ++i) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -519,8 +519,8 @@ void HighsImplications::separateImpliedBounds(
HighsCutPool& cutpool, double feastol) {
HighsDomain& globaldomain = mipsolver.mipdata_->domain;

HighsInt inds[2];
double vals[2];
std::array<HighsInt, 2> inds;
std::array<double, 2> vals;
double rhs;

HighsInt numboundchgs = 0;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/mip/HighsPathSeparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void HighsPathSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation,
HighsInt currentPath[maxPathLen];
std::vector<std::pair<std::vector<HighsInt>, std::vector<double>>>
aggregatedPath;
double scales[2];
std::array<double, 2> scales;
for (HighsInt i = 0; i != lp.num_row_; ++i) {
switch (rowtype[i]) {
case RowType::kUnusuable:
Expand Down
2 changes: 1 addition & 1 deletion src/parallel/HighsSplitDeque.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool> splitRequest;
Expand Down
Loading

0 comments on commit 0f31d20

Please sign in to comment.