Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ if(TOOLCHAIN STREQUAL GCC)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

set(platform MemPool CACHE STRING "Platform (MemPool, SoftHier, QEMU, Siracusa, Siracusa_w_neureka, PULP-Open, GAP9, Generic, Snitch)")
set_property(CACHE platform PROPERTY STRINGS MemPool SoftHier QEMU Siracusa Siracusa_w_neureka PULP-Open GAP9 Generic Snitch)
set(platform MemPool CACHE STRING "Platform (MemPool, SoftHier, QEMU, Siracusa, Siracusa_w_neureka, PULP-Open, GAP9, Generic, Snitch, Spatz)")
set_property(CACHE platform PROPERTY STRINGS MemPool SoftHier QEMU Siracusa Siracusa_w_neureka PULP-Open GAP9 Generic Snitch Spatz)

if(platform STREQUAL MemPool)
message(STATUS "Building for platform 'MemPool'")
Expand All @@ -46,6 +46,8 @@ elseif(platform STREQUAL SoftHier)
message(STATUS "Building for platform 'SoftHier'")
elseif(platform STREQUAL Chimera)
message(STATUS "Building for platform 'Chimera'")
elseif(platform STREQUAL Spatz)
message(STATUS "Building for platform 'Spatz'")
else()
message(FATAL_ERROR "Invalid platform '${platform}' specified!")
endif()
Expand Down Expand Up @@ -300,4 +302,28 @@ if(platform STREQUAL Chimera)
endif()



if(platform STREQUAL Spatz)
# Only LLVM supported for Spatz
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/spatz/toolchain_llvm.cmake)

include(${CMAKE_CURRENT_LIST_DIR}/cmake/spatz/spatz.cmake OPTIONAL)

project(deeploy LANGUAGES C ASM)

message(STATUS "============================= ${platform} Configuration ============================")
message(STATUS "[cMake ] ISA = " ${ISA})
message(STATUS "================================================================================")
message(STATUS "")

add_subdirectory(TargetLibraries/Generic)
add_subdirectory(TargetLibraries/Spatz)
target_include_directories(deeployspatz PUBLIC TargetLibraries/Generic/inc)

add_subdirectory(DeeployTest)
target_link_libraries(deeploylib INTERFACE deeploybasic deeployspatz)

endif()


print_simulation_config()
12 changes: 12 additions & 0 deletions Deeploy/Targets/Spatz/Bindings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from Deeploy.DeeployTypes import NodeBinding

from Deeploy.Targets.Generic.TypeCheckers import AddChecker
from Deeploy.Targets.Spatz.Templates import AddTemplate


SpatzAddBindings = [
NodeBinding(
AddChecker(),
AddTemplate.
)
]
48 changes: 48 additions & 0 deletions Deeploy/Targets/Spatz/Deployer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2023 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0

from typing import Callable, Dict, Type

import onnx_graphsurgeon as gs

from Deeploy.AbstractDataTypes import Pointer
from Deeploy.CommonExtensions.NetworkDeployers.SignPropDeployer import SignPropDeployer
from Deeploy.CommonExtensions.OptimizationPasses.TopologyOptimizationPasses.DebugPasses import DebugPrintMergePass
from Deeploy.CommonExtensions.OptimizationPasses.TopologyOptimizationPasses.LoweringOptimizationPasses import \
NCHWtoNHWCPass, TransposeMatmulInputsPass
from Deeploy.DeeployTypes import DeploymentPlatform, TopologyOptimizer
from Deeploy.Targets.Generic.TopologyOptimizationPasses.Passes import TransposeConstOptPass, TransposeMergePass


class SpatzDeployer(SignPropDeployer):

def __init__(self,
graph: gs.Graph,
deploymentPlatform: DeploymentPlatform,
inputTypes: Dict[str, Type[Pointer]],
loweringOptimizer: TopologyOptimizer,
scheduler: Callable = lambda x: x,
name: str = 'DeeployNetwork',
default_channels_first = False,
deeployStateDir: str = "DeeployStateDir",
inputOffsets: Dict[str, int] = {}):

super().__init__(graph,
deploymentPlatform,
inputTypes,
loweringOptimizer,
scheduler,
name,
default_channels_first = default_channels_first,
deeployStateDir = deeployStateDir)

# self.inputOffsets = inputOffsets
#
# self.loweringOptimizer.passes += [
# TransposeMatmulInputsPass(),
# NCHWtoNHWCPass(self.default_channels_first),
# TransposeMergePass(),
# TransposeConstOptPass(),
# DebugPrintMergePass()
# ]
71 changes: 71 additions & 0 deletions Deeploy/Targets/Spatz/Platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from typing import List

from Deeploy.DeeployTypes import VariableBuffer, TransientBuffer, ConstantBuffer, StructBuffer, \
NodeMapper, NodeTemplate, TopologyOptimizer, DeploymentEngine, DeploymentPlatform

# from Deeploy.Targets.Spatz.Bindings import SpatzAddBindings # <- TODO create this
from Deeploy.Targets.Generic.Bindings import BasicAddBindings
from Deeploy.Targets.Generic.Layers import AddLayer
from Deeploy.Targets.Generic.Parsers import AddParser

from Deeploy.Targets.Generic.Templates import AllocateTemplate as GenericAllocateTemplate
from Deeploy.Targets.Spatz.Templates import AllocateTemplate as SpatzAllocateTemplate
from Deeploy.Targets.Spatz.Templates import FreeTemplate as SpatzFreeTemplate

SpatzAddMapper = NodeMapper(AddParser(), BasicAddBindings)

SpatzMapping = {
'Add': AddLayer([SpatzAddMapper]),
# sparse attention : ...
}


class SpatzaVariableBuffer(VariableBuffer):
initTemplate = GenericAllocateTemplate.referenceInitTemplate
allocTemplate = SpatzAllocateTemplate.referenceAllocateTemplate
deallocTemplate = SpatzFreeTemplate.spatzLocalTemplate


class SpatzTransientBuffer(TransientBuffer):
initTemplate = GenericAllocateTemplate.referenceInitTemplate
allocTemplate = SpatzAllocateTemplate.referenceAllocateTemplate
deallocTemplate = SpatzFreeTemplate.spatzLocalTemplate


class SpatzConstantBuffer(ConstantBuffer):
initTemplate = GenericAllocateTemplate.referenceGlobalInitTemplate
allocTemplate = GenericAllocateTemplate.referenceAllocateTemplate
deallocTemplate = NodeTemplate("") # const not deallocated


class SpatzStructBuffer(StructBuffer):
initTemplate = GenericAllocateTemplate.referenceStructInitTemplate
allocTemplate = GenericAllocateTemplate.referenceAllocateTemplate
deallocTemplate = NodeTemplate("") # struct not deallocated ?


SpatzOptimizer = TopologyOptimizer([
# TODO add something ?
], name = "SpatzOptimizer")

includeList = [
"DeeploySpatzMath.h",
]


class SpatzEngine(DeploymentEngine):
def __init__(self, name: str, Mapping = SpatzMapping, initCode = "", includeList = includeList) -> None:
super().__init__(name, Mapping, initCode, includeList)


class SpatzPlatform(DeploymentPlatform):

def __init__( self,
engines = [SpatzEngine("SpatzVectorProcessor")],
variableBuffer = SpatzaVariableBuffer,
transientBuffer = SpatzTransientBuffer,
constantBuffer = SpatzConstantBuffer,
structBuffer = SpatzStructBuffer,
includeList: List[str] = includeList
):
super().__init__(engines, variableBuffer, constantBuffer, structBuffer, transientBuffer)
5 changes: 5 additions & 0 deletions Deeploy/Targets/Spatz/Templates/AddTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from Deeploy.DeeployTypes import NodeTemplate

... = NodeTemplate("\

")
5 changes: 5 additions & 0 deletions Deeploy/Targets/Spatz/Templates/AllocateTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from Deeploy.DeeployTypes import NodeTemplate

# allocate
referenceAllocateTemplate = NodeTemplate(
"${name} = (${type.typeName}) snrt_l1alloc(${type.referencedType.typeWidth//8} * ${size});\n")
5 changes: 5 additions & 0 deletions Deeploy/Targets/Spatz/Templates/FreeTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from Deeploy.DeeployTypes import NodeTemplate

# snrt_l1alloc currently does not support free-ing of memory (spatz/sw/snRuntime/src/alloc.c)
spatzLocalTemplate = NodeTemplate("")
spatzGlobalTemplate = NodeTemplate("")
2 changes: 2 additions & 0 deletions DeeployTest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ elseif(DEEPLOY_ARCH STREQUAL SNITCH)
add_subdirectory(Platforms/Snitch)
elseif(DEEPLOY_ARCH STREQUAL CHIMERA)
add_subdirectory(Platforms/Chimera)
elseif(DEEPLOY_ARCH STREQUAL SPATZ)
add_subdirectory(Platforms/Spatz)
elseif(platform STREQUAL GAP9)

# Search for hex files generated by Python code generator
Expand Down
17 changes: 17 additions & 0 deletions DeeployTest/Platforms/Spatz/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2024 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0

set(ProjectId ${TESTNAME})

file(GLOB_RECURSE SOURCES
main.c
)

add_deeploy_executable(${ProjectId} EXCLUDE_FROM_ALL ${SOURCES})

target_link_libraries(${ProjectId} PRIVATE network deeploylib)
target_compile_options(${ProjectId} INTERFACE network)

# Add QuestaSim RTL simulation for Spatz (mirroring Snitch's vsim)
add_spatz_vsim_simulation(${ProjectId})
69 changes: 69 additions & 0 deletions DeeployTest/Platforms/Spatz/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

#include <stdint.h>
#include <string.h>
#include "printf.h"

#include "Network.h"
#include "testinputs.h"
#include "testoutputs.h"

int main() {
const unsigned int cid = snrt_cluster_core_idx();

// do it only with one of the two spatz cores
if (cid==0){
printf("Initializing network...\r\n");

InitNetwork(0, 1);

for (uint32_t buf = 0; buf < DeeployNetwork_num_inputs; buf++) {
snrt_dma_start_1d(DeeployNetwork_inputs[buf], testInputVector[buf], DeeployNetwork_inputs_bytes[buf]);
}

printf("Running network...\r\n");
RunNetwork(0, 1);

int32_t tot_err = 0;
uint32_t tot = 0;
OUTPUTTYPE diff;
OUTPUTTYPE expected, actual;

for (uint32_t buf = 0; buf < DeeployNetwork_num_outputs; buf++) {
tot += DeeployNetwork_outputs_bytes[buf] / sizeof(OUTPUTTYPE);
for (uint32_t i = 0;
i < DeeployNetwork_outputs_bytes[buf] / sizeof(OUTPUTTYPE); i++) {
expected = ((OUTPUTTYPE *)testOutputVector[buf])[i];
actual = ((OUTPUTTYPE *)DeeployNetwork_outputs[buf])[i];
diff = expected - actual;

#if ISOUTPUTFLOAT == 1
// RUNWANG: Allow margin of error for float32_t
if ((diff < -1e-4) || (diff > 1e-4)) {
tot_err += 1;
printf("Expected: %10.6f ", (float)expected);
printf("Actual: %10.6f ", (float)actual);
printf("Diff: %10.6f at Index %12u in Output %u\r\n", (float)diff, i,
buf);
}
#else
// RUNWANG: No margin for integer comparison
if (diff != 0) {
tot_err += 1;
printf("Expected: %4d ", expected);
printf("Actual: %4d ", actual);
printf("Diff: %4d at Index %12u in Output %u\r\n", diff, i, buf);
}
#endif
}
}

printf("Errors: %d out of %d \r\n", tot_err, tot);

return tot_err;
} else {
// wait for core 0 to finish
snrt_cluster_hw_barrier();
return 0;
}

}
11 changes: 11 additions & 0 deletions DeeployTest/deeployRunner_spatz.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys

from testUtils.deeployRunner import main

if __name__ == "__main__":
sys.exit(
main(
default_platform = "Spatz",
default_simulator = "vsim",
)
)
2 changes: 2 additions & 0 deletions DeeployTest/testUtils/deeployRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def main(default_platform: Optional[str] = None,
"snitch": "Snitch",
"chimera": "Chimera",
"softhier": "SoftHier",
"spatz": "Spatz",
}

if args.platform:
Expand Down Expand Up @@ -388,6 +389,7 @@ def main(default_platform: Optional[str] = None,
"Snitch": "gvsoc",
"Chimera": "gvsoc",
"SoftHier": "gvsoc",
"Spatz": "vsim",
}
simulator = simulator_map.get(platform, "host")
log.info(f"No simulator specified, using default for {platform}: {simulator}")
Expand Down
19 changes: 18 additions & 1 deletion DeeployTest/testUtils/platformMapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from Deeploy.DeeployTypes import DeploymentPlatform, NetworkDeployer, TopologyOptimizer
from Deeploy.MemoryLevelExtension.MemoryLevels import MemoryHierarchy, MemoryLevel
from Deeploy.MemoryLevelExtension.NetworkDeployers.MemoryLevelDeployer import MemoryPlatform, MemoryPlatformWrapper
from Deeploy.Targets.Spatz.Deployer import SpatzDeployer
from Deeploy.Targets.Spatz.Platform import SpatzOptimizer, SpatzPlatform
from Deeploy.Targets.Chimera.Deployer import ChimeraDeployer
from Deeploy.Targets.Chimera.Platform import ChimeraOptimizer, ChimeraPlatform
from Deeploy.Targets.CortexM.Deployer import CMSISDeployer
Expand All @@ -31,7 +33,7 @@
from Deeploy.Targets.SoftHier.Platform import SoftHierOptimizer, SoftHierPlatform

_SIGNPROP_PLATFORMS = ["Apollo3", "Apollo4", "QEMU-ARM", "Generic", "MemPool", "SoftHier"]
_NONSIGNPROP_PLATFORMS = ["Siracusa", "Siracusa_w_neureka", "PULPOpen", "Snitch", "Chimera", "GAP9"]
_NONSIGNPROP_PLATFORMS = ["Siracusa", "Siracusa_w_neureka", "PULPOpen", "Snitch", "Chimera", "GAP9", "Spatz"]
_PLATFORMS = _SIGNPROP_PLATFORMS + _NONSIGNPROP_PLATFORMS


Expand Down Expand Up @@ -76,6 +78,9 @@ def mapPlatform(platformName: str) -> Tuple[DeploymentPlatform, bool]:
elif platformName == "Chimera":
Platform = ChimeraPlatform()

elif platformName == "Spatz":
Platform = SpatzPlatform()

else:
raise RuntimeError(f"Deployment platform {platformName} is not implemented")

Expand Down Expand Up @@ -272,6 +277,18 @@ def mapDeployer(platform: DeploymentPlatform,
name = name,
default_channels_first = default_channels_first,
deeployStateDir = deeployStateDir)

elif isinstance(platform, (SpatzPlatform)):
deployer = SpatzDeployer(
graph,
platform,
inputTypes,
SpatzOptimizer,
scheduler,
name = name,
default_channels_first = default_channels_first,
deeployStateDir = deeployStateDir
)

else:
raise RuntimeError(f"Deployer for platform {platform} is not implemented")
Expand Down
8 changes: 8 additions & 0 deletions DeeployTest/test_platforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ def param_id(param):
"model_tests": SNITCH_MODEL_TESTS,
"default_num_cores": SNITCH_DEFAULT_NUM_CORES,
},
"spatz": {
"platform": "Spatz",
"simulator": "vsim",
# TODO: Define KERNEL_TESTS and MODEL_TESTS for Spatz
"kernel_tests": [],
"model_tests": [],
# "default_num_cores": <set if known>,
},
"gap9": {
"platform": "GAP9",
"simulator": "gvsoc",
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ ${LLVM_INSTALL_DIR}: ${TOOLCHAIN_DIR}/llvm-project
llvm: ${LLVM_INSTALL_DIR}


# runtimes for different architectures
${LLVM_CLANG_RT_RISCV_RV32IM}: ${TOOLCHAIN_DIR}/llvm-project
cd ${TOOLCHAIN_DIR}/llvm-project && mkdir -p build-compiler-rt-riscv-rv32im \
&& cd build-compiler-rt-riscv-rv32im; \
Expand Down
Loading