diff options
author | Fredrik Svedberg <fredrik.svedberg@arm.com> | 2023-04-11 22:35:04 +0200 |
---|---|---|
committer | Fredrik Svedberg <fredrik.svedberg@arm.com> | 2023-04-17 14:16:44 +0200 |
commit | 0ac0804e76e098695ee2b8a9e24e2f0a1efc324f (patch) | |
tree | 9ccb766221987a415244079ed6c596a47d693b20 /ethosu/vela/operation_util.py | |
parent | c1ad80b3a581dd39b39a112d6c2026f6560207a4 (diff) | |
download | ethos-u-vela-0ac0804e76e098695ee2b8a9e24e2f0a1efc324f.tar.gz |
MLBEDSW-7196 Add LSTM support
Added int8 and int16 UNIDIRECTIONAL_SEQUENCE_LSTM support.
The implementation does not include support for:
* CIFG
* Peephole
* Projection
* Normalisation
This change also:
* Removed unused Op.BlockLSTM operation type.
* Removed the only one consumer limitation on putting the SplitSliceRead
on the tensor consumer(s), if all consumers fullfills the requirements
* Added Op.VariableTensorWrite as a Operation.memory_function to make
sure writes to variable tensors:
* Always use linear mode
* Are not moved to fast scratch
* Are not fused with other elementwise operation tensor ranges
Change-Id: Ief831738924ac3d1f2ba6d41f10bd6dc969911f3
Signed-off-by: Fredrik Svedberg <fredrik.svedberg@arm.com>
Diffstat (limited to 'ethosu/vela/operation_util.py')
-rw-r--r-- | ethosu/vela/operation_util.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/ethosu/vela/operation_util.py b/ethosu/vela/operation_util.py index 74836eb2..ef4949fa 100644 --- a/ethosu/vela/operation_util.py +++ b/ethosu/vela/operation_util.py @@ -27,8 +27,10 @@ from .operation import ActivationFunction from .operation import Op from .operation import Operation from .operation import Padding +from .reader_util import clone_and_reshape_tensor from .shape4d import Shape4D from .tensor import create_const_tensor +from .tensor import create_equivalence_id from .tensor import QuantizationParameters from .tensor import Tensor @@ -117,6 +119,55 @@ def create_cast_op( return op +def create_fused_activation(op_type: Op, name: str, ifm: Tensor, quantization: QuantizationParameters) -> Operation: + assert op_type.is_activation_op() + op = create_avgpool_nop(name) + op.activation = ActivationFunction(op_type) + ofm = Tensor(ifm.shape, ifm.dtype, f"{op.name}_tens0") + ofm.quantization = quantization + op.add_input_tensor(ifm) + op.set_output_tensor(ofm) + op.set_ifm_ofm_shapes() + return op + + +def create_fullyconnected( + name: str, + ifm: Tensor, + weights: Tensor, + bias: Optional[Tensor], + quantization: QuantizationParameters, + vela_weight_order: bool = True, +) -> Operation: + # Reshape weights if needed + if not vela_weight_order: + weights = clone_and_reshape_tensor(weights, (1, 0), False) + + n_ofm = weights.shape[-1] + + # Setup bias if needed + if not bias: + bias_values = [0] * n_ofm + dtype = DataType.int64 if ifm.dtype == DataType.int16 else DataType.int32 + bias = create_const_tensor(f"{name}_bias", [n_ofm], dtype, bias_values) + # Set equivalence_id based on values to avoid placing duplicate data in flash + bias.equivalence_id = create_equivalence_id(tuple(bias_values)) + bias.value_id = bias.equivalence_id + + # Setup ofm + ofm = Tensor([ifm.shape[0], n_ofm], ifm.dtype, f"{name}_tens0") + ofm.quantization = quantization + + # Create op and add tensors + op = Operation(Op.FullyConnected, name) + op.add_input_tensor(ifm) + op.add_input_tensor(weights) + op.add_input_tensor(bias) + op.set_output_tensor(ofm) + op.set_ifm_ofm_shapes() + return op + + def create_depthwise_maxpool( name: str, ifm: Tensor, |