Skip to content

Commit 2147f44

Browse files
committed
DeeployTest: Add Dma tests
1 parent 91390de commit 2147f44

File tree

7 files changed

+758
-3
lines changed

7 files changed

+758
-3
lines changed

.github/workflows/CI.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,24 @@ jobs:
971971
python testRegexMatching.py
972972
shell: bash
973973

974+
deeploy-test-dmas:
975+
runs-on: ${{ needs.select-docker-image-and-runner.outputs.runner }}
976+
needs: select-docker-image-and-runner
977+
container:
978+
image: ${{ needs.select-docker-image-and-runner.outputs.image }}
979+
steps:
980+
- name: Checkout Repo
981+
uses: actions/checkout@v4
982+
with:
983+
submodules: recursive
984+
- name: Build Deeploy
985+
run: pip install -e .
986+
- name: Run Test
987+
run: |
988+
cd DeeployTest
989+
python testDmas.py
990+
shell: bash
991+
974992
linting:
975993
runs-on: ${{ needs.select-docker-image-and-runner.outputs.runner }}
976994
needs: select-docker-image-and-runner

DeeployTest/testDmas.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import itertools
2+
import subprocess
3+
from typing import Tuple
4+
5+
6+
def test(dma: str, inputShape: Tuple[int, ...], tileShape: Tuple[int, ...], nodeCount: int, dataType: str,
7+
doublebuffer: bool):
8+
cfg_str = f"""
9+
- input shape: {inputShape}
10+
- tile shape: {tileShape}
11+
- node count: {nodeCount}
12+
- data type: {dataType}
13+
- doublebuffering: {doublebuffer}
14+
- dma: {dma}
15+
"""
16+
17+
print(f"test{dma}: Testing {dma} with followig configuration:" + cfg_str)
18+
19+
cmd = [f"python testRunner_{dma}.py", f"-t test{dma}", "-DNUM_CORES=8"]
20+
cmd.append(f"--input-shape {' '.join(str(x) for x in inputShape)}")
21+
cmd.append(f"--tile-shape {' '.join(str(x) for x in tileShape)}")
22+
cmd.append(f"--node-count {nodeCount}")
23+
cmd.append(f"--type {dataType}")
24+
if doublebuffer:
25+
cmd.append("--doublebuffer")
26+
27+
full_cmd = " ".join(cmd)
28+
29+
print(f"Running command:\n{full_cmd}\n")
30+
31+
try:
32+
subprocess.run(full_cmd, shell = True, check = True)
33+
except subprocess.CalledProcessError:
34+
print(f"test{dma}: Failed test:" + cfg_str)
35+
print(f"Rerun with command:\n{full_cmd}")
36+
exit(-1)
37+
38+
39+
# input shape, tile shape, node count, data type
40+
test_shapes_and_more = [
41+
((10, 10), (10, 10), 1, "uint8_t"),
42+
((10, 10), (10, 4), 1, "uint8_t"),
43+
((10, 10), (10, 4), 1, "uint16_t"),
44+
((10, 10), (10, 4), 1, "uint32_t"),
45+
((10, 10), (3, 4), 1, "uint32_t"),
46+
((10, 10), (3, 4), 2, "uint32_t"),
47+
((10, 10, 10), (2, 3, 4), 1, "uint8_t"),
48+
((10, 10, 10, 10), (2, 3, 5, 4), 1, "uint8_t"),
49+
((10, 10, 10, 10), (2, 3, 5, 4), 1, "uint32_t"),
50+
((10, 10, 10, 10, 10), (2, 3, 5, 7, 4), 1, "uint8_t"),
51+
]
52+
53+
is_doublebuffers = [True, False]
54+
dmas = ["MchanDma", "L3Dma", "SnitchDma"]
55+
56+
for testShape, doublebuffer, dma in itertools.product(test_shapes_and_more, is_doublebuffers, dmas):
57+
inputShape, tileShape, nodeCount, dataType = testShape
58+
test(dma, inputShape, tileShape, nodeCount, dataType, doublebuffer)

DeeployTest/testRunner_L3Dma.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import numpy as np
2+
from testUtils.codeGenerate import generateTestNetwork
3+
from testUtils.dmaUtils import MemcpyLayer, MemcpyParser, MemcpyTileConstraint, MemcpyTypeChecker, generate_graph, \
4+
memcpyTemplate, prepare_deployer_with_custom_tiling, setup_pulp_deployer
5+
from testUtils.testRunner import TestRunner, TestRunnerArgumentParser
6+
from testUtils.typeMapping import baseTypeFromName, dtypeFromDeeployType
7+
8+
from Deeploy.AbstractDataTypes import PointerClass
9+
from Deeploy.CommonExtensions.CodeTransformationPasses.MemoryAllocation import ArgumentStructGeneration, \
10+
MemoryManagementGeneration
11+
from Deeploy.DeeployTypes import CodeTransformation, NodeBinding, NodeMapper
12+
from Deeploy.Targets.PULPOpen.Bindings import L3MemoryAwareFunctionCallClosure, TilingCallClosure
13+
from Deeploy.Targets.PULPOpen.CodeTransformationPasses.PULPL3Tiling import PULPL3Tiling
14+
from Deeploy.Targets.PULPOpen.Dmas.L3Dma import l3DmaHack
15+
from Deeploy.TilingExtension.CodeTransformationPasses.TilingVariableReplacement import TilingVariableReplacement, \
16+
TilingVariableReplacementUpdate
17+
from Deeploy.TilingExtension.TilerExtension import TilingReadyNodeBindings
18+
19+
testRunnerArgumentParser = TestRunnerArgumentParser(tiling_arguments = True)
20+
testRunnerArgumentParser.add_argument('--input-shape',
21+
nargs = '+',
22+
required = True,
23+
dest = 'input_shape',
24+
type = int,
25+
help = "Shape of the copied tensor")
26+
testRunnerArgumentParser.add_argument('--tile-shape',
27+
nargs = '+',
28+
required = True,
29+
dest = 'tile_shape',
30+
type = int,
31+
help = "Shape of the tiles produced in the manual tiling solution")
32+
testRunnerArgumentParser.add_argument('--node-count',
33+
dest = 'node_count',
34+
type = int,
35+
default = 1,
36+
help = "Number of generated memcpy nodes")
37+
testRunnerArgumentParser.add_argument('--type', type = str, default = "uint8_t", help = "Tensor elements datatype")
38+
testRunner = TestRunner('Siracusa', 'gvsoc', True, testRunnerArgumentParser)
39+
40+
inputShape = testRunner._args.input_shape
41+
tileShape = testRunner._args.tile_shape
42+
node_count = testRunner._args.node_count
43+
_type = baseTypeFromName(testRunner._args.type)
44+
dtype = dtypeFromDeeployType(_type)
45+
defaultMemory = "L3"
46+
targetMemory = "L2"
47+
48+
assert len(inputShape) == len(tileShape), \
49+
f'Input and tile shape should be of the same dimensionality. Received {len(inputShape)}D input shape vs. {len(tileShape)}D tile shape.'
50+
assert all(tileDim <= inDim for inDim, tileDim in zip(inputShape, tileShape)), \
51+
f'Each tile shape dimension should be smaller then the corresponding input one. Received {tileShape} > {inputShape}'
52+
53+
graph = generate_graph(node_count, inputShape, dtype)
54+
inputTypes = {"input_0": PointerClass(_type)}
55+
deployer = setup_pulp_deployer(defaultMemory, targetMemory, graph, inputTypes, testRunner._args.doublebuffer)
56+
57+
transformer = CodeTransformation([
58+
TilingVariableReplacement(targetMemory),
59+
TilingCallClosure(writeback = False, generateStruct = True),
60+
TilingVariableReplacementUpdate(targetMemory),
61+
PULPL3Tiling("L3", "L2", l3DmaHack),
62+
ArgumentStructGeneration(),
63+
L3MemoryAwareFunctionCallClosure(writeback = False),
64+
MemoryManagementGeneration("L2"),
65+
MemoryManagementGeneration("L3.*"),
66+
MemoryManagementGeneration(),
67+
])
68+
69+
binding = NodeBinding(MemcpyTypeChecker(), memcpyTemplate, transformer)
70+
tilingReadyBindings = TilingReadyNodeBindings([binding], MemcpyTileConstraint())
71+
memcpyMapper = NodeMapper(MemcpyParser(), tilingReadyBindings)
72+
memcpyMapping = {"Memcpy": MemcpyLayer([memcpyMapper])}
73+
deployer.Platform.engines[0].Mapping.update(memcpyMapping)
74+
75+
prepare_deployer_with_custom_tiling(deployer, defaultMemory, targetMemory, tileShape, testRunner._args.doublebuffer)
76+
77+
if not testRunner._args.skipgen:
78+
if dtype == np.float32:
79+
test_inputs = np.random.rand(*inputShape)
80+
else:
81+
info = np.iinfo(dtype)
82+
test_inputs = np.arange(stop = np.prod(inputShape), dtype = dtype).reshape(inputShape)
83+
test_outputs = test_inputs
84+
generateTestNetwork(deployer, [test_inputs], [test_outputs], inputTypes, testRunner._dir_gen)
85+
86+
# Deconstructed testRunner.run() with skipped generation because we did the generation already
87+
testRunner.configure_cmake_project()
88+
testRunner.build_binary()
89+
if not testRunner._args.skipsim:
90+
testRunner.run_simulation()

DeeployTest/testRunner_MchanDma.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import numpy as np
2+
from testUtils.codeGenerate import generateTestNetwork
3+
from testUtils.dmaUtils import MemcpyLayer, MemcpyParser, MemcpyTileConstraint, MemcpyTypeChecker, generate_graph, \
4+
memcpyTemplate, prepare_deployer_with_custom_tiling, setup_pulp_deployer
5+
from testUtils.testRunner import TestRunner, TestRunnerArgumentParser
6+
from testUtils.typeMapping import baseTypeFromName, dtypeFromDeeployType
7+
8+
from Deeploy.AbstractDataTypes import PointerClass
9+
from Deeploy.CommonExtensions.CodeTransformationPasses.MemoryAllocation import ArgumentStructGeneration, \
10+
MemoryManagementGeneration
11+
from Deeploy.DeeployTypes import CodeTransformation, NodeBinding, NodeMapper
12+
from Deeploy.Targets.PULPOpen.Bindings import MemoryAwareFunctionCallClosure, TilingCallClosure
13+
from Deeploy.Targets.PULPOpen.CodeTransformationPasses.PULPClusterTiling import PULPClusterTiling
14+
from Deeploy.Targets.PULPOpen.Dmas.MchanDma import MchanDma
15+
from Deeploy.TilingExtension.CodeTransformationPasses.TilingVariableReplacement import TilingVariableReplacement, \
16+
TilingVariableReplacementUpdate
17+
from Deeploy.TilingExtension.TilerExtension import TilingReadyNodeBindings
18+
19+
testRunnerArgumentParser = TestRunnerArgumentParser(tiling_arguments = True)
20+
testRunnerArgumentParser.add_argument('--input-shape',
21+
nargs = '+',
22+
required = True,
23+
dest = 'input_shape',
24+
type = int,
25+
help = "Shape of the copied tensor")
26+
testRunnerArgumentParser.add_argument('--tile-shape',
27+
nargs = '+',
28+
required = True,
29+
dest = 'tile_shape',
30+
type = int,
31+
help = "Shape of the tiles produced in the manual tiling solution")
32+
testRunnerArgumentParser.add_argument('--node-count',
33+
dest = 'node_count',
34+
type = int,
35+
default = 1,
36+
help = "Number of generated memcpy nodes")
37+
testRunnerArgumentParser.add_argument('--type', type = str, default = "uint8_t", help = "Tensor elements datatype")
38+
testRunner = TestRunner('Siracusa', 'gvsoc', True, testRunnerArgumentParser)
39+
40+
inputShape = testRunner._args.input_shape
41+
tileShape = testRunner._args.tile_shape
42+
node_count = testRunner._args.node_count
43+
_type = baseTypeFromName(testRunner._args.type)
44+
dtype = dtypeFromDeeployType(_type)
45+
defaultMemory = "L2"
46+
targetMemory = "L1"
47+
48+
assert len(inputShape) == len(tileShape), \
49+
f'Input and tile shape should be of the same dimensionality. Received {len(inputShape)}D input shape vs. {len(tileShape)}D tile shape.'
50+
assert all(tileDim <= inDim for inDim, tileDim in zip(inputShape, tileShape)), \
51+
f'Each tile shape dimension should be smaller then the corresponding input one. Received {tileShape} > {inputShape}'
52+
53+
graph = generate_graph(node_count, inputShape, dtype)
54+
inputTypes = {"input_0": PointerClass(_type)}
55+
deployer = setup_pulp_deployer(defaultMemory, targetMemory, graph, inputTypes, testRunner._args.doublebuffer)
56+
57+
transformer = CodeTransformation([
58+
TilingVariableReplacement(targetMemory),
59+
TilingCallClosure(writeback = False, generateStruct = True),
60+
TilingVariableReplacementUpdate(targetMemory),
61+
PULPClusterTiling(defaultMemory, targetMemory, MchanDma()),
62+
ArgumentStructGeneration(),
63+
MemoryManagementGeneration(targetMemory),
64+
TilingVariableReplacement(defaultMemory),
65+
MemoryAwareFunctionCallClosure(writeback = False, generateStruct = True),
66+
MemoryManagementGeneration(defaultMemory),
67+
MemoryManagementGeneration(),
68+
])
69+
70+
binding = NodeBinding(MemcpyTypeChecker(), memcpyTemplate, transformer)
71+
tilingReadyBindings = TilingReadyNodeBindings([binding], MemcpyTileConstraint())
72+
memcpyMapper = NodeMapper(MemcpyParser(), tilingReadyBindings)
73+
memcpyMapping = {"Memcpy": MemcpyLayer([memcpyMapper])}
74+
deployer.Platform.engines[0].Mapping.update(memcpyMapping)
75+
76+
prepare_deployer_with_custom_tiling(deployer, defaultMemory, targetMemory, tileShape, testRunner._args.doublebuffer)
77+
78+
if not testRunner._args.skipgen:
79+
if dtype == np.float32:
80+
test_inputs = np.random.rand(*inputShape)
81+
else:
82+
info = np.iinfo(dtype)
83+
test_inputs = np.arange(stop = np.prod(inputShape), dtype = dtype).reshape(inputShape)
84+
test_outputs = test_inputs
85+
generateTestNetwork(deployer, [test_inputs], [test_outputs], inputTypes, testRunner._dir_gen)
86+
87+
# Deconstructed testRunner.run() with skipped generation because we did the generation already
88+
testRunner.configure_cmake_project()
89+
testRunner.build_binary()
90+
if not testRunner._args.skipsim:
91+
testRunner.run_simulation()
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import numpy as np
2+
from testUtils.codeGenerate import generateTestNetwork
3+
from testUtils.dmaUtils import MemcpyLayer, MemcpyParser, MemcpyTileConstraint, MemcpyTypeChecker, generate_graph, \
4+
memcpyTemplate, prepare_deployer_with_custom_tiling, setup_snitch_deployer
5+
from testUtils.testRunner import TestRunner, TestRunnerArgumentParser
6+
from testUtils.typeMapping import baseTypeFromName, dtypeFromDeeployType
7+
8+
from Deeploy.AbstractDataTypes import PointerClass
9+
from Deeploy.CommonExtensions.CodeTransformationPasses.MemoryAllocation import ArgumentStructGeneration, \
10+
MemoryManagementGeneration
11+
from Deeploy.DeeployTypes import CodeTransformation, NodeBinding, NodeMapper
12+
from Deeploy.Targets.Snitch.Bindings import MemoryAwareFunctionCallClosure, TilingCallClosure
13+
from Deeploy.Targets.Snitch.CodeTransformationPasses import SnitchClusterTiling
14+
from Deeploy.Targets.Snitch.CodeTransformationPasses.SnitchClusterSynch import SnitchSynchCoresPass
15+
from Deeploy.Targets.Snitch.CodeTransformationPasses.SnitchCoreFilter import SnitchCoreFilterPass
16+
from Deeploy.Targets.Snitch.CodeTransformationPasses.SnitchProfileExecutionBlock import SnitchProfileExecutionBlockPass
17+
from Deeploy.Targets.Snitch.SnitchDma import SnitchDma
18+
from Deeploy.TilingExtension.CodeTransformationPasses.TilingVariableReplacement import TilingVariableReplacement, \
19+
TilingVariableReplacementUpdate
20+
from Deeploy.TilingExtension.TilerExtension import TilingReadyNodeBindings
21+
22+
testRunnerArgumentParser = TestRunnerArgumentParser(tiling_arguments = True)
23+
testRunnerArgumentParser.add_argument('--input-shape',
24+
nargs = '+',
25+
required = True,
26+
dest = 'input_shape',
27+
type = int,
28+
help = "Shape of the copied tensor")
29+
testRunnerArgumentParser.add_argument('--tile-shape',
30+
nargs = '+',
31+
required = True,
32+
dest = 'tile_shape',
33+
type = int,
34+
help = "Shape of the tiles produced in the manual tiling solution")
35+
testRunnerArgumentParser.add_argument('--node-count',
36+
dest = 'node_count',
37+
type = int,
38+
default = 1,
39+
help = "Number of generated memcpy nodes")
40+
testRunnerArgumentParser.add_argument('--type', type = str, default = "uint8_t", help = "Tensor elements datatype")
41+
testRunner = TestRunner('Snitch', 'gvsoc', tiling = True, argument_parser = testRunnerArgumentParser)
42+
43+
inputShape = testRunner._args.input_shape
44+
tileShape = testRunner._args.tile_shape
45+
node_count = testRunner._args.node_count
46+
_type = baseTypeFromName(testRunner._args.type)
47+
dtype = dtypeFromDeeployType(_type)
48+
defaultMemory = "L2"
49+
targetMemory = "L1"
50+
51+
assert len(inputShape) == len(tileShape), \
52+
f'Input and tile shape should be of the same dimensionality. Received {len(inputShape)}D input shape vs. {len(tileShape)}D tile shape.'
53+
assert all(tileDim <= inDim for inDim, tileDim in zip(inputShape, tileShape)), \
54+
f'Each tile shape dimension should be smaller then the corresponding input one. Received {tileShape} > {inputShape}'
55+
56+
graph = generate_graph(node_count, inputShape, dtype)
57+
inputTypes = {"input_0": PointerClass(_type)}
58+
deployer = setup_snitch_deployer(defaultMemory, targetMemory, graph, inputTypes, testRunner._args.doublebuffer)
59+
60+
transformer = CodeTransformation([
61+
SnitchCoreFilterPass("compute"),
62+
SnitchProfileExecutionBlockPass(),
63+
TilingVariableReplacement(targetMemory),
64+
TilingCallClosure(writeback = False),
65+
SnitchSynchCoresPass(),
66+
TilingVariableReplacementUpdate(targetMemory),
67+
SnitchClusterTiling(defaultMemory, targetMemory, SnitchDma()),
68+
ArgumentStructGeneration(),
69+
MemoryManagementGeneration(targetMemory),
70+
MemoryAwareFunctionCallClosure(writeback = False, generateStruct = True),
71+
MemoryManagementGeneration(defaultMemory),
72+
MemoryManagementGeneration(),
73+
])
74+
75+
binding = NodeBinding(MemcpyTypeChecker(), memcpyTemplate, transformer)
76+
tilingReadyBindings = TilingReadyNodeBindings([binding], MemcpyTileConstraint())
77+
memcpyMapper = NodeMapper(MemcpyParser(), tilingReadyBindings)
78+
memcpyMapping = {"Memcpy": MemcpyLayer([memcpyMapper])}
79+
deployer.Platform.engines[0].Mapping.update(memcpyMapping)
80+
81+
prepare_deployer_with_custom_tiling(deployer, defaultMemory, targetMemory, tileShape, testRunner._args.doublebuffer)
82+
83+
if not testRunner._args.skipgen:
84+
if dtype == np.float32:
85+
test_inputs = np.random.rand(*inputShape)
86+
else:
87+
info = np.iinfo(dtype)
88+
test_inputs = np.arange(stop = np.prod(inputShape), dtype = dtype).reshape(inputShape)
89+
test_outputs = test_inputs
90+
generateTestNetwork(deployer, [test_inputs], [test_outputs], inputTypes, testRunner._dir_gen)
91+
92+
# Deconstructed testRunner.run() with skipped generation because we did the generation already
93+
testRunner.configure_cmake_project()
94+
testRunner.build_binary()
95+
if not testRunner._args.skipsim:
96+
testRunner.run_simulation()

0 commit comments

Comments
 (0)