/*
 * Copyright (c) 2016-2023 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "arm_compute/core/Utils.h"

#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/utils/StringUtils.h"
#include "arm_compute/function_info/ActivationLayerInfo.h"

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <fstream>
#include <map>
#include <string>

namespace arm_compute
{
std::string read_file(const std::string &filename, bool binary)
{
    std::string   out;
    std::ifstream fs;

#ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED
    try
    {
#endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */
        fs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        std::ios_base::openmode mode = std::ios::in;

        if (binary)
        {
            mode |= std::ios::binary;
        }

        fs.open(filename, mode);

        // Go to the end of the file
        fs.seekg(0, std::ios::end);
        // Reserve the memory required to store the file's content
        out.reserve(fs.tellg());
        // Go back to the beginning of the file
        fs.seekg(0, std::ios::beg);
        // Copy the content of the file
        out.assign(std::istreambuf_iterator<char>(fs), std::istreambuf_iterator<char>());
#ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED
    }
    catch (const std::ifstream::failure &e)
    {
        ARM_COMPUTE_ERROR_VAR("Accessing %s: %s", filename.c_str(), e.what());
    }
#endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */

    return out;
}

const std::string &string_from_channel(Channel channel)
{
    static std::map<Channel, const std::string> channels_map = {{Channel::UNKNOWN, "UNKNOWN"},
                                                                {Channel::R, "R"},
                                                                {Channel::G, "G"},
                                                                {Channel::B, "B"},
                                                                {Channel::A, "A"},
                                                                {Channel::Y, "Y"},
                                                                {Channel::U, "U"},
                                                                {Channel::V, "V"},
                                                                {Channel::C0, "C0"},
                                                                {Channel::C1, "C1"},
                                                                {Channel::C2, "C2"},
                                                                {Channel::C3, "C3"}};

    return channels_map[channel];
}

const std::string &string_from_border_mode(BorderMode border_mode)
{
    static std::map<BorderMode, const std::string> border_mode_map = {
        {BorderMode::UNDEFINED, "UNDEFINED"},
        {BorderMode::CONSTANT, "CONSTANT"},
        {BorderMode::REPLICATE, "REPLICATE"},
    };

    return border_mode_map[border_mode];
}

const std::string &string_from_norm_type(NormType type)
{
    static std::map<NormType, const std::string> norm_type_map = {
        {NormType::IN_MAP_1D, "IN_MAP_1D"},
        {NormType::IN_MAP_2D, "IN_MAP_2D"},
        {NormType::CROSS_MAP, "CROSS_MAP"},
    };

    return norm_type_map[type];
}

const std::string &string_from_pooling_type(PoolingType type)
{
    static std::map<PoolingType, const std::string> pool_type_map = {
        {PoolingType::MAX, "MAX"},
        {PoolingType::AVG, "AVG"},
        {PoolingType::L2, "L2"},
    };

    return pool_type_map[type];
}

bool is_pool_region_entirely_outside_input(const PoolingLayerInfo &info)
{
    if (info.is_global_pooling || info.exclude_padding || info.pool_size.x() == 0 || info.pool_size.y() == 0)
    {
        return false;
    }
    const auto ps                = info.pad_stride_info;
    const auto pool_le_padding_x = info.pool_size.x() <= std::max({ps.pad_left(), ps.pad_right()});
    const auto pool_le_padding_y = info.pool_size.y() <= std::max({ps.pad_top(), ps.pad_bottom()});
    return pool_le_padding_x || pool_le_padding_y;
}

bool is_pool_3d_region_entirely_outside_input(const Pooling3dLayerInfo &info)
{
    if (info.is_global_pooling || info.pool_size.x() == 0 || info.pool_size.y() == 0 || info.pool_size.z() == 0)
    {
        return false;
    }
    const auto ps                = info.padding;
    const auto pool_le_padding_x = info.pool_size.x() <= std::max({ps.left, ps.right});
    const auto pool_le_padding_y = info.pool_size.y() <= std::max({ps.top, ps.bottom});
    const auto pool_le_padding_z = info.pool_size.z() <= std::max({ps.front, ps.back});
    return pool_le_padding_x || pool_le_padding_y || pool_le_padding_z;
}

const std::string &string_from_gemmlowp_output_stage(GEMMLowpOutputStageType output_stage)
{
    static std::map<GEMMLowpOutputStageType, const std::string> output_stage_map = {
        {GEMMLowpOutputStageType::NONE, ""},
        {GEMMLowpOutputStageType::QUANTIZE_DOWN, "quantize_down"},
        {GEMMLowpOutputStageType::QUANTIZE_DOWN_FIXEDPOINT, "quantize_down_fixedpoint"},
        {GEMMLowpOutputStageType::QUANTIZE_DOWN_FLOAT, "quantize_down_float"}};

    return output_stage_map[output_stage];
}

std::string string_from_pixel_value(const PixelValue &value, const DataType data_type)
{
    std::stringstream ss;
    std::string       converted_string;

    switch (data_type)
    {
        case DataType::U8:
        case DataType::QASYMM8:
            // Needs conversion to 32 bit, otherwise interpreted as ASCII values
            ss << uint32_t(value.get<uint8_t>());
            converted_string = ss.str();
            break;
        case DataType::S8:
        case DataType::QASYMM8_SIGNED:
        case DataType::QSYMM8_PER_CHANNEL:
            // Needs conversion to 32 bit, otherwise interpreted as ASCII values
            ss << int32_t(value.get<int8_t>());
            converted_string = ss.str();
            break;
        case DataType::U16:
        case DataType::QASYMM16:
            ss << value.get<uint16_t>();
            converted_string = ss.str();
            break;
        case DataType::S16:
        case DataType::QSYMM16:
            ss << value.get<int16_t>();
            converted_string = ss.str();
            break;
        case DataType::U32:
            ss << value.get<uint32_t>();
            converted_string = ss.str();
            break;
        case DataType::S32:
            ss << value.get<int32_t>();
            converted_string = ss.str();
            break;
        case DataType::F32:
            converted_string = float_to_string_with_full_precision(value.get<float>());
            break;
        case DataType::F16:
            static_assert(sizeof(half) == 2, "Half must be 16 bit");
            ss << value.get<half>();
            converted_string = ss.str();
            break;
        default:
            ARM_COMPUTE_ERROR("Not handled");
    }

    return converted_string;
}

PadStrideInfo calculate_same_pad(TensorShape                  input_shape,
                                 TensorShape                  weights_shape,
                                 PadStrideInfo                conv_info,
                                 DataLayout                   data_layout,
                                 const Size2D                &dilation,
                                 const DimensionRoundingType &rounding_type)
{
    const auto &strides = conv_info.stride();
    ARM_COMPUTE_ERROR_ON_MSG((strides.first < 1 || strides.second < 1),
                             "Stride values should be greater than or equal to 1.");

    const unsigned int width_idx     = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
    const unsigned int height_idx    = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
    const unsigned int in_width      = input_shape[width_idx];
    const unsigned int in_height     = input_shape[height_idx];
    const unsigned int kernel_width  = weights_shape[width_idx];
    const unsigned int kernel_height = weights_shape[height_idx];

    // Calculate output dimensions
    const auto         is_ceil    = static_cast<unsigned int>(rounding_type == DimensionRoundingType::CEIL);
    const unsigned int out_width  = ((in_width - is_ceil) + strides.first - 1) / strides.first + is_ceil;
    const unsigned int out_height = ((in_height - is_ceil) + strides.second - 1) / strides.second + is_ceil;

    // Calculate effective weights sizes
    const int real_weight_width  = (kernel_width - 1) * dilation.x() + 1;
    const int real_weight_height = (kernel_height - 1) * dilation.y() + 1;

    // Calculate total pad
    const int pad_width = std::max(0, static_cast<int>((out_width - 1) * strides.first + real_weight_width - in_width));
    const int pad_height =
        std::max(0, static_cast<int>((out_height - 1) * strides.second + real_weight_height - in_height));

    // Calculate individual paddings
    const unsigned int pad_left   = pad_width / 2;
    const unsigned int pad_top    = pad_height / 2;
    const unsigned int pad_right  = pad_width - pad_left;
    const unsigned int pad_bottom = pad_height - pad_top;

    PadStrideInfo same_info(strides.first, strides.second, pad_left, pad_right, pad_top, pad_bottom, rounding_type);

    // Check for correctness of predicted output shape against the one calculated using the generated info
    const auto out_dims = scaled_dimensions(in_width, in_height, kernel_width, kernel_height, same_info, dilation);
    ARM_COMPUTE_ERROR_ON(out_dims.first != out_width || out_dims.second != out_height);
    ARM_COMPUTE_UNUSED(out_dims);

    return same_info;
}

std::pair<unsigned int, unsigned int> deconvolution_output_dimensions(unsigned int         in_width,
                                                                      unsigned int         in_height,
                                                                      unsigned int         kernel_width,
                                                                      unsigned int         kernel_height,
                                                                      const PadStrideInfo &pad_stride_info)
{
    const unsigned int pad_left   = pad_stride_info.pad_left();
    const unsigned int pad_top    = pad_stride_info.pad_top();
    const unsigned int pad_right  = pad_stride_info.pad_right();
    const unsigned int pad_bottom = pad_stride_info.pad_bottom();
    const unsigned int stride_x   = pad_stride_info.stride().first;
    const unsigned int stride_y   = pad_stride_info.stride().second;

    ARM_COMPUTE_ERROR_ON(in_width < 1 || in_height < 1);
    ARM_COMPUTE_ERROR_ON(((in_width - 1) * stride_x + kernel_width) < (pad_left + pad_right));
    ARM_COMPUTE_ERROR_ON(((in_height - 1) * stride_y + kernel_height) < (pad_top + pad_bottom));
    const int w = stride_x * (in_width - 1) + kernel_width - (pad_left + pad_right);
    const int h = stride_y * (in_height - 1) + kernel_height - (pad_top + pad_bottom);

    return std::make_pair<unsigned int, unsigned int>(w, h);
}

std::pair<unsigned int, unsigned int> scaled_dimensions(int                  width,
                                                        int                  height,
                                                        int                  kernel_width,
                                                        int                  kernel_height,
                                                        const PadStrideInfo &pad_stride_info,
                                                        const Size2D        &dilation)
{
    const int dilation_x = dilation.x();
    const int dilation_y = dilation.y();
    const int pad_left   = pad_stride_info.pad_left();
    const int pad_top    = pad_stride_info.pad_top();
    const int pad_right  = pad_stride_info.pad_right();
    const int pad_bottom = pad_stride_info.pad_bottom();
    const int stride_x   = pad_stride_info.stride().first;
    const int stride_y   = pad_stride_info.stride().second;
    int       w          = 0;
    int       h          = 0;
    switch (pad_stride_info.round())
    {
        case DimensionRoundingType::FLOOR:
            w = static_cast<int>(std::floor(
                (static_cast<float>(width + pad_left + pad_right - (dilation_x * (kernel_width - 1) + 1)) / stride_x) +
                1));
            h = static_cast<int>(
                std::floor((static_cast<float>(height + pad_top + pad_bottom - (dilation_y * (kernel_height - 1) + 1)) /
                            stride_y) +
                           1));
            break;
        case DimensionRoundingType::CEIL:
            w = static_cast<int>(std::ceil(
                (static_cast<float>(width + pad_left + pad_right - (dilation_x * (kernel_width - 1) + 1)) / stride_x) +
                1));
            h = static_cast<int>(
                std::ceil((static_cast<float>(height + pad_top + pad_bottom - (dilation_y * (kernel_height - 1) + 1)) /
                           stride_y) +
                          1));
            break;
        default:
            ARM_COMPUTE_ERROR("Unsupported rounding type");
    }

    w = std::max(1, w);
    h = std::max(1, h);
    return std::make_pair(static_cast<unsigned int>(w), static_cast<unsigned int>(h));
}

std::pair<int, int> scaled_dimensions_signed(
    int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info)
{
    const int pad_left   = pad_stride_info.pad_left();
    const int pad_top    = pad_stride_info.pad_top();
    const int pad_right  = pad_stride_info.pad_right();
    const int pad_bottom = pad_stride_info.pad_bottom();
    const int stride_x   = pad_stride_info.stride().first;
    const int stride_y   = pad_stride_info.stride().second;
    int       w          = 0;
    int       h          = 0;
    switch (pad_stride_info.round())
    {
        case DimensionRoundingType::FLOOR:
            w = static_cast<int>(
                std::floor((static_cast<float>(width + pad_left + pad_right - kernel_width) / stride_x) + 1));
            h = static_cast<int>(
                std::floor((static_cast<float>(height + pad_top + pad_bottom - kernel_height) / stride_y) + 1));
            break;
        case DimensionRoundingType::CEIL:
            w = static_cast<int>(
                std::ceil((static_cast<float>(width + pad_left + pad_right - kernel_width) / stride_x) + 1));
            h = static_cast<int>(
                std::ceil((static_cast<float>(height + pad_top + pad_bottom - kernel_height) / stride_y) + 1));
            break;
        default:
            ARM_COMPUTE_ERROR("Unsupported rounding type");
    }

    return std::make_pair(static_cast<int>(w), static_cast<int>(h));
}

std::tuple<int, int, int> scaled_3d_dimensions_signed(int                       width,
                                                      int                       height,
                                                      int                       depth,
                                                      int                       kernel_width,
                                                      int                       kernel_height,
                                                      int                       kernel_depth,
                                                      const Pooling3dLayerInfo &pool3d_info)
{
    const int pad_left   = pool3d_info.padding.left;
    const int pad_top    = pool3d_info.padding.top;
    const int pad_right  = pool3d_info.padding.right;
    const int pad_bottom = pool3d_info.padding.bottom;
    const int pad_front  = pool3d_info.padding.front;
    const int pad_back   = pool3d_info.padding.back;
    const int stride_x   = pool3d_info.stride.x();
    const int stride_y   = pool3d_info.stride.y();
    const int stride_z   = pool3d_info.stride.z();
    int       w          = 0;
    int       h          = 0;
    int       d          = 0;

    switch (pool3d_info.round_type)
    {
        case DimensionRoundingType::FLOOR:
            w = static_cast<int>(
                std::floor((static_cast<float>(width + pad_left + pad_right - kernel_width) / stride_x) + 1));
            h = static_cast<int>(
                std::floor((static_cast<float>(height + pad_top + pad_bottom - kernel_height) / stride_y) + 1));
            d = static_cast<int>(
                std::floor((static_cast<float>(depth + pad_front + pad_back - kernel_depth) / stride_z) + 1));
            break;
        case DimensionRoundingType::CEIL:
            w = static_cast<int>(
                std::ceil((static_cast<float>(width + pad_left + pad_right - kernel_width) / stride_x) + 1));
            h = static_cast<int>(
                std::ceil((static_cast<float>(height + pad_top + pad_bottom - kernel_height) / stride_y) + 1));
            d = static_cast<int>(
                std::ceil((static_cast<float>(depth + pad_front + pad_back - kernel_depth) / stride_z) + 1));
            break;
        default:
            ARM_COMPUTE_ERROR("Unsupported rounding type");
    }

    return std::make_tuple(static_cast<int>(w), static_cast<int>(h), static_cast<int>(d));
}

bool needs_serialized_reduction(ReductionOperation op, DataType dt, unsigned int axis)
{
    const bool is_min_max        = (op == ReductionOperation::MAX || op == ReductionOperation::MIN);
    const bool is_quantized_type = is_data_type_quantized(dt);
    const bool is_first_dim      = (axis == 0);

    return !is_first_dim || (is_quantized_type && !is_min_max);
}

QuantizationInfo get_softmax_output_quantization_info(DataType input_type, bool is_log)
{
    // Note: Output quantization info for softmax should always have
    // * Softmax with QASYMM8: scale = 1/256, offset = 0
    // * Softmax with QASYMM8_SIGNED: scale = 1/256, offset = -128
    // * LogSoftmax with QASYMM8: scale = 1/256, offset = 0
    // * LogSoftmax with QASYMM8_SIGNED: scale = 16/256, offset = 127
    if (is_data_type_quantized_asymmetric_signed(input_type))
    {
        if (is_log)
        {
            return QuantizationInfo(16.f / 256, 127);
        }
        else
        {
            return QuantizationInfo(1.f / 256, -128);
        }
    }
    return QuantizationInfo(1.f / 256, 0);
}

std::pair<int32_t, int32_t> get_quantized_activation_min_max(const ActivationLayerInfo &act_info,
                                                             DataType                   data_type,
                                                             UniformQuantizationInfo    oq_info)
{
    const bool is_qasymm8_signed = is_data_type_quantized_asymmetric_signed(data_type);
    const auto a                 = act_info.a();
    const auto b                 = act_info.b();
    const int  a_int          = is_qasymm8_signed ? quantize_qasymm8_signed(a, oq_info) : quantize_qasymm8(a, oq_info);
    const int  b_int          = is_qasymm8_signed ? quantize_qasymm8_signed(b, oq_info) : quantize_qasymm8(b, oq_info);
    const auto type_max_value = std::get<1>(get_min_max(data_type)).get<int32_t>();

    const int32_t min_activation = act_info.activation() != ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU
                                       ? std::min(oq_info.offset, type_max_value)
                                       : b_int;
    const int32_t max_activation =
        act_info.activation() == ActivationLayerInfo::ActivationFunction::RELU ? type_max_value : a_int;

    return std::make_pair(min_activation, max_activation);
}

std::unordered_map<const ITensorInfo *, PaddingSize> get_padding_info(std::initializer_list<const ITensor *> tensors)
{
    std::unordered_map<const ITensorInfo *, PaddingSize> res;

    for (const ITensor *tensor : tensors)
    {
        if (tensor)
        {
            res.insert({tensor->info(), tensor->info()->padding()});
        }
    }

    return res;
}

std::unordered_map<const ITensorInfo *, PaddingSize> get_padding_info(std::initializer_list<const ITensorInfo *> infos)
{
    std::unordered_map<const ITensorInfo *, PaddingSize> res;

    for (const ITensorInfo *info : infos)
    {
        if (info)
        {
            res.insert({info, info->padding()});
        }
    }

    return res;
}

bool has_padding_changed(const std::unordered_map<const ITensorInfo *, PaddingSize> &padding_map)
{
    return std::find_if(padding_map.begin(), padding_map.end(),
                        [](const std::pair<const ITensorInfo *, PaddingSize> &padding_info)
                        { return (padding_info.first->padding() != padding_info.second); }) != padding_map.end();
}

#ifdef ARM_COMPUTE_ASSERTS_ENABLED
void print_consecutive_elements(std::ostream      &s,
                                DataType           dt,
                                const uint8_t     *ptr,
                                unsigned int       n,
                                int                stream_width,
                                const std::string &element_delim)
{
    switch (dt)
    {
        case DataType::U8:
        case DataType::QASYMM8:
            print_consecutive_elements_impl<uint8_t>(s, ptr, n, stream_width, element_delim);
            break;
        case DataType::S8:
        case DataType::QSYMM8:
        case DataType::QASYMM8_SIGNED:
        case DataType::QSYMM8_PER_CHANNEL:
            print_consecutive_elements_impl<int8_t>(s, reinterpret_cast<const int8_t *>(ptr), n, stream_width,
                                                    element_delim);
            break;
        case DataType::U16:
        case DataType::QASYMM16:
            print_consecutive_elements_impl<uint16_t>(s, reinterpret_cast<const uint16_t *>(ptr), n, stream_width,
                                                      element_delim);
            break;
        case DataType::S16:
        case DataType::QSYMM16:
            print_consecutive_elements_impl<int16_t>(s, reinterpret_cast<const int16_t *>(ptr), n, stream_width,
                                                     element_delim);
            break;
        case DataType::U32:
            print_consecutive_elements_impl<uint32_t>(s, reinterpret_cast<const uint32_t *>(ptr), n, stream_width,
                                                      element_delim);
            break;
        case DataType::S32:
            print_consecutive_elements_impl<int32_t>(s, reinterpret_cast<const int32_t *>(ptr), n, stream_width,
                                                     element_delim);
            break;
        case DataType::U64:
            print_consecutive_elements_impl<uint64_t>(s, reinterpret_cast<const uint64_t *>(ptr), n, stream_width,
                                                      element_delim);
            break;
        case DataType::S64:
            print_consecutive_elements_impl<int64_t>(s, reinterpret_cast<const int64_t *>(ptr), n, stream_width,
                                                     element_delim);
            break;
        case DataType::BFLOAT16:
            print_consecutive_elements_impl<bfloat16>(s, reinterpret_cast<const bfloat16 *>(ptr), n, stream_width,
                                                      element_delim);
            break;
        case DataType::F16:
            print_consecutive_elements_impl<half>(s, reinterpret_cast<const half *>(ptr), n, stream_width,
                                                  element_delim);
            break;
        case DataType::F32:
            print_consecutive_elements_impl<float>(s, reinterpret_cast<const float *>(ptr), n, stream_width,
                                                   element_delim);
            break;
        default:
            ARM_COMPUTE_ERROR("Undefined element size for given data type");
    }
}

int max_consecutive_elements_display_width(std::ostream &s, DataType dt, const uint8_t *ptr, unsigned int n)
{
    switch (dt)
    {
        case DataType::U8:
        case DataType::QASYMM8:
            return max_consecutive_elements_display_width_impl<uint8_t>(s, ptr, n);
        case DataType::S8:
        case DataType::QSYMM8:
        case DataType::QASYMM8_SIGNED:
        case DataType::QSYMM8_PER_CHANNEL:
            return max_consecutive_elements_display_width_impl<int8_t>(s, reinterpret_cast<const int8_t *>(ptr), n);
        case DataType::U16:
        case DataType::QASYMM16:
            return max_consecutive_elements_display_width_impl<uint16_t>(s, reinterpret_cast<const uint16_t *>(ptr), n);
        case DataType::S16:
        case DataType::QSYMM16:
            return max_consecutive_elements_display_width_impl<int16_t>(s, reinterpret_cast<const int16_t *>(ptr), n);
        case DataType::U32:
            return max_consecutive_elements_display_width_impl<uint32_t>(s, reinterpret_cast<const uint32_t *>(ptr), n);
        case DataType::S32:
            return max_consecutive_elements_display_width_impl<int32_t>(s, reinterpret_cast<const int32_t *>(ptr), n);
        case DataType::U64:
            return max_consecutive_elements_display_width_impl<uint64_t>(s, reinterpret_cast<const uint64_t *>(ptr), n);
        case DataType::S64:
            return max_consecutive_elements_display_width_impl<int64_t>(s, reinterpret_cast<const int64_t *>(ptr), n);
        case DataType::BFLOAT16:
            return max_consecutive_elements_display_width_impl<bfloat16>(s, reinterpret_cast<const bfloat16 *>(ptr), n);
        case DataType::F16:
            return max_consecutive_elements_display_width_impl<half>(s, reinterpret_cast<const half *>(ptr), n);
        case DataType::F32:
            return max_consecutive_elements_display_width_impl<float>(s, reinterpret_cast<const float *>(ptr), n);
        default:
            ARM_COMPUTE_ERROR("Undefined element size for given data type");
    }
    return 0;
}
#endif /* ARM_COMPUTE_ASSERTS_ENABLED */

} // namespace arm_compute
