Skip to content

Commit

Permalink
add snitch support
Browse files Browse the repository at this point in the history
  • Loading branch information
tahaelbayad committed Nov 14, 2024
1 parent 63a1916 commit 1619545
Show file tree
Hide file tree
Showing 34 changed files with 3,159 additions and 3 deletions.
35 changes: 33 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ if(TOOLCHAIN STREQUAL GCC)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

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

if(platform STREQUAL MemPool)
message(STATUS "Building for platform 'MemPool'")
Expand All @@ -30,6 +30,8 @@ elseif(platform STREQUAL PULPOpen)
message(STATUS "Building for platform 'PULP-Open'")
elseif(platform STREQUAL Generic)
message(STATUS "Building for platform 'Generic'")
elseif(platform STREQUAL Snitch)
message(STATUS "Building for platform 'Snitch'")
else()
message(FATAL_ERROR "Invalid platform '${platform}' specified!")
endif()
Expand Down Expand Up @@ -181,4 +183,33 @@ if(platform STREQUAL Siracusa OR platform STREQUAL Siracusa_w_neureka OR platfor

endif()

if(platform STREQUAL Snitch)

if(TOOLCHAIN STREQUAL LLVM)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/snitch/toolchain_llvm.cmake)
else()
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/snitch/toolchain_gcc.cmake)
endif()

include(${CMAKE_CURRENT_LIST_DIR}/cmake/snitch/snitch.cmake)

include(${CMAKE_CURRENT_LIST_DIR}/cmake/snitch/snitch_cluster/snitch_cluster.cmake)

project(deeploy LANGUAGES C ASM)

message(STATUS "============================= ${platform} Configuration ============================")
message(STATUS "[cMake ] Number of total cores = " ${NUM_CORES})
message(STATUS "================================================================================")
message(STATUS "")

add_subdirectory(TargetLibraries/Generic)
add_subdirectory(TargetLibraries/Snitch)
target_include_directories(deeploysnitch PUBLIC TargetLibraries/Generic/inc)

add_subdirectory(DeeployTest)
target_link_libraries(deeploylib INTERFACE deeploybasic deeploysnitch)

endif()


print_simulation_config()
77 changes: 77 additions & 0 deletions Deeploy/Targets/Snitch/Deployer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# ----------------------------------------------------------------------
#
# File: SnitchDeployer.py
#
# Last edited: 23.04.2024
#
# Copyright (C) 2024, ETH Zurich and University of Bologna.
#
# Authors:
# - Philip Wiese ([email protected]), ETH Zurich
#
# ----------------------------------------------------------------------
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Callable, Dict, Type

import onnx_graphsurgeon as gs

from Deeploy.AbstractDataTypes import Pointer
from Deeploy.DeeployTypes import DeploymentPlatform, TopologyOptimizer

# from Deeploy.NetworkDeployers.SignPropDeployer import SignPropDeployer
from Deeploy.CommonExtensions.NetworkDeployers.SignPropDeployer import SignPropDeployer

# from Deeploy.OptimizationPasses.TopologyOptimizationPasses.BasicPasses import ReshapeConstOptPass, \
# TransposeConstOptPass, TransposeMergePass, TransposeSplitPass
from Deeploy.Targets.Generic.TopologyOptimizationPasses.Passes import ReshapeConstOptPass, TransposeConstOptPass, \
TransposeMergePass, TransposeSplitPass

# from Deeploy.OptimizationPasses.TopologyOptimizationPasses.LoweringOptimizationPasses import NCHWtoNHWCPass, \
# RemoveGlobalOutputReshapePass, TransposeMatmulInputsPass
from Deeploy.CommonExtensions.OptimizationPasses.TopologyOptimizationPasses.LoweringOptimizationPasses import \
NCHWtoNHWCPass, RemoveGlobalOutputReshapePass, TransposeMatmulInputsPass

class SnitchDeployer(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 = {}):
super().__init__(graph,
deploymentPlatform,
inputTypes,
loweringOptimizer,
scheduler,
name,
default_channels_first = default_channels_first,
deeployStateDir = deeployStateDir,
inputOffsets = inputOffsets)

self.loweringOptimizer.passes += [
TransposeMatmulInputsPass(),
NCHWtoNHWCPass(self.default_channels_first),
TransposeSplitPass(),
TransposeMergePass(),
TransposeConstOptPass(),
ReshapeConstOptPass(),
RemoveGlobalOutputReshapePass(),
]
179 changes: 179 additions & 0 deletions Deeploy/Targets/Snitch/Platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# ----------------------------------------------------------------------
#
# File: SnitchPlatform.py
#
# Last edited: 23.04.2024
#
# Copyright (C) 2024, ETH Zurich and University of Bologna.
#
# Authors:
# - Philip Wiese ([email protected]), ETH Zurich
#
# ----------------------------------------------------------------------
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import List

import numpy as np

# from Deeploy.Bindings.BasicBindings import BasicGatherBindings, BasicMatMulBinding, BasicPad1DBindings, \
# BasicPad2DBindings, BasicReshapeBindings, BasicRQIntegerDivBinding

from Deeploy.Targets.Generic.Bindings import BasicGatherBindings,BasicMatMulBinding, BasicPad1DBindings, \
BasicPad2DBindings, BasicReshapeBindings, BasicRQIntegerDivBinding

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

# from Deeploy.Layers.BasicLayers import GatherLayer, MatMulLayer, PadLayer, ReshapeLayer, RQIntegerDivLayer
from Deeploy.Targets.Generic.Layers import GatherLayer, MatMulLayer, PadLayer, ReshapeLayer, RQIntegerDivLayer

# from Deeploy.OptimizationPasses.TopologyOptimizationPasses.BasicPasses import IntegerDivRequantMergePass, \
# MergeConstAddAndRequantPass, MergeTrueIntegerDivRequantShiftPass, RQSSplitPass, SkipEmptyConcatPass, \
# SkipUnityRequantPass, iGELURequantMergePass, iHardswishRequantMergePass

from Deeploy.Targets.Generic.TopologyOptimizationPasses.Passes import IntegerDivRequantMergePass, \
MergeConstAddAndRequantPass, MergeTrueIntegerDivRequantShiftPass, RQSSplitPass, SkipEmptyConcatPass, \
SkipUnityRequantPass, iGELURequantMergePass, iHardswishRequantMergePass

# from Deeploy.Parsers.BasicParsers import GatherParser, MatMulParser, Pad1DParser, Pad2DParser, RQIntegerDivParser, \
# UnsqueezeParser
from Deeploy.Targets.Generic.Parsers import GatherParser, MatMulParser, Pad1DParser, Pad2DParser, RQIntegerDivParser, \
UnsqueezeParser

# from Deeploy.Templates.BasicTemplates import AllocateTemplate as BasicAllocateTemplate
from Deeploy.Targets.Generic.Templates import AllocateTemplate as BasicAllocateTemplate

from Deeploy.Targets.Snitch.Templates import AllocateTemplate, FreeTemplate

GatherMapper = NodeMapper(GatherParser(), BasicGatherBindings)
Pad1DMapper = NodeMapper(Pad1DParser(), BasicPad1DBindings)
Pad2DMapper = NodeMapper(Pad2DParser(), BasicPad2DBindings)
UnsqueezeMapper = NodeMapper(UnsqueezeParser(), BasicReshapeBindings)

RQIntegerDivMapper = NodeMapper(RQIntegerDivParser(), [BasicRQIntegerDivBinding])

MatMulMapper = NodeMapper(MatMulParser(), [BasicMatMulBinding])

SnitchMapping = {
'RQIntegerDiv': RQIntegerDivLayer([RQIntegerDivMapper]),
'Gather': GatherLayer([GatherMapper]),
'Pad': PadLayer([Pad1DMapper, Pad2DMapper]),
'Unsqueeze': ReshapeLayer([UnsqueezeMapper]),
'MatMul': MatMulLayer([MatMulMapper]),
}


class SnitchVariableBuffer(VariableBuffer):

initTemplate = AllocateTemplate.snitchL2InitTemplate
allocTemplate = AllocateTemplate.snitchGenericAllocate
deallocTemplate = FreeTemplate.snitchGenericFree

def _bufferRepresentation(self):

if hasattr(self, "_memoryLevel"):
memoryLevel = self._memoryLevel
else:
memoryLevel = None

return {
"type": self._instance,
"name": self.name,
"size": int(np.prod(self.shape)),
"_memoryLevel": memoryLevel
}


class SnitchTransientBuffer(TransientBuffer):

initTemplate = AllocateTemplate.snitchL2InitTemplate
allocTemplate = AllocateTemplate.snitchGenericAllocate
deallocTemplate = FreeTemplate.snitchGenericFree

# allocTemplate = AllocateTemplate.snitchL2AllocateTemplate
# deallocTemplate = FreeTemplate.snitchL2GlobalTemplate

def _bufferRepresentation(self):

if hasattr(self, "_memoryLevel"):
memoryLevel = self._memoryLevel
else:
memoryLevel = None

return {"type": self._type, "name": self.name, "size": self.size, "_memoryLevel": memoryLevel}


class SnitchConstantBuffer(ConstantBuffer):

initTemplate = AllocateTemplate.snitchGenericGlobalInitTemplate
allocTemplate = AllocateTemplate.snitchL2GlobalAllocateTemplate
deallocTemplate = FreeTemplate.snitchL2GlobalTemplate

def _bufferRepresentation(self):
nodeRep = super()._bufferRepresentation()

if hasattr(self, "_memoryLevel"):
memoryLevel = self._memoryLevel
else:
memoryLevel = None

nodeRep["_memoryLevel"] = memoryLevel

return nodeRep


class SnitchStructBuffer(StructBuffer):

initTemplate = BasicAllocateTemplate.referenceStructInitTemplate
allocTemplate = BasicAllocateTemplate.referenceStructAllocateTemplate
deallocTemplate = NodeTemplate("")


SnitchOptimizer = TopologyOptimizer([
SkipEmptyConcatPass(),
SkipUnityRequantPass(previous_op_regex = "Concat", num_inputs = 2),
SkipUnityRequantPass(previous_op_regex = "Reshape|Transpose", num_inputs = 1),
SkipUnityRequantPass(previous_op_regex = "Reshape|Transpose", num_inputs = 1),
RQSSplitPass(),
MergeTrueIntegerDivRequantShiftPass(),
IntegerDivRequantMergePass(),
iGELURequantMergePass(),
iHardswishRequantMergePass(),
MergeConstAddAndRequantPass(),
])

_includeList = [
"snrt.h",
"DeeploySnitchMath.h",
]


class SnitchClusterEngine(DeploymentEngine):

def __init__(self, name: str, Mapping = SnitchMapping, initCode = "", includeList = _includeList) -> None:
super().__init__(name, Mapping, initCode, includeList)


class SnitchPlatform(DeploymentPlatform):

def __init__(self,
engines = [SnitchClusterEngine("SnitchCluster")],
variableBuffer = SnitchVariableBuffer,
constantBuffer = SnitchConstantBuffer,
structBuffer = SnitchStructBuffer,
transientBuffer = SnitchTransientBuffer,
includeList: List[str] = _includeList):
super().__init__(engines, variableBuffer, constantBuffer, structBuffer, transientBuffer)
79 changes: 79 additions & 0 deletions Deeploy/Targets/Snitch/Templates/AllocateTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# ----------------------------------------------------------------------
#
# File: AllocateTemplate.py
#
# Last edited: 23.04.2024
#
# Copyright (C) 2024, ETH Zurich and University of Bologna.
#
# Authors:
# - Philip Wiese ([email protected]), ETH Zurich
#
# ----------------------------------------------------------------------
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from Deeploy.DeeployTypes import NodeTemplate

snitchL2InitTemplate = NodeTemplate("${type.typeName} ${name};\n")

snitchL1InitTemplate = NodeTemplate("${type.typeName} ${name};\n")

snitchL2AllocateTemplate = NodeTemplate(
"${name} = (${type.typeName}) snrt_l3alloc(sizeof(${type.referencedType.typeName}) * ${size});\n")

snitchL1AllocateTemplate = NodeTemplate(
"${name} = (${type.typeName}) snrt_l1alloc(sizeof(${type.referencedType.typeName}) * ${size});\n")

snitchL2GlobalInitTemplate = NodeTemplate("static ${type.referencedType.typeName} ${name}[${size}] = {${values}};\n")

snitchL1GlobalInitTemplate = NodeTemplate("static ${type.referencedType.typeName} ${name}[${size}] = {${values}};\n")

snitchL2GlobalAllocateTemplate = NodeTemplate("")

snitchL1GlobalAllocateTemplate = NodeTemplate("")

snitchL2StructInitTemplate = NodeTemplate("""static ${type.typeName} ${name};
""")

snitchL2StructAllocateTemplate = NodeTemplate(""" % for key, value in structDict.items():
${name}.${key} = ${value};
% endfor """)

snitchGenericStructInitTemplate = NodeTemplate("""
% if _memoryLevel == "L1":
static ${type.typeName} ${name};\n
% elif _memoryLevel == "L2" or _memoryLevel is None:
static ${type.typeName} ${name};\n
% endif
""")

snitchGenericGlobalInitTemplate = NodeTemplate("""
% if _memoryLevel == "L1":
static ${type.referencedType.typeName} ${name}[${size}] = {${values}};\n
% elif _memoryLevel == "L2" or _memoryLevel is None:
static ${type.referencedType.typeName} ${name}[${size}] = {${values}};\n
% endif
""")

snitchGenericAllocate = NodeTemplate("""
% if _memoryLevel == "L1":
${name} = (${type.typeName}) snrt_l1alloc(sizeof(${type.referencedType.typeName}) * ${size});\n
% elif _memoryLevel == "L2" or _memoryLevel is None:
${name} = (${type.typeName}) snrt_l3alloc(sizeof(${type.referencedType.typeName}) * ${size});\n% else:
//COMPILER BLOCK - MEMORYLEVEL ${_memoryLevel} NOT FOUND \n
${name} = (${type.typeName}) snrt_l3alloc(sizeof(${type.referencedType.typeName}) * ${size});\n
// ${name} with size ${size} allocated in L2!
% endif
""")
Loading

0 comments on commit 1619545

Please sign in to comment.