Skip to content

Commit

Permalink
[mlir][Transforms] GreedyPatternRewriteDriver: Worklist randomizer
Browse files Browse the repository at this point in the history
Instead of always taking the last op from the worklist, take a random one. For testing/debugging purposes only. This feature can be used to ensure that lowering pipelines work correctly regardless of the order in which ops are processed by the GreedyPatternRewriteDriver.

The randomizer can be enabled by setting a numeric `MLIR_GREEDY_REWRITE_RANDOMIZER_SEED` option.

Note: When enabled, 27 tests are currently failing. Partly because FileCheck tests are looking for exact IR.

Discussion: https://discourse.llvm.org/t/discussion-fuzzing-pattern-application/67911

Differential Revision: https://reviews.llvm.org/D142447
  • Loading branch information
matthias-springer committed May 31, 2023
1 parent 6614d36 commit ce954e1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
7 changes: 7 additions & 0 deletions mlir/include/mlir/Config/mlir-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@
easier debugging. */
#cmakedefine01 MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS

/* If set, greedy pattern application is randomized: ops on the worklist are
chosen at random. For testing/debugging purposes only. This feature can be
used to ensure that lowering pipelines work correctly regardless of the order
in which ops are processed by the GreedyPatternRewriteDriver. This flag is
numeric seed that is passed to the random number generator. */
#cmakedefine MLIR_GREEDY_REWRITE_RANDOMIZER_SEED ${MLIR_GREEDY_REWRITE_RANDOMIZER_SEED}

#endif
41 changes: 40 additions & 1 deletion mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"

#ifdef MLIR_GREEDY_REWRITE_RANDOMIZER_SEED
#include <random>
#endif // MLIR_GREEDY_REWRITE_RANDOMIZER_SEED

using namespace mlir;

#define DEBUG_TYPE "greedy-rewriter"
Expand Down Expand Up @@ -165,7 +169,7 @@ class Worklist {
/// Reverse the worklist.
void reverse();

private:
protected:
/// The worklist of operations.
std::vector<Operation *> list;

Expand Down Expand Up @@ -225,6 +229,37 @@ void Worklist::reverse() {
map[list[i]] = i;
}

#ifdef MLIR_GREEDY_REWRITE_RANDOMIZER_SEED
/// A worklist that pops elements at a random position. This worklist is for
/// testing/debugging purposes only. It can be used to ensure that lowering
/// pipelines work correctly regardless of the order in which ops are processed
/// by the GreedyPatternRewriteDriver.
class RandomizedWorklist : public Worklist {
public:
RandomizedWorklist() : Worklist() {
generator.seed(MLIR_GREEDY_REWRITE_RANDOMIZER_SEED);
}

/// Pop a random non-empty op from the worklist.
Operation *pop() {
Operation *op = nullptr;
do {
assert(!list.empty() && "cannot pop from empty worklist");
int64_t pos = generator() % list.size();
op = list[pos];
list.erase(list.begin() + pos);
for (int64_t i = pos, e = list.size(); i < e; ++i)
map[list[i]] = i;
map.erase(op);
} while (!op);
return op;
}

private:
std::minstd_rand0 generator;
};
#endif // MLIR_GREEDY_REWRITE_RANDOMIZER_SEED

//===----------------------------------------------------------------------===//
// GreedyPatternRewriteDriver
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -272,7 +307,11 @@ class GreedyPatternRewriteDriver : public PatternRewriter,

/// The worklist for this transformation keeps track of the operations that
/// need to be (re)visited.
#ifdef MLIR_GREEDY_REWRITE_RANDOMIZER_SEED
RandomizedWorklist worklist;
#else
Worklist worklist;
#endif // MLIR_GREEDY_REWRITE_RANDOMIZER_SEED

/// Non-pattern based folder for operations.
OperationFolder folder;
Expand Down

0 comments on commit ce954e1

Please sign in to comment.