Skip to content

Commit 23e9f02

Browse files
marchioaAlex Marchioni
andauthored
fix bug in Generic GEMM with no bias (#126)
In generic platform, GEMM was not correctly hoisting the bias tensor when required. To solve the issue, bias hoisting has been moved from `MatMulParser.parseNodeCtxt` to `GEMMParser.parseNode`. Moreover, the default value of `noBiasHoisting` flag in `GenericGEMMParser` has been changed from True to False to be compliant with the template. ## Added - testFloatGEMMnobias ## Changed - Generic\Parser.py file (`MatMulParser`, `GEMMParser`, and `GenericGEMMParser`) ## Fixed - fix bias hoisting in GEMM with no bias Co-authored-by: Alex Marchioni <[email protected]>
1 parent 41baa7b commit 23e9f02

File tree

5 files changed

+9
-23
lines changed

5 files changed

+9
-23
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This file contains the changelog for the Deeploy project. The changelog is divid
2020
- Prepare Post v0.2.0 Release [#104](https://github.com/pulp-platform/Deeploy/pull/104)
2121
- Use Docker digests instead of arch-specific tags [#106](https://github.com/pulp-platform/Deeploy/pull/106)
2222
- Fix `Unsqueeze` Op. when using ONNX opset 13 or higher (from attribute to input) [#119](https://github.com/pulp-platform/Deeploy/pull/119)
23+
- Fix bias hoisting in generic GEMM with no bias [#126](https://github.com/pulp-platform/Deeploy/pull/126)
2324

2425
### Added
2526
- Add manual type inference feature (CLI: `--input-type-map`/`--input-offset-map`) to resolve ambiguities when test inputs are not representative enough
@@ -53,6 +54,7 @@ This file contains the changelog for the Deeploy project. The changelog is divid
5354
- Memory/I/O summaries and input/output logging in deployers
5455
- RequantHelpers.py for Neureka's TileConstraints
5556
- Added assertion that all the graph tensors after lowering have a shape annotated
57+
- Added testFloatGEMMnobias
5658

5759
### Changed
5860
- Replaced platform-specific tags (`*-amd64`, `*-arm64`) with direct digest references in `Noelware/docker-manifest-action`.
@@ -102,6 +104,7 @@ This file contains the changelog for the Deeploy project. The changelog is divid
102104
- Fixed aliasing
103105
- Missing layout transformation of the const's (bias, mul, add, shift in Conv/RequantizedConv)
104106
- Keep mul/add rank of requantized Neureka tile constraints
107+
- Fix bias hoisting in generic GEMM with no bias
105108

106109
### Removed
107110
- Delete outdated and unused `.gitlab-ci.yml` file

Deeploy/Targets/Generic/Parsers.py

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,14 +1682,6 @@ def parseNodeCtxt(self,
16821682
for idx, outputNode in enumerate(node.outputs):
16831683
self.operatorRepresentation[outputs[idx]] = ctxt.lookup(outputNode.name).name
16841684

1685-
# Create fake C node for GEMM-compatibility and hoist it
1686-
if not self.noBiasHoisting:
1687-
values = np.zeros(ctxt.lookup(node.inputs[0].name).shape, dtype = inputNode.dtype)
1688-
zeroTensor = gs.Constant(f'{node.name}_C_Tensor', values = values)
1689-
ctxt.hoistConstant(zeroTensor, _type = ctxt.lookup(inputNode.name)._type)
1690-
node.inputs.append(zeroTensor)
1691-
self.operatorRepresentation['C'] = f'{node.name}_C_Tensor'
1692-
16931685
# Store the input and output shapes in the operator representation
16941686
self.operatorRepresentation['size'] = np.prod(ctxt.lookup(node.inputs[0].name).shape)
16951687
self.operatorRepresentation['A_shape'] = ctxt.lookup(node.inputs[0].name).shape
@@ -1772,8 +1764,7 @@ def parseNodeCtxt(self,
17721764
class GEMMParser(MatMulParser):
17731765

17741766
def __init__(self, noBiasHoisting = True):
1775-
self.noBiasHoisting = noBiasHoisting
1776-
super().__init__()
1767+
super().__init__(noBiasHoisting)
17771768

17781769
def parseNode(self, node: gs.Node) -> (bool):
17791770

@@ -1805,6 +1796,10 @@ def parseNode(self, node: gs.Node) -> (bool):
18051796
else:
18061797
self.operatorRepresentation['transB'] = 0
18071798

1799+
if len(node.inputs) == 2 and not self.noBiasHoisting:
1800+
C = gs.Constant(f"{node.name}_C", np.zeros((1,)))
1801+
node.inputs.append(C)
1802+
18081803
return True
18091804
# This might be a matmul node -> Cast up
18101805
else:
@@ -1836,18 +1831,6 @@ def parseNodeCtxt(self,
18361831
# Create flag for same dimension between bias matrix and the final batch dimension
18371832
self.operatorRepresentation['C_batched'] = (self.operatorRepresentation['batch'] == np.prod(
18381833
newCtxt.lookup(node.inputs[2].name).shape[:-2]))
1839-
elif not self.noBiasHoisting:
1840-
# Create mock bias matrix if not present in the inputs
1841-
values = np.zeros((1))
1842-
zeroTensor = gs.Constant(f'{node.name}_C_Tensor', values = values)
1843-
newCtxt.hoistConstant(zeroTensor)
1844-
1845-
# Store it in the operator representation
1846-
self.operatorRepresentation['C'] = f'{node.name}_C_Tensor'
1847-
self.operatorRepresentation['C_shape'] = (0,)
1848-
1849-
# Create flag for same dimension between bias matrix and the final batch dimension
1850-
self.operatorRepresentation['C_batched'] = False
18511834

18521835
self.operatorRepresentation['size'] = np.prod(newCtxt.lookup(node.inputs[0].name).shape)
18531836

@@ -2324,7 +2307,7 @@ def parseNodeCtxt(self,
23242307

23252308
class GenericGEMMParser(GEMMParser):
23262309

2327-
def __init__(self, noBiasHoisting = True):
2310+
def __init__(self, noBiasHoisting = False):
23282311
super().__init__(noBiasHoisting)
23292312

23302313
def parseNode(self, node: gs.Node) -> (bool):
4.26 KB
Binary file not shown.
9.53 KB
Binary file not shown.
2.26 KB
Binary file not shown.

0 commit comments

Comments
 (0)