Skip to content

Commit 4e3d0fe

Browse files
committed
Use splitting only if reduction is large
1 parent 0748242 commit 4e3d0fe

5 files changed

Lines changed: 59 additions & 32 deletions

File tree

highs/ipm/hipo/factorhighs/Analyse.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,14 @@ Int Analyse::run(Symbolic& S) {
14921492
S.relind_clique_ = std::move(relind_clique_);
14931493
S.consecutive_sums_ = std::move(consecutive_sums_);
14941494
S.clique_block_start_ = std::move(clique_block_start_);
1495-
S.tree_splitting_ = std::move(tree_splitting_);
1495+
1496+
// use the tree splitting only if it achieves a good relative reduction of the
1497+
// number of tasks
1498+
if (sn_count_ - tree_splitting_.tasks() > sn_count_ * kTaskReductionThresh) {
1499+
S.tree_splitting_ = std::move(tree_splitting_);
1500+
S.use_splitting_ = true;
1501+
} else
1502+
S.use_splitting_ = false;
14961503

14971504
HIPO_CLOCK_STOP(1, data_, kTimeAnalyse);
14981505

highs/ipm/hipo/factorhighs/FactorHiGHSSettings.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ const double kDynamicDiagCoeff = 1e-24;
5151
const Int kMetisSeed = 42;
5252

5353
// tree splitting
54-
const double kSmallThreshCoeff = 0.001;
54+
const double kSmallThreshCoeff = 0.001; // 0.1%
5555
const double kSpopsWeightSplitting = 30.0;
56+
const double kTaskReductionThresh = 0.8; // 80%
5657

5758
struct Regul {
5859
double primal{};

highs/ipm/hipo/factorhighs/Factorise.cpp

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -378,37 +378,47 @@ void Factorise::spawn(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
378378
// immediately. This avoids the overhead of spawning a task if a supernode has
379379
// a single child.
380380

381-
const NodeData* data = S_.treeSplitting().find(sn);
381+
if (S_.useSplitting()) {
382+
const NodeData* data = S_.treeSplitting().find(sn);
382383

383-
if (!data) {
384-
// sn is head of small subtree, but not the first subtree in the group.
385-
// It is processed in another task.
386-
return;
387-
}
384+
if (!data) {
385+
// sn is head of small subtree, but not the first subtree in the group.
386+
// It is processed in another task.
387+
return;
388+
}
388389

389-
if (data->type == NodeType::single) {
390-
// sn is single node; run only that
391-
auto f = [this, sn]() { processSupernode(sn, true); };
390+
if (data->type == NodeType::single) {
391+
// sn is single node; run only that
392+
auto f = [this, sn]() { processSupernode(sn, true); };
392393

393-
if (do_spawn)
394-
tg.spawn(std::move(f));
395-
else
396-
f();
394+
if (do_spawn)
395+
tg.spawn(std::move(f));
396+
else
397+
f();
397398

398-
} else {
399-
// sn is head of the first subtree in a group of small subtrees; run all
400-
// of them
401-
402-
auto f = [this, data]() {
403-
for (Int i = 0; i < data->group.size(); ++i) {
404-
Int st_head = data->group[i];
405-
Int start = data->firstdesc[i];
406-
Int end = st_head + 1;
407-
for (Int sn = start; sn < end; ++sn) {
408-
processSupernode(sn, false);
399+
} else {
400+
// sn is head of the first subtree in a group of small subtrees; run all
401+
// of them
402+
403+
auto f = [this, data]() {
404+
for (Int i = 0; i < data->group.size(); ++i) {
405+
Int st_head = data->group[i];
406+
Int start = data->firstdesc[i];
407+
Int end = st_head + 1;
408+
for (Int sn = start; sn < end; ++sn) {
409+
processSupernode(sn, false);
410+
}
409411
}
410-
}
411-
};
412+
};
413+
414+
if (do_spawn)
415+
tg.spawn(std::move(f));
416+
else
417+
f();
418+
}
419+
420+
} else {
421+
auto f = [this, sn]() { processSupernode(sn, true); };
412422

413423
if (do_spawn)
414424
tg.spawn(std::move(f));
@@ -420,7 +430,12 @@ void Factorise::spawn(Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
420430
void Factorise::sync(Int sn, const TaskGroupSpecial& tg) {
421431
// If spawn(sn,tg) created a task, then sync it.
422432
// This happens only if sn is found in the treeSplitting data structure.
423-
if (S_.treeSplitting().belong(sn)) tg.sync();
433+
434+
if (S_.useSplitting()) {
435+
if (S_.treeSplitting().belong(sn)) tg.sync();
436+
} else {
437+
tg.sync();
438+
}
424439
}
425440

426441
bool Factorise::run(Numeric& num) {

highs/ipm/hipo/factorhighs/Symbolic.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "ipm/hipo/auxiliary/Log.h"
77

88
namespace hipo {
9-
9+
1010
void Symbolic::setParallel(bool par_tree, bool par_node) {
1111
parallel_tree_ = par_tree;
1212
parallel_node_ = par_node;
@@ -39,6 +39,7 @@ Int64 Symbolic::maxStackSize() const { return max_stack_size_; }
3939
bool Symbolic::parTree() const { return parallel_tree_; }
4040
bool Symbolic::parNode() const { return parallel_node_; }
4141
double Symbolic::storage() const { return serial_storage_; }
42+
bool Symbolic::useSplitting() const { return use_splitting_; }
4243

4344
const std::vector<Int64>& Symbolic::ptr() const { return ptr_; }
4445
const std::vector<Int>& Symbolic::iperm() const { return iperm_; }
@@ -78,7 +79,8 @@ void Symbolic::print(const Log& log, bool verbose) const {
7879
log_stream << textline("Max tree speedup:") << fix(flops_ / critops_, 0, 2)
7980
<< '\n';
8081
log_stream << textline("Number of tasks:")
81-
<< integer(tree_splitting_.tasks()) << '\n';
82+
<< integer(use_splitting_ ? tree_splitting_.tasks() : sn_)
83+
<< '\n';
8284
log_stream << textline("Artificial nz:") << sci(artificial_nz_, 0, 1)
8385
<< '\n';
8486
log_stream << textline("Artificial ops:") << sci(artificial_ops_, 0, 1)

highs/ipm/hipo/factorhighs/Symbolic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#include <map>
55
#include <vector>
66

7+
#include "TreeSplitting.h"
78
#include "ipm/hipo/auxiliary/IntConfig.h"
89
#include "ipm/hipo/auxiliary/Log.h"
9-
#include "TreeSplitting.h"
1010

1111
namespace hipo {
1212

@@ -102,6 +102,7 @@ class Symbolic {
102102
std::string ordering;
103103

104104
TreeSplitting tree_splitting_;
105+
bool use_splitting_ = false;
105106

106107
friend class Analyse;
107108

@@ -130,6 +131,7 @@ class Symbolic {
130131
bool parTree() const;
131132
bool parNode() const;
132133
double storage() const;
134+
bool useSplitting() const;
133135
const std::vector<Int64>& ptr() const;
134136
const std::vector<Int>& iperm() const;
135137
const std::vector<Int>& snParent() const;

0 commit comments

Comments
 (0)