blob: 51f80ebd9aa02a1b658bd91afd4b617553dc0c14 [file] [log] [blame]
Patrik Gustavsson8f1f9aa2021-06-28 07:41:58 +02001# Copyright (C) 2021 Arm Limited or its affiliates. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
4#
5# Licensed under the Apache License, Version 2.0 (the License); you may
6# not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an AS IS BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# Description:
17# The TosaSupportedOperators class which is a collection of all supported operators and parameter checks.
18from collections import defaultdict
19
20from .data_type import DataType
21from .operation import Op
22from .supported_operators_util import docstring_format_args
23from .supported_operators_util import list_formatter
24from .tosa_mapping import optype_to_tosa_op_type
25
26
27class TosaSupportedOperators:
28 # TODO currently sparsely populated
29 # Categorised lists of supported operators
30 convolution_ops = set((Op.Conv2DBias,))
31 convolution_like_ops = convolution_ops
32 mac_main_ops = convolution_like_ops
33
34 type_conversion_ops = set((Op.Rescale,))
Patrik Gustavsson5e26eda2021-06-30 09:07:16 +020035 relu_ops = set((Op.Clamp, Op.ReluN,))
Patrik Gustavsson8f1f9aa2021-06-28 07:41:58 +020036 activation_ops = relu_ops
37
38 npu_post_ops = activation_ops
39 supported_operators = mac_main_ops | type_conversion_ops | npu_post_ops
40
41 # Supported data types
42 # TODO will differ compared to TensorFlow Lite, currently set to the same
43 supported_op_dtypes = set((DataType.uint8, DataType.int8, DataType.int16, DataType.int32))
44
45 def __init__(self):
46 # Setup the generic constraints. Note: the order matters
47 self.generic_constraints = []
48 self.generic_constraints.append(TosaSupportedOperators.constraint_tens_dtype)
49
50 # Setup specific constraints. Note: the order matters
51 self.specific_constraints = defaultdict(list)
52
53 def is_operator_supported(self, op):
54 ext_type = optype_to_tosa_op_type(op.type)
55 if op.type not in TosaSupportedOperators.supported_operators:
56 if op.type not in (Op.Placeholder, Op.SubgraphInput, Op.Const):
57 print(f"Info: {ext_type} '{op.name}' is not a NPU op")
58 return False
59
60 for constraint in self.generic_constraints + self.specific_constraints[op.type]:
61 valid, extra = constraint(op)
62 if not valid:
63 print(f"Warning: {ext_type} '{op.name}' is not supported on the NPU")
64 print(f" - {constraint.__doc__}")
65 if extra:
66 print(f" {extra}")
67 return False
68
69 return True
70
71 # TODO this function is the same for TensorFlow Lite, but input might differ
72 @classmethod
73 @docstring_format_args([list_formatter(supported_op_dtypes)])
74 def constraint_tens_dtype(cls, op):
75 "Tensors must be of type: {}"
76 valid = True
77 extra = []
78 tensors = [tens for tens in op.get_ifm_ifm2_weights_ofm() if tens]
79 if not tensors:
80 tensors = [tens for tens in op.inputs if tens]
81 for tens in tensors:
82 if tens.dtype not in cls.supported_op_dtypes:
83 valid = False
84 extra.append(f"Tensor '{tens.name}' has data type: {tens.dtype}")
85 return valid, ", ".join(extra)