Skip to content

Optimization pass - #9

Merged
smaniu merged 7 commits into
masterfrom
optimization
Jul 19, 2026
Merged

Optimization pass#9
smaniu merged 7 commits into
masterfrom
optimization

Conversation

@smaniu

@smaniu smaniu commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Performance

  • Fill-in strategies (min-fill-in, degree+fill-in): eliminate
    per-neighbour unordered_set copies and short-circuit neighbour_improved.
  • Degree strategy : switch graph/queue containers from std::unordered_* to
    boost::unordered_flat_*.

Correctness fixes

  1. Graph::get_neighbours isolated-node UB — returned a dereferenced
    end() for a present-but-isolated node; now returns a shared empty set.
  2. Delta2D strategy/graph desync — read a removed node's neighbours
    (assertion in debug, SIGSEGV under NDEBUG); fixed by clearing the
    reused strategy queue before re-init.
  3. MCSPermutationStrategy::recompute didn't override the base (took
    its set by value → MCS was dead code); signature matched + override,
    with -Woverloaded-virtual added to catch the class of bug.
  4. CE::con_edge contracted inside its selection loop instead of once
    after it (reached via LBN+).
  5. Missing virtual destructors on LowerBound / MetaLowerBoundHeuristic
    — deleted through base unique_ptrs in main.cpp (UB;
    new-delete-type-mismatch under ASan).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on improving performance of permutation strategies and fixing several correctness/UB issues in the treewidth bounds/heuristics pipeline (notably around graph/strategy state synchronization, virtual overrides, and isolated-node handling).

Changes:

  • Replaces several std::unordered_* graph/queue containers with boost::unordered_flat_* and removes extra per-neighbour set copying in hot paths.
  • Fixes multiple correctness problems: Graph::get_neighbours isolated-node UB, Delta2D queue/graph desync (adds PermutationStrategy::clear()), and MCSPermutationStrategy::recompute not actually overriding the base.
  • Expands/updates tests to cover previously excluded paths (Delta2D, LBN/LBN+) and documents the MCS override fix.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_upper.cpp Updates golden-test commentary to reflect the fixed MCS override behavior.
tests/test_serialization.cpp Switches test set type to boost::unordered_flat_set to match updated APIs.
tests/test_lower.cpp Adds coverage for Delta2D and LBN/LBN+ now that key correctness fixes are in place.
tests/test_graph.cpp Switches to boost::unordered_flat_set and adds a regression test for isolated-node get_neighbours.
include/treewidth/TreeDecomposition.h Uses flat containers and reduces copying (emplace_back, avoids bag copy in output).
include/treewidth/PermutationStrategy.h Introduces clear() and updates recompute signature/container types.
include/treewidth/MetaLowerBoundHeuristic.h Adds missing virtual destructor.
include/treewidth/MCSPermutationStrategy.h Fixes override signature and adds override.
include/treewidth/LowerBoundMMD.h Updates to LowerBound graph-pointer model and flat set types.
include/treewidth/LowerBound.h Makes LowerBound::graph rebindable via pointer; adds virtual destructor; updates MMD+ implementation.
include/treewidth/LBN.h Attempts to avoid destructive-base side effects by estimating on disposable graph copies.
include/treewidth/Graph.h Migrates to flat containers; optimizes neighbour-improvement; fixes isolated-node get_neighbours; makes contract_edge safe under mutation.
include/treewidth/FillInPermutationStrategy.h Updates recompute signature and eliminates unnecessary set copies.
include/treewidth/Delta2D.h Clears shared strategy queue between per-node runs to prevent desync; updates to graph-pointer model.
include/treewidth/CE.h Moves contraction to occur once after selection loop (but introduces an edge case regression; see comments).
include/treewidth/Bag.h Updates constructor to accept boost::unordered_flat_set.
CMakeLists.txt Adds -Woverloaded-virtual to help catch override/signature bugs.
Comments suppressed due to low confidence (1)

include/treewidth/CE.h:37

  • con_edge() now calls graph.contract_edge(min_v, node) unconditionally after the neighbour-selection loop. If the chosen node has no neighbours (neigh is empty), min_v stays at its default 0 and the function will attempt to contract a non-existent edge (behavior changed vs. previous code where no contraction happened when neigh was empty). Add an early return when neigh is empty to preserve the old behavior and avoid contracting an invalid edge.
    boost::unordered_flat_set<unsigned long> neigh = graph.get_neighbours(node);
    //getting the neighbour with least overlap
    unsigned long min_v = 0;
    unsigned long min_ovl = neigh.size();
    for(auto v:neigh){

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread include/treewidth/LBN.h
Comment on lines +39 to 44
//estimate on a disposable copy: the base bound is destructive, and
//graph_temp (the neighbour-improved graph) must survive to the next
//iteration (cf. LBNPlus, which likewise copies into graph_temp1)
Graph graph_temp_eval = graph_temp;
lower_bound.setGraph(graph_temp_eval);
unsigned long lower_temp = lower_bound.estimate();
@smaniu
smaniu merged commit 9a5da33 into master Jul 19, 2026
5 checks passed
@smaniu
smaniu deleted the optimization branch July 20, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants