# Copyright (C) 2020-2021 Arm Limited or its affiliates. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the License); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an AS IS BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Description:
# Mark purpose and select formats for Tensors.
from .operation import CustomType
from .operation import Op
from .rewrite_graph import visit_graph_post_order
from .tensor import MemType
from .tensor import TensorFormat
from .tensor import TensorPurpose


def get_format(purpose, arch):
    if purpose in (TensorPurpose.FeatureMap, TensorPurpose.LUT, TensorPurpose.Scratch, TensorPurpose.ScratchFast):
        fmt = arch.default_feature_map_format
    elif purpose == TensorPurpose.Weights:
        fmt = arch.default_weight_format
    elif purpose == TensorPurpose.Unknown:
        fmt = TensorFormat.Unknown
    else:
        assert 0, "unknown tensor purpose {}".format(purpose)
    return fmt


def mark_purpose(tens, arch, purpose):
    # Sets tensor's purpose, format, mem_area and mem_type
    if tens.purpose == TensorPurpose.Unknown:
        tens.purpose = purpose
    elif tens.purpose not in (purpose, TensorPurpose.LUT):
        assert 0, "Cannot resolve tensor purpose {} and {} for tensor {}".format(tens.purpose, purpose, tens)
    fmt = get_format(purpose, arch)
    tens.set_format(fmt, arch)
    tens.mem_area = arch.tensor_storage_mem_area[tens.purpose]
    tens.mem_type = arch.tensor_storage_mem_type[tens.purpose]

    if (
        len(tens.ops) == 1
        and tens.ops[0].type == Op.Const
        and purpose not in (TensorPurpose.Scratch, TensorPurpose.ScratchFast)
    ):
        tens.mem_area = arch.permanent_storage_mem_area  # special case constants, as they must be in permanent storage
        tens.mem_type = MemType.Permanent_NPU


def rewrite_mark_tensor_purpose(op, arch):
    # find disconnected outputs and mark as feature maps
    for tens in op.outputs:
        if not tens.consumers():
            mark_purpose(tens, arch, TensorPurpose.FeatureMap)
    weight_tensors = op.get_weight_tensors()
    for tens in op.inputs:
        if tens is None:
            continue
        if tens.purpose != TensorPurpose.Unknown:
            purpose = tens.purpose
        elif tens in weight_tensors:
            purpose = TensorPurpose.Weights
        else:
            purpose = TensorPurpose.FeatureMap
        mark_purpose(tens, arch, purpose)
    if op.type == Op.Reshape:
        # Reshape's input and output point to same data
        op.ofm.mem_area = op.ifm.mem_area

    if op.type == Op.Custom and op.attrs.get("custom_type") == CustomType.ExistingNpuOp:
        scratch_tensor = None

        if len(op.inputs) >= 3:
            scratch_tensor = op.inputs[2]  # should be existing scratch tensor
            if scratch_tensor.name.endswith("_scratch"):
                scratch_tensor.purpose = TensorPurpose.Scratch

        if len(op.inputs) >= 4:
            scratch_fast_tensor = op.inputs[3]  # should be existing scratch fast tensor
            if scratch_fast_tensor.name.endswith("_scratch_fast"):
                scratch_fast_tensor.purpose = TensorPurpose.ScratchFast

        if scratch_tensor is None:
            op.error("Scratch tensor not found.")


def mark_tensor_purpose(nng, arch, verbose_tensor_purpose=False):
    # Sets purpose, format, mem_area and mem_type for all tensors in the graph
    for sg in nng.subgraphs:
        visit_graph_post_order(sg.output_tensors, arch, [], [rewrite_mark_tensor_purpose])
        for tens in sg.output_tensors:
            mark_purpose(tens, arch, TensorPurpose.FeatureMap)

    if verbose_tensor_purpose:
        nng.print_graph_with_tensors()

    return nng
