Skip to content

Commit 6774d40

Browse files
committed
Small subtrees divided among threads
1 parent 64838ce commit 6774d40

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

highs/ipm/hipo/factorhighs/Analyse.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,9 @@ void Analyse::generateParallelLayer(Int threads) {
13231323
// percentage of total ops below which a subtree is considered small
13241324
const double small_thresh_coeff = 0.01;
13251325

1326+
std::vector<double> subtree_ops(sn_count_, 0.0);
1327+
double total_ops = dense_ops_;
1328+
13261329
if (threads > 1) {
13271330
std::stringstream log_stream;
13281331
log_stream << "Searching parallel layer\n";
@@ -1331,8 +1334,6 @@ void Analyse::generateParallelLayer(Int threads) {
13311334
std::vector<Int> head, next;
13321335
childrenLinkedList(sn_parent_, head, next);
13331336

1334-
double total_ops = dense_ops_;
1335-
13361337
// compute number of operations for each supernode
13371338
std::vector<double> sn_ops(sn_count_);
13381339
for (Int sn = 0; sn < sn_count_; ++sn) {
@@ -1357,7 +1358,6 @@ void Analyse::generateParallelLayer(Int threads) {
13571358
}
13581359

13591360
// compute number of operations to process each subtree
1360-
std::vector<double> subtree_ops(sn_count_, 0.0);
13611361
for (Int sn = 0; sn < sn_count_; ++sn) {
13621362
subtree_ops[sn] += sn_ops[sn];
13631363
if (sn_parent_[sn] != -1) {
@@ -1578,6 +1578,8 @@ void Analyse::generateParallelLayer(Int threads) {
15781578
// no stack needed for small subtrees
15791579
smallSubtreesInfo_[index].stack = -1;
15801580

1581+
smallSubtreesInfo_[index].ops_fraction = subtree_ops[node] / total_ops;
1582+
15811583
++index;
15821584
}
15831585
}

highs/ipm/hipo/factorhighs/Factorise.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,14 @@ void Factorise::processSupernodes(Int start, Int end) {
330330
}
331331
}
332332

333+
void Factorise::processSmallSubtrees(Int i, Int j) {
334+
for (Int tree = i; tree < j; ++tree) {
335+
Int start = S_.smallSubtreeInfo(tree).start;
336+
Int end = S_.smallSubtreeInfo(tree).end;
337+
processSupernodes(start, end);
338+
}
339+
}
340+
333341
bool Factorise::run(Numeric& num) {
334342
#if HIPO_TIMING_LEVEL >= 1
335343
Clock clock;
@@ -354,16 +362,36 @@ bool Factorise::run(Numeric& num) {
354362
highs::parallel::spawn([=]() { processSupernodes(start, end); });
355363
}
356364

357-
// wait for subtrees in the layer to complete
358-
for (Int i = 0; i < S_.layerIndex().size(); ++i) {
359-
highs::parallel::sync();
360-
}
361-
362365
// process small subtrees
366+
// They are grouped together and spawned when a group has more than 5% of
367+
// total operations
368+
Int small_start{};
369+
double small_ops_current{};
370+
Int small_spawned{};
363371
for (Int i = 0; i < S_.smallSubtrees().size(); ++i) {
364-
Int start = S_.smallSubtreeInfo(i).start;
365-
Int end = S_.smallSubtreeInfo(i).end;
366-
processSupernodes(start, end);
372+
small_ops_current += S_.smallSubtreeInfo(i).ops_fraction;
373+
374+
if (small_ops_current > 0.05) {
375+
// spawn start to current
376+
highs::parallel::spawn(
377+
[=]() { processSmallSubtrees(small_start, i + 1); });
378+
379+
small_start = i + 1;
380+
small_ops_current = 0.0;
381+
++small_spawned;
382+
}
383+
}
384+
if (small_ops_current > 0) {
385+
// spawn start to end
386+
++small_spawned;
387+
highs::parallel::spawn([=]() {
388+
processSmallSubtrees(small_start, S_.smallSubtrees().size());
389+
});
390+
}
391+
392+
// wait for subtrees to complete
393+
for (Int i = 0; i < S_.layerIndex().size() + small_spawned; ++i) {
394+
highs::parallel::sync();
367395
}
368396

369397
// process nodes above layer

highs/ipm/hipo/factorhighs/Factorise.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class Factorise {
6666
void permute(const std::vector<Int>& iperm);
6767
void processSupernode(Int sn);
6868
void processSupernodes(Int start, Int end);
69+
void processSmallSubtrees(Int start, Int end);
6970

7071
public:
7172
Factorise(const Symbolic& S, const std::vector<Int>& rowsA,

highs/ipm/hipo/factorhighs/Symbolic.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ namespace hipo {
1212

1313
// info about subtrees in the parallel layer
1414
struct SubtreeInfo {
15-
Int start; // first node in subtree
16-
Int end; // first node not in subtree
17-
int64_t stack; // minimum stack size
15+
Int start; // first node in subtree
16+
Int end; // first node not in subtree
17+
int64_t stack; // minimum stack size
18+
double ops_fraction; // fraction of operations in subtree
1819
};
1920

2021
// Symbolic factorisation object

0 commit comments

Comments
 (0)