blob: 13273e7ac0ae7e5ea41feeb4b8385f168a3a689f [file] [log] [blame]
Johan Alfven9070f0f2023-02-07 13:01:03 +01001# SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
Tim Hall79d07d22020-04-27 18:20:16 +01002#
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.
Rickard Bolinbc6ee582022-11-04 08:24:29 +000016#
Tim Hall79d07d22020-04-27 18:20:16 +010017# Description:
Louis Verhaard17afa282020-10-14 08:32:41 +020018# Mark purpose and select formats for Tensors.
Jonas Ohlsson0957e3e2021-09-01 15:57:21 +020019from .graph_optimiser_util import memory_only_ops
Louis Verhaardaee5d752020-09-30 09:01:52 +020020from .operation import CustomType
21from .operation import Op
Louis Verhaard17afa282020-10-14 08:32:41 +020022from .rewrite_graph import visit_graph_post_order
Patrik Gustavssoneca2e952020-05-27 09:15:11 +020023from .tensor import MemType
Diego Russoe8a10452020-04-21 17:39:10 +010024from .tensor import TensorFormat
25from .tensor import TensorPurpose
Tim Hall79d07d22020-04-27 18:20:16 +010026
27
Louis Verhaard17afa282020-10-14 08:32:41 +020028def get_format(purpose, arch):
Fredrik Svedberge22ba8c2021-01-27 16:53:41 +010029 if purpose in (TensorPurpose.FeatureMap, TensorPurpose.LUT, TensorPurpose.Scratch, TensorPurpose.ScratchFast):
Louis Verhaard17afa282020-10-14 08:32:41 +020030 fmt = arch.default_feature_map_format
31 elif purpose == TensorPurpose.Weights:
32 fmt = arch.default_weight_format
33 elif purpose == TensorPurpose.Unknown:
34 fmt = TensorFormat.Unknown
35 else:
36 assert 0, "unknown tensor purpose {}".format(purpose)
37 return fmt
Tim Hall79d07d22020-04-27 18:20:16 +010038
39
Louis Verhaard17afa282020-10-14 08:32:41 +020040def mark_purpose(tens, arch, purpose):
41 # Sets tensor's purpose, format, mem_area and mem_type
42 if tens.purpose == TensorPurpose.Unknown:
43 tens.purpose = purpose
Johan Alfven9070f0f2023-02-07 13:01:03 +010044 elif tens.purpose == TensorPurpose.Virtual:
45 return
Louis Verhaard17afa282020-10-14 08:32:41 +020046 elif tens.purpose not in (purpose, TensorPurpose.LUT):
47 assert 0, "Cannot resolve tensor purpose {} and {} for tensor {}".format(tens.purpose, purpose, tens)
Patrik Gustavssonee99bb12021-04-08 09:04:00 +020048
Louis Verhaard17afa282020-10-14 08:32:41 +020049 fmt = get_format(purpose, arch)
50 tens.set_format(fmt, arch)
51 tens.mem_area = arch.tensor_storage_mem_area[tens.purpose]
52 tens.mem_type = arch.tensor_storage_mem_type[tens.purpose]
53
Fredrik Svedberge22ba8c2021-01-27 16:53:41 +010054 if (
55 len(tens.ops) == 1
56 and tens.ops[0].type == Op.Const
57 and purpose not in (TensorPurpose.Scratch, TensorPurpose.ScratchFast)
58 ):
Louis Verhaard17afa282020-10-14 08:32:41 +020059 tens.mem_area = arch.permanent_storage_mem_area # special case constants, as they must be in permanent storage
60 tens.mem_type = MemType.Permanent_NPU
Tim Hall79d07d22020-04-27 18:20:16 +010061
62
Louis Verhaard17afa282020-10-14 08:32:41 +020063def rewrite_mark_tensor_purpose(op, arch):
64 # find disconnected outputs and mark as feature maps
65 for tens in op.outputs:
66 if not tens.consumers():
67 mark_purpose(tens, arch, TensorPurpose.FeatureMap)
68 weight_tensors = op.get_weight_tensors()
69 for tens in op.inputs:
Louis Verhaard0411edb2020-11-16 16:37:11 +010070 if tens is None:
71 continue
Louis Verhaard17afa282020-10-14 08:32:41 +020072 if tens.purpose != TensorPurpose.Unknown:
73 purpose = tens.purpose
74 elif tens in weight_tensors:
75 purpose = TensorPurpose.Weights
76 else:
77 purpose = TensorPurpose.FeatureMap
Raul Farkasfe853152023-03-14 12:36:45 +000078 # Treat Dynamic Weights as FeatureMap to avoid issues during scheduling caused by
79 # having non constant OPs that produce tensors used as weights.
80 if any(op.type != Op.Const and tens == op.ofm and purpose == TensorPurpose.Weights for op in tens.ops):
81 purpose = TensorPurpose.FeatureMap
Louis Verhaard17afa282020-10-14 08:32:41 +020082 mark_purpose(tens, arch, purpose)
Jonas Ohlsson0957e3e2021-09-01 15:57:21 +020083 if op.type in memory_only_ops:
84 # Memory only operator input and output point to same data
Louis Verhaard17afa282020-10-14 08:32:41 +020085 op.ofm.mem_area = op.ifm.mem_area
Tim Hall79d07d22020-04-27 18:20:16 +010086
Louis Verhaard17afa282020-10-14 08:32:41 +020087 if op.type == Op.Custom and op.attrs.get("custom_type") == CustomType.ExistingNpuOp:
88 scratch_tensor = None
Tim Hall79d07d22020-04-27 18:20:16 +010089
Louis Verhaard17afa282020-10-14 08:32:41 +020090 if len(op.inputs) >= 3:
91 scratch_tensor = op.inputs[2] # should be existing scratch tensor
92 if scratch_tensor.name.endswith("_scratch"):
93 scratch_tensor.purpose = TensorPurpose.Scratch
Tim Hall79d07d22020-04-27 18:20:16 +010094
Fredrik Svedberge22ba8c2021-01-27 16:53:41 +010095 if len(op.inputs) >= 4:
96 scratch_fast_tensor = op.inputs[3] # should be existing scratch fast tensor
97 if scratch_fast_tensor.name.endswith("_scratch_fast"):
98 scratch_fast_tensor.purpose = TensorPurpose.ScratchFast
99
Louis Verhaard17afa282020-10-14 08:32:41 +0200100 if scratch_tensor is None:
Michael McGeagh528a56d2020-12-16 11:33:21 +0000101 op.error("Scratch tensor not found.")
Tim Hall79d07d22020-04-27 18:20:16 +0100102
103
104def mark_tensor_purpose(nng, arch, verbose_tensor_purpose=False):
Louis Verhaard17afa282020-10-14 08:32:41 +0200105 # Sets purpose, format, mem_area and mem_type for all tensors in the graph
Tim Hall79d07d22020-04-27 18:20:16 +0100106 for sg in nng.subgraphs:
Louis Verhaard17afa282020-10-14 08:32:41 +0200107 visit_graph_post_order(sg.output_tensors, arch, [], [rewrite_mark_tensor_purpose])
Tim Hall79d07d22020-04-27 18:20:16 +0100108 for tens in sg.output_tensors:
Louis Verhaard17afa282020-10-14 08:32:41 +0200109 mark_purpose(tens, arch, TensorPurpose.FeatureMap)
Tim Hall79d07d22020-04-27 18:20:16 +0100110
111 if verbose_tensor_purpose:
112 nng.print_graph_with_tensors()
113
114 return nng