Skip to content

Commit b94186b

Browse files
committed
[Deeploy] add support for Deeploy as a dependency
1 parent 51d8157 commit b94186b

28 files changed

Lines changed: 1268 additions & 22 deletions

.gitignore

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,47 @@
1-
next_steps.*
2-
build/
3-
output*
4-
list/
5-
transcript
1+
# Environment & secrets
2+
.env
3+
.env.*
4+
.env.local
5+
6+
# IDE & editor
67
.vscode/
7-
gvsoc_config.json
8+
9+
# python
10+
__pycache__/
11+
*.pyc
12+
13+
# Build & output
14+
build/
15+
output/
16+
output_*.txt
17+
next_steps.*
818
power_report.csv
19+
20+
# Logs & traces
21+
log.txt
922
trace_file.txt
1023
insn.txt
1124
debug_*
12-
compile_commands.json
25+
26+
# CMake
1327
CMakeCache.txt
1428
cmake_install.cmake
15-
CMakeFiles
29+
CMakeFiles/
30+
compile_commands.json
1631
/*/Makefile
1732
/*/*/Makefile
1833
/*/*/*/Makefile
1934
/*/*/*/*/Makefile
20-
log.txt
21-
gvsoc/
35+
36+
# Test & CI
2237
testsuite.py
23-
test.conf
2438
testsuite*
39+
test.conf
2540
testlogs/
41+
42+
# Project-specific
43+
gvsoc/
44+
gvsoc_config.json
45+
power_report.csv
46+
list/
47+
transcript

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
1717
set(CMAKE_VERBOSE_MAKEFILE TRUE)
1818

1919
set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs")
20-
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE
20+
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE
2121
"-Wl,--whole-archive <LIBRARY> -Wl,--no-whole-archive"
2222
)
2323
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED True)
@@ -80,6 +80,7 @@ add_subdirectory(targets)
8080
add_subdirectory(hal)
8181
# add_subdirectory(devices)
8282
add_subdirectory(drivers)
83+
add_subdirectory(kernels)
8384

8485
################################################################################
8586
# Testing #

Makefile

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (C) 2025 ETH Zurich and University of Bologna
22
#
3-
# Licensed under the Solderpad Hardware License, Version 0.51
4-
# (the "License"); you may not use this file except in compliance
3+
# Licensed under the Solderpad Hardware License, Version 0.51
4+
# (the "License"); you may not use this file except in compliance
55
# with the License. You may obtain a copy of the License at
66
#
77
# http://www.apache.org/licenses/LICENSE-2.0
@@ -15,7 +15,7 @@
1515
#
1616
# Authors: Victor Isachi <victor.isachi@unibo.it>
1717
# Alberto Dequino <alberto.dequino@unibo.it>
18-
#
18+
#
1919
# Magia-sdk Makefile
2020

2121
SHELL := /bin/bash
@@ -47,6 +47,14 @@ ISA ?= rv32imcxgap9
4747
gui ?= 0
4848
tiles ?= 2
4949

50+
LLVM_CMAKE ?= cmake
51+
LLVM_DIR ?= llvm
52+
LLVM_REPO ?= git@github.com:pulp-platform/llvm-project.git
53+
LLVM_COMMIT ?= b494f2d8dde88723026db8ec16ac6c7ee1e140ca
54+
LLVM_INSTALL_DIR ?= $(CURR_DIR)/llvm/install
55+
LLVM_BUILD_DIR ?= $(LLVM_DIR)/llvm-project/build
56+
LLVM_JOBS ?= 8
57+
5058
tiles_2 := $(shell echo $$(( $(tiles) * $(tiles) )))
5159
tiles_log := $(shell awk 'BEGIN { printf "%.0f", log($(tiles_2))/log(2) }')
5260
tiles_log_real := $(shell awk 'BEGIN { printf "%.0f", log($(tiles))/log(2) }')
@@ -85,7 +93,7 @@ endif
8593
set_mesh:
8694
ifeq ($(tiles), 1)
8795
$(eval mesh_dv=0)
88-
endif
96+
endif
8997

9098
run: set_mesh
9199
@echo 'Magia is available at https://github.com/pulp-platform/MAGIA.git'
@@ -107,10 +115,10 @@ else ifeq ($(platform), rtl)
107115
cp ./build/bin/$(test) $(BUILD_DIR)/build/verif
108116
objcopy --srec-len 1 --output-target=srec $(BIN) $(BIN).s19
109117
scripts/parse_s19.pl $(BIN).s19 > $(BIN).txt
110-
python3 scripts/s19tomem.py $(BIN).txt $(BUILD_DIR)/build/stim_instr.txt $(BUILD_DIR)/build/stim_data.txt
118+
python3 scripts/s19tomem.py $(BIN).txt $(BUILD_DIR)/build/stim_instr.txt $(BUILD_DIR)/build/stim_data.txt
111119
cd $(BUILD_DIR) && \
112120
cp -sf ../../../sim/modelsim.ini modelsim.ini && \
113-
ln -sfn ../../../sim/work work
121+
ln -sfn ../../../sim/work work
114122
riscv32-unknown-elf-objdump -d -S -Mmarch=$(ISA) $(BIN) > $(BIN).dump
115123
riscv32-unknown-elf-objdump -d -l -s -Mmarch=$(ISA) $(BIN) > $(BIN).objdump
116124
python3 scripts/objdump2itb.py $(BIN).objdump > $(BIN).itb
@@ -171,8 +179,44 @@ gvsoc_init:
171179
cd $(GVSOC_DIR) && \
172180
git submodule update --init --recursive && \
173181
cd core && \
174-
git checkout lz/magia-v2-core && \
182+
git checkout master && \
175183
cd ../pulp && \
176-
git checkout lz/magia-v2-pulp
184+
git checkout master
177185

186+
llvm:
187+
mkdir -p $(LLVM_DIR)
188+
if [ ! -d "$(LLVM_DIR)/llvm-project/.git" ]; then \
189+
cd $(LLVM_DIR) && git clone $(LLVM_REPO); \
190+
fi
191+
cd $(LLVM_DIR)/llvm-project && \
192+
git checkout $(LLVM_COMMIT) && \
193+
git submodule update --init --recursive --jobs=$(LLVM_JOBS) .
194+
mkdir -p $(LLVM_INSTALL_DIR)
195+
cd $(LLVM_DIR)/llvm-project && mkdir -p build && cd build && \
196+
$(LLVM_CMAKE) \
197+
-DCMAKE_INSTALL_PREFIX=$(LLVM_INSTALL_DIR) \
198+
-DCMAKE_CXX_COMPILER=${CXX} \
199+
-DCMAKE_C_COMPILER=${CC} \
200+
-DLLVM_OPTIMIZED_TABLEGEN=True \
201+
-DLLVM_ENABLE_PROJECTS="clang;lld" \
202+
-DLLVM_TARGETS_TO_BUILD="RISCV" \
203+
-DLLVM_DEFAULT_TARGET_TRIPLE=riscv32-unknown-elf \
204+
-DLLVM_ENABLE_LLD=False \
205+
-DLLVM_APPEND_VC_REV=ON \
206+
-DCMAKE_BUILD_TYPE=Release \
207+
../llvm && \
208+
make -j$(LLVM_JOBS) all && \
209+
make install
178210

211+
deploy:
212+
ifndef test
213+
$(error Proper formatting is: make deploy test=<test_name> platform=rtl|gvsoc)
214+
endif
215+
ifndef platform
216+
$(error Proper formatting is: make run test=<test_name> platform=rtl|gvsoc)
217+
endif
218+
python deployment/generate.py \
219+
-s ./deployment/tests/$(test) \
220+
-d ./tests/magia/mesh/$(test) && \
221+
make clean build tiles=$(tiles) compiler=$(compiler) eval=$(eval) && \
222+
make run test=test_$(test) platform=gvsoc
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# SPDX-FileCopyrightText: 2024 ETH Zurich and University of Bologna
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
6+
from Deeploy.AbstractDataTypes import PointerClass
7+
from Deeploy.CommonExtensions.DataTypes import int8_t, int32_t
8+
from Deeploy.DeeployTypes import CodeTransformation, NodeBinding
9+
from Deeploy.Targets.Generic.TypeCheckers import AddChecker
10+
from MagiaDeeployTarget.Templates import AddTemplate
11+
12+
BasicTransformer = CodeTransformation([])
13+
14+
MagiaAddBindings = [
15+
NodeBinding(
16+
AddChecker(
17+
[PointerClass(int8_t), PointerClass(int8_t)],
18+
[PointerClass(int32_t)]
19+
),
20+
AddTemplate.referenceTemplate,
21+
BasicTransformer,
22+
),
23+
]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# SPDX-FileCopyrightText: 2026 ETH Zurich and University of Bologna
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from typing import Callable, Dict, List, Type
6+
7+
import numpy as np
8+
import onnx_graphsurgeon as gs
9+
10+
from Deeploy.AbstractDataTypes import Pointer
11+
from Deeploy.CommonExtensions.NetworkDeployers.SignPropDeployer import SignPropDeployer
12+
from Deeploy.DeeployTypes import ConstantBuffer, DeploymentPlatform, NodeTemplate, TopologyOptimizer, VariableBuffer
13+
14+
15+
class MagiaDeployer(SignPropDeployer):
16+
17+
def __init__(
18+
self,
19+
graph: gs.Graph,
20+
deploymentPlatform: DeploymentPlatform,
21+
inputTypes: Dict[str, Type[Pointer]],
22+
loweringOptimizer: TopologyOptimizer,
23+
scheduler: Callable = lambda x: x,
24+
name: str = 'DeeployNetwork',
25+
default_channels_first = False,
26+
deeployStateDir: str = "DeeployStateDir",
27+
inputOffsets: Dict[str, int] = {}
28+
):
29+
30+
super().__init__(
31+
graph,
32+
deploymentPlatform,
33+
inputTypes,
34+
loweringOptimizer,
35+
scheduler,
36+
name,
37+
default_channels_first = default_channels_first,
38+
deeployStateDir = deeployStateDir,
39+
inputOffsets = inputOffsets,
40+
)
41+
42+
self.loweringOptimizer.passes += [
43+
# Extra optimizer passes on the lowering optimization pass.
44+
# It seems to be different than the "normal" optimization passes
45+
# defined on the Platform.
46+
]
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# SPDX-FileCopyrightText: 2026 ETH Zurich and University of Bologna
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
import numpy as np
6+
import onnx_graphsurgeon as gs
7+
8+
from Deeploy.DeeployTypes import ConstantBuffer, DeploymentEngine, DeploymentPlatform, NetworkContext, NodeMapper, \
9+
NodeTemplate, StructBuffer, TopologyOptimizer, TransientBuffer, VariableBuffer
10+
from Deeploy.Targets.Generic.Layers import AddLayer
11+
from Deeploy.Targets.Generic.Parsers import AddParser
12+
from Deeploy.Targets.Generic.Templates import AllocateTemplate as BasicAllocateTemplate
13+
from MagiaDeeployTarget.Bindings import MagiaAddBindings
14+
from MagiaDeeployTarget.Templates import AllocateTemplate, FreeTemplate
15+
16+
17+
AddMapper = NodeMapper(AddParser(), MagiaAddBindings)
18+
19+
MagiaMapping = {'Add': AddLayer([AddMapper])}
20+
21+
22+
class MagiaVariableBuffer(VariableBuffer):
23+
24+
initTemplate = AllocateTemplate.magiaInitTemplate
25+
allocTemplate = AllocateTemplate.magiaAllocateTemplate
26+
deallocTemplate = FreeTemplate.magiaFreeTemplate
27+
28+
def _bufferRepresentation(self):
29+
buffRepr = {
30+
"type": self._instance,
31+
"name": self.name,
32+
"size": int(np.prod(self.shape)),
33+
"_memoryLevel": getattr(self, "_memoryLevel", None),
34+
}
35+
return buffRepr
36+
37+
38+
class MagiaTransientBuffer(TransientBuffer):
39+
40+
initTemplate = AllocateTemplate.magiaInitTemplate
41+
allocTemplate = AllocateTemplate.magiaAllocateTemplate
42+
deallocTemplate = FreeTemplate.magiaFreeTemplate
43+
44+
def _bufferRepresentation(self):
45+
buffRepr = {
46+
"type": self._type,
47+
"name": self.name,
48+
"size": self.size,
49+
"_memoryLevel": getattr(self, "_memoryLevel", None),
50+
}
51+
return buffRepr
52+
53+
54+
class MagiaConstantBuffer(ConstantBuffer):
55+
56+
initTemplate = AllocateTemplate.magiaGlobalInitTemplate
57+
allocTemplate = AllocateTemplate.magiaGlobalAllocateTemplate
58+
deallocTemplate = FreeTemplate.magiaGlobalTemplate
59+
60+
def _bufferRepresentation(self):
61+
buffRepr = super()._bufferRepresentation()
62+
buffRepr["_memoryLevel"] = getattr(self, "_memoryLevel", None)
63+
return buffRepr
64+
65+
66+
class MagiaStructBuffer(StructBuffer):
67+
68+
initTemplate = BasicAllocateTemplate.referenceStructInitTemplate
69+
allocTemplate = BasicAllocateTemplate.referenceStructAllocateTemplate
70+
deallocTemplate = NodeTemplate("")
71+
72+
73+
MagiaOptimizer = TopologyOptimizer(
74+
[
75+
# Insert here the ONNX optimization passes.
76+
],
77+
name = "MagiaOptimizer")
78+
79+
_includeList = ["tile.h", "idma.h", "redmule.h", "eventunit.h"]
80+
81+
82+
class MagiaMeshEngine(DeploymentEngine):
83+
84+
def __init__(self,
85+
name: str,
86+
Mapping = MagiaMapping,
87+
initCode: str = "",
88+
includeList: list[str] = _includeList,
89+
n_tiles: int = 4) -> None:
90+
super().__init__(name, Mapping, initCode, includeList)
91+
self.n_tiles = n_tiles
92+
93+
94+
class MagiaPlatform(DeploymentPlatform):
95+
96+
def __init__(self,
97+
engines = [MagiaMeshEngine("MagiaMesh")],
98+
variableBuffer = MagiaVariableBuffer,
99+
constantBuffer = MagiaConstantBuffer,
100+
structBuffer = MagiaStructBuffer,
101+
transientBuffer = MagiaTransientBuffer) -> None:
102+
super().__init__(engines, variableBuffer, constantBuffer, structBuffer, transientBuffer)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SPDX-FileCopyrightText: 2024 ETH Zurich and University of Bologna
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from typing import Dict, List, Tuple
6+
7+
from Deeploy.DeeployTypes import NetworkContext, NodeTemplate, OperatorRepresentation
8+
9+
10+
class _MagiaAddTemplate(NodeTemplate):
11+
12+
def alignToContext(self, ctxt: NetworkContext,
13+
operatorRepresentation: OperatorRepresentation) -> Tuple[NetworkContext, Dict, List[str]]:
14+
15+
data_in_1 = ctxt.lookup(operatorRepresentation['data_in_1'])
16+
data_in_2 = ctxt.lookup(operatorRepresentation['data_in_2'])
17+
data_out = ctxt.lookup(operatorRepresentation['data_out'])
18+
19+
input_1_offset = 0
20+
if hasattr(data_in_1, "_signed") and hasattr(data_in_1, "nLevels"):
21+
input_1_offset = (data_in_1._signed == 0) * int(data_in_1.nLevels / 2)
22+
input_2_offset = 0
23+
if hasattr(data_in_2, "_signed") and hasattr(data_in_2, "nLevels"):
24+
input_2_offset = (data_in_2._signed == 0) * int(data_in_2.nLevels / 2)
25+
output_offset = 0
26+
if hasattr(data_out, "_signed") and hasattr(data_out, "nLevels"):
27+
output_offset = -(data_out._signed == 0) * int(data_out.nLevels // 2)
28+
29+
operatorRepresentation['offset'] = input_1_offset + input_2_offset + output_offset
30+
31+
return ctxt, operatorRepresentation, []
32+
33+
34+
referenceTemplate = _MagiaAddTemplate("""
35+
// Magia Add (Name: ${nodeName}, Op: ${nodeOp})
36+
MAGIA_add(${data_in_1}, ${data_in_2}, ${data_out}, ${size}, ${offset});
37+
""")

0 commit comments

Comments
 (0)