From 6e37824ac390835d3d9c82d197f58e992ccc584f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 25 Sep 2024 22:18:33 -0400 Subject: [PATCH] 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. --- src/test/fuzz/cluster_linearize.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/test/fuzz/cluster_linearize.cpp b/src/test/fuzz/cluster_linearize.cpp index 9ce7dbfd7d..4c7906a8b2 100644 --- a/src/test/fuzz/cluster_linearize.cpp +++ b/src/test/fuzz/cluster_linearize.cpp @@ -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 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())); }