xref: /llvm-project/mlir/docs/Tools/mlir-reduce.md (revision 286a7a4023361aa63230596e88366c3d86776921)
17dec20dbSChia-hung Duan# MLIR Reduce
27dec20dbSChia-hung Duan
37dec20dbSChia-hung Duan[TOC]
47dec20dbSChia-hung Duan
57dec20dbSChia-hung DuanAn MLIR input may trigger bugs after series of transformations. To root cause
67dec20dbSChia-hung Duanthe problem or help verification after fixes, developers want to be able to
77dec20dbSChia-hung Duanreduce the size of a reproducer for a bug. This document describes
87dec20dbSChia-hung Duan`mlir-reduce`, which is similar to
97dec20dbSChia-hung Duan[bugpoint](https://llvm.org/docs/CommandGuide/bugpoint.html), a tool that can
107dec20dbSChia-hung Duanreduce the size of the input needed to trigger the error.
117dec20dbSChia-hung Duan
127dec20dbSChia-hung Duan`mlir-reduce` supports reducing the input in several ways, including simply
137dec20dbSChia-hung Duandeleting code not required to reproduce an error, applying the reducer
147dec20dbSChia-hung Duanpatterns heuristically or run with optimization passes to reduce the input. To
157dec20dbSChia-hung Duanuse it, the first thing you need to do is, provide a command which tells if an
167dec20dbSChia-hung Duaninput is interesting, e.g., exhibits the characteristics that you would like to
177dec20dbSChia-hung Duanfocus on. For example, you may want to see if `mlir-opt` invocation fails after
187dec20dbSChia-hung Duanit runs on the certain MLIR input. Afterwards, select your reduction strategy
19*286a7a40SMarkus Böckthen `mlir-reduce` will do the remaining works for you.
207dec20dbSChia-hung Duan
217dec20dbSChia-hung Duan## How to Use it
227dec20dbSChia-hung Duan
2370eb3bffSChia-hung Duan`mlir-reduce` adopts the reduction-tree algorithm to reduce the input. It
2470eb3bffSChia-hung Duangenerates several reduced outputs and further reduces in between them according
257dec20dbSChia-hung Duanto the tree traversal strategy. The different strategies may lead to different
2670eb3bffSChia-hung Duanresults and different time complexity. You can run as
277dec20dbSChia-hung Duan`-reduction-tree='traversal-mode=0'` to select the mode for example.
287dec20dbSChia-hung Duan
2970eb3bffSChia-hung Duan### Write the script for testing interestingness
307dec20dbSChia-hung Duan
3170eb3bffSChia-hung DuanAs mentioned, you need to provide a command to `mlir-reduce` which identifies
3270eb3bffSChia-hung Duancases you're interested in. For each intermediate output generated during
3370eb3bffSChia-hung Duanreduction, `mlir-reduce` will run the command over the it, the script should
3470eb3bffSChia-hung Duanreturns 1 for interesting case, 0 otherwise. The sample script,
357dec20dbSChia-hung Duan
367dec20dbSChia-hung Duan```shell
377dec20dbSChia-hung Duanmlir-opt -convert-vector-to-spirv $1 | grep "failed to materialize"
387dec20dbSChia-hung Duanif [[ $? -eq 1 ]]; then
397dec20dbSChia-hung Duan  exit 1
407dec20dbSChia-hung Duanelse
417dec20dbSChia-hung Duan  exit 0
427dec20dbSChia-hung Duanfi
437dec20dbSChia-hung Duan```
447dec20dbSChia-hung Duan
457dec20dbSChia-hung DuanThe sample usage will be like, note that the `test` argument is part of the mode
467dec20dbSChia-hung Duanargument.
477dec20dbSChia-hung Duan
487dec20dbSChia-hung Duan```shell
497dec20dbSChia-hung Duanmlir-reduce $INPUT -reduction-tree='traversal-mode=0 test=$TEST_SCRIPT'
507dec20dbSChia-hung Duan```
517dec20dbSChia-hung Duan
527dec20dbSChia-hung Duan## Available reduction strategies
537dec20dbSChia-hung Duan
547dec20dbSChia-hung Duan### Operation elimination
557dec20dbSChia-hung Duan
567dec20dbSChia-hung Duan`mlir-reduce` will try to remove the operations directly. This is the most
577dec20dbSChia-hung Duanaggressive reduction as it may result in an invalid output as long as it ends up
587dec20dbSChia-hung Duanretaining the error message that the test script is interesting. To avoid that,
597dec20dbSChia-hung Duan`mlir-reduce` always checks the validity and it expects the user will provide a
607dec20dbSChia-hung Duanvalid input as well.
617dec20dbSChia-hung Duan
627dec20dbSChia-hung Duan### Rewrite patterns into simpler forms
637dec20dbSChia-hung Duan
647dec20dbSChia-hung DuanIn some cases, rewrite an operation into a simpler or smaller form can still
657dec20dbSChia-hung Duanretain the interestingness. For example, `mlir-reduce` will try to rewrite a
667dec20dbSChia-hung Duan`tensor<?xindex>` with unknown rank into a constant rank one like
677dec20dbSChia-hung Duan`tensor<1xi32>`. Not only produce a simpler operation, it may introduce further
687dec20dbSChia-hung Duanreduction chances because of precise type information.
697dec20dbSChia-hung Duan
707dec20dbSChia-hung DuanMLIR supports dialects and `mlir-reduce` supports rewrite patterns for every
717dec20dbSChia-hung Duandialect as well. Which means you can have the dialect specific rewrite patterns.
727dec20dbSChia-hung DuanTo do that, you need to implement the `DialectReductionPatternInterface`. For
737dec20dbSChia-hung Duanexample,
747dec20dbSChia-hung Duan
757dec20dbSChia-hung Duan```c++
767dec20dbSChia-hung Duan#include "mlir/Reducer/ReductionPatternInterface.h"
777dec20dbSChia-hung Duan
787dec20dbSChia-hung Duanstruct MyReductionPatternInterface : public DialectReductionPatternInterface {
797dec20dbSChia-hung Duan  virtual void
807dec20dbSChia-hung Duan  populateReductionPatterns(RewritePatternSet &patterns) const final {
817dec20dbSChia-hung Duan    populateMyReductionPatterns(patterns);
827dec20dbSChia-hung Duan  }
837dec20dbSChia-hung Duan}
847dec20dbSChia-hung Duan```
857dec20dbSChia-hung Duan
867dec20dbSChia-hung Duan`mlir-reduce` will call `populateReductionPatterns` to collect the reduction
877dec20dbSChia-hung Duanrewrite patterns provided by each dialect. Here's a hint, if you use
887dec20dbSChia-hung Duan[DRR](../DeclarativeRewrites.md) to write the reduction patterns, you can
897dec20dbSChia-hung Duanleverage the method `populateWithGenerated` generated by `mlir-tblgen`.
907dec20dbSChia-hung Duan
917dec20dbSChia-hung Duan### Reduce with built-in optimization passes
927dec20dbSChia-hung Duan
937dec20dbSChia-hung DuanMLIR provides amount of transformation passes and some of them are useful for
947dec20dbSChia-hung Duanreducing the input size, e.g., Symbol-DCE. `mlir-reduce` will schedule them
957dec20dbSChia-hung Duanalong with above two strategies.
967dec20dbSChia-hung Duan
977dec20dbSChia-hung Duan## Build a custom mlir-reduce
987dec20dbSChia-hung Duan
997dec20dbSChia-hung DuanIn the cases of, 1. have defined a custom syntax, 2. the failure is specific to
1007dec20dbSChia-hung Duancertain dialects or 3. there's a dialect specific reducer patterns, you need to
1017dec20dbSChia-hung Duanbuild your own `mlir-reduce`. Link it with `MLIRReduceLib` and implement it
1027dec20dbSChia-hung Duanlike,
1037dec20dbSChia-hung Duan
1047dec20dbSChia-hung Duan```c++
1057dec20dbSChia-hung Duan#include "mlir/Tools/mlir-reduce/MlirReduceMain.h"
1067dec20dbSChia-hung Duanusing namespace mlir;
1077dec20dbSChia-hung Duan
1087dec20dbSChia-hung Duanint main(int argc, char **argv) {
1097dec20dbSChia-hung Duan  DialectRegistry registry;
1107dec20dbSChia-hung Duan  registerMyDialects(registry);
1117dec20dbSChia-hung Duan  // Register the DialectReductionPatternInterface if any.
1127dec20dbSChia-hung Duan  MLIRContext context(registry);
1137dec20dbSChia-hung Duan  return failed(mlirReduceMain(argc, argv, context));
1147dec20dbSChia-hung Duan}
1157dec20dbSChia-hung Duan
1167dec20dbSChia-hung Duan```
1177dec20dbSChia-hung Duan
1187dec20dbSChia-hung Duan## Future works
1197dec20dbSChia-hung Duan
1207dec20dbSChia-hung Duan`mlir-reduce` is missing several features,
1217dec20dbSChia-hung Duan
1227dec20dbSChia-hung Duan*   `-reduction-tree` now only supports `Single-Path` traversal mode, extends it
123*286a7a40SMarkus Böckwith different traversal strategies may reduce the input better.
124*286a7a40SMarkus Böck*   Produce the optimal result when interrupted. The reduction process may take
1257dec20dbSChia-hung Duana quite long time, it'll be better to get an optimal result so far while an
126*286a7a40SMarkus Böckinterrupt is triggered.
127