From 85b77901b72865cc0071f294bd9177288c0bc4e3 Mon Sep 17 00:00:00 2001 From: Johan Alfven Date: Thu, 15 Jun 2023 09:24:01 +0200 Subject: MLBEDSW-7709: MLCE: Crash when rewriting split op - A crash occurred due to NoneType subscriptable error when rewriting a Slice op. The reason was that the Size tensor did not contain any data. - Added constraint pushing the Slice operator to the CPU if begin or size tensor are empty. - Added test to supported operators - Updated SUPPORTED_OPS.md Change-Id: Ide204cae24e5871f0e6ae1fdc98ac68d0ce4d3ae Signed-off-by: Johan Alfven --- SUPPORTED_OPS.md | 10 ++++++++-- ethosu/vela/test/test_tflite_supported_operators.py | 17 +++++++++++++++++ ethosu/vela/tflite_supported_operators.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/SUPPORTED_OPS.md b/SUPPORTED_OPS.md index fdceb43c..5258946c 100644 --- a/SUPPORTED_OPS.md +++ b/SUPPORTED_OPS.md @@ -19,7 +19,7 @@ limitations under the License. # Supported Ops This file was automatically generated by Vela using the `--supported-ops-report` parameter. -Vela version: `3.8.1.dev3+gc66541d` +Vela version: `3.8.1.dev7+g0f09dd2` This file complies with [**Gitiles Markdown syntax**](https://github.com/google/gitiles/blob/master/Documentation/markdown.md) @@ -66,7 +66,7 @@ Please check the supported operator list for your chosen runtime for further inf | RESIZE_NEAREST_NEIGHBOR | [Generic](#tflite-generic-constraints), [Specific](#tflite-resize_nearest_neighbor-constraints) | | RSQRT | [Generic](#tflite-generic-constraints), [Specific](#tflite-rsqrt-constraints) | | SHAPE | [Generic](#tflite-generic-constraints) | -| SLICE | [Generic](#tflite-generic-constraints) | +| SLICE | [Generic](#tflite-generic-constraints), [Specific](#tflite-slice-constraints) | | SOFTMAX | [Generic](#tflite-generic-constraints), [Specific](#tflite-softmax-constraints) | | SPLIT | [Generic](#tflite-generic-constraints), [Specific](#tflite-split-constraints) | | SPLIT_V | [Generic](#tflite-generic-constraints), [Specific](#tflite-split_v-constraints) | @@ -328,6 +328,12 @@ This is a list of constraints that the RSQRT operator must satisfy in order to b - IFM and OFM data types must match - IFM must be int8 +### TFLite SLICE Constraints + +This is a list of constraints that the SLICE operator must satisfy in order to be scheduled on the NPU. + +- Begin and Size Input tensors must be constant + ### TFLite SOFTMAX Constraints This is a list of constraints that the SOFTMAX operator must satisfy in order to be scheduled on the NPU. diff --git a/ethosu/vela/test/test_tflite_supported_operators.py b/ethosu/vela/test/test_tflite_supported_operators.py index cbad1713..6f3553d8 100644 --- a/ethosu/vela/test/test_tflite_supported_operators.py +++ b/ethosu/vela/test/test_tflite_supported_operators.py @@ -675,3 +675,20 @@ def test_rsqrt_support(): # Test not supported op (int16) op = testutil.create_elemwise_op(Op.Rsqrt, "op", [1, 8, 8, 8], [1, 8, 8, 8], [1, 8, 8, 8], datatype=DataType.int16) assert not support.is_operator_supported(op) + + +def test_constraint_slice_inputs_const(): + # Begin and Size tensor cannot be non-const tensors + # Test not supported op + ifm = Tensor([3, 1, 256], DataType.int8, "in") + begin = Tensor([3], DataType.int32, "begin") + size = Tensor([3], DataType.int32, "size") + ofm = Tensor([1, 1, 256], DataType.int8, "size") + op = testutil.create_op(Op.Slice, [ifm, begin, size], ofm) + assert not support.is_operator_supported(op) + # Test supported op + begin = create_const_tensor("begin", [3], DataType.int32, [0, 0, 0]) + size = create_const_tensor("size", [3], DataType.int32, [2, 1, 256]) + op.set_input_tensor(begin, 1) + op.set_input_tensor(begin, 2) + assert support.is_operator_supported(op) diff --git a/ethosu/vela/tflite_supported_operators.py b/ethosu/vela/tflite_supported_operators.py index a24eebc5..f965d2ba 100644 --- a/ethosu/vela/tflite_supported_operators.py +++ b/ethosu/vela/tflite_supported_operators.py @@ -331,6 +331,9 @@ class TFLiteSupportedOperators: # Rsqrt specific checks self.specific_constraints[Op.Rsqrt].append(TFLiteSupportedOperators.constraint_rsqrt_input_int8) + # Slice specific checks: + self.specific_constraints[Op.Slice].append(TFLiteSupportedOperators.constraint_slice_inputs_const) + def is_operator_supported(self, op): ext_type = optype_to_builtintype(op.type) if op.type not in TFLiteSupportedOperators.supported_operators: @@ -942,3 +945,18 @@ class TFLiteSupportedOperators: ifm_dtype = op.ifm.dtype valid = ifm_dtype == DataType.int8 return valid, f"Op has ifm_dtype={ifm_dtype}" + + @staticmethod + def constraint_slice_inputs_const(op): + "Begin and Size Input tensors must be constant" + valid = True + extra = [] + _, begin, sizes = op.inputs + if begin.values is None: + valid = False + extra.append(f"Begin tensor '{begin.name}'") + if sizes.values is None: + valid = False + extra.append(f"Size tensor '{sizes.name}'") + extra = ", ".join(extra) + return valid, f"Op has non-constant tensors: {extra}" -- cgit v1.2.1