clusterlin tests: optimize clusterlin_simple_linearize

Whenever a non-topological permutation is encountered, fast forward to the
last permutation with the same non-topological prefix, skipping over
potentially many permutations that are non-topological for the same reason.

With that, increase the checking of all permutations to clusters of size 8
instead of 7.
This commit is contained in:
Pieter Wuille committed 2025-06-14 18:27:24 -04:00
1 parent 98c1c88b6f
commit 6e37824ac3
1 file changed
+16 -10
+16 -10
View File
@@ -972,27 +972,33 @@ FUZZ_TARGET(clusterlin_simple_linearize)
// If SimpleLinearize claims optimal result, and the cluster is sufficiently small (there are // If SimpleLinearize claims optimal result, and the cluster is sufficiently small (there are
// n! linearizations), test that the result is as good as every valid linearization. // n! linearizations), test that the result is as good as every valid linearization.
if (optimal && depgraph.TxCount() <= 7) { if (optimal && depgraph.TxCount() <= 8) {
std::vector<DepGraphIndex> perm_linearization; std::vector<DepGraphIndex> perm_linearization;
// Initialize with the lexicographically-first linearization. // Initialize with the lexicographically-first linearization.
for (DepGraphIndex i : depgraph.Positions()) perm_linearization.push_back(i); for (DepGraphIndex i : depgraph.Positions()) perm_linearization.push_back(i);
// Iterate over all valid permutations. // Iterate over all valid permutations.
do { do {
// Determine whether perm_linearization is topological. /** What prefix of perm_linearization is topological. */
DepGraphIndex topo_length{0};
TestBitSet perm_done; TestBitSet perm_done;
bool perm_is_topo{true}; while (topo_length < perm_linearization.size()) {
for (auto i : perm_linearization) { auto i = perm_linearization[topo_length];
perm_done.Set(i); perm_done.Set(i);
if (!depgraph.Ancestors(i).IsSubsetOf(perm_done)) { if (!depgraph.Ancestors(i).IsSubsetOf(perm_done)) break;
perm_is_topo = false; ++topo_length;
break;
}
} }
// If so, verify that the obtained linearization is as good as the permutation. if (topo_length == perm_linearization.size()) {
if (perm_is_topo) { // If all of perm_linearization is topological, verify that the obtained
// linearization is no worse than it.
auto perm_chunking = ChunkLinearization(depgraph, perm_linearization); auto perm_chunking = ChunkLinearization(depgraph, perm_linearization);
auto cmp = CompareChunks(simple_chunking, perm_chunking); auto cmp = CompareChunks(simple_chunking, perm_chunking);
assert(cmp >= 0); assert(cmp >= 0);
} else {
// Otherwise, fast forward to the last permutation with the same non-topological
// prefix.
auto first_non_topo = perm_linearization.begin() + topo_length;
assert(std::is_sorted(first_non_topo + 1, perm_linearization.end()));
std::reverse(first_non_topo + 1, perm_linearization.end());
} }
} while(std::next_permutation(perm_linearization.begin(), perm_linearization.end())); } while(std::next_permutation(perm_linearization.begin(), perm_linearization.end()));
} }