Skip to content

Commit 3aa1f58

Browse files
committed
Add Siracusa_w_redmule platform (RedMulE accelerator integration)
Minimal port of RedMulE-platform code from the user's redmule_platform branch (which had accumulated unrelated CCT_Optim merges) onto a clean devel base. What landed: - New target Deeploy/Targets/Redmule/ (Platform, Engine, Deployer, Bindings, Parsers, Tiler, Templates, TileConstraints, TopologyOptimizationPasses). - FP32 RedMulE matmul kernel TargetLibraries/PULPOpen/src/Matmul_fp32_Redmule.c - Test runner DeeployTest/testRunner_tiled_siracusa_w_redmule.py plus Float test fixtures (testFloat{Matmul,MatmulLarge,MatmulLarge256,2DConvolution,2dConvLarge,GEMM,GEMMtransB}). - Wiring in platformMapping.py, top-level CMakeLists.txt, DeeployTest/CMakeLists.txt, TargetLibraries/PULPOpen/CMakeLists.txt. - Makefile: GVSOC_COMMIT_HASH points at runwangdl/gvsoc fork 35d00d1 (carries the light_redmule vendored copy + Siracusa cluster wiring). Fixes / portings required for devel compatibility: - Deeploy/Targets/PULPOpen/Templates/FloatGemmTemplate.py: define float32_tPtr locally (unresolved import left on devel). - Deeploy/Targets/Redmule/TopologyOptimizationPasses/Passes.py: switch from the retired _permuteLastTwoDims / _appendTransposeNode helpers to upstream's _appendTranspose. - Add empty __init__.py to Targets/{Chimera,Redmule,SoftHier}. What intentionally did NOT land: - CCT_Optim-era edits to PULPOpen Templates (Add/Conv/GELU/Layernorm/ MatMul/MaxPool/Relu/Softmax), Generic Layers.py computeOps, CCT test suites, parallel/unroll rewrites. - Buggy -march=rv32imc inside meson-build-script-rv32imf.txt. - Hard-to-merge edits to DeeployTest/Platforms/Siracusa/src/deeploytest.c. - The old-style .github/workflows/TestRunnerTiledSiracusaWithRedmule.yml; new-style ci-platform-siracusa-redmule-tiled.yml TBD. Verified end-to-end: testFloatMatmul on GVSoC (runwangdl/gvsoc@35d00d1, pulp submodule @ 371772c) passes with 'Errors: 0 out of 256'.
1 parent 3b011bb commit 3aa1f58

48 files changed

Lines changed: 1721 additions & 11 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ if(TOOLCHAIN STREQUAL GCC)
2020
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
2121
endif()
2222

23-
set(platform MemPool CACHE STRING "Platform (MemPool, SoftHier, QEMU, Siracusa, Siracusa_w_neureka, PULP-Open, GAP9, Generic, Snitch)")
24-
set_property(CACHE platform PROPERTY STRINGS MemPool SoftHier QEMU Siracusa Siracusa_w_neureka PULP-Open GAP9 Generic Snitch)
23+
set(platform MemPool CACHE STRING "Platform (MemPool, SoftHier, QEMU, Siracusa, Siracusa_w_neureka, Siracusa_w_redmule, PULP-Open, GAP9, Generic, Snitch)")
24+
set_property(CACHE platform PROPERTY STRINGS MemPool SoftHier QEMU Siracusa Siracusa_w_neureka Siracusa_w_redmule PULP-Open GAP9 Generic Snitch)
2525

2626
if(platform STREQUAL MemPool)
2727
message(STATUS "Building for platform 'MemPool'")
@@ -31,6 +31,8 @@ elseif(platform STREQUAL Siracusa)
3131
message(STATUS "Building for platform 'Siracusa'")
3232
elseif(platform STREQUAL Siracusa_w_neureka)
3333
message(STATUS "Building for platform 'Siracusa_w_neureka'")
34+
elseif(platform STREQUAL Siracusa_w_redmule)
35+
message(STATUS "Building for platform 'Siracusa_w_redmule'")
3436
elseif(platform STREQUAL PULPOpen)
3537
message(STATUS "Building for platform 'PULP-Open'")
3638
elseif(platform STREQUAL GAP9)
@@ -196,7 +198,7 @@ if(platform STREQUAL QEMU-ARM)
196198

197199
endif()
198200

199-
if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka OR platform STREQUAL PULPOpen)
201+
if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka OR platform STREQUAL Siracusa_w_redmule OR platform STREQUAL PULPOpen)
200202

201203
if(TOOLCHAIN STREQUAL LLVM)
202204
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/pulp/toolchain_llvm.cmake)
@@ -206,7 +208,7 @@ if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka OR platfor
206208

207209
include(${CMAKE_CURRENT_LIST_DIR}/cmake/pulp/pulp.cmake)
208210

209-
if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka)
211+
if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka OR platform STREQUAL Siracusa_w_redmule)
210212
include(${CMAKE_CURRENT_LIST_DIR}/cmake/pulp/siracusa/siracusa.cmake)
211213
elseif(platform STREQUAL PULPOpen)
212214
include(${CMAKE_CURRENT_LIST_DIR}/cmake/pulp/pulp-open/pulp-open.cmake)

Deeploy/Targets/Chimera/__init__.py

Whitespace-only changes.

Deeploy/Targets/PULPOpen/Templates/FloatGemmTemplate.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
from typing import Dict, List, Tuple
66

7-
from Deeploy.AbstractDataTypes import float32_tPtr
7+
from Deeploy.AbstractDataTypes import PointerClass
8+
from Deeploy.CommonExtensions.DataTypes import float32_t
89
from Deeploy.DeeployTypes import NetworkContext, NodeTemplate, OperatorRepresentation
910

11+
float32_tPtr = PointerClass(float32_t)
12+
1013

1114
class PULPFloatGEMMTemplate(NodeTemplate):
1215

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# ----------------------------------------------------------------------
2+
#
3+
# File: NeurekaBindings.py
4+
#
5+
# Last edited: 10.07.2024
6+
#
7+
# Copyright (C) 2024, ETH Zurich and University of Bologna.
8+
#
9+
# Author:
10+
# Luka Macan, University of Bologna
11+
# Moritz Scherer, ETH Zurich
12+
#
13+
# ----------------------------------------------------------------------
14+
# SPDX-License-Identifier: Apache-2.0
15+
#
16+
# Licensed under the Apache License, Version 2.0 (the License); you may
17+
# not use this file except in compliance with the License.
18+
# You may obtain a copy of the License at
19+
#
20+
# www.apache.org/licenses/LICENSE-2.0
21+
#
22+
# Unless required by applicable law or agreed to in writing, software
23+
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
24+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25+
# See the License for the specific language governing permissions and
26+
# limitations under the License.
27+
28+
from Deeploy.AbstractDataTypes import PointerClass
29+
from Deeploy.CommonExtensions.DataTypes import float32_t
30+
from Deeploy.DeeployTypes import NodeBinding
31+
from Deeploy.Targets.Generic.TypeCheckers import MatMulChecker, ConvChecker, GEMMChecker
32+
from Deeploy.Targets.Redmule.Templates import MatmulTemplate, ConvTemplate, GEMMTemplate
33+
from Deeploy.Targets.PULPOpen.Bindings import ForkTransformer
34+
35+
RedmuleMatmulBindings = [
36+
NodeBinding(MatMulChecker([PointerClass(float32_t), PointerClass(float32_t)], [PointerClass(float32_t)]),
37+
MatmulTemplate.referenceTemplate, ForkTransformer)
38+
]
39+
40+
RedmuleConv2DBindings = [
41+
NodeBinding(
42+
ConvChecker([PointerClass(float32_t), PointerClass(float32_t),
43+
PointerClass(float32_t)], [PointerClass(float32_t)]), ConvTemplate.reference2DIm2ColTemplate,
44+
ForkTransformer)
45+
]
46+
47+
RedmuleGEMMBindings = [
48+
NodeBinding(
49+
GEMMChecker([PointerClass(float32_t), PointerClass(float32_t),
50+
PointerClass(float32_t)], [PointerClass(float32_t)]), GEMMTemplate.referenceTemplate,
51+
ForkTransformer)
52+
]
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# ----------------------------------------------------------------------
2+
#
3+
# File: Deployer.py
4+
#
5+
# Last edited: 08.05.2025
6+
#
7+
# Copyright (C) 2024, ETH Zurich and University of Bologna.
8+
#
9+
# Author: Run Wang, ETH Zurich
10+
#
11+
# ----------------------------------------------------------------------
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
# Licensed under the Apache License, Version 2.0 (the License); you may
15+
# not use this file except in compliance with the License.
16+
# You may obtain a copy of the License at
17+
#
18+
# www.apache.org/licenses/LICENSE-2.0
19+
#
20+
# Unless required by applicable law or agreed to in writing, software
21+
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
22+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
# See the License for the specific language governing permissions and
24+
# limitations under the License.
25+
26+
from typing import Callable, Dict, Type
27+
28+
import onnx_graphsurgeon as gs
29+
30+
from Deeploy.AbstractDataTypes import Pointer
31+
from Deeploy.DeeployTypes import DeploymentPlatform, TopologyOptimizer
32+
from Deeploy.Targets.PULPOpen.Deployer import PULPDeployer
33+
from Deeploy.Targets.Redmule.TopologyOptimizationPasses.Passes import RedMuleAdjustWeightMemoryLayoutPass, RedMuleGEMMTransposePass
34+
class RedmuleDeployer(PULPDeployer):
35+
36+
def __init__(self,
37+
graph: gs.Graph,
38+
deploymentPlatform: DeploymentPlatform,
39+
inputTypes: Dict[str, Type[Pointer]],
40+
loweringOptimizer: TopologyOptimizer,
41+
scheduler: Callable = lambda graph: list(graph.nodes),
42+
name: str = 'DeeployNetwork',
43+
default_channels_first = False,
44+
deeployStateDir: str = "DeeployStateDir",
45+
inputOffsets = {}):
46+
super().__init__(graph, deploymentPlatform, inputTypes, loweringOptimizer, scheduler, name,
47+
default_channels_first, deeployStateDir, inputOffsets)
48+
49+
self.loweringOptimizer.passes += [
50+
RedMuleAdjustWeightMemoryLayoutPass("Redmule"),
51+
RedMuleGEMMTransposePass("Redmule")
52+
]

Deeploy/Targets/Redmule/Engine.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# ----------------------------------------------------------------------
2+
#
3+
# File: Engine.py
4+
#
5+
# Last edited: 26.07.2024
6+
#
7+
# Copyright (C) 2024, ETH Zurich and University of Bologna.
8+
#
9+
# Author: Moritz Scherer, ETH Zurich
10+
#
11+
# ----------------------------------------------------------------------
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
# Licensed under the Apache License, Version 2.0 (the License); you may
15+
# not use this file except in compliance with the License.
16+
# You may obtain a copy of the License at
17+
#
18+
# www.apache.org/licenses/LICENSE-2.0
19+
#
20+
# Unless required by applicable law or agreed to in writing, software
21+
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
22+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
# See the License for the specific language governing permissions and
24+
# limitations under the License.
25+
26+
from typing import List
27+
28+
import onnx_graphsurgeon as gs
29+
from Deeploy.Targets.Generic.Layers import GEMMLayer
30+
from Deeploy.DeeployTypes import DeploymentEngine, NodeMapper
31+
from Deeploy.Targets.Generic.Layers import MatMulLayer, ConvLayer
32+
from Deeploy.Targets.Generic.Parsers import MatMulParser
33+
from Deeploy.Targets.Redmule.Tiler import RedmuleMatMulTilingReadyBindings, RedmuleConvTilingReadyBindings, RedmuleGEMMTilingReadyBindings
34+
from Deeploy.Targets.PULPOpen.Parsers import PULPFPConv2DParser
35+
from Deeploy.Targets.Redmule.Parsers import GEMMRedmuleParser
36+
37+
MatMulRedmuleMapper = NodeMapper(
38+
MatMulParser(), RedmuleMatMulTilingReadyBindings)
39+
Conv2DRedmuleMapper = NodeMapper(
40+
PULPFPConv2DParser(), RedmuleConvTilingReadyBindings)
41+
GEMMMRedmuleMapper = NodeMapper(GEMMRedmuleParser(), RedmuleGEMMTilingReadyBindings)
42+
43+
RedmuleMapping = {
44+
'MatMul': MatMulLayer([MatMulRedmuleMapper]),
45+
'Conv': ConvLayer([Conv2DRedmuleMapper]),
46+
'Gemm': GEMMLayer([GEMMMRedmuleMapper]),
47+
}
48+
49+
_includeList = []
50+
51+
_redmuleInitCode = r"""
52+
// Redmule engine initialization
53+
"""
54+
55+
56+
class RedmuleEngine(DeploymentEngine):
57+
58+
def __init__(self,
59+
name: str,
60+
Mapping = RedmuleMapping,
61+
initCode: str = _redmuleInitCode,
62+
includeList: List[str] = _includeList) -> None:
63+
super().__init__(name, Mapping, initCode, includeList)
64+
65+

Deeploy/Targets/Redmule/Parsers.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# ----------------------------------------------------------------------
2+
#
3+
# File: BasicParsers.py
4+
#
5+
# Last edited: 15.12.2021
6+
#
7+
# Copyright (C) 2021, ETH Zurich and University of Bologna.
8+
#
9+
# Authors:
10+
# - Moritz Scherer, ETH Zurich
11+
# - Victor Jung, ETH Zurich
12+
#
13+
# ----------------------------------------------------------------------
14+
# SPDX-License-Identifier: Apache-2.0
15+
#
16+
# Licensed under the Apache License, Version 2.0 (the License); you may
17+
# not use this file except in compliance with the License.
18+
# You may obtain a copy of the License at
19+
#
20+
# www.apache.org/licenses/LICENSE-2.0
21+
#
22+
# Unless required by applicable law or agreed to in writing, software
23+
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
24+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25+
# See the License for the specific language governing permissions and
26+
# limitations under the License.
27+
28+
import math
29+
from typing import Tuple
30+
31+
import numpy as np
32+
import onnx_graphsurgeon as gs
33+
34+
from Deeploy.DeeployTypes import NetworkContext, NodeParser
35+
from Deeploy.Targets.Generic.Parsers import MatMulParser
36+
37+
class GEMMRedmuleParser(MatMulParser):
38+
39+
def __init__(self, noBiasHoisting = True):
40+
self.noBiasHoisting = noBiasHoisting
41+
super().__init__()
42+
43+
def parseNode(self, node: gs.Node) -> (bool):
44+
45+
ret = all([
46+
len(node.inputs) >= 2,
47+
len(node.outputs) == 1,
48+
node.attrs['alpha'] == 1
49+
])
50+
51+
if ret:
52+
if 'transA' in node.attrs:
53+
self.operatorRepresentation['transA'] = node.attrs['transA']
54+
else:
55+
self.operatorRepresentation['transA'] = 0
56+
57+
if 'transB' in node.attrs:
58+
self.operatorRepresentation['transB'] = node.attrs['transB']
59+
else:
60+
self.operatorRepresentation['transB'] = 0
61+
if 'alpha' in node.attrs:
62+
self.operatorRepresentation['alpha'] = node.attrs['alpha']
63+
else:
64+
self.operatorRepresentation['alpha'] = 1
65+
if 'beta' in node.attrs:
66+
self.operatorRepresentation['beta'] = node.attrs['beta']
67+
else:
68+
self.operatorRepresentation['beta'] = 1
69+
70+
return ret
71+
72+
def parseNodeCtxt(self,
73+
ctxt: NetworkContext,
74+
node: gs.Node,
75+
channels_first: bool = True) -> Tuple[NetworkContext, bool]:
76+
77+
newCtxt, ret = super().parseNodeCtxt(ctxt, node, channels_first)
78+
79+
if ret:
80+
inputs = ['A', 'B']
81+
outputs = ['data_out']
82+
83+
for idx, inputNode in enumerate(node.inputs):
84+
if idx < len(inputs):
85+
self.operatorRepresentation[inputs[idx]] = newCtxt.lookup(inputNode.name).name
86+
for idx, outputNode in enumerate(node.outputs):
87+
self.operatorRepresentation[outputs[idx]] = newCtxt.lookup(outputNode.name).name
88+
89+
if len(node.inputs) == 3:
90+
self.operatorRepresentation['C'] = newCtxt.lookup(node.inputs[2].name).name
91+
elif not self.noBiasHoisting:
92+
values = np.zeros((1))
93+
zeroTensor = gs.Constant(f'{node.name}_C_Tensor', values = values)
94+
newCtxt.hoistConstant(zeroTensor)
95+
self.operatorRepresentation['C'] = f'{node.name}_C_Tensor'
96+
97+
self.operatorRepresentation['size'] = np.prod(newCtxt.lookup(node.inputs[0].name).shape)
98+
99+
return newCtxt, ret
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# ----------------------------------------------------------------------
2+
#
3+
# File: Platform.py
4+
#
5+
# Last edited: 08.05.2025
6+
#
7+
# Copyright (C) 2024, ETH Zurich and University of Bologna.
8+
#
9+
# Author: Run Wang, ETH Zurich
10+
#
11+
# ----------------------------------------------------------------------
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
# Licensed under the Apache License, Version 2.0 (the License); you may
15+
# not use this file except in compliance with the License.
16+
# You may obtain a copy of the License at
17+
#
18+
# www.apache.org/licenses/LICENSE-2.0
19+
#
20+
# Unless required by applicable law or agreed to in writing, software
21+
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
22+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
# See the License for the specific language governing permissions and
24+
# limitations under the License.
25+
26+
from Deeploy.DeeployTypes import TopologyOptimizer
27+
from Deeploy.Targets.Redmule.Engine import RedmuleEngine
28+
from Deeploy.Targets.PULPOpen.Platform import PULPClusterEngine, \
29+
PULPOptimizer, PULPPlatform, PULPStructBuffer, PULPTransientBuffer, PULPVariableBuffer, PULPConstantBuffer
30+
31+
RedmuleOptimizer = TopologyOptimizer([
32+
*PULPOptimizer.passes
33+
])
34+
35+
class RedmulePlatform(PULPPlatform):
36+
37+
def __init__(self,
38+
engines = [RedmuleEngine("Redmule"), PULPClusterEngine("PULPCluster")],
39+
variableBuffer = PULPVariableBuffer,
40+
constantBuffer = PULPConstantBuffer,
41+
structBuffer = PULPStructBuffer,
42+
transientBuffer = PULPTransientBuffer) -> None:
43+
super().__init__(engines, variableBuffer, constantBuffer, structBuffer, transientBuffer)
44+
45+

0 commit comments

Comments
 (0)