Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions .github/workflows/ci-platform-generic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ jobs:
testFloatSoftmax
testFloatTranspose
testFloatMul
testFloatPow
testFloatSqrt
testFloatRMSNorm
testFloat16Pow
testFloat16Sqrt
testFloat16RMSNorm
Quant
Dequant
QuantizedLinear
Expand Down
11 changes: 5 additions & 6 deletions Deeploy/DeeployTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,15 +325,15 @@ def fromNode(cls, node: gs.Node):
return (cls(name = node.name, shape = node.shape if not isinstance(node, gs.Constant) else node.values.shape))

def has_live_aliases(self, ctxt: NetworkContext) -> bool:
"""Checks whether this VariableBuffer has any live aliases, i.e. buffers that are still live and are aliased by this buffer.
"""Checks whether this VariableBuffer has any live ancestors, i.e. buffers that are still live and are aliased by this buffer.
Parameters
----------
ctxt : NetworkContext
Current NetworkContext
Returns
-------
bool
True if this VariableBuffer has any live aliases, False otherwise
True if this VariableBuffer has any live ancestors, False otherwise
"""
# Do a breadth-first search across the aliasing double-linked list
live = self._live
Expand Down Expand Up @@ -2562,10 +2562,10 @@ def codeTransform(self, verbose: CodeGenVerbosity = _NoVerbosity):
self.ctxt = layer.codeTransform(self.ctxt, verbose)
self.transformed = True

def _selectEngine(self, node: gs.Node) -> DeploymentEngine:
def _mapNode(self, node: gs.Node) -> Union[ONNXLayer, Any]:
for engine in self.Platform.engines:
if node.op in engine.Mapping:
return engine
return engine.Mapping[node.op](node)
raise RuntimeError(f"No mapping found for node {node.name} with op type {node.op}")

def _bindLayers(self):
Expand All @@ -2582,8 +2582,7 @@ def _bindLayers(self):
flatSchedule += subGraph

for node in flatSchedule:
engine = self._selectEngine(node)
layer = engine.Mapping[node.op](node)
layer = self._mapNode(node)
if isinstance(layer, ONNXLayer):
log.debug(f" {SUCCESS_MARK} Bind {node.name} to layer {layer.__class__.__name__}")
self.layerBinding[layer.node.name] = layer
Expand Down
28 changes: 21 additions & 7 deletions Deeploy/Targets/Generic/Bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
from Deeploy.AbstractDataTypes import PointerClass
from Deeploy.CommonExtensions.CodeTransformationPasses.MemoryAllocation import ArgumentStructGeneration, \
MemoryManagementGeneration, MemoryPassthroughGeneration
from Deeploy.CommonExtensions.DataTypes import FloatDataTypes, IntegerDataTypes, SignedIntegerDataTypes, float32_t, \
int8_t, int32_t, uint8_t
from Deeploy.CommonExtensions.DataTypes import FloatDataTypes, IntegerDataTypes, SignedIntegerDataTypes, float16_t, \
float32_t, int8_t, int32_t, uint8_t
from Deeploy.DeeployTypes import CodeTransformation, NodeBinding
from Deeploy.FutureExtension.CodeTransformationPasses.FutureCodeTransformation import FutureGeneration
from Deeploy.Targets.Generic.Templates import AddTemplate, BatchNormalizationTemplate, ConcatTemplate, ConvTemplate, \
ConvTransposeTemplate, DebugPrintTemplate, DequantTemplate, DummyTemplate, DWConvTemplate, FloatAddTemplate, \
FloatConvTemplate, FloatDivTemplate, FloatDWConvTemplate, FloatGELUTemplate, FloatGemmTemplate, \
FloatLayernormTemplate, FloatMatMulTemplate, FloatMaxPoolTemplate, FloatMulTemplate, FloatPadTemplate, \
FloatReduceMeanTemplate, FloatReluTemplate, FloatSoftmaxTemplate, GatherTemplate, GemmTemplate, \
IntegerDivTemplate, ITAMaxTemplate, ITAPartialMaxTemplate, MatMulTemplate, MaxPoolTemplate, MulTemplate, \
PadTemplate, QuantTemplate, ReduceMeanTemplate, ReduceSumTemplate, RequantShiftTemplate, ReshapeTemplate, \
RQIntegerDivTemplate, RQSiGELUTemplate, SliceTemplate, TransposeTemplate, iGELUTemplate, iLayernormTemplate, \
iRMSNormTemplate, iSoftmaxTemplate
FloatPowTemplate, FloatReduceMeanTemplate, FloatReluTemplate, FloatSoftmaxTemplate, FloatSqrtTemplate, \
GatherTemplate, GemmTemplate, IntegerDivTemplate, ITAMaxTemplate, ITAPartialMaxTemplate, MatMulTemplate, \
MaxPoolTemplate, MulTemplate, PadTemplate, QuantTemplate, ReduceMeanTemplate, ReduceSumTemplate, \
RequantShiftTemplate, ReshapeTemplate, RQIntegerDivTemplate, RQSiGELUTemplate, SliceTemplate, TransposeTemplate, \
iGELUTemplate, iLayernormTemplate, iRMSNormTemplate, iSoftmaxTemplate
from Deeploy.Targets.Generic.TypeCheckers import AddChecker, BatchNormChecker, ConcatChecker, ConvChecker, \
DebugPrintChecker, DequantChecker, DivChecker, DummyChecker, GatherChecker, GELUChecker, GEMMChecker, \
LayerNormChecker, MatMulChecker, MaxPoolChecker, MulChecker, PadChecker, QuantChecker, ReduceMeanChecker, \
Expand Down Expand Up @@ -118,6 +118,20 @@
BasicTransformer)
]

BasicPowBindings = [
NodeBinding(DummyChecker([PointerClass(float32_t), PointerClass(float32_t)], [PointerClass(float32_t)]),
FloatPowTemplate.referenceTemplate, BasicTransformer),
NodeBinding(DummyChecker([PointerClass(float16_t), PointerClass(float16_t)], [PointerClass(float16_t)]),
FloatPowTemplate.referenceTemplate, BasicTransformer)
]

BasicSqrtBindings = [
NodeBinding(DummyChecker([PointerClass(float32_t)], [PointerClass(float32_t)]), FloatSqrtTemplate.referenceTemplate,
BasicTransformer),
NodeBinding(DummyChecker([PointerClass(float16_t)], [PointerClass(float16_t)]), FloatSqrtTemplate.referenceTemplate,
BasicTransformer)
]

BasicDivBindings = [
NodeBinding(DivChecker([PointerClass(int32_t), PointerClass(int32_t)], [PointerClass(int32_t)]),
IntegerDivTemplate.referenceTemplate, BasicTransformer)
Expand Down
12 changes: 12 additions & 0 deletions Deeploy/Targets/Generic/Layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ def computeOps(self):
return matmul + rqs


class PowLayer(ONNXLayer):

def __init__(self, maps: List[NodeMapper]):
super().__init__(maps)


class SqrtLayer(ONNXLayer):

def __init__(self, maps: List[NodeMapper]):
super().__init__(maps)


class DivLayer(ONNXLayer):

def __init__(self, maps: List[NodeMapper]):
Expand Down
120 changes: 120 additions & 0 deletions Deeploy/Targets/Generic/Parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,65 @@ def parseNodeCtxt(self,
return ctxt, True


class PowParser(NodeParser):

def __init__(self):
super().__init__()

def parseNode(self, node: gs.Node) -> bool:
return node.op == 'Pow' and len(node.inputs) == 2 and len(node.outputs) == 1

def parseNodeCtxt(self,
ctxt: NetworkContext,
node: gs.Node,
channels_first: bool = True) -> Tuple[NetworkContext, bool]:

# Lookup both inputs (data and exponent)
data_in = ctxt.lookup(node.inputs[0].name)
exponent_tensor = ctxt.lookup(node.inputs[1].name)
data_out = ctxt.lookup(node.outputs[0].name)

self.operatorRepresentation['data_in'] = data_in.name
self.operatorRepresentation['exponent'] = exponent_tensor.name
self.operatorRepresentation['data_out'] = data_out.name

# Extract exponent value from the constant tensor
if isinstance(exponent_tensor, ConstantBuffer):
exp_value = int(exponent_tensor.values.flatten()[0])
self.operatorRepresentation['exponent_value'] = exp_value
else:
# Tensor exponent not supported
raise ValueError(f"Node {node.name}: Exponent must be a constant. "
f"Variable tensor exponents are not supported.")

self.operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, True


class SqrtParser(NodeParser):

def __init__(self):
super().__init__()

def parseNode(self, node: gs.Node) -> bool:
return node.op == 'Sqrt' and len(node.inputs) == 1 and len(node.outputs) == 1

def parseNodeCtxt(self,
ctxt: NetworkContext,
node: gs.Node,
channels_first: bool = True) -> Tuple[NetworkContext, bool]:

data_in = ctxt.lookup(node.inputs[0].name)
data_out = ctxt.lookup(node.outputs[0].name)

self.operatorRepresentation['data_in'] = data_in.name
self.operatorRepresentation['data_out'] = data_out.name
self.operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, True


class DivParser(NodeParser):

def __init__(self):
Expand Down Expand Up @@ -2747,3 +2806,64 @@ def parseNodeCtxt(self,
"ch_im_out"] * self.operatorRepresentation["dim_im_out_y"]
return newCtxt, True
return ctxt, False


############################


class PowParser(NodeParser):

def __init__(self):
super().__init__()

def parseNode(self, node: gs.Node) -> bool:
return node.op == 'Pow' and len(node.inputs) == 2 and len(node.outputs) == 1

def parseNodeCtxt(self,
ctxt: NetworkContext,
node: gs.Node,
channels_first: bool = True) -> Tuple[NetworkContext, bool]:

data_in = ctxt.lookup(node.inputs[0].name)
exponent = node.inputs[1]
data_out = ctxt.lookup(node.outputs[0].name)

self.operatorRepresentation['data_in'] = data_in.name
self.operatorRepresentation['data_out'] = data_out.name

# Check if exponent is a constant
if isinstance(exponent, gs.Constant):
exp_value = float(exponent.values)
self.operatorRepresentation['exponent'] = exp_value
self.operatorRepresentation['is_constant_exp'] = True
else:
exp_tensor = ctxt.lookup(exponent.name)
self.operatorRepresentation['exponent'] = exp_tensor.name
self.operatorRepresentation['is_constant_exp'] = False

self.operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, True


class SqrtParser(NodeParser):

def __init__(self):
super().__init__()

def parseNode(self, node: gs.Node) -> bool:
return node.op == 'Sqrt' and len(node.inputs) == 1 and len(node.outputs) == 1

def parseNodeCtxt(self,
ctxt: NetworkContext,
node: gs.Node,
channels_first: bool = True) -> Tuple[NetworkContext, bool]:

data_in = ctxt.lookup(node.inputs[0].name)
data_out = ctxt.lookup(node.outputs[0].name)

self.operatorRepresentation['data_in'] = data_in.name
self.operatorRepresentation['data_out'] = data_out.name
self.operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, True
23 changes: 14 additions & 9 deletions Deeploy/Targets/Generic/Platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@
BasicDequantBindings, BasicDivBindings, BasicDWConv1DBinding, BasicDWConv2DBindings, BasicGatherBindings, \
BasicGELUBindings, BasicGEMMBindings, BasicITAPartialSoftmaxBinding, BasicITASoftmaxBinding, \
BasicLayerNormBindings, BasicMatMulBindings, BasicMaxPool1DBindings, BasicMaxPool2DBindings, BasicMulBindings, \
BasicPad1DBindings, BasicPad2DBindings, BasicQuantBindings, BasicReduceMeanBindings, BasicReduceSumBindings, \
BasicReluBinding, BasicReshapeBindings, BasicRQIntegerDivBinding, BasicRQSBindings, BasicRQSGELUBinding, \
BasicSliceBindings, BasicSoftmaxBindings, BasicTransposeBindings, DummyBinding
BasicPad1DBindings, BasicPad2DBindings, BasicPowBindings, BasicQuantBindings, BasicReduceMeanBindings, \
BasicReduceSumBindings, BasicReluBinding, BasicReshapeBindings, BasicRQIntegerDivBinding, BasicRQSBindings, \
BasicRQSGELUBinding, BasicSliceBindings, BasicSoftmaxBindings, BasicSqrtBindings, BasicTransposeBindings, \
DummyBinding
from Deeploy.Targets.Generic.Layers import AddLayer, BatchNormalizationLayer, ConcatLayer, ConvLayer, \
ConvTransposeLayer, DebugPrintLayer, DequantLayer, DivLayer, GatherLayer, GELULayer, GEMMLayer, ITAMaxLayer, \
LayerNormLayer, MatMulLayer, MaxPoolLayer, MulLayer, PadLayer, QuantLayer, ReduceMeanLayer, ReduceSumLayer, \
ReluLayer, RequantShiftLayer, ReshapeLayer, RQIntegerDivLayer, RQSiGELULayer, SliceLayer, SoftmaxLayer, \
TransposeLayer
LayerNormLayer, MatMulLayer, MaxPoolLayer, MulLayer, PadLayer, PowLayer, QuantLayer, ReduceMeanLayer, \
ReduceSumLayer, ReluLayer, RequantShiftLayer, ReshapeLayer, RQIntegerDivLayer, RQSiGELULayer, SliceLayer, \
SoftmaxLayer, SqrtLayer, TransposeLayer
from Deeploy.Targets.Generic.Parsers import AddParser, BatchNormParser, ConcatParser, ConvTranspose1DParser, \
DebugParser, DequantParser, DivParser, DummyParser, FlattenParser, GatherParser, GELUParser, GenericConv1DParser, \
GenericConv2DParser, GenericDWConv1DParser, GenericDWConv2DParser, GenericGEMMParser, GenericMaxPool2DParser, \
IntegerDivParser, ITAMaxParser, ITAPartialMaxParser, LayerNormParser, MatMulParser, MaxPool1DParser, MulParser, \
Pad1DParser, Pad2DParser, QuantParser, ReduceMeanParser, ReduceSumParser, ReluParser, RequantShiftParser, \
ReshapeParser, RQIntegerDivParser, RQSiGELUParser, SliceParser, SoftmaxParser, TransposeParser, UnsqueezeParser, \
iLayerNormParser, iSoftmaxParser
Pad1DParser, Pad2DParser, PowParser, QuantParser, ReduceMeanParser, ReduceSumParser, ReluParser, \
RequantShiftParser, ReshapeParser, RQIntegerDivParser, RQSiGELUParser, SliceParser, SoftmaxParser, SqrtParser, \
TransposeParser, UnsqueezeParser, iLayerNormParser, iSoftmaxParser
from Deeploy.Targets.Generic.Templates import AllocateTemplate, FreeTemplate
from Deeploy.Targets.Generic.TopologyOptimizationPasses.Passes import DequantPatternPass, ExtractPaddingFromConvPass, \
ExtractPaddingFromPoolPass, MatMulAddMergePass, MergeConstAddAndRequantPass, QuantPatternPass, \
Expand All @@ -52,6 +53,8 @@
MaxPoolMapper = NodeMapper(GenericMaxPool2DParser(), BasicMaxPool2DBindings)
MaxPool1DMapper = NodeMapper(MaxPool1DParser(), BasicMaxPool1DBindings)
MulMapper = NodeMapper(MulParser(), BasicMulBindings)
PowMapper = NodeMapper(PowParser(), BasicPowBindings)
SqrtMapper = NodeMapper(SqrtParser(), BasicSqrtBindings)
Pad1DMapper = NodeMapper(Pad1DParser(), BasicPad1DBindings)
Pad2DMapper = NodeMapper(Pad2DParser(), BasicPad2DBindings)
ReduceMeanMapper = NodeMapper(ReduceMeanParser(), BasicReduceMeanBindings)
Expand Down Expand Up @@ -98,6 +101,8 @@
'MatMulInteger': MatMulLayer([MatMulMapper]),
'MaxPool': MaxPoolLayer([MaxPool1DMapper, MaxPoolMapper]),
'Mul': MulLayer([MulMapper]),
'Pow': PowLayer([PowMapper]),
'Sqrt': SqrtLayer([SqrtMapper]),
'Pad': PadLayer([Pad1DMapper, Pad2DMapper]),
'ReduceMean': ReduceMeanLayer([ReduceMeanMapper]),
'ReduceSum': ReduceSumLayer([ReduceSumMapper]),
Expand Down
48 changes: 48 additions & 0 deletions Deeploy/Targets/Generic/Templates/FloatPowTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0

from typing import Dict, List, Tuple

import numpy as np

from Deeploy.DeeployTypes import NetworkContext, NodeTemplate, OperatorRepresentation


class _PowTemplate(NodeTemplate):

def alignToContext(self, ctxt: NetworkContext,
operatorRepresentation: OperatorRepresentation) -> Tuple[NetworkContext, Dict, List[str]]:

# Get input and output tensors
data_in = ctxt.lookup(operatorRepresentation['data_in'])
data_out = ctxt.lookup(operatorRepresentation['data_out'])

# Get data type (fp32 or fp16)
data_type = data_in._type.typeName
operatorRepresentation['data_type'] = data_type

# Exponent must be a constant integer
if 'exponent' in operatorRepresentation:
exponent_input = operatorRepresentation['exponent']
if isinstance(exponent_input, str):
# It's a tensor name - not supported for integer exponent version
raise ValueError("Tensor exponent not supported. Use constant integer exponent.")
else:
# Convert to integer
operatorRepresentation['exponent_value'] = int(exponent_input)

# Calculate size
operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, operatorRepresentation, []


referenceTemplate = _PowTemplate("""
// Pow (Name: ${nodeName}, Op: ${nodeOp})
% if 'float32' in data_type:
Pow_fp32_int32_fp32(${data_in}, ${exponent_value}, ${data_out}, ${size});
% elif 'float16' in data_type:
Pow_fp16_int32_fp16(${data_in}, ${exponent_value}, ${data_out}, ${size});
% endif
""")
38 changes: 38 additions & 0 deletions Deeploy/Targets/Generic/Templates/FloatSqrtTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna
#
# SPDX-License-Identifier: Apache-2.0

from typing import Dict, List, Tuple

import numpy as np

from Deeploy.DeeployTypes import NetworkContext, NodeTemplate, OperatorRepresentation


class _SqrtTemplate(NodeTemplate):

def alignToContext(self, ctxt: NetworkContext,
operatorRepresentation: OperatorRepresentation) -> Tuple[NetworkContext, Dict, List[str]]:

# Get input and output tensors
data_in = ctxt.lookup(operatorRepresentation['data_in'])
data_out = ctxt.lookup(operatorRepresentation['data_out'])

# Get data type (fp32 or fp16)
data_type = data_in._type.typeName
operatorRepresentation['data_type'] = data_type

# Calculate size
operatorRepresentation['size'] = int(np.prod(data_in.shape))

return ctxt, operatorRepresentation, []


referenceTemplate = _SqrtTemplate("""
// Sqrt (Name: ${nodeName}, Op: ${nodeOp})
% if 'float32' in data_type:
Sqrt_fp32_fp32(${data_in}, ${data_out}, ${size});
% elif 'float16' in data_type:
Sqrt_fp16_fp16(${data_in}, ${data_out}, ${size});
% endif
""")
Binary file added DeeployTest/Tests/testFloat16Pow/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16Pow/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16Pow/outputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16RMSNorm/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16RMSNorm/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16RMSNorm/outputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16Sqrt/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16Sqrt/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloat16Sqrt/outputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatPow/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatPow/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatPow/outputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatRMSNorm/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatRMSNorm/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatRMSNorm/outputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatSqrt/inputs.npz
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatSqrt/network.onnx
Binary file not shown.
Binary file added DeeployTest/Tests/testFloatSqrt/outputs.npz
Binary file not shown.
Loading