Skip to content
20 changes: 19 additions & 1 deletion lib/NeuraDialect/NeuraPasses.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
#include "mlir/Pass/PassManager.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Transforms/Passes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"

#include "Conversion/ConversionPasses.h"
#include "NeuraDialect/NeuraDialect.h"
#include "NeuraDialect/NeuraOps.h"
#include "NeuraDialect/NeuraPasses.h"
#include "NeuraDialect/NeuraTypes.h"

std::string filename = "opgraph.dot";
std::error_code EC;
llvm::raw_fd_ostream os(filename, EC, llvm::sys::fs::OF_Text);

// This pass pipeline can convert all the other dialects into the Neura dialect
void mlir::neura::registerNeuraConversionPassPipeline() {
PassPipelineRegistration<>(
Expand All @@ -17,5 +23,17 @@ void mlir::neura::registerNeuraConversionPassPipeline() {
// Convert all the other dialects into the Neura dialect
pm.addPass(mlir::createLowerArithToNeuraPass());
pm.addPass(mlir::createLowerLlvmToNeuraPass());
pm.addPass(mlir::createPrintOpGraphPass(os));

pm.addPass(mlir::neura::createCanonicalizeCastPass());
pm.addPass(mlir::neura::createCanonicalizeLiveInPass());
pm.addPass(mlir::neura::createLeveragePredicatedValuePass());
pm.addPass(mlir::createPrintOpGraphPass(os));

pm.addPass(mlir::neura::createTransformCtrlToDataFlowPass());
pm.addPass(mlir::neura::createFoldConstantPass());
pm.addPass(mlir::neura::createFusePatternPass());
pm.addPass(mlir::neura::createInsertDataMovPass());
pm.addPass(mlir::createPrintOpGraphPass(os));
});
}
}
28 changes: 28 additions & 0 deletions test/visualize/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# MLIR Code Visualization Guide

This guide explains how to visualize MLIR (Multi-Level Intermediate Representation) code using various tools and techniques.

## Usage

First, run `apt install graphviz` to install Graphviz. For an MLIR file, use the option `--view-op-graph` to generate a Graphviz visualization of a function. Then, use the `dot` command to create an image file from the visualization.

Example:

```bash
mlir-neura-opt --assign-accelerator --lower-arith-to-neura --fuse-pattern --view-op-graph test.mlir 2> test.dot
dot -Tpng test.dot -o test.png
```

It will generate a `test.png` file in the current directory, as shown below:

![test](test.png)

If there are multiple graphs in one dot file, you can use the option `-O` to generate multiple DFGs from one dot file.

Example:

```bash
dot -Tpng test.dot -O
```

It will generate `test.dot.png`, `test.dot.1.png`, `test.dot.2.png`, etc.
12 changes: 12 additions & 0 deletions test/visualize/test.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Test 1: Verify dot generation for fused operations
// RUN: mlir-neura-opt --assign-accelerator --lower-arith-to-neura --fuse-pattern --view-op-graph %s 2>&1 | FileCheck %s --check-prefix=CHECK-DOT-GENERATION

func.func @test_dot_generation(%a: f32, %b: f32, %c: f32) -> f32 {
%temp = arith.addf %a, %b : f32
%res = arith.addf %temp, %c : f32
// CHECK-DOT-GENERATION: digraph G
// CHECK-DOT-GENERATION: label = "func.func : ()\n\naccelerator: \"neura\"\nfunction_type: (f32, f32, f32) -> f...\nsym_name: \"test_dot_generation...";
// CHECK-DOT-GENERATION: label = "neura.fadd_fadd : (f32)\n"
return %res : f32
}

Binary file added test/visualize/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions test/visualize/test2.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Test PrintOpGraphPass in neura-compiler
// RUN: neura-compiler --neura-conversion %s
// RUN: FileCheck %s --input-file=%S/opgraph.dot -check-prefix=CHECK-GRAPH

func.func @test_print_op_graph(%a: f32, %b: f32) -> f32 {
%c = arith.constant 1.0 : f32
%d = arith.addf %a, %b : f32
%e = arith.mulf %d, %c : f32
return %e : f32
}

// CHECK-GRAPH: digraph G
// CHECK-GRAPH: compound = true;
// CHECK-GRAPH: label = "func.func : ()\n\naccelerator: \"neura\"\nfunction_type: (f32, f32) -> f32\nsym_name: \"test_print_op_graph...";
// CHECK-GRAPH: label = "neura.fadd : (f32)\n"
// CHECK-GRAPH: label = "neura.return : ()\n"
// CHECK-GRAPH: digraph G
// CHECK-GRAPH: label = "func.func : ()\n\naccelerator: \"neura\"\nfunction_type: (f32, f32) -> f32\nsym_name: \"test_print_op_graph...";
// CHECK-GRAPH: label = "neura.constant : (!neura.data<f32, i1>)
// CHECK-GRAPH: label = "neura.fadd : (!neura.data<f32, i1>)\n"
// CHECK-GRAPH: digraph G
// CHECK-GRAPH: label = "func.func : ()\n\naccelerator: \"neura\"\nfunction_type: (f32, f32) -> f32\nsym_name: \"test_print_op_graph...";
// CHECK-GRAPH: label = "neura.constant : (!neura.data<f32, i1>)
// CHECK-GRAPH: label = "neura.data_mov : (!neura.data<f32, i1>)
// CHECK-GRAPH: label = "neura.fadd : (!neura.data<f32, i1>)\n"
2 changes: 2 additions & 0 deletions test/visualize/visualize.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mlir-neura-opt --assign-accelerator --lower-arith-to-neura --fuse-pattern --view-op-graph test.mlir 2> test.dot
dot -Tpng test.dot -o test.png
1 change: 1 addition & 0 deletions tools/mlir-neura-opt/mlir-neura-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int main(int argc, char **argv) {

mlir::neura::registerPasses();
mlir::registerPasses();
mlir::registerViewOpGraphPass();

// Runs the MLIR optimizer.
return mlir::asMainReturnCode(
Expand Down