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