@@ -58,13 +58,6 @@ Factorise::Factorise(const Symbolic& S, const std::vector<Int>& rowsA,
5858 // create linked lists of children in supernodal elimination tree
5959 childrenLinkedList (S_.snParent (), first_child_, next_child_);
6060
61- if (S_.parTree ()) {
62- // create reverse linked lists of children
63- first_child_reverse_ = first_child_;
64- next_child_reverse_ = next_child_;
65- reverseLinkedList (first_child_reverse_, next_child_reverse_);
66- }
67-
6861 // compute largest diagonal entry in absolute value
6962 max_diag_ = 0.0 ;
7063 min_diag_ = kHighsInf ;
@@ -174,19 +167,6 @@ void Factorise::processSupernode(Int sn) {
174167
175168 if (flag_stop_) return ;
176169
177- if (S_.parTree ()) {
178- // spawn children of this supernode in reverse order
179- Int child_to_spawn = first_child_reverse_[sn];
180- while (child_to_spawn != -1 ) {
181- highs::parallel::spawn ([=]() { processSupernode (child_to_spawn); });
182- child_to_spawn = next_child_reverse_[child_to_spawn];
183- }
184-
185- // wait for first child to finish, before starting the parent (if there is a
186- // first child)
187- if (first_child_reverse_[sn] != -1 ) highs::parallel::sync ();
188- }
189-
190170#if HIPO_TIMING_LEVEL >= 2
191171 Clock clock;
192172#endif
@@ -238,17 +218,10 @@ void Factorise::processSupernode(Int sn) {
238218 // Schur contribution of the current child
239219 std::vector<double >& child_clique = schur_contribution_[child_sn];
240220
241- if (S_.parTree ()) {
242- // sync with spawned child, apart from the first one
243- if (child_sn != first_child_[sn]) highs::parallel::sync ();
244-
245- if (flag_stop_) return ;
246-
247- if (child_clique.size () == 0 ) {
248- if (log_) log_->printDevInfo (" Missing child supernode contribution\n " );
249- flag_stop_ = true ;
250- return ;
251- }
221+ if (child_clique.size () == 0 ) {
222+ if (log_) log_->printDevInfo (" Missing child supernode contribution\n " );
223+ flag_stop_ = true ;
224+ return ;
252225 }
253226
254227 // determine size of clique of child
@@ -351,6 +324,12 @@ void Factorise::processSupernode(Int sn) {
351324#endif
352325}
353326
327+ void Factorise::processSupernodes (Int start, Int end) {
328+ for (Int sn = start; sn < end; ++sn) {
329+ processSupernode (sn);
330+ }
331+ }
332+
354333bool Factorise::run (Numeric& num) {
355334#if HIPO_TIMING_LEVEL >= 1
356335 Clock clock;
@@ -368,24 +347,33 @@ bool Factorise::run(Numeric& num) {
368347 sn_columns_.resize (S_.sn ());
369348
370349 if (S_.parTree ()) {
371- Int spawned_roots{};
372- // spawn tasks for root supernodes
373- for (Int sn = 0 ; sn < S_.sn (); ++sn) {
374- if (S_.snParent (sn) == -1 ) {
375- highs::parallel::spawn ([=]() { processSupernode (sn); });
376- ++spawned_roots;
377- }
350+ // process subtrees in the layer
351+ for (Int i = 0 ; i < S_.layerIndex ().size (); ++i) {
352+ Int start = S_.layerSubtreeInfo (i).start ;
353+ Int end = S_.layerSubtreeInfo (i).end ;
354+ highs::parallel::spawn ([=]() { processSupernodes (start, end); });
355+ }
356+
357+ // process small subtrees
358+ for (Int i = 0 ; i < S_.smallSubtrees ().size (); ++i) {
359+ Int start = S_.smallSubtreeInfo (i).start ;
360+ Int end = S_.smallSubtreeInfo (i).end ;
361+ processSupernodes (start, end);
378362 }
379363
380- // sync tasks for root supernodes
381- for (Int root = 0 ; root < spawned_roots ; ++root ) {
364+ // wait for subtrees in the layer to complete
365+ for (Int i = 0 ; i < S_. layerIndex (). size () ; ++i ) {
382366 highs::parallel::sync ();
383367 }
368+
369+ // process nodes above layer
370+ for (auto it = S_.aboveLayer ().begin (); it != S_.aboveLayer ().end (); ++it) {
371+ processSupernode (*it);
372+ }
373+
384374 } else {
385375 // go through each supernode serially
386- for (Int sn = 0 ; sn < S_.sn (); ++sn) {
387- processSupernode (sn);
388- }
376+ processSupernodes (0 , S_.sn ());
389377 }
390378
391379 if (flag_stop_) return true ;
0 commit comments