/*
 * Copyright (c) 2019-2021 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/runtime/CPP/functions/CPPDetectionPostProcessLayer.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/Validate.h"

#include "src/common/utils/Log.h"
#include "src/core/helpers/AutoConfiguration.h"

#include <cstddef>
#include <ios>
#include <list>

namespace arm_compute
{
namespace
{
Status validate_arguments(const ITensorInfo            *input_box_encoding,
                          const ITensorInfo            *input_class_score,
                          const ITensorInfo            *input_anchors,
                          ITensorInfo                  *output_boxes,
                          ITensorInfo                  *output_classes,
                          ITensorInfo                  *output_scores,
                          ITensorInfo                  *num_detection,
                          DetectionPostProcessLayerInfo info,
                          const unsigned int            kBatchSize,
                          const unsigned int            kNumCoordBox)
{
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input_box_encoding, input_class_score, input_anchors);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input_box_encoding, 1, DataType::F32, DataType::QASYMM8,
                                                         DataType::QASYMM8_SIGNED);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input_box_encoding, input_anchors);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_box_encoding->num_dimensions() > 3,
                                    "The location input tensor shape should be [4, N, kBatchSize].");
    if (input_box_encoding->num_dimensions() > 2)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG_VAR(
            input_box_encoding->dimension(2) != kBatchSize,
            "The third dimension of the input box_encoding tensor should be equal to %d.", kBatchSize);
    }
    ARM_COMPUTE_RETURN_ERROR_ON_MSG_VAR(input_box_encoding->dimension(0) != kNumCoordBox,
                                        "The first dimension of the input box_encoding tensor should be equal to %d.",
                                        kNumCoordBox);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(
        input_class_score->dimension(0) != (info.num_classes() + 1),
        "The first dimension of the input class_prediction should be equal to the number of classes plus one.");

    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_anchors->num_dimensions() > 3,
                                    "The anchors input tensor shape should be [4, N, kBatchSize].");
    if (input_anchors->num_dimensions() > 2)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG_VAR(input_anchors->dimension(0) != kNumCoordBox,
                                            "The first dimension of the input anchors tensor should be equal to %d.",
                                            kNumCoordBox);
    }
    ARM_COMPUTE_RETURN_ERROR_ON_MSG((input_box_encoding->dimension(1) != input_class_score->dimension(1)) ||
                                        (input_box_encoding->dimension(1) != input_anchors->dimension(1)),
                                    "The second dimension of the inputs should be the same.");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(num_detection->num_dimensions() > 1,
                                    "The num_detection output tensor shape should be [M].");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG((info.iou_threshold() <= 0.0f) || (info.iou_threshold() > 1.0f),
                                    "The intersection over union should be positive and less than 1.");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.max_classes_per_detection() <= 0,
                                    "The number of max classes per detection should be positive.");

    const unsigned int num_detected_boxes = info.max_detections() * info.max_classes_per_detection();

    // Validate configured outputs
    if (output_boxes->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output_boxes->tensor_shape(),
                                                           TensorShape(4U, num_detected_boxes, 1U));
        ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output_boxes, 1, DataType::F32);
    }
    if (output_classes->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output_classes->tensor_shape(),
                                                           TensorShape(num_detected_boxes, 1U));
        ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output_classes, 1, DataType::F32);
    }
    if (output_scores->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output_scores->tensor_shape(),
                                                           TensorShape(num_detected_boxes, 1U));
        ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output_scores, 1, DataType::F32);
    }
    if (num_detection->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(num_detection->tensor_shape(), TensorShape(1U));
        ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(num_detection, 1, DataType::F32);
    }

    return Status{};
}

inline void
DecodeBoxCorner(BBox &box_centersize, BBox &anchor, Iterator &decoded_it, DetectionPostProcessLayerInfo info)
{
    const float half_factor = 0.5f;

    // BBox is equavalent to CenterSizeEncoding [y,x,h,w]
    const float y_center = box_centersize[0] / info.scale_value_y() * anchor[2] + anchor[0];
    const float x_center = box_centersize[1] / info.scale_value_x() * anchor[3] + anchor[1];
    const float half_h =
        half_factor * static_cast<float>(std::exp(box_centersize[2] / info.scale_value_h())) * anchor[2];
    const float half_w =
        half_factor * static_cast<float>(std::exp(box_centersize[3] / info.scale_value_w())) * anchor[3];

    // Box Corner encoding boxes are saved as [xmin, ymin, xmax, ymax]
    auto decoded_ptr   = reinterpret_cast<float *>(decoded_it.ptr());
    *(decoded_ptr)     = x_center - half_w; // xmin
    *(1 + decoded_ptr) = y_center - half_h; // ymin
    *(2 + decoded_ptr) = x_center + half_w; // xmax
    *(3 + decoded_ptr) = y_center + half_h; // ymax
}

/** Decode a bbox according to a anchors and scale info.
 *
 * @param[in]  input_box_encoding The input prior bounding boxes.
 * @param[in]  input_anchors      The corresponding input variance.
 * @param[in]  info               The detection informations
 * @param[out] decoded_boxes      The decoded bboxes.
 */
void DecodeCenterSizeBoxes(const ITensor                *input_box_encoding,
                           const ITensor                *input_anchors,
                           DetectionPostProcessLayerInfo info,
                           Tensor                       *decoded_boxes)
{
    const QuantizationInfo &qi_box     = input_box_encoding->info()->quantization_info();
    const QuantizationInfo &qi_anchors = input_anchors->info()->quantization_info();
    BBox                    box_centersize{{}};
    BBox                    anchor{{}};

    Window win;
    win.use_tensor_dimensions(input_box_encoding->info()->tensor_shape());
    win.set_dimension_step(0U, 4U);
    win.set_dimension_step(1U, 1U);
    Iterator box_it(input_box_encoding, win);
    Iterator anchor_it(input_anchors, win);
    Iterator decoded_it(decoded_boxes, win);

    if (input_box_encoding->info()->data_type() == DataType::QASYMM8)
    {
        execute_window_loop(
            win,
            [&](const Coordinates &)
            {
                const auto box_ptr    = reinterpret_cast<const qasymm8_t *>(box_it.ptr());
                const auto anchor_ptr = reinterpret_cast<const qasymm8_t *>(anchor_it.ptr());
                box_centersize =
                    BBox({dequantize_qasymm8(*box_ptr, qi_box), dequantize_qasymm8(*(box_ptr + 1), qi_box),
                          dequantize_qasymm8(*(2 + box_ptr), qi_box), dequantize_qasymm8(*(3 + box_ptr), qi_box)});
                anchor = BBox({dequantize_qasymm8(*anchor_ptr, qi_anchors),
                               dequantize_qasymm8(*(anchor_ptr + 1), qi_anchors),
                               dequantize_qasymm8(*(2 + anchor_ptr), qi_anchors),
                               dequantize_qasymm8(*(3 + anchor_ptr), qi_anchors)});
                DecodeBoxCorner(box_centersize, anchor, decoded_it, info);
            },
            box_it, anchor_it, decoded_it);
    }
    else if (input_box_encoding->info()->data_type() == DataType::QASYMM8_SIGNED)
    {
        execute_window_loop(
            win,
            [&](const Coordinates &)
            {
                const auto box_ptr    = reinterpret_cast<const qasymm8_signed_t *>(box_it.ptr());
                const auto anchor_ptr = reinterpret_cast<const qasymm8_signed_t *>(anchor_it.ptr());
                box_centersize        = BBox({dequantize_qasymm8_signed(*box_ptr, qi_box),
                                              dequantize_qasymm8_signed(*(box_ptr + 1), qi_box),
                                              dequantize_qasymm8_signed(*(2 + box_ptr), qi_box),
                                              dequantize_qasymm8_signed(*(3 + box_ptr), qi_box)});
                anchor                = BBox({dequantize_qasymm8_signed(*anchor_ptr, qi_anchors),
                                              dequantize_qasymm8_signed(*(anchor_ptr + 1), qi_anchors),
                                              dequantize_qasymm8_signed(*(2 + anchor_ptr), qi_anchors),
                                              dequantize_qasymm8_signed(*(3 + anchor_ptr), qi_anchors)});
                DecodeBoxCorner(box_centersize, anchor, decoded_it, info);
            },
            box_it, anchor_it, decoded_it);
    }
    else
    {
        execute_window_loop(
            win,
            [&](const Coordinates &)
            {
                const auto box_ptr    = reinterpret_cast<const float *>(box_it.ptr());
                const auto anchor_ptr = reinterpret_cast<const float *>(anchor_it.ptr());
                box_centersize        = BBox({*box_ptr, *(box_ptr + 1), *(2 + box_ptr), *(3 + box_ptr)});
                anchor                = BBox({*anchor_ptr, *(anchor_ptr + 1), *(2 + anchor_ptr), *(3 + anchor_ptr)});
                DecodeBoxCorner(box_centersize, anchor, decoded_it, info);
            },
            box_it, anchor_it, decoded_it);
    }
}

void SaveOutputs(const Tensor              *decoded_boxes,
                 const std::vector<int>    &result_idx_boxes_after_nms,
                 const std::vector<float>  &result_scores_after_nms,
                 const std::vector<int>    &result_classes_after_nms,
                 std::vector<unsigned int> &sorted_indices,
                 const unsigned int         num_output,
                 const unsigned int         max_detections,
                 ITensor                   *output_boxes,
                 ITensor                   *output_classes,
                 ITensor                   *output_scores,
                 ITensor                   *num_detection)
{
    // xmin,ymin,xmax,ymax -> ymin,xmin,ymax,xmax
    unsigned int i = 0;
    for (; i < num_output; ++i)
    {
        const unsigned int box_in_idx = result_idx_boxes_after_nms[sorted_indices[i]];
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(0, i)))) =
            *(reinterpret_cast<float *>(decoded_boxes->ptr_to_element(Coordinates(1, box_in_idx))));
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(1, i)))) =
            *(reinterpret_cast<float *>(decoded_boxes->ptr_to_element(Coordinates(0, box_in_idx))));
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(2, i)))) =
            *(reinterpret_cast<float *>(decoded_boxes->ptr_to_element(Coordinates(3, box_in_idx))));
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(3, i)))) =
            *(reinterpret_cast<float *>(decoded_boxes->ptr_to_element(Coordinates(2, box_in_idx))));
        *(reinterpret_cast<float *>(output_classes->ptr_to_element(Coordinates(i)))) =
            static_cast<float>(result_classes_after_nms[sorted_indices[i]]);
        *(reinterpret_cast<float *>(output_scores->ptr_to_element(Coordinates(i)))) =
            result_scores_after_nms[sorted_indices[i]];
    }
    for (; i < max_detections; ++i)
    {
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(1, i)))) = 0.0f;
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(0, i)))) = 0.0f;
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(3, i)))) = 0.0f;
        *(reinterpret_cast<float *>(output_boxes->ptr_to_element(Coordinates(2, i)))) = 0.0f;
        *(reinterpret_cast<float *>(output_classes->ptr_to_element(Coordinates(i))))  = 0.0f;
        *(reinterpret_cast<float *>(output_scores->ptr_to_element(Coordinates(i))))   = 0.0f;
    }
    *(reinterpret_cast<float *>(num_detection->ptr_to_element(Coordinates(0)))) = num_output;
}
} // namespace

CPPDetectionPostProcessLayer::CPPDetectionPostProcessLayer(std::shared_ptr<IMemoryManager> memory_manager)
    : _memory_group(std::move(memory_manager)),
      _nms(),
      _input_box_encoding(nullptr),
      _input_scores(nullptr),
      _input_anchors(nullptr),
      _output_boxes(nullptr),
      _output_classes(nullptr),
      _output_scores(nullptr),
      _num_detection(nullptr),
      _info(),
      _num_boxes(),
      _num_classes_with_background(),
      _num_max_detected_boxes(),
      _dequantize_scores(false),
      _decoded_boxes(),
      _decoded_scores(),
      _selected_indices(),
      _class_scores(),
      _input_scores_to_use(nullptr)
{
}

void CPPDetectionPostProcessLayer::configure(const ITensor                *input_box_encoding,
                                             const ITensor                *input_scores,
                                             const ITensor                *input_anchors,
                                             ITensor                      *output_boxes,
                                             ITensor                      *output_classes,
                                             ITensor                      *output_scores,
                                             ITensor                      *num_detection,
                                             DetectionPostProcessLayerInfo info)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input_box_encoding, input_scores, input_anchors, output_boxes, output_classes,
                                 output_scores);
    ARM_COMPUTE_LOG_PARAMS(input_box_encoding, input_scores, input_anchors, output_boxes, output_classes, output_scores,
                           num_detection, info);

    _num_max_detected_boxes = info.max_detections() * info.max_classes_per_detection();

    auto_init_if_empty(*output_boxes->info(),
                       TensorInfo(TensorShape(_kNumCoordBox, _num_max_detected_boxes, _kBatchSize), 1, DataType::F32));
    auto_init_if_empty(*output_classes->info(),
                       TensorInfo(TensorShape(_num_max_detected_boxes, _kBatchSize), 1, DataType::F32));
    auto_init_if_empty(*output_scores->info(),
                       TensorInfo(TensorShape(_num_max_detected_boxes, _kBatchSize), 1, DataType::F32));
    auto_init_if_empty(*num_detection->info(), TensorInfo(TensorShape(1U), 1, DataType::F32));

    // Perform validation step
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(
        input_box_encoding->info(), input_scores->info(), input_anchors->info(), output_boxes->info(),
        output_classes->info(), output_scores->info(), num_detection->info(), info, _kBatchSize, _kNumCoordBox));

    _input_box_encoding          = input_box_encoding;
    _input_scores                = input_scores;
    _input_anchors               = input_anchors;
    _output_boxes                = output_boxes;
    _output_classes              = output_classes;
    _output_scores               = output_scores;
    _num_detection               = num_detection;
    _info                        = info;
    _num_boxes                   = input_box_encoding->info()->dimension(1);
    _num_classes_with_background = _input_scores->info()->dimension(0);
    _dequantize_scores = (info.dequantize_scores() && is_data_type_quantized(input_box_encoding->info()->data_type()));

    auto_init_if_empty(*_decoded_boxes.info(),
                       TensorInfo(TensorShape(_kNumCoordBox, _input_box_encoding->info()->dimension(1), _kBatchSize), 1,
                                  DataType::F32));
    auto_init_if_empty(
        *_decoded_scores.info(),
        TensorInfo(TensorShape(_input_scores->info()->dimension(0), _input_scores->info()->dimension(1), _kBatchSize),
                   1, DataType::F32));
    auto_init_if_empty(
        *_selected_indices.info(),
        TensorInfo(TensorShape(info.use_regular_nms() ? info.detection_per_class() : info.max_detections()), 1,
                   DataType::S32));
    const unsigned int num_classes_per_box = std::min(info.max_classes_per_detection(), info.num_classes());
    auto_init_if_empty(
        *_class_scores.info(),
        TensorInfo(info.use_regular_nms() ? TensorShape(_num_boxes) : TensorShape(_num_boxes * num_classes_per_box), 1,
                   DataType::F32));

    _input_scores_to_use = _dequantize_scores ? &_decoded_scores : _input_scores;

    // Manage intermediate buffers
    _memory_group.manage(&_decoded_boxes);
    _memory_group.manage(&_decoded_scores);
    _memory_group.manage(&_selected_indices);
    _memory_group.manage(&_class_scores);
    _nms.configure(&_decoded_boxes, &_class_scores, &_selected_indices,
                   info.use_regular_nms() ? info.detection_per_class() : info.max_detections(),
                   info.nms_score_threshold(), info.iou_threshold());

    // Allocate and reserve intermediate tensors and vectors
    _decoded_boxes.allocator()->allocate();
    _decoded_scores.allocator()->allocate();
    _selected_indices.allocator()->allocate();
    _class_scores.allocator()->allocate();
}

Status CPPDetectionPostProcessLayer::validate(const ITensorInfo            *input_box_encoding,
                                              const ITensorInfo            *input_class_score,
                                              const ITensorInfo            *input_anchors,
                                              ITensorInfo                  *output_boxes,
                                              ITensorInfo                  *output_classes,
                                              ITensorInfo                  *output_scores,
                                              ITensorInfo                  *num_detection,
                                              DetectionPostProcessLayerInfo info)
{
    constexpr unsigned int kBatchSize   = 1;
    constexpr unsigned int kNumCoordBox = 4;
    const TensorInfo       _decoded_boxes_info =
        TensorInfo(TensorShape(kNumCoordBox, input_box_encoding->dimension(1)), 1, DataType::F32);
    const TensorInfo _decoded_scores_info = TensorInfo(TensorShape(input_box_encoding->dimension(1)), 1, DataType::F32);
    const TensorInfo _selected_indices_info = TensorInfo(TensorShape(info.max_detections()), 1, DataType::S32);

    ARM_COMPUTE_RETURN_ON_ERROR(CPPNonMaximumSuppression::validate(&_decoded_boxes_info, &_decoded_scores_info,
                                                                   &_selected_indices_info, info.max_detections(),
                                                                   info.nms_score_threshold(), info.iou_threshold()));
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input_box_encoding, input_class_score, input_anchors, output_boxes,
                                                   output_classes, output_scores, num_detection, info, kBatchSize,
                                                   kNumCoordBox));

    return Status{};
}

void CPPDetectionPostProcessLayer::run()
{
    const unsigned int num_classes    = _info.num_classes();
    const unsigned int max_detections = _info.max_detections();

    DecodeCenterSizeBoxes(_input_box_encoding, _input_anchors, _info, &_decoded_boxes);

    // Decode scores if necessary
    if (_dequantize_scores)
    {
        if (_input_box_encoding->info()->data_type() == DataType::QASYMM8)
        {
            for (unsigned int idx_c = 0; idx_c < _num_classes_with_background; ++idx_c)
            {
                for (unsigned int idx_b = 0; idx_b < _num_boxes; ++idx_b)
                {
                    *(reinterpret_cast<float *>(_decoded_scores.ptr_to_element(Coordinates(idx_c, idx_b)))) =
                        dequantize_qasymm8(
                            *(reinterpret_cast<qasymm8_t *>(_input_scores->ptr_to_element(Coordinates(idx_c, idx_b)))),
                            _input_scores->info()->quantization_info());
                }
            }
        }
        else if (_input_box_encoding->info()->data_type() == DataType::QASYMM8_SIGNED)
        {
            for (unsigned int idx_c = 0; idx_c < _num_classes_with_background; ++idx_c)
            {
                for (unsigned int idx_b = 0; idx_b < _num_boxes; ++idx_b)
                {
                    *(reinterpret_cast<float *>(_decoded_scores.ptr_to_element(Coordinates(idx_c, idx_b)))) =
                        dequantize_qasymm8_signed(*(reinterpret_cast<qasymm8_signed_t *>(
                                                      _input_scores->ptr_to_element(Coordinates(idx_c, idx_b)))),
                                                  _input_scores->info()->quantization_info());
                }
            }
        }
    }

    // Regular NMS
    if (_info.use_regular_nms())
    {
        std::vector<int>          result_idx_boxes_after_nms;
        std::vector<int>          result_classes_after_nms;
        std::vector<float>        result_scores_after_nms;
        std::vector<unsigned int> sorted_indices;

        for (unsigned int c = 0; c < num_classes; ++c)
        {
            // For each boxes get scores of the boxes for the class c
            for (unsigned int i = 0; i < _num_boxes; ++i)
            {
                *(reinterpret_cast<float *>(_class_scores.ptr_to_element(Coordinates(i)))) =
                    *(reinterpret_cast<float *>(_input_scores_to_use->ptr_to_element(
                        Coordinates(c + 1, i)))); // i * _num_classes_with_background + c + 1
            }

            // Run Non-maxima Suppression
            _nms.run();

            for (unsigned int i = 0; i < _info.detection_per_class(); ++i)
            {
                const auto selected_index =
                    *(reinterpret_cast<int *>(_selected_indices.ptr_to_element(Coordinates(i))));
                if (selected_index == -1)
                {
                    // Nms will return -1 for all the last M-elements not valid
                    break;
                }
                result_idx_boxes_after_nms.emplace_back(selected_index);
                result_scores_after_nms.emplace_back(
                    (reinterpret_cast<float *>(_class_scores.buffer()))[selected_index]);
                result_classes_after_nms.emplace_back(c);
            }
        }

        // We select the max detection numbers of the highest score of all classes
        const auto num_selected = result_scores_after_nms.size();
        const auto num_output   = std::min<unsigned int>(max_detections, num_selected);

        // Sort selected indices based on result scores
        sorted_indices.resize(num_selected);
        std::iota(sorted_indices.begin(), sorted_indices.end(), 0);
        std::partial_sort(sorted_indices.data(), sorted_indices.data() + num_output,
                          sorted_indices.data() + num_selected,
                          [&](unsigned int first, unsigned int second)
                          { return result_scores_after_nms[first] > result_scores_after_nms[second]; });

        SaveOutputs(&_decoded_boxes, result_idx_boxes_after_nms, result_scores_after_nms, result_classes_after_nms,
                    sorted_indices, num_output, max_detections, _output_boxes, _output_classes, _output_scores,
                    _num_detection);
    }
    // Fast NMS
    else
    {
        const unsigned int num_classes_per_box =
            std::min<unsigned int>(_info.max_classes_per_detection(), _info.num_classes());
        std::vector<float> max_scores;
        std::vector<int>   box_indices;
        std::vector<int>   max_score_classes;

        for (unsigned int b = 0; b < _num_boxes; ++b)
        {
            std::vector<float> box_scores;
            for (unsigned int c = 0; c < num_classes; ++c)
            {
                box_scores.emplace_back(
                    *(reinterpret_cast<float *>(_input_scores_to_use->ptr_to_element(Coordinates(c + 1, b)))));
            }

            std::vector<unsigned int> max_score_indices;
            max_score_indices.resize(_info.num_classes());
            std::iota(max_score_indices.data(), max_score_indices.data() + _info.num_classes(), 0);
            std::partial_sort(max_score_indices.data(), max_score_indices.data() + num_classes_per_box,
                              max_score_indices.data() + num_classes,
                              [&](unsigned int first, unsigned int second)
                              { return box_scores[first] > box_scores[second]; });

            for (unsigned int i = 0; i < num_classes_per_box; ++i)
            {
                const float score_to_add = box_scores[max_score_indices[i]];
                *(reinterpret_cast<float *>(_class_scores.ptr_to_element(Coordinates(b * num_classes_per_box + i)))) =
                    score_to_add;
                max_scores.emplace_back(score_to_add);
                box_indices.emplace_back(b);
                max_score_classes.emplace_back(max_score_indices[i]);
            }
        }

        // Run Non-maxima Suppression
        _nms.run();
        std::vector<unsigned int> selected_indices;
        for (unsigned int i = 0; i < max_detections; ++i)
        {
            // NMS returns M valid indices, the not valid tail is filled with -1
            if (*(reinterpret_cast<int *>(_selected_indices.ptr_to_element(Coordinates(i)))) == -1)
            {
                // Nms will return -1 for all the last M-elements not valid
                break;
            }
            selected_indices.emplace_back(*(reinterpret_cast<int *>(_selected_indices.ptr_to_element(Coordinates(i)))));
        }
        // We select the max detection numbers of the highest score of all classes
        const auto num_output = std::min<unsigned int>(_info.max_detections(), selected_indices.size());

        SaveOutputs(&_decoded_boxes, box_indices, max_scores, max_score_classes, selected_indices, num_output,
                    max_detections, _output_boxes, _output_classes, _output_scores, _num_detection);
    }
}
} // namespace arm_compute
