Yosys Bug; Cannot handle smaller int
- Dominant language
- MLIR
- Stars
- 906
- Forks
- 171
- Avg merge
- 4d 12h
- Merged PRs (30d)
- 32
Description
I have been looking the past couple of days on how to compile a more strictly defined NN implementation down to a lut3/bool implementation through Yosys.
What I have found is that the a straight forward implementation that uses 8b throughout the implementation successfully generates a lowering. While if I use a 'growing' inference size definition, Yosys seems not be able to handles this, and generates an program that does not pass the arg0 to hoisted function anymore. And so, the canonicalizer, removes everything.
I've tested with the latest HEIR build, using `bazel run //tools:heir-opt -- --mlir-to-cggi --mlir-print-ir-after-all --debug`. Cleaned up dbg files, below; only the yosys pass:
[dbg_8b.txt](https://github.com/user-attachments/files/25572563/dbg_8b.txt)
[dbg_growing.txt](https://github.com/user-attachments/files/25572822/dbg_growing.txt)
I assume something goes wrong inside the RTLImporter?
Input 8b MLIR:
```
// 1. Conv2D Maps: (N, OutC, OutH, OutW, KH, KW)
#map_conv_in = affine_map<(d0, d1, d2, d3, d4, d5) -> (d0, 0, d2 + d4, d3 + d5)>
#map_conv_filt = affine_map<(d0, d1, d2, d3, d4, d5) -> (d1, 0, d4, d5)>
#map_conv_out = affine_map<(d0, d1, d2, d3, d4, d5) -> (d0, d1, d2, d3)>
// 2. Identity Map for ReLU
#map_identity = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2, d3)>
// 3. Fully Connected (Fused Flatten) Maps: (N, F_Out, C, H, W)
#map_fc_in = affine_map<(d0, d1, d2, d3, d4) -> (d0, d2, d3, d4)>
#map_fc_w = affine_map<(d0, d1, d2, d3, d4) -> (d2, d3, d4, d1)>
#map_fc_out = affine_map<(d0, d1, d2, d3, d4) -> (d0, d1)>
module attributes {tf_saved_model.semantics} {
func.func @main(%arg0: tensor<1x1x3x3xi8> {secret.secret}) -> tensor<1x2xi8> {
%zero_i8 = arith.constant 0 : i8
// --- Weights ---
// Conv Filter: OutC=1, InC=1, KH=2, KW=2
%w_conv2d = arith.constant dense<[[[[1, -1], [1, 0]]]]> : tensor<1x1x2x2xi8>
// FC Weights: InC=1, InH=2, InW=2, OutFeatures=2
%w_fc1 = arith.constant dense<[
[[[0, 1], [0, -1]], [[-1, 0], [-1, 0]]]
]> : tensor<1x2x2x2xi8>
// --- 1. Conv2D (3x3 -> 2x2) ---
%conv_init = arith.constant dense<0> : tensor<1x1x2x2xi8>
%conv1_out = linalg.generic {
indexing_maps = [#map_conv_in, #map_conv_filt, #map_conv_out],
iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"]
} ins(%arg0, %w_conv2d : tensor<1x1x3x3xi8>, tensor<1x1x2x2xi8>)
outs(%conv_init : tensor<1x1x2x2xi8>) {
^bb0(%in: i8, %filt: i8, %acc: i8):
%m = arith.muli %in, %filt : i8
%res = arith.addi %acc, %m : i8
linalg.yield %res : i8
} -> tensor<1x1x2x2xi8>
// --- 2. ReLU ---
%relu_init = arith.constant dense<0> : tensor<1x1x2x2xi8>
%relu_out = linalg.generic {
indexing_maps = [#map_identity, #map_identity],
iterator_types = ["parallel", "parallel", "parallel", "parallel"]
} ins(%conv1_out : tensor<1x1x2x2xi8>)
outs(%relu_init : tensor<1x1x2x2xi8>) {
^bb0(%in: i8, %out: i8):
%max = arith.maxsi %in, %zero_i8 : i8
linalg.yield %max : i8
} -> tensor<1x1x2x2xi8>
// --- 3. Fully Connected (Reduction over C, H, W) ---
%fc_init = arith.constant dense<0> : tensor<1x2xi8>
%final_out = linalg.generic {
indexing_maps = [#map_fc_in, #map_fc_w, #map_fc_out],
iterator_types = ["parallel", "parallel", "reduction", "reduction", "reduction"]
} ins(%relu_out, %w_fc1 : tensor<1x1x2x2xi8>, tensor<1x2x2x2xi8>)
outs(%fc_init : tensor<1x2xi8>) {
^bb0(%a_in: i8, %b_in: i8, %acc: i8):
%mul = arith.muli %a_in, %b_in : i8
%res = arith.addi %acc, %mul : i8
linalg.yield %res : i8
} -> tensor<1x2xi8>
return %final_out : tensor<1x2xi8>
}
}
```
The growing definition:
```
// 1. Conv2D Maps: (N, OutC, OutH, OutW, KH, KW)
#map_conv_in = affine_map<(d0, d1, d2, d3, d4, d5) -> (d0, 0, d2 + d4, d3 + d5)>
#map_conv_filt = affine_map<(d0, d1, d2, d3, d4, d5) -> (d1, 0, d4, d5)>
#map_conv_out = affine_map<(d0, d1, d2, d3, d4, d5) -> (d0, d1, d2, d3)>
// 2. Identity Map for ReLU
#map_identity = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2, d3)>
// 3. Fully Connected (Fused Flatten) Maps: (N, F_Out, C, H, W)
#map_fc_in = affine_map<(d0, d1, d2, d3, d4) -> (d0, d2, d3, d4)>
#map_fc_w = affine_map<(d0, d1, d2, d3, d4) -> (d2, d3, d4, d1)>
#map_fc_out = affine_map<(d0, d1, d2, d3, d4) -> (d0, d1)>
module attributes {tf_saved_model.semantics} {
func.func @main(%arg0: tensor<1x1x3x3xi2> {secret.secret}) -> tensor<1x2xi8> {
%zero_i4 = arith.constant 0 : i4
// --- Weights ---
// Conv Filter: OutC=1, InC=1, KH=2, KW=2
%w_conv2d = arith.constant dense<[[[[1, -1], [1, 0]]]]> : tensor<1x1x2x2xi2>
// FC Weights: InC=1, InH=2, InW=2, OutFeatures=2
%w_fc1 = arith.constant dense<[
[[[0, 1], [0, -1]], [[-1, 0], [-1, 0]]]
]> : tensor<1x2x2x2xi2>
// --- 1. Conv2D (3x3 -> 2x2) ---
%conv_init = arith.constant dense<0> : tensor<1x1x2x2xi4>
%conv1_out = linalg.generic {
indexing_maps = [#map_conv_in, #map_conv_filt, #map_conv_out],
iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"]
} ins(%arg0, %w_conv2d : tensor<1x1x3x3xi2>, tensor<1x1x2x2xi2>)
outs(%conv_init : tensor<1x1x2x2xi4>) {
^bb0(%in: i2, %filt: i2, %acc: i4):
%m = arith.muli %in, %filt : i2
%m_ext = arith.extsi %m : i2 to i4
%res = arith.addi %acc, %m_ext : i4
linalg.yield %res : i4
} -> tensor<1x1x2x2xi4>
// --- 2. ReLU ---
%relu_init = arith.constant dense<0> : tensor<1x1x2x2xi4>
%relu_out = linalg.generic {
indexing_maps = [#map_identity, #map_identity],
iterator_types = ["parallel", "parallel", "parallel", "parallel"]
} ins(%conv1_out : tensor<1x1x2x2xi4>)
outs(%relu_init : tensor<1x1x2x2xi4>) {
^bb0(%in: i4, %out: i4):
%max = arith.maxsi %in, %zero_i4 : i4
linalg.yield %max : i4
} -> tensor<1x1x2x2xi4>
// --- 3. Fully Connected (Reduction over C, H, W) ---
%fc_init = arith.constant dense<0> : tensor<1x2xi8>
%final_out = linalg.generic {
indexing_maps = [#map_fc_in, #map_fc_w, #map_fc_out],
iterator_types = ["parallel", "parallel", "reduction", "reduction", "reduction"]
} ins(%relu_out, %w_fc1 : tensor<1x1x2x2xi4>, tensor<1x2x2x2xi2>)
outs(%fc_init : tensor<1x2xi8>) {
^bb0(%a_in: i4, %b_in: i2, %acc: i8):
%b_in_ext = arith.extsi %b_in : i2 to i4
%mul = arith.muli %a_in, %b_in_ext : i4
%mul_ext = arith.extsi %mul : i4 to i8
%res = arith.addi %acc, %mul_ext : i8
linalg.yield %res : i8
} -> tensor<1x2xi8>
return %final_out : tensor<1x2xi8>
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.