---
# System prepended metadata

title: 766 Project

---

# 766 Project

## the structure of the code
```bash
llvm-project/mlir/examples/toy/766_Project
├── CMakeLists.txt
├── include
│    ├── CMakeLists.txt
│    └── rv
│        ├── AST.h
│        ├── CMakeLists.txt
│        ├── Dialect.h
│        ├── Lexer.h
│        ├── MLIRGen.h
│        ├── Ops.td
│        ├── Parser.h
│        ├── Passes.h
│        ├── ShapeInferenceInterface.h
│        └── ShapeInferenceInterface.td
├── mlir
│    ├── Dialect.cpp
│    ├── LowerToAffineLoops.cpp
│    ├── LowerToLinalg.cpp
│    ├── LowerToLLVM.cpp
│    ├── MLIRGen.cpp
│    ├── RvCombine.cpp
│    ├── RvCombine.td
│    └── ShapeInferencePass.cpp
├── parser
│    └── AST.cpp
└── rvc.cpp
```


## the instructions on how to install and compile it
- the following instructions for compiling and testing MLIR assume that you have `git`, `ninja` , and a working C++ toolchain (see [LLVM requirements](https://llvm.org/docs/GettingStarted.html#requirements) ).
```
tar -xvf llvm-project.tar
mkdir llvm-project/build
cd llvm-project/build
cmake -G Ninja ../llvm \
   -DLLVM_ENABLE_PROJECTS=mlir \
   -DLLVM_BUILD_EXAMPLES=ON \
   -DLLVM_TARGETS_TO_BUILD="X86;NVPTX;AMDGPU" \
   -DCMAKE_BUILD_TYPE=Release \
   -DLLVM_ENABLE_ASSERTIONS=ON

cmake --build . --target check-mlir
```


## how to execute it and the output result

- Example rv language file: (loc:`llvm-project/`)


    ```
    def main() {
      var a = random([3,3]);
      var b = mirror(a);
      var c = mirror(c);
      print(c);
    }
    ```
- output the AST dump
    ```bash
    $ cd llvm-project/build
    $ ./bin/rvcompiler ../Project.rv -emit=ast
    ```
    - Result
    ```
      Module:
        Function 
          Proto 'main' @../Project.rv:1:1'
          Params: []
          Block {
            VarDecl a<> @../Project.rv:2:3
              Call 'random' [ @../Project.rv:2:11
                Literal: <2>[ 3.000000e+00, 3.000000e+00] @../Project.rv:2:18
              ]
            VarDecl b<> @../Project.rv:3:3
              Call 'mirror' [ @../Project.rv:3:11
                var: a @../Project.rv:3:18
              ]
            VarDecl c<> @../Project.rv:4:3
              Call 'mirror' [ @../Project.rv:4:11
                var: c @../Project.rv:4:18
              ]
            Print [ @../Project.rv:5:3
              var: c @../Project.rv:5:9
            ]
          } // Block
    ```
- output the RV MLIR dump
    ```bash
    $ cd llvm-project/build
    $ ./bin/rvcompiler ../Project.rv -emit=mlir
    ```
    - Result
    ```
    module {
      func @main() {
        %0 = rv.constant dense<[[0.58667810009172094, 0.18284343424385574, 0.74184698692608952], [0.26800174977071667, 0.49109666398311808, 0.52816471295811451], [0.93644980384802901, 0.050125705567247096, 0.45304548947748052]]> : tensor<3x3xf64>
        %1 = rv.random(%0 : tensor<3x3xf64>) to tensor<3x3xf64>
        %2 = rv.mirror(%1 : tensor<3x3xf64>) to tensor<*xf64>
        %3 = rv.mirror(%2 : tensor<*xf64>) to tensor<*xf64>
        rv.print %3 : tensor<*xf64>
        rv.return
      }
    }
    ```
- output the optimized RV MLIR dump
    ```bash
    $ cd llvm-project/build
    $ ./bin/rvcompiler ../Project.rv -emit=mlir -opt
    ```
    - Result
    ```
    module {
      func @main() {
        %0 = rv.constant dense<[[0.56669999732016585, 0.67866260589969463, 0.15685468686598106], [0.98641828866043046, 0.94971041099620535, 0.17802006247361193], [0.53551200802228971, 0.61328230873368783, 0.99628740828311412]]> : tensor<3x3xf64>
        rv.print %0 : tensor<3x3xf64>
        rv.return
      }
    }
    ```
- output the MLIR dump after affine lowering
    ```bash
    $ cd llvm-project/build
    $ ./bin/rvcompiler ../Project.rv -emit=mlir-affine
    ```
    - Result
    ```
    #map0 = affine_map<() -> (0, 0)>
    #map1 = affine_map<() -> (0, 1)>
    #map2 = affine_map<() -> (0, 2)>
    #map3 = affine_map<() -> (1, 0)>
    #map4 = affine_map<() -> (1, 1)>
    #map5 = affine_map<() -> (1, 2)>
    #map6 = affine_map<() -> (2, 0)>
    #map7 = affine_map<() -> (2, 1)>
    #map8 = affine_map<() -> (2, 2)>


    module {
      func @main() {
        %cst = constant 0.36338698834338551 : f64
        %cst_0 = constant 0.530150028192508 : f64
        %cst_1 = constant 0.82920207866896045 : f64
        %cst_2 = constant 0.29569983263299793 : f64
        %cst_3 = constant 0.16361790670250445 : f64
        %cst_4 = constant 0.031894812840919391 : f64
        %cst_5 = constant 0.50437756465020478 : f64
        %cst_6 = constant 0.2924746029509579 : f64
        %cst_7 = constant 0.85389933216101455 : f64
        %0 = alloc() : memref<3x3xf64>
        affine.store %cst, %0[0, 0] : memref<3x3xf64>
        affine.store %cst_0, %0[0, 1] : memref<3x3xf64>
        affine.store %cst_1, %0[0, 2] : memref<3x3xf64>
        affine.store %cst_2, %0[1, 0] : memref<3x3xf64>
        affine.store %cst_3, %0[1, 1] : memref<3x3xf64>
        affine.store %cst_4, %0[1, 2] : memref<3x3xf64>
        affine.store %cst_5, %0[2, 0] : memref<3x3xf64>
        affine.store %cst_6, %0[2, 1] : memref<3x3xf64>
        affine.store %cst_7, %0[2, 2] : memref<3x3xf64>
        rv.print %0 : memref<3x3xf64>
        dealloc %0 : memref<3x3xf64>
        return
      }
    }
    ```
- output the MLIR dump after llvm lowering
    ```bash
    $ cd llvm-project/build
    $ ./bin/rvcompiler ../Project.rv -emit=mlir-llvm
    ```
    - Result:
        - (It is too long, so omit here.)
        
## More Test cases

### Simplify Redundant Mirror
- code location: 'testRV/RvMirrorOpToMLIR.rv'
```
$ ./bin/rvcompiler ../testRV/RvMirrorOpToMLIR.rv -emit=mlir


module {
  func @main() {
    %0 = rv.constant dense<[[0.99055617581613187, 0.4577125503950345, 0.78588427779538761], [0.31036054264305185, 0.28437613103742532, 0.87492007616670808], [0.62184807407755782, 0.39391030715494896, 0.59313715276920109]]> : tensor<3x3xf64>
    %1 = rv.random(%0 : tensor<3x3xf64>) to tensor<3x3xf64>
    %2 = rv.mirror(%1 : tensor<3x3xf64>) to tensor<*xf64>
    %3 = rv.mirror(%2 : tensor<*xf64>) to tensor<*xf64>
    rv.print %3 : tensor<*xf64>
    rv.return
  }
}

$ ./bin/rvcompiler ../testRV/RvMirrorOpToMLIR.rv -emit=mlir -opt


module {
  func @main() {
    %0 = rv.constant dense<[[0.83912366388324821, 0.44261707386123811, 0.33018950667706759], [0.76750983147300311, 0.76841511566583776, 0.2553054374900206], [0.91140548834176993, 0.16412140716059198, 0.11435252153982992]]> : tensor<3x3xf64>
    rv.print %0 : tensor<3x3xf64>
    rv.return
  }
}
```

### Combine GaussianBlur
- code loc: `testRV/CombineGaussianBlur.rv`
```
$ ./bin/rvcompiler ../testRV/CombineGaussianBlur.rv -emit=mlir


module {
  func @main() {
    %0 = rv.constant dense<[[0.67344053959168515, 0.60641465643719517, 0.99606582522209075, 0.12589796405560241, 0.26318976807556571], [0.24713234288950095, 0.10807281830723994, 0.34380397170027904, 0.20951433815505091, 0.88062222948326829], [0.35679883712753602, 0.13027272984863852, 0.54567724491733927, 0.21244211039153957, 0.86181090067225086], [0.65601056379080314, 0.55368729892824187, 0.52028686810298208, 0.97748306858236111, 0.37388746131858203], [0.78387898243213028, 0.041873124447592128, 0.68098003123001194, 0.60820046840617459, 0.57949002626328261]]> : tensor<5x5xf64>
    %1 = rv.random(%0 : tensor<5x5xf64>) to tensor<5x5xf64>
    %2 = rv.constant dense<[[0.10699730205096369, 0.11310981661256507, 0.10699730205096369], [0.11310981661256507, 0.11957152534588486, 0.11310981661256507], [0.10699730205096369, 0.11310981661256507, 0.10699730205096369]]> : tensor<3x3xf64>
    %3 = rv.GaussianBlur(%1 : tensor<5x5xf64>, %2 : tensor<3x3xf64>) {padding = dense<5> : tensor<2xi64>, sigma = 3 : i64, strides = dense<1> : tensor<2xi64>} to tensor<3x3xf64>
    %4 = rv.constant dense<[[0.10879654809508495, 0.11225012125576295, 0.10879654809508495], [0.11225012125576295, 0.11581332259660831, 0.11225012125576295], [0.10879654809508495, 0.11225012125576295, 0.10879654809508495]]> : tensor<3x3xf64>
    %5 = rv.GaussianBlur(%3 : tensor<3x3xf64>, %4 : tensor<3x3xf64>) {padding = dense<3> : tensor<2xi64>, sigma = 4 : i64, strides = dense<1> : tensor<2xi64>} to tensor<3x3xf64>
    rv.print %5 : tensor<3x3xf64>
    rv.return
  }
}

$ ./bin/rvcompiler ../testRV/CombineGaussianBlur.rv -emit=mlir -opt


module {
  func @main() {
    %0 = rv.constant dense<[[0.29288132036704634, 0.30376146095980028, 0.99648759001702424, 0.29114217324701241, 0.25695968664109692], [0.63820080581968686, 0.32812325345730559, 0.055664444368176372, 0.31803894383741493, 0.099620419135140456], [0.71789624668559815, 0.28239718511812256, 0.297198178385011, 0.18178490092129676, 0.043054022846302963], [0.62430311209722567, 0.45766726436916144, 0.56298474807431209, 0.32387286858813508, 0.028098788125486482], [0.034474765432288293, 0.60848261630557599, 0.89383727633107324, 0.71201962265745722, 0.31161820157972081]]> : tensor<5x5xf64>
    %1 = rv.constant dense<[[0.10962969557990561, 0.11184436233734502, 0.10962969557990561], [0.11184436233734502, 0.1141037683309974, 0.11184436233734502], [0.10962969557990561, 0.11184436233734502, 0.10962969557990561]]> : tensor<3x3xf64>
    %2 = rv.GaussianBlur(%0 : tensor<5x5xf64>, %1 : tensor<3x3xf64>) {padding = dense<5> : tensor<2xi64>, sigma = 5 : i64, strides = dense<1> : tensor<2xi64>} to tensor<3x3xf64>
    rv.print %2 : tensor<3x3xf64>
    rv.return
  }
}

$ ./bin/rvcompiler ../testRV/CombineGaussianBlur.rv -emit=mlir-affine
#map0 = affine_map<() -> (0, 0)>
#map1 = affine_map<() -> (0, 1)>
#map2 = affine_map<() -> (0, 2)>
#map3 = affine_map<() -> (0, 3)>
#map4 = affine_map<() -> (0, 4)>
#map5 = affine_map<() -> (1, 0)>
#map6 = affine_map<() -> (1, 1)>
#map7 = affine_map<() -> (1, 2)>
#map8 = affine_map<() -> (1, 3)>
#map9 = affine_map<() -> (1, 4)>
#map10 = affine_map<() -> (2, 0)>
#map11 = affine_map<() -> (2, 1)>
#map12 = affine_map<() -> (2, 2)>
#map13 = affine_map<() -> (2, 3)>
#map14 = affine_map<() -> (2, 4)>
#map15 = affine_map<() -> (3, 0)>
#map16 = affine_map<() -> (3, 1)>
#map17 = affine_map<() -> (3, 2)>
#map18 = affine_map<() -> (3, 3)>
#map19 = affine_map<() -> (3, 4)>
#map20 = affine_map<() -> (4, 0)>
#map21 = affine_map<() -> (4, 1)>
#map22 = affine_map<() -> (4, 2)>
#map23 = affine_map<() -> (4, 3)>
#map24 = affine_map<() -> (4, 4)>


module {
  func @main() {
    %cst = constant 0.51559695718604925 : f64
    %cst_0 = constant 0.18705926890813712 : f64
    %cst_1 = constant 0.94873884597268832 : f64
    %cst_2 = constant 0.50935973530139766 : f64
    %cst_3 = constant 0.95965838523565716 : f64
    %cst_4 = constant 0.47740535460291678 : f64
    %cst_5 = constant 0.10207996708437798 : f64
    %cst_6 = constant 0.022548819902608552 : f64
    %cst_7 = constant 0.44302081896132828 : f64
    %cst_8 = constant 0.88069220533626724 : f64
    %cst_9 = constant 0.27709743952243471 : f64
    %cst_10 = constant 0.47627130731766637 : f64
    %cst_11 = constant 0.76278520457576271 : f64
    %cst_12 = constant 0.11869498301236657 : f64
    %cst_13 = constant 0.10749559202580508 : f64
    %cst_14 = constant 0.88861018972872297 : f64
    %cst_15 = constant 0.24225702939660151 : f64
    %cst_16 = constant 0.95543529044624198 : f64
    %cst_17 = constant 0.96225318217754974 : f64
    %cst_18 = constant 0.19989876877511795 : f64
    %cst_19 = constant 0.088242317125314065 : f64
    %cst_20 = constant 0.54657876563564822 : f64
    %cst_21 = constant 0.67054864702306161 : f64
    %cst_22 = constant 0.43745769580707777 : f64
    %cst_23 = constant 0.88744083321068479 : f64
    %cst_24 = constant 0.1141037683309974 : f64
    %cst_25 = constant 0.11184436233734502 : f64
    %cst_26 = constant 0.10962969557990561 : f64
    %0 = alloc() : memref<3x3xf64>
    %1 = alloc() : memref<3x3xf64>
    %2 = alloc() : memref<5x5xf64>
    affine.store %cst, %2[0, 0] : memref<5x5xf64>
    affine.store %cst_0, %2[0, 1] : memref<5x5xf64>
    affine.store %cst_1, %2[0, 2] : memref<5x5xf64>
    affine.store %cst_2, %2[0, 3] : memref<5x5xf64>
    affine.store %cst_3, %2[0, 4] : memref<5x5xf64>
    affine.store %cst_4, %2[1, 0] : memref<5x5xf64>
    affine.store %cst_5, %2[1, 1] : memref<5x5xf64>
    affine.store %cst_6, %2[1, 2] : memref<5x5xf64>
    affine.store %cst_7, %2[1, 3] : memref<5x5xf64>
    affine.store %cst_8, %2[1, 4] : memref<5x5xf64>
    affine.store %cst_9, %2[2, 0] : memref<5x5xf64>
    affine.store %cst_10, %2[2, 1] : memref<5x5xf64>
    affine.store %cst_11, %2[2, 2] : memref<5x5xf64>
    affine.store %cst_12, %2[2, 3] : memref<5x5xf64>
    affine.store %cst_13, %2[2, 4] : memref<5x5xf64>
    affine.store %cst_14, %2[3, 0] : memref<5x5xf64>
    affine.store %cst_15, %2[3, 1] : memref<5x5xf64>
    affine.store %cst_16, %2[3, 2] : memref<5x5xf64>
    affine.store %cst_17, %2[3, 3] : memref<5x5xf64>
    affine.store %cst_18, %2[3, 4] : memref<5x5xf64>
    affine.store %cst_19, %2[4, 0] : memref<5x5xf64>
    affine.store %cst_20, %2[4, 1] : memref<5x5xf64>
    affine.store %cst_21, %2[4, 2] : memref<5x5xf64>
    affine.store %cst_22, %2[4, 3] : memref<5x5xf64>
    affine.store %cst_23, %2[4, 4] : memref<5x5xf64>
    affine.store %cst_26, %1[0, 0] : memref<3x3xf64>
    affine.store %cst_25, %1[0, 1] : memref<3x3xf64>
    affine.store %cst_26, %1[0, 2] : memref<3x3xf64>
    affine.store %cst_25, %1[1, 0] : memref<3x3xf64>
    affine.store %cst_24, %1[1, 1] : memref<3x3xf64>
    affine.store %cst_25, %1[1, 2] : memref<3x3xf64>
    affine.store %cst_26, %1[2, 0] : memref<3x3xf64>
    affine.store %cst_25, %1[2, 1] : memref<3x3xf64>
    affine.store %cst_26, %1[2, 2] : memref<3x3xf64>
    linalg.conv(%1, %2, %0) {padding = dense<5> : tensor<2xi64>} : memref<3x3xf64>, memref<5x5xf64>, memref<3x3xf64>
    rv.print %0 : memref<3x3xf64>
    dealloc %2 : memref<5x5xf64>
    dealloc %1 : memref<3x3xf64>
    dealloc %0 : memref<3x3xf64>
    return
  }
}
```
### Combine Multiple Circle
- code loc: `testRV/CombineMultipleCircle.rv`
```
$ ./bin/rvcompiler ../testRV/CombineMultipleCircle.rv -emit=mlir


module {
  func @main() {
    %0 = rv.constant dense<[[0.052338750125998049, 0.64989800641774109, 0.0046459441094873211, 0.54073891301673782, 0.39148174989571877, 0.79864054303552978, 0.99955046037191075, 0.36500339972088269, 0.27019363561188503, 0.88287511043384448], [0.19335292894083678, 0.68918886254038147, 0.29121645600125962, 0.79810090819285295, 0.7126213757845673, 0.27418302664262384, 0.95735016975428455, 0.03888110119797341, 0.15100295802159372, 0.92471321063335665], [0.37891601323099622, 0.8680040016155709, 0.22377969009046428, 0.45873787461721238, 0.35592405887130835, 0.061973160627285556, 0.1229355522072574, 0.70399386887624571, 0.60615416132200239, 0.52734504897489443], [0.9261531219473822, 0.65849291144800037, 0.17724305492697426, 0.93079906652253075, 0.19923182399907699, 0.56872480528835434, 0.72943960909239924, 0.19878228390532651, 0.93372820500923703, 0.99963324470428438], [0.081657393873509662, 0.12708113348441252, 0.68882210677900446, 0.37287384987476929, 0.92518204167726548, 0.40144348256357176, 0.64705687651739308, 0.88253221096588863, 0.44032458376154515, 0.79805983453898688], [0.80724542113358411, 0.81924059745820266, 0.66606383568889638, 0.031025111224048357, 0.27797847160975375, 0.021987894560204769, 0.092998271851333913, 0.40091402381701119, 0.72598176343645049, 0.69915243317333631], [0.92825907279190567, 0.6521348849181714, 0.35764534415567545, 0.1055021277188799, 0.58293395097504086, 0.55687716815475241, 0.67422693300723424, 0.31237355960177887, 0.7556594520600789, 0.60795513755080999], [0.31200680430606326, 0.83731684593358857, 0.73503627103522251, 8.2891061940645362E-4, 0.2101906953426966, 0.66021831271248788, 0.40227239318297819, 0.85724757186008971, 0.54275052321271533, 0.84259697741018468], [0.65530740593341519, 0.34999594434629938, 0.66183757440272606, 0.32137124162231162, 0.38102105557034771, 0.93981604601247981, 0.3433591361825164, 0.47401932742168162, 0.34073006936382971, 0.06934089915330563], [0.17317176012935664, 0.26898914169007404, 0.72147578407147706, 0.53081710428503204, 0.37449126940895394, 0.30440973504651792, 0.087694271974123203, 0.048718201950526889, 0.61678329464829684, 0.84335372403420217]]> : tensor<10x10xf64>
    %1 = rv.random(%0 : tensor<10x10xf64>) to tensor<10x10xf64>
    %2 = rv.constant dense<[2.000000e+00, 3.000000e+00, 1.000000e+00]> : tensor<3xf64>
    %3 = rv.circle(%1 : tensor<10x10xf64>, %2 : tensor<3xf64>) to tensor<*xf64>
    %4 = rv.constant dense<[5.000000e+00, 2.000000e+00, 2.000000e+00]> : tensor<3xf64>
    %5 = rv.circle(%3 : tensor<*xf64>, %4 : tensor<3xf64>) to tensor<*xf64>
    rv.print %5 : tensor<*xf64>
    rv.return
  }
}

$ ./bin/rvcompiler ../testRV/CombineMultipleCircle.rv -emit=mlir -opt


module {
  func @main() {
    %0 = rv.constant dense<[[0.64765742777272006, 0.67752968365211486, 0.65570394166545198, 0.98605263511932117, 0.77609078342844307, 0.56004858275877711, 0.64116273570859927, 0.38740969467321862, 0.47261733490629931, 0.32759465432148177], [0.36231244092914855, 0.95250395170995217, 0.62013140489353402, 0.18748135035274613, 0.083303363566893787, 0.59638624759222669, 0.05539660530881798, 0.54754824077130682, 0.44699716216279062, 0.1885543787798632], [0.62833051645584892, 0.054540227658366892, 0.68632095897864598, 0.79068238511247668, 0.77761114797443676, 0.72734427765353782, 0.21600443973019925, 0.050662315008538919, 0.19910879675257429, 0.39439125191159141], [0.42711609295900727, 0.84676622452529438, 0.071920935563706295, 0.082820034158797948, 0.83281885964461544, 0.84801171899214933, 0.64286861691757502, 0.47398159488755354, 0.23542141319970666, 0.11548595182387436], [0.80157624920903525, 0.59773385412885516, 0.067989903068165256, 0.42170765363690799, 0.7852152049472626, 0.15129326663505904, 0.018093901229134714, 0.84061181025608056, 0.69884150787202715, 0.46509106339192535], [0.029166189035943799, 0.32717202386221478, 0.51963129105029227, 0.71548714801458979, 0.1178544085090302, 0.29724243855906762, 0.44283142520246627, 0.33385884870489074, 0.34790475356760658, 0.64194022195504052], [0.7282501006164821, 0.77502084652661385, 0.48870644648033496, 0.80017103618018848, 0.85784088115107304, 0.32152530565928916, 0.64818275470667652, 0.50070949760298689, 0.7955069005468427, 0.88360416837204436], [0.61619544942686122, 0.59708314929021666, 0.48133802203523834, 0.68418535249502643, 0.018790802461463401, 0.26655322651683971, 0.83547861959574676, 0.036884703690598118, 0.1071650367729203, 0.53432012700211262], [0.50197576708252345, 0.13633122580886409, 0.8614921508643274, 0.021607058132815667, 0.85181837382345382, 0.97934655983901885, 0.31884949669188328, 0.29464979902592014, 0.31320540807824832, 0.66675425072515115], [0.93659002098096067, 0.041455508229069182, 0.44177509678610372, 0.42529646699563434, 0.84162654487491895, 0.29961597747151553, 0.74682177265492355, 0.48980929911593407, 0.80032547554016364, 0.54232867273610486]]> : tensor<10x10xf64>
    %1 = rv.constant dense<[[5.000000e+00, 2.000000e+00, 2.000000e+00], [2.000000e+00, 3.000000e+00, 1.000000e+00]]> : tensor<2x3xf64>
    %2 = rv.circle(%0 : tensor<10x10xf64>, %1 : tensor<2x3xf64>) to tensor<10x10xf64>
    rv.print %2 : tensor<10x10xf64>
    rv.return
  }
}
```
### Associative Filter2D
- code loc: `testRV/AssociativeFilter2D.rv`
```
$ ./bin/rvcompiler ../testRV/AssociativeFilter2D.rv -emit=mlir


module {
  func @main() {
    %0 = rv.constant dense<[[0.011816020594824115, 0.12111105263284923, 0.63275345351209555, 0.59839507220238219, 0.37992717622775918], [0.98069827537084852, 0.78184842820365374, 0.62402313697339185, 0.7863288208778616, 0.22235187898499514], [0.64592171490468164, 0.55090426725843189, 0.60769978100792499, 0.41096218415115132, 0.11732529388616109], [0.73390701074800779, 0.45394347349831066, 0.24604012409506371, 0.27218568337717358, 0.78217382160116633], [0.40811446560924614, 0.53025801644206882, 0.83413963338087294, 0.40715344036331097, 0.82290777742066779]]> : tensor<5x5xf64>
    %1 = rv.random(%0 : tensor<5x5xf64>) to tensor<5x5xf64>
    %2 = rv.constant dense<[[0.011816020594824115, 0.12111105263284923, 0.63275345351209555], [0.59839507220238219, 0.37992717622775918, 0.98069827537084852], [0.78184842820365374, 0.62402313697339185, 0.7863288208778616]]> : tensor<3x3xf64>
    %3 = rv.random(%2 : tensor<3x3xf64>) to tensor<3x3xf64>
    %4 = rv.constant dense<[[0.011816020594824115, 0.12111105263284923, 0.63275345351209555, 0.59839507220238219], [0.37992717622775918, 0.98069827537084852, 0.78184842820365374, 0.62402313697339185], [0.7863288208778616, 0.22235187898499514, 0.64592171490468164, 0.55090426725843189], [0.60769978100792499, 0.41096218415115132, 0.11732529388616109, 0.73390701074800779]]> : tensor<4x4xf64>
    %5 = rv.random(%4 : tensor<4x4xf64>) to tensor<4x4xf64>
    %6 = rv.filter2D(%1 : tensor<5x5xf64>, %3 : tensor<3x3xf64>) to tensor<*xf64>
    %7 = rv.filter2D(%6 : tensor<*xf64>, %5 : tensor<4x4xf64>) to tensor<*xf64>
    rv.print %7 : tensor<*xf64>
    rv.return
  }
}
$ ./bin/rvcompiler ../testRV/AssociativeFilter2D.rv -emit=mlir -opt


module {
  func @main() {
    %0 = rv.constant dense<[[0.39775953227549771, 0.21087086676194838, 0.29266868405634011, 0.64262042503925987, 0.93106558310383258], [0.34087031769606763, 0.2264572392341016, 0.11754525225495233, 0.0097290873572831448, 0.08769730203212113], [0.35779931645737928, 0.11592189740199683, 0.93961292921547446, 0.55435662789007489, 0.93674006542970434], [0.3496819731545085, 0.95471955880276837, 0.065017372865703596, 0.5285013371745596, 0.84942872070215114], [0.50632252008948597, 0.73059996251510451, 0.3044056451434296, 0.079425495620549416, 0.88316250819860142]]> : tensor<5x5xf64>
    %1 = rv.constant dense<[[0.39775953227549771, 0.21087086676194838, 0.29266868405634011], [0.64262042503925987, 0.93106558310383258, 0.34087031769606763], [0.2264572392341016, 0.11754525225495233, 0.0097290873572831448]]> : tensor<3x3xf64>
    %2 = rv.constant dense<[[0.39775953227549771, 0.21087086676194838, 0.29266868405634011, 0.64262042503925987], [0.93106558310383258, 0.34087031769606763, 0.2264572392341016, 0.11754525225495233], [0.0097290873572831448, 0.08769730203212113, 0.35779931645737928, 0.11592189740199683], [0.93961292921547446, 0.55435662789007489, 0.93674006542970434, 0.3496819731545085]]> : tensor<4x4xf64>
    %3 = rv.filter2D(%1 : tensor<3x3xf64>, %2 : tensor<4x4xf64>) to tensor<3x3xf64>
    %4 = rv.filter2D(%0 : tensor<5x5xf64>, %3 : tensor<3x3xf64>) to tensor<5x5xf64>
    rv.print %4 : tensor<5x5xf64>
    rv.return
  }
}
```

### knowing bugs and lemitations of the code
- Only GaussianBlur and mirror operation are able to be lowered into affine and llvm.
- Optimization for reordering GaussianBlur and resize have some error. 