Skip to content

Commit afb55d8

Browse files
committed
Improved comments and removed unused function in Numeric
1 parent 53f4cf0 commit afb55d8

File tree

6 files changed

+17
-102
lines changed

6 files changed

+17
-102
lines changed

highs/ipm/hipo/factorhighs/FactorHiGHS.h

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ class FHsolver {
6565
const Int nb_; // block size
6666
static const Int default_nb_ = 128;
6767

68-
// columns of factorisation, stored by supernode
68+
// Columns of factorisation, stored by supernode.
69+
// This memory is allocated the first time that it is used. Subsequent
70+
// factorisations reuse the same memory.
6971
std::vector<std::vector<double>> sn_columns_;
7072

7173
public:
@@ -107,34 +109,6 @@ class FHsolver {
107109
void setRegularisation(double reg_p, double reg_d);
108110
};
109111

110-
/* To do
111-
112-
- At the moment, the format handler allocates new space for frontal each time,
113-
and then moves the values into sn_columns_, with the previous space being
114-
deallocated. This is very inefficient, because it causes many memory
115-
allocation/deallocation. It may also cause fragmentation.
116-
- Have sn_columns_ outside of factorise, into FHsolver. Then, pass it into
117-
Factorise and assemble the contributions directly in place. Numeric then
118-
receives a pointer to the data, so that it can access the data in the same way
119-
as now. Format handler needs to assign zeros during initialization each time.
120-
- In this way, the space for the columns of the factor is persistent throughout
121-
the ipm iterations, no extra allocation/deallocation is needed, no copies are
122-
needed. Potentially, there may be more contention of the cache lines, but this
123-
is to be seen.
124-
125-
- For the moment, the same can be done with cliques. No need to
126-
allocate/deallocate them. They can stay allocated and be reused. This would
127-
probably considerably increase the memory usage though and the stack approach
128-
is to be preferred. However, the latter requires a different parallelisation.
129-
130-
131-
- at the moment, I managed to keep the same interface to Numeric, but it's a bit
132-
ugly. Maybe Numeric should be an object that is crested by Factorise, which
133-
only contains pointers to data. Then I can just copy into the general numeric
134-
object within FactorHiGHSSolver and include the pointers to the most up to
135-
date data.
136-
*/
137-
138112
} // namespace hipo
139113

140114
#endif

highs/ipm/hipo/factorhighs/Factorise.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,15 @@ bool Factorise::run(Numeric& num) {
358358

359359
total_reg_.assign(n_, 0.0);
360360

361-
// allocate space for list of generated elements and columns of L
361+
// allocate space
362362
schur_contribution_.resize(S_.sn());
363-
sn_columns_.resize(S_.sn());
364363
swaps_.resize(S_.sn());
365364
pivot_2x2_.resize(S_.sn());
366365

366+
// This should actually allocate only the first time, then sn_columns_ reuses
367+
// the memory of previous factorisations.
368+
sn_columns_.resize(S_.sn());
369+
367370
if (S_.parTree()) {
368371
Int spawned_roots{};
369372
// spawn tasks for root supernodes

highs/ipm/hipo/factorhighs/Factorise.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class Factorise {
3434
std::vector<std::vector<double>> schur_contribution_{};
3535

3636
// columns of L, stored as dense supernodes
37+
// This memory is managed outside of Factorise, so that it can be reused for
38+
// all ipm iterations.
3739
std::vector<std::vector<double>>& sn_columns_;
3840

3941
// swaps of columns for each supernode, ordered locally within a block

highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ void HybridHybridFormatHandler::initFrontal() {
2222
Int frontal_size = getDiagStart(ldf_, sn_size_, nb_, n_blocks, diag_start_);
2323
frontal_.assign(frontal_size + extra_space, 0.0);
2424
// NB: the plus 10 is not needed, but it avoids weird problems later on.
25+
26+
// frontal_ is actually allocated just the first time, then the memory is
27+
// reused from the previous factorisations and just initialised.
2528
}
2629

2730
void HybridHybridFormatHandler::initClique() {

highs/ipm/hipo/factorhighs/Numeric.cpp

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -234,73 +234,4 @@ double Numeric::computeOmega(const std::vector<double>& b,
234234
return omega_1 + omega_2;
235235
}
236236

237-
void Numeric::conditionNumber() const {
238-
HighsRandom random;
239-
240-
const Int n = S_->size();
241-
242-
// estimate largest eigenvalue with power iteration:
243-
// x <- x / ||x||
244-
// y <- M * x
245-
// lambda = ||y||
246-
247-
double lambda_large{};
248-
std::vector<double> x(n);
249-
for (Int i = 0; i < n; ++i) x[i] = random.fraction();
250-
251-
for (Int iter = 0; iter < 10; ++iter) {
252-
// normalize x
253-
double x_norm = norm2(x);
254-
vectorScale(x, 1.0 / x_norm);
255-
256-
// multiply by matrix
257-
std::vector<double> y(n);
258-
symProduct(ptrA_, rowsA_, valA_, x, y);
259-
260-
double norm_y = norm2(y);
261-
262-
if (std::abs(lambda_large - norm_y) / std::max(1.0, lambda_large) < 1e-2) {
263-
// converged
264-
break;
265-
}
266-
267-
lambda_large = norm_y;
268-
x = std::move(y);
269-
}
270-
271-
// estimate inverse of smallest eigenvalue with inverse power iteration:
272-
// x <- x / ||x||
273-
// y <- M^-1 * x
274-
// lambda_inv = ||y||
275-
276-
double lambda_small_inv{};
277-
for (Int i = 0; i < n; ++i) x[i] = random.fraction();
278-
279-
for (Int iter = 0; iter < 10; ++iter) {
280-
// normalize x
281-
double x_norm = norm2(x);
282-
vectorScale(x, 1.0 / x_norm);
283-
284-
// solve with matrix
285-
std::vector<double> y(x);
286-
SH_->forwardSolve(y);
287-
SH_->diagSolve(y);
288-
SH_->backwardSolve(y);
289-
290-
double norm_y = norm2(y);
291-
292-
if (std::abs(lambda_small_inv - norm_y) / std::max(1.0, lambda_small_inv) <
293-
1e-2) {
294-
// converged
295-
break;
296-
}
297-
298-
lambda_small_inv = norm_y;
299-
x = std::move(y);
300-
}
301-
302-
// condition number: lambda_large / lambda_small
303-
double cond = lambda_large * lambda_small_inv;
304-
}
305-
306237
} // namespace hipo

highs/ipm/hipo/factorhighs/Numeric.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include "Symbolic.h"
1010
#include "ipm/hipo/auxiliary/IntConfig.h"
1111

12+
// Numeric allows to perform solve, though a pointer to the numerical factor,
13+
// that is stored in FHsolver. It also holds auxiliary data about swaps,
14+
// pivots...
15+
1216
namespace hipo {
1317

1418
class Numeric {
@@ -58,8 +62,6 @@ class Numeric {
5862
double computeOmega(const std::vector<double>& b,
5963
const std::vector<double>& x,
6064
const std::vector<double>& res) const;
61-
62-
void conditionNumber() const;
6365
};
6466

6567
} // namespace hipo

0 commit comments

Comments
 (0)