# Copyright (C) 2020 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:
# Insert DMA operations into the graph for transfering weights.
from . import rewrite_graph
from .operation import NpuBlockType
from .operation import Op
from .operation import Operation
from .tensor import MemArea
from .tensor import MemType
from .tensor import TensorPurpose
from .weight_compressor import compress_weights


def weights_fit_sram(arch, op, tens, nng):
    if tens.purpose != TensorPurpose.Weights:
        return True

    min_weight_size = 0
    if len(tens.shape) == 4:
        min_weight_size = tens.shape[0] * tens.shape[1] * tens.shape[2] * arch.OFMSplitDepth
    elif len(tens.shape) == 2:
        min_weight_size = tens.shape[0] * arch.OFMSplitDepth

    # Need to be fit into Sram, as a double buffer
    # Only evaluate when the compression test limit will make it impossible to fit
    w_comp_test_limit = 2
    if (w_comp_test_limit * min_weight_size * 2) > arch.sram_size:
        # check worst compression ratio
        npu_block_type = op.attrs.get("npu_block_type", NpuBlockType.Default)
        compress_weights(arch, nng, tens, npu_block_type, 16, 16, op.get_dilation_h_w())

        worst_buffer_size = tens.compression_scale_for_worst_weight_stream * min_weight_size * 2
        if worst_buffer_size > arch.sram_size:
            print(
                "Weights, {}, are too big to be DMAed to SRAM, estimated minimum size is {} bytes".format(
                    tens.name, worst_buffer_size
                )
            )
            return False
    return True


def insert_dma_cmd(op, arch, nng):
    if op.type == Op.DMA or not op.run_on_npu:
        return op

    is_lut_used = any(inp.purpose == TensorPurpose.LUT for inp in op.inputs)
    max_ifm_shram_avail = (
        (arch.available_shram_banks(is_lut_used) - arch.shram_reserved_output_banks) * arch.shram_bank_size // 2
    )

    for idx, tens in enumerate(op.inputs):

        if tens.mem_type not in (MemType.Scratch, MemType.Scratch_fast):
            # Tensor is in permanent storage
            # Only when permanent storage differs from fast storage, there is a point moving the data
            if (
                tens.mem_area in (MemArea.Dram, MemArea.OffChipFlash)
                and arch.permanent_storage_mem_area != arch.fast_storage_mem_area
            ) or tens.purpose == TensorPurpose.LUT:
                if tens.purpose in (TensorPurpose.Weights, TensorPurpose.LUT) or (
                    tens.purpose == TensorPurpose.FeatureMap
                    and op.type.is_binary_elementwise_op()
                    and tens.shape != []
                    and tens.shape != op.outputs[0].shape
                    and tens.storage_size() > max_ifm_shram_avail
                ):
                    only_vector_product_consumers = True
                    for oper in tens.consumers():
                        if oper is None or oper.type.npu_block_type != NpuBlockType.VectorProduct:
                            only_vector_product_consumers = False
                            break

                    # Tensor products has no need for DMA, tensors are only read once and can be in flash.
                    # Other operations re-reads tensors, this is better done from SRAM.
                    # LUTs must be placed in the last 2 blocks of SHRAM.
                    if (
                        not only_vector_product_consumers and weights_fit_sram(arch, op, tens, nng)
                    ) or tens.purpose == TensorPurpose.LUT:
                        # Insert a DMA command here, as well as a new tensor situated in SRAM of the same size.
                        new_tens = tens.clone_into_fast_storage(arch)
                        dma_cmd = Operation(Op.DMA, tens.ops[0].name + "_dma")
                        dma_cmd.inputs = [tens]
                        dma_cmd.set_output_tensor(new_tens)
                        dma_cmd.attrs["source"] = tens.mem_area
                        dma_cmd.attrs["destination"] = new_tens.mem_area
                        dma_cmd.run_on_npu = True
                        if tens.purpose == TensorPurpose.LUT:
                            new_tens.mem_area = MemArea.Shram
                        op.inputs[idx] = new_tens
    return op


def insert_dma_commands(nng, arch, verbose_graph=False):

    for idx, sg in enumerate(nng.subgraphs):
        nng.subgraphs[idx] = rewrite_graph.rewrite_graph_pre_order(nng, sg, arch, [], [insert_dma_cmd])
    if verbose_graph:
        nng.print_graph()
    return nng
