Skip to content

Commit b48fb0f

Browse files
committed
Change names and add explanation
1 parent 62f7fa8 commit b48fb0f

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

highs/ipm/hipo/factorhighs/Factorise.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,19 @@ void Factorise::processSupernode(Int sn, const bool should_parallelise) {
191191
if (do_parallelise) {
192192
// if there is only one child, do not parallelise
193193
if (first_child_[sn] != -1 && next_child_[first_child_[sn]] == -1) {
194-
spawnNode(first_child_[sn], tg, false);
194+
spawn(first_child_[sn], tg, false);
195195
do_parallelise = false;
196196
} else {
197197
// spawn children of this supernode in reverse order
198198
Int child_to_spawn = first_child_reverse_[sn];
199199
while (child_to_spawn != -1) {
200-
spawnNode(child_to_spawn, tg);
200+
spawn(child_to_spawn, tg);
201201
child_to_spawn = next_child_reverse_[child_to_spawn];
202202
}
203203

204204
// wait for first child to finish, before starting the parent (if there is
205205
// a first child)
206-
if (first_child_reverse_[sn] != -1) syncNode(first_child_[sn], tg);
206+
if (first_child_reverse_[sn] != -1) sync(first_child_[sn], tg);
207207
}
208208
}
209209

@@ -262,13 +262,18 @@ void Factorise::processSupernode(Int sn, const bool should_parallelise) {
262262
// Child contribution is found:
263263
// - in cliquestack, if we are processing the tree in serial.
264264
// - in schur_contribution_ if we are processing the tree in parallel.
265-
// Children are always summed from last to first.
265+
// Children are summed:
266+
// - in reverse order in serial, so that the correct child is found on top
267+
// of the CliqueStack.
268+
// - in forward order otherwise, so that if a small subtree is synced, and
269+
// it is not the first in its group, it will already have synced when it
270+
// is needed.
266271

267272
const double* child_clique;
268273

269274
if (do_parallelise) {
270275
// sync with spawned child, apart from the first one
271-
if (child_sn != first_child_[sn]) syncNode(child_sn, tg);
276+
if (child_sn != first_child_[sn]) sync(child_sn, tg);
272277
if (flag_stop_.load(std::memory_order_relaxed)) return;
273278
}
274279

@@ -379,7 +384,7 @@ void Factorise::processSupernode(Int sn, const bool should_parallelise) {
379384
HIPO_CLOCK_STOP(2, data_, kTimeFactoriseTerminate);
380385
}
381386

382-
void Factorise::spawnNode(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
387+
void Factorise::spawn(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
383388
// If do_spawn is true, a task is actually spawned, otherwise it is executed
384389
// immediately. This avoids the overhead of spawning a task if a supernode has
385390
// a single child.
@@ -388,7 +393,7 @@ void Factorise::spawnNode(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
388393

389394
if (!data) {
390395
// sn is head of small subtree, but not the first subtree in the group.
391-
// It will be processed in another task.
396+
// It is processed in another task.
392397
return;
393398
}
394399

@@ -423,8 +428,8 @@ void Factorise::spawnNode(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
423428
}
424429
}
425430

426-
void Factorise::syncNode(Int sn, const TaskGroupSpecial& tg) {
427-
// If spawnNode(sn,tg) created a task, then sync it.
431+
void Factorise::sync(Int sn, const TaskGroupSpecial& tg) {
432+
// If spawn(sn,tg) created a task, then sync it.
428433
// This happens only if sn is found in the treeSplitting data structure.
429434
if (S_.treeSplitting().belong(sn)) tg.sync();
430435
}
@@ -448,7 +453,7 @@ bool Factorise::run(Numeric& num) {
448453
if (S_.parTree()) {
449454
// spawn tasks for root supernodes
450455
for (Int sn = 0; sn < S_.sn(); ++sn) {
451-
if (S_.snParent(sn) == -1) (spawnNode(sn, tg));
456+
if (S_.snParent(sn) == -1) (spawn(sn, tg));
452457
}
453458

454459
// sync tasks for root supernodes

highs/ipm/hipo/factorhighs/Factorise.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class Factorise {
7676
public:
7777
void permute(const std::vector<Int>& iperm);
7878
void processSupernode(Int sn, const bool should_parallelise);
79-
void spawnNode(Int sn, const TaskGroupSpecial& tg, bool do_spawn = true);
80-
void syncNode(Int sn, const TaskGroupSpecial& tg);
79+
void spawn(Int sn, const TaskGroupSpecial& tg, bool do_spawn = true);
80+
void sync(Int sn, const TaskGroupSpecial& tg);
8181

8282
public:
8383
Factorise(const Symbolic& S, const std::vector<Int>& rowsM,

highs/ipm/hipo/factorhighs/TreeSplitting.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,46 @@ class TreeSplitting {
3737
NodeData& insertSubtree(Int sn);
3838

3939
const NodeData* find(Int sn) const;
40-
40+
4141
bool belong(Int sn) const { return belong_[sn]; }
4242
Int tasks() const { return split_.size(); }
4343
};
4444

45+
// Consider a supernode p, with children {a,b,c,d,e,f,g}.
46+
// p is NodeType::single.
47+
// c,f are NodeType::single.
48+
// {a,b,d} is a group of small subtrees.
49+
// {e,g} is a group of small subtrees.
50+
//
51+
// Information NodeData::firstdesc and NodeData::group is only used if type is
52+
// subtree. So, split_ looks like this:
53+
// p -> {single, -, -}
54+
// a -> {subtree, {Fa,Fb,Fd}, {a,b,d}}
55+
// c -> {single, -, -}
56+
// e -> {subtree, {Fe, Fg}, {e,g}}
57+
// f -> {single, -, -}
58+
// where Fj is the first descendant of node j.
59+
// belong_[j] is true for j=p,a,c,e,f and false for j=b,d,g.
60+
//
61+
// - When a is ran, a task is executed that executes the whole subtree of nodes
62+
// a, b and d.
63+
// - When b is ran, nothing happens, since it was already executed as part of
64+
// the task that executed a.
65+
// - When c is ran, a task is created that executes only that supernode.
66+
// - When d is ran, nothing happens, since it was already executed as part of
67+
// the task that executed a.
68+
// - When e is ran, a task is executed that executes the whole subtree of nodes
69+
// e and f.
70+
// - When f is ran, a task is created that executes only that supernode.
71+
// - When g is ran, nothing happens, since it was already executed as part of
72+
// the task that executed e.
73+
//
74+
// It is important that node a is processed before b and d, so that when b or d
75+
// are synced, their operations are already performed. Otherwise, syncing node b
76+
// would complete even though the operations for node b have not been performed.
77+
// In other words, children should be synced in forward order, and thus spawned
78+
// in reverse order.
79+
//
80+
4581
} // namespace hipo
4682
#endif

0 commit comments

Comments
 (0)