// Copyright (c) 2023, ARM Limited.
//
//    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
//
//         http://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.

#include <cmath>
#include <limits>
#include <memory>
#include <type_traits>

#include "verifiers.h"

namespace TosaReference
{

namespace
{
static_assert(std::numeric_limits<float>::is_iec559,
              "TOSA Reference Model has not been built with standard IEE574 32-bit float support; ULP based "
              "verifcation is invalid");
static_assert(std::numeric_limits<double>::is_iec559,
              "TOSA Reference Model has not been built with standard IEE574 64-bit float support; ULP based "
              "verifcation is invalid");

bool tosaCheckULP(float testValue, double referenceValue, int64_t ulpCount)
{

    // Start by sanitizing the input.

    // The concept of ULP isn't defined for NaN's
    if (std::isnan(referenceValue) || std::isnan(testValue))
    {
        return false;
    }

    // Make the sign of the reference value positive
    // and adjust the test value appropriately.
    if (referenceValue < 0)
    {
        referenceValue = -referenceValue;
        testValue      = -testValue;
    }

    // At this point we are ready to calculate the ULP bounds for the reference value.
    double referenceMin, referenceMax;

    // If the reference is infinity e.g. the result of an overflow the test value must
    // be infinity of an appropriate sign.
    if (std::isinf(referenceValue))
    {
        // We already canonicalized the input such that the reference value is positive
        // so no need to check again here.
        referenceMin = std::numeric_limits<float>::infinity();
        referenceMax = std::numeric_limits<float>::infinity();
    }
    else if (referenceValue == 0)
    {
        // For zero we require that the results match exactly with the correct sign.
        referenceMin = 0;
        referenceMax = 0;
    }
    else
    {
        // Find the exponent of the reference value.
        int referenceExponent;
        std::frexp(referenceValue, &referenceExponent);

        // Work out the values magnitude - by raising 2 to the power of the
        // exponent and taking the normalized minimum for denormal values
        const double referencePower2 =
            std::max(std::ldexp(1.0, referenceExponent), static_cast<double>(std::numeric_limits<float>::min()));
        // Get the value of changing the last bit - by shifting the least significant bit to this magnitude
        // i.e. the ULP.
        double ulpValue = referencePower2 * std::ldexp(1.0, -23);

        // It is possible that within one ULP we cross a boundary where we need to change the exponent,
        // if this happens we will take the ULP for the larger exponent.
        if (referenceValue + ulpValue > 2 * referencePower2)
        {
            ulpValue = 2 * ulpValue;
        }

        // Scale by the number of ULPs requested by the user.
        referenceMax = referenceValue + ulpValue * ulpCount;
        referenceMin = referenceValue - ulpValue * ulpCount;

        // Handle the overflow cases.
        if (referenceMax > std::numeric_limits<float>::max())
        {
            referenceMax = std::numeric_limits<float>::infinity();
        }

        if (referenceMin > std::numeric_limits<float>::max())
        {
            referenceMin = std::numeric_limits<float>::infinity();
        }

        // And the underflow cases.
        if (referenceMax < std::numeric_limits<float>::min())
        {
            referenceMax = std::numeric_limits<float>::min();
        }

        if (referenceMin < std::numeric_limits<float>::min())
        {
            referenceMin = 0;
        }
    }

    // And finally... Do the comparison.
    return static_cast<double>(testValue) >= referenceMin && static_cast<double>(testValue) <= referenceMax;
}
}    // namespace

bool verifyULP(const CTensor* referenceTensor, const CTensor* implementationTensor, uint64_t ulp)
{
    // Validate that tensors are provided
    TOSA_REF_REQUIRE(referenceTensor != nullptr, "reference tensor is missing");
    TOSA_REF_REQUIRE(implementationTensor != nullptr, "implementation tensor is missing");

    // Get number of elements
    const auto elementCount =
        numElements(std::vector<int32_t>(referenceTensor->shape, referenceTensor->shape + referenceTensor->num_dims));
    TOSA_REF_REQUIRE(elementCount > 0, "invalid shape for reference tensor");

    switch (implementationTensor->data_type)
    {
        case tosa_datatype_fp32_t: {
            const auto* refData = reinterpret_cast<const float*>(referenceTensor->data);
            TOSA_REF_REQUIRE(refData != nullptr, "missing data for reference");
            const auto* impData = reinterpret_cast<const float*>(implementationTensor->data);
            TOSA_REF_REQUIRE(impData != nullptr, "missing data for implementation");
            return std::equal(refData, std::next(refData, elementCount), impData, std::next(impData, elementCount),
                              [ulp](const auto& referenceValue, const auto& implementationValue) {
                                  return tosaCheckULP(referenceValue, implementationValue, ulp);
                              });
        }
        default:
            WARNING("tosa verifier: data-type not supported.");
            break;
    }

    return false;
}
}    // namespace TosaReference
