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
2024-09-25 22:18:33 -04:00
parent 98c1c88b6f
commit 6e37824ac3

View File

@@ -972,27 +972,33 @@ FUZZ_TARGET(clusterlin_simple_linearize)
// 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.
if (optimal && depgraph.TxCount() <= 7) {
if (optimal && depgraph.TxCount() <= 8) {
std::vector<DepGraphIndex> perm_linearization;
// Initialize with the lexicographically-first linearization.
for (DepGraphIndex i : depgraph.Positions()) perm_linearization.push_back(i);
// Iterate over all valid permutations.
do {
// Determine whether perm_linearization is topological.
/** What prefix of perm_linearization is topological. */
DepGraphIndex topo_length{0};
TestBitSet perm_done;
bool perm_is_topo{true};
for (auto i : perm_linearization) {
while (topo_length < perm_linearization.size()) {
auto i = perm_linearization[topo_length];
perm_done.Set(i);
if (!depgraph.Ancestors(i).IsSubsetOf(perm_done)) {
perm_is_topo = false;
break;
}
if (!depgraph.Ancestors(i).IsSubsetOf(perm_done)) break;
++topo_length;
}
// If so, verify that the obtained linearization is as good as the permutation.
if (perm_is_topo) {
if (topo_length == perm_linearization.size()) {
// 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 cmp = CompareChunks(simple_chunking, perm_chunking);
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()));
}