//
// Copyright © 2017-2023 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <armnn/backends/TensorHandle.hpp>

#include <armnn/Tensor.hpp>
#include <armnn/Types.hpp>
#include <armnn/utility/PolymorphicDowncast.hpp>

#include <reference/RefTensorHandle.hpp>

#include <BFloat16.hpp>
#include <Half.hpp>

namespace armnn
{
/// Creates a profiling event that uses GetGuid() and GetName() from the calling class
#define ARMNN_SCOPED_PROFILING_EVENT_REF_NAME_GUID(label) \
ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::CpuRef, \
                                              this->GetGuid(), \
                                              this->GetName() + "_" + label, \
                                              armnn::WallClockTimer())

////////////////////////////////////////////
/// float32 helpers
////////////////////////////////////////////

template <typename TensorHandleType = RefTensorHandle>
inline const TensorInfo& GetTensorInfo(const ITensorHandle* tensorHandle)
{
    // We know that reference workloads use RefTensorHandles for inputs and outputs
    const TensorHandleType* refTensorHandle =
        PolymorphicDowncast<const TensorHandleType*>(tensorHandle);
    return refTensorHandle->GetTensorInfo();
}

template <typename DataType, typename PayloadType>
const DataType* GetInputTensorData(unsigned int idx, const PayloadType& data)
{
    const ITensorHandle* tensorHandle = data.m_Inputs[idx];
    return reinterpret_cast<const DataType*>(tensorHandle->Map());
}

template <typename DataType, typename PayloadType>
DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
{
    ITensorHandle* tensorHandle = data.m_Outputs[idx];
    return reinterpret_cast<DataType*>(tensorHandle->Map());
}

template <typename DataType>
DataType* GetOutputTensorData(ITensorHandle* tensorHandle)
{
    return reinterpret_cast<DataType*>(tensorHandle->Map());
}

template <typename PayloadType>
const float* GetInputTensorDataFloat(unsigned int idx, const PayloadType& data)
{
    return GetInputTensorData<float>(idx, data);
}

template <typename PayloadType>
float* GetOutputTensorDataFloat(unsigned int idx, const PayloadType& data)
{
    return GetOutputTensorData<float>(idx, data);
}

template <typename PayloadType>
const Half* GetInputTensorDataHalf(unsigned int idx, const PayloadType& data)
{
    return GetInputTensorData<Half>(idx, data);
}

template <typename PayloadType>
Half* GetOutputTensorDataHalf(unsigned int idx, const PayloadType& data)
{
    return GetOutputTensorData<Half>(idx, data);
}

template <typename PayloadType>
const BFloat16* GetInputTensorDataBFloat16(unsigned int idx, const PayloadType& data)
{
    return GetInputTensorData<BFloat16>(idx, data);
}

template <typename PayloadType>
BFloat16* GetOutputTensorDataBFloat16(unsigned int idx, const PayloadType& data)
{
    return GetOutputTensorData<BFloat16>(idx, data);
}

////////////////////////////////////////////
/// u8 helpers
////////////////////////////////////////////

template<typename T>
std::vector<float> Dequantize(const T* quant, const TensorInfo& info)
{
    std::vector<float> ret(info.GetNumElements());
    for (size_t i = 0; i < info.GetNumElements(); i++)
    {
        ret[i] = armnn::Dequantize(quant[i], info.GetQuantizationScale(), info.GetQuantizationOffset());
    }
    return ret;
}

template<typename T>
inline void Dequantize(const T* inputData, float* outputData, const TensorInfo& info)
{
    for (unsigned int i = 0; i < info.GetNumElements(); i++)
    {
        outputData[i] = Dequantize<T>(inputData[i], info.GetQuantizationScale(), info.GetQuantizationOffset());
    }
}

inline void Quantize(uint8_t* quant, const float* dequant, const TensorInfo& info)
{
    for (size_t i = 0; i < info.GetNumElements(); i++)
    {
        quant[i] = armnn::Quantize<uint8_t>(dequant[i], info.GetQuantizationScale(), info.GetQuantizationOffset());
    }
}

} //namespace armnn
