@@ -451,6 +451,71 @@ void Analyse::fundamentalSupernodes() {
451451 sn_parent_.back () = -1 ;
452452}
453453
454+ void Analyse::relaxSn () {
455+ // =================================================
456+ // Build information about supernodes
457+ // =================================================
458+ std::vector<Int> sn_size (sn_count_);
459+ std::vector<Int> clique_size (sn_count_);
460+ fake_nz_.assign (sn_count_, 0 );
461+ for (Int i = 0 ; i < sn_count_; ++i) {
462+ sn_size[i] = sn_start_[i + 1 ] - sn_start_[i];
463+ clique_size[i] = col_count_[sn_start_[i]] - sn_size[i];
464+ }
465+
466+ // build linked lists of children
467+ std::vector<Int> first_child, next_child;
468+ childrenLinkedList (sn_parent_, first_child, next_child);
469+
470+ // =================================================
471+ // Merge supernodes
472+ // =================================================
473+ merged_into_.assign (sn_count_, -1 );
474+ merged_sn_ = 0 ;
475+
476+ for (Int sn = 0 ; sn < sn_count_; ++sn) {
477+ Int child = first_child[sn];
478+ Int64 nz_fakenz = int64_limit;
479+ Int size_fakenz = 0 ;
480+ Int child_fakenz = -1 ;
481+
482+ while (child != -1 ) {
483+ // how many zero rows would become nonzero
484+ const Int rows_filled =
485+ sn_size[sn] + clique_size[sn] - clique_size[child];
486+
487+ // how many zero entries would become nonzero
488+ const Int64 nz_added = (Int64)rows_filled * sn_size[child];
489+
490+ // how many artificial nonzeros would the merged supernode have
491+ const Int64 total_art_nz = nz_added + fake_nz_[sn] + fake_nz_[child];
492+
493+ const double flops_added =
494+ rows_filled * rows_filled * sn_size[child] +
495+ 2 * rows_filled *
496+ (sn_size[child] * (sn_size[child] + clique_size[child]) -
497+ sn_size[child] * (sn_size[child] + 1 ) / 2 );
498+
499+ const double spops_removed =
500+ clique_size[child] * (clique_size[child] + 1 ) / 2 ;
501+
502+ const double net_ops = flops_added - 50.0 * spops_removed;
503+
504+ if (net_ops < 0 ) {
505+ // merge child with parent
506+
507+ sn_size[sn] += sn_size[child];
508+ fake_nz_[sn] = total_art_nz;
509+
510+ ++merged_sn_;
511+ merged_into_[child] = sn;
512+ }
513+
514+ child = next_child[child];
515+ }
516+ }
517+ }
518+
454519double Analyse::doRelaxSupernodes (Int64 max_artificial_nz) {
455520 // =================================================
456521 // Build information about supernodes
@@ -1313,7 +1378,7 @@ Int Analyse::run(Symbolic& S) {
13131378
13141379 HIPO_CLOCK_START (2 );
13151380 fundamentalSupernodes ();
1316- relaxSupernodes ();
1381+ relaxSn ();
13171382 afterRelaxSn ();
13181383 HIPO_CLOCK_STOP (2 , data_, kTimeAnalyseSn );
13191384
0 commit comments