google / google/heir

Yosys Bug; Cannot handle smaller int

Open
#2,706 3 comments 0 reactions 0 assignees View on GitHub
dialect: cggi dialect: tfhe_rust
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.