Skip to content

Commit 8a8f97b

Browse files
committed
Remove redundant copy operations in FactorHiGHSSolver
Add Zed editor caches to .gitignore Fix a compiler warning about potential infinite loops
1 parent 543e011 commit 8a8f97b

File tree

4 files changed

+86
-70
lines changed

4 files changed

+86
-70
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ local.properties
3333
# PDT-specific
3434
.buildpath
3535

36+
#################
37+
## Zed Editor
38+
#################
39+
.cache
3640

3741
#################
3842
## Visual Studio
@@ -292,4 +296,4 @@ highs-problem-set
292296
# Generated HiGHS options file
293297
Options.md
294298

295-
build-latest
299+
build-latest

highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "FactorHiGHSSolver.h"
22

3-
#include <limits>
4-
53
#include "Status.h"
64
#include "ipm/hipo/auxiliary/Auxiliary.h"
75
#include "ipm/hipo/auxiliary/Log.h"
@@ -92,9 +90,9 @@ Int FactorHiGHSSolver::buildNEvalues(const HighsSparseMatrix& A,
9290
const std::vector<double>& scaling) {
9391
// given the NE structure already computed, fill in the NE values
9492

95-
assert(!ptrNE_.empty() && !rowsNE_.empty());
93+
assert(!ptrLower_.empty() && !rowsLower_.empty());
9694

97-
valNE_.assign(rowsNE_.size(), 0.0);
95+
valLower_.assign(rowsLower_.size(), 0.0);
9896

9997
std::vector<double> work(A.num_row_, 0.0);
10098

@@ -127,9 +125,9 @@ Int FactorHiGHSSolver::buildNEvalues(const HighsSparseMatrix& A,
127125
// intersection of row with rows below finished.
128126

129127
// read from work, using indices of column "row" of AAt
130-
for (Int el = ptrNE_[row]; el < ptrNE_[row + 1]; ++el) {
131-
Int index = rowsNE_[el];
132-
valNE_[el] = work[index];
128+
for (Int el = ptrLower_[row]; el < ptrLower_[row + 1]; ++el) {
129+
Int index = rowsLower_[el];
130+
valLower_[el] = work[index];
133131
work[index] = 0.0;
134132
}
135133
}
@@ -170,11 +168,11 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
170168
}
171169
}
172170

173-
ptrNE_.clear();
174-
rowsNE_.clear();
171+
ptrLower_.clear();
172+
rowsLower_.clear();
175173

176174
// ptr is allocated its exact size
177-
ptrNE_.resize(A.num_row_ + 1, 0);
175+
ptrLower_.resize(A.num_row_ + 1, 0);
178176

179177
// keep track if given entry is nonzero, in column considered
180178
std::vector<bool> is_nz(A.num_row_, false);
@@ -211,74 +209,101 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
211209
// intersection of row with rows below finished.
212210

213211
// if the total number of nonzeros exceeds the maximum, return error.
214-
if ((Int64)ptrNE_[row] + nz_in_col >= nz_limit) return kStatusOverflow;
212+
if ((Int64)ptrLower_[row] + nz_in_col >= nz_limit) return kStatusOverflow;
215213

216214
// update pointers
217-
ptrNE_[row + 1] = ptrNE_[row] + nz_in_col;
215+
ptrLower_[row + 1] = ptrLower_[row] + nz_in_col;
218216

219217
// now assign indices
220218
for (Int i = 0; i < nz_in_col; ++i) {
221219
Int index = temp_index[i];
222220
// push_back is better then reserve, because the final length is not known
223-
rowsNE_.push_back(index);
221+
rowsLower_.push_back(index);
224222
is_nz[index] = false;
225223
}
226224
}
227225

228226
return kStatusOk;
229227
}
230228

231-
Int FactorHiGHSSolver::factorAS(const HighsSparseMatrix& A,
232-
const std::vector<double>& scaling) {
233-
// only execute factorisation if it has not been done yet
234-
assert(!this->valid_);
235-
236-
Clock clock;
237-
238-
// initialise
239-
std::vector<Int> ptrLower;
240-
std::vector<Int> rowsLower;
241-
std::vector<double> valLower;
242-
229+
Int FactorHiGHSSolver::buildASstructure(const HighsSparseMatrix& A,
230+
const std::vector<double>& scaling) {
243231
Int nA = A.num_col_;
244232
Int mA = A.num_row_;
245233
Int nzA = A.numNz();
246234

247-
ptrLower.resize(nA + mA + 1);
248-
rowsLower.resize(nA + nzA + mA);
249-
valLower.resize(nA + nzA + mA);
235+
ptrLower_.resize(nA + mA + 1);
236+
rowsLower_.resize(nA + nzA + mA);
237+
valLower_.resize(nA + nzA + mA);
250238

251239
// build lower triangle
252240
Int next = 0;
253241

254242
for (Int i = 0; i < nA; ++i) {
255243
// diagonal element
256-
rowsLower[next] = i;
257-
valLower[next++] = -scaling[i];
244+
rowsLower_[next] = i;
245+
valLower_[next] = -scaling[i];
246+
next++;
258247

259248
// column of A
260249
for (Int el = A.start_[i]; el < A.start_[i + 1]; ++el) {
261-
rowsLower[next] = A.index_[el] + nA;
262-
valLower[next++] = A.value_[el];
250+
rowsLower_[next] = A.index_[el] + nA;
251+
valLower_[next] = A.value_[el];
252+
next++;
263253
}
264254

265-
ptrLower[i + 1] = next;
255+
ptrLower_[i + 1] = next;
266256
}
267257

268258
// 2,2 block
269259
for (Int i = 0; i < mA; ++i) {
270-
rowsLower[next] = nA + i;
271-
valLower[next++] = 0.0;
272-
ptrLower[nA + i + 1] = ptrLower[nA + i] + 1;
260+
rowsLower_[next] = nA + i;
261+
valLower_[next++] = 0.0;
262+
ptrLower_[nA + i + 1] = ptrLower_[nA + i] + 1;
263+
}
264+
return 0;
265+
}
266+
267+
Int FactorHiGHSSolver::updateASdiagonal(const HighsSparseMatrix& A,
268+
const std::vector<double>& scaling) {
269+
Int nA = A.num_col_;
270+
271+
// build lower triangle
272+
Int next = 0;
273+
274+
for (Int i = 0; i < nA; ++i) {
275+
// diagonal element
276+
valLower_[next] = -scaling[i];
277+
next++;
278+
279+
// move the pointer by the number of nonzeros in the i-th column of A
280+
next += A.start_[i + 1] - A.start_[i];
281+
}
282+
return 0;
283+
}
284+
285+
Int FactorHiGHSSolver::factorAS(const HighsSparseMatrix& A,
286+
const std::vector<double>& scaling) {
287+
// only execute factorisation if it has not been done yet
288+
assert(!this->valid_);
289+
290+
Clock clock;
291+
292+
if (amat_set_ == true) {
293+
std::ignore = updateASdiagonal(A, scaling);
294+
} else {
295+
std::ignore = buildASstructure(A, scaling);
296+
amat_set_ = true;
273297
}
298+
274299
if (info_) info_->matrix_time += clock.stop();
275300

276301
// set static regularisation, since it may have changed
277302
FH_.setRegularisation(regul_.primal, regul_.dual);
278303

279304
// factorise matrix
280305
clock.start();
281-
if (FH_.factorise(S_, rowsLower, ptrLower, valLower))
306+
if (FH_.factorise(S_, rowsLower_, ptrLower_, valLower_))
282307
return kStatusErrorFactorise;
283308
if (info_) {
284309
info_->factor_time += clock.stop();
@@ -305,11 +330,8 @@ Int FactorHiGHSSolver::factorNE(const HighsSparseMatrix& A,
305330

306331
// factorise
307332
clock.start();
308-
// make copies of structure, because factorise object will take ownership and
309-
// modify them.
310-
std::vector<Int> ptrNE(ptrNE_);
311-
std::vector<Int> rowsNE(rowsNE_);
312-
if (FH_.factorise(S_, rowsNE, ptrNE, valNE_)) return kStatusErrorFactorise;
333+
if (FH_.factorise(S_, rowsLower_, ptrLower_, valLower_))
334+
return kStatusErrorFactorise;
313335
if (info_) {
314336
info_->factor_time += clock.stop();
315337
info_->factor_number++;
@@ -385,9 +407,7 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
385407
log_.printDevInfo("Building AS structure\n");
386408

387409
Clock clock;
388-
std::vector<Int> ptrLower;
389-
std::vector<Int> rowsLower;
390-
if (Int status = getASstructure(model_.A(), ptrLower, rowsLower))
410+
if (Int status = getASstructure(model_.A(), ptrLower_, rowsLower_))
391411
return status;
392412
if (info_) info_->matrix_structure_time = clock.stop();
393413

@@ -399,7 +419,7 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
399419
log_.printDevInfo("Performing AS analyse phase\n");
400420

401421
clock.start();
402-
Int status = FH_.analyse(S, rowsLower, ptrLower, pivot_signs);
422+
Int status = FH_.analyse(S, rowsLower_, ptrLower_, pivot_signs);
403423
if (info_) info_->analyse_AS_time = clock.stop();
404424

405425
if (status && log_.debug(2)) {
@@ -410,17 +430,6 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
410430
return status ? kStatusErrorAnalyse : kStatusOk;
411431
}
412432

413-
void FactorHiGHSSolver::freeNEmemory() {
414-
// Swap NE data structures with empty vectors, to guarantee that memory is
415-
// freed.
416-
417-
std::vector<Int>().swap(ptrNE_);
418-
std::vector<Int>().swap(rowsNE_);
419-
std::vector<Int>().swap(ptrA_rw_);
420-
std::vector<Int>().swap(idxA_rw_);
421-
std::vector<Int>().swap(corr_A_);
422-
}
423-
424433
Int FactorHiGHSSolver::analyseNE(Symbolic& S, Int64 nz_limit) {
425434
// Perform analyse phase of augmented system and return symbolic factorisation
426435
// in object S and the status. If building the matrix failed, the status is
@@ -438,7 +447,7 @@ Int FactorHiGHSSolver::analyseNE(Symbolic& S, Int64 nz_limit) {
438447
log_.printDevInfo("Performing NE analyse phase\n");
439448

440449
clock.start();
441-
Int status = FH_.analyse(S, rowsNE_, ptrNE_, pivot_signs);
450+
Int status = FH_.analyse(S, rowsLower_, ptrLower_, pivot_signs);
442451
if (info_) info_->analyse_NE_time = clock.stop();
443452

444453
if (status && log_.debug(2)) {
@@ -548,7 +557,6 @@ Int FactorHiGHSSolver::chooseNla() {
548557
if (status == kStatusOk) {
549558
if (options_.nla == kOptionNlaAugmented) {
550559
S_ = std::move(symb_AS);
551-
freeNEmemory();
552560
} else {
553561
S_ = std::move(symb_NE);
554562
}
@@ -681,4 +689,4 @@ void FactorHiGHSSolver::setParallel() {
681689
S_.setParallel(parallel_tree, parallel_node);
682690
}
683691

684-
} // namespace hipo
692+
} // namespace hipo

highs/ipm/hipo/ipm/FactorHiGHSSolver.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#ifndef HIPO_FACTORHIGHS_SOLVER_H
22
#define HIPO_FACTORHIGHS_SOLVER_H
33

4-
#include <algorithm>
5-
64
#include "Info.h"
75
#include "IpmData.h"
86
#include "LinearSolver.h"
@@ -20,11 +18,12 @@ class FactorHiGHSSolver : public LinearSolver {
2018
Symbolic S_;
2119

2220
// normal equations data
23-
std::vector<Int> ptrNE_;
24-
std::vector<Int> rowsNE_;
25-
std::vector<double> valNE_;
26-
std::vector<Int> ptrA_rw_, idxA_rw_;
27-
std::vector<Int> corr_A_;
21+
std::vector<Int> ptrLower_;
22+
std::vector<Int> rowsLower_;
23+
std::vector<double> valLower_;
24+
std::vector<Int> ptrA_rw_, idxA_rw_; // Symbolic row-wise (CSR) copy of A
25+
std::vector<Int> corr_A_; // ?
26+
bool amat_set_ = false;
2827

2928
const Regularisation& regul_;
3029

@@ -42,7 +41,11 @@ class FactorHiGHSSolver : public LinearSolver {
4241
Int buildNEstructure(const HighsSparseMatrix& A, Int64 nz_limit = kHighsIInf);
4342
Int buildNEvalues(const HighsSparseMatrix& A,
4443
const std::vector<double>& scaling);
45-
void freeNEmemory();
44+
45+
Int buildASstructure(const HighsSparseMatrix& A,
46+
const std::vector<double>& scaling);
47+
Int updateASdiagonal(const HighsSparseMatrix& A,
48+
const std::vector<double>& scaling);
4649

4750
Int analyseAS(Symbolic& S);
4851
Int analyseNE(Symbolic& S, Int64 nz_limit = kHighsIInf);

highs/ipm/hipo/ipm/Solver.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <cassert>
44
#include <cmath>
5+
#include <cstdint>
56
#include <iostream>
67

78
#include "ipm/hipo/auxiliary/AutoDetect.h"
@@ -417,7 +418,7 @@ double Solver::stepToBoundary(const std::vector<double>& x,
417418
double alpha = 1.0;
418419
Int bl = -1;
419420

420-
for (Int i = 0; i < x.size(); ++i) {
421+
for (uint64_t i = 0; i < x.size(); ++i) {
421422
if ((lo && model_.hasLb(i)) || (!lo && model_.hasUb(i))) {
422423
double c = (cor ? (*cor)[i] * weight : 0.0);
423424
if (x[i] + alpha * (dx[i] + c) < 0.0) {

0 commit comments

Comments
 (0)