/*
 * Copyright (c) 2018-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/CPPDetectionOutputLayer.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/Validate.h"
#include "src/core/helpers/AutoConfiguration.h"

#include "src/common/utils/Log.h"

#include <list>

namespace arm_compute
{
namespace
{
Status validate_arguments(const ITensorInfo *input_loc, const ITensorInfo *input_conf, const ITensorInfo *input_priorbox, const ITensorInfo *output, DetectionOutputLayerInfo info)
{
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input_loc, input_conf, input_priorbox, output);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input_loc, 1, DataType::F32);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input_loc, input_conf, input_priorbox);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_loc->num_dimensions() > 2, "The location input tensor should be [C1, N].");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_conf->num_dimensions() > 2, "The location input tensor should be [C2, N].");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(input_priorbox->num_dimensions() > 3, "The priorbox input tensor should be [C3, 2, N].");

    ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.eta() <= 0.f && info.eta() > 1.f, "Eta should be between 0 and 1");

    const int num_priors = input_priorbox->tensor_shape()[0] / 4;
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(static_cast<size_t>((num_priors * info.num_loc_classes() * 4)) != input_loc->tensor_shape()[0], "Number of priors must match number of location predictions.");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(static_cast<size_t>((num_priors * info.num_classes())) != input_conf->tensor_shape()[0], "Number of priors must match number of confidence predictions.");

    // Validate configured output
    if(output->total_size() != 0)
    {
        const unsigned int max_size = info.keep_top_k() * (input_loc->num_dimensions() > 1 ? input_loc->dimension(1) : 1);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output->tensor_shape(), TensorShape(7U, max_size));
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input_loc, output);
    }

    return Status{};
}

/** Function used to sort pair<float, T> in descend order based on the score (first) value.
 */
template <typename T>
bool SortScorePairDescend(const std::pair<float, T> &pair1,
                          const std::pair<float, T> &pair2)
{
    return pair1.first > pair2.first;
}

/** Get location predictions from input_loc.
 *
 * @param[in]  input_loc                The input location prediction.
 * @param[in]  num                      The number of images.
 * @param[in]  num_priors               number of predictions per class.
 * @param[in]  num_loc_classes          number of location classes. It is 1 if share_location is true,
 *                                      and is equal to number of classes needed to predict otherwise.
 * @param[in]  share_location           If true, all classes share the same location prediction.
 * @param[out] all_location_predictions All the location predictions.
 *
 */
void retrieve_all_loc_predictions(const ITensor *input_loc, const int num,
                                  const int num_priors, const int num_loc_classes,
                                  const bool share_location, std::vector<LabelBBox> &all_location_predictions)
{
    for(int i = 0; i < num; ++i)
    {
        for(int c = 0; c < num_loc_classes; ++c)
        {
            int label = share_location ? -1 : c;
            if(all_location_predictions[i].find(label) == all_location_predictions[i].end())
            {
                all_location_predictions[i][label].resize(num_priors);
            }
            else
            {
                ARM_COMPUTE_ERROR_ON(all_location_predictions[i][label].size() != static_cast<size_t>(num_priors));
                break;
            }
        }
    }
    for(int i = 0; i < num; ++i)
    {
        for(int p = 0; p < num_priors; ++p)
        {
            for(int c = 0; c < num_loc_classes; ++c)
            {
                const int label    = share_location ? -1 : c;
                const int base_ptr = i * num_priors * num_loc_classes * 4 + p * num_loc_classes * 4 + c * 4;
                //xmin, ymin, xmax, ymax
                all_location_predictions[i][label][p][0] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr)));
                all_location_predictions[i][label][p][1] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 1)));
                all_location_predictions[i][label][p][2] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 2)));
                all_location_predictions[i][label][p][3] = *reinterpret_cast<float *>(input_loc->ptr_to_element(Coordinates(base_ptr + 3)));
            }
        }
    }
}

/** Get confidence predictions from input_conf.
 *
 * @param[in]  input_loc                The input location prediction.
 * @param[in]  num                      The number of images.
 * @param[in]  num_priors               Number of predictions per class.
 * @param[in]  num_loc_classes          Number of location classes. It is 1 if share_location is true,
 *                                      and is equal to number of classes needed to predict otherwise.
 * @param[out] all_location_predictions All the location predictions.
 *
 */
void retrieve_all_conf_scores(const ITensor *input_conf, const int num,
                              const int num_priors, const int                 num_classes,
                              std::vector<std::map<int, std::vector<float>>> &all_confidence_scores)
{
    std::vector<float> tmp_buffer;
    tmp_buffer.resize(num * num_priors * num_classes);
    for(int i = 0; i < num; ++i)
    {
        for(int c = 0; c < num_classes; ++c)
        {
            for(int p = 0; p < num_priors; ++p)
            {
                tmp_buffer[i * num_classes * num_priors + c * num_priors + p] =
                    *reinterpret_cast<float *>(input_conf->ptr_to_element(Coordinates(i * num_classes * num_priors + p * num_classes + c)));
            }
        }
    }
    for(int i = 0; i < num; ++i)
    {
        for(int c = 0; c < num_classes; ++c)
        {
            all_confidence_scores[i][c].resize(num_priors);
            all_confidence_scores[i][c].assign(&tmp_buffer[i * num_classes * num_priors + c * num_priors],
                                               &tmp_buffer[i * num_classes * num_priors + c * num_priors + num_priors]);
        }
    }
}

/** Get prior boxes from input_priorbox.
 *
 * @param[in]  input_priorbox           The input location prediction.
 * @param[in]  num_priors               Number of priors.
 * @param[in]  num_loc_classes          number of location classes. It is 1 if share_location is true,
 *                                      and is equal to number of classes needed to predict otherwise.
 * @param[out] all_prior_bboxes         If true, all classes share the same location prediction.
 * @param[out] all_location_predictions All the location predictions.
 *
 */
void retrieve_all_priorbox(const ITensor     *input_priorbox,
                           const int          num_priors,
                           std::vector<BBox> &all_prior_bboxes,
                           std::vector<std::array<float, 4>> &all_prior_variances)
{
    for(int i = 0; i < num_priors; ++i)
    {
        all_prior_bboxes[i] =
        {
            {
                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4))),
                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 1))),
                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 2))),
                *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates(i * 4 + 3)))
            }
        };
    }

    std::array<float, 4> var({ { 0, 0, 0, 0 } });
    for(int i = 0; i < num_priors; ++i)
    {
        for(int j = 0; j < 4; ++j)
        {
            var[j] = *reinterpret_cast<float *>(input_priorbox->ptr_to_element(Coordinates((num_priors + i) * 4 + j)));
        }
        all_prior_variances[i] = var;
    }
}

/** Decode a bbox according to a prior bbox.
 *
 * @param[in]  prior_bbox                 The input prior bounding boxes.
 * @param[in]  prior_variance             The corresponding input variance.
 * @param[in]  code_type                  The detection output code type used to decode the results.
 * @param[in]  variance_encoded_in_target If true, the variance is encoded in target.
 * @param[in]  clip_bbox                  If true, the results should be between 0.f and 1.f.
 * @param[in]  bbox                       The input bbox to decode
 * @param[out] decode_bbox                The decoded bboxes.
 *
 */
void DecodeBBox(const BBox &prior_bbox, const std::array<float, 4> &prior_variance,
                const DetectionOutputLayerCodeType code_type, const bool variance_encoded_in_target,
                const bool clip_bbox, const BBox &bbox, BBox &decode_bbox)
{
    // if the variance is encoded in target, we simply need to add the offset predictions
    // otherwise we need to scale the offset accordingly.
    switch(code_type)
    {
        case DetectionOutputLayerCodeType::CORNER:
        {
            decode_bbox[0] = prior_bbox[0] + (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]);
            decode_bbox[1] = prior_bbox[1] + (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]);
            decode_bbox[2] = prior_bbox[2] + (variance_encoded_in_target ? bbox[2] : prior_variance[2] * bbox[2]);
            decode_bbox[3] = prior_bbox[3] + (variance_encoded_in_target ? bbox[3] : prior_variance[3] * bbox[3]);

            break;
        }
        case DetectionOutputLayerCodeType::CENTER_SIZE:
        {
            const float prior_width  = prior_bbox[2] - prior_bbox[0];
            const float prior_height = prior_bbox[3] - prior_bbox[1];

            // Check if the prior width and height are right
            ARM_COMPUTE_ERROR_ON(prior_width <= 0.f);
            ARM_COMPUTE_ERROR_ON(prior_height <= 0.f);

            const float prior_center_x = (prior_bbox[0] + prior_bbox[2]) / 2.;
            const float prior_center_y = (prior_bbox[1] + prior_bbox[3]) / 2.;

            const float decode_bbox_center_x = (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]) * prior_width + prior_center_x;
            const float decode_bbox_center_y = (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]) * prior_height + prior_center_y;
            const float decode_bbox_width    = (variance_encoded_in_target ? std::exp(bbox[2]) : std::exp(prior_variance[2] * bbox[2])) * prior_width;
            const float decode_bbox_height   = (variance_encoded_in_target ? std::exp(bbox[3]) : std::exp(prior_variance[3] * bbox[3])) * prior_height;

            decode_bbox[0] = (decode_bbox_center_x - decode_bbox_width / 2.f);
            decode_bbox[1] = (decode_bbox_center_y - decode_bbox_height / 2.f);
            decode_bbox[2] = (decode_bbox_center_x + decode_bbox_width / 2.f);
            decode_bbox[3] = (decode_bbox_center_y + decode_bbox_height / 2.f);

            break;
        }
        case DetectionOutputLayerCodeType::CORNER_SIZE:
        {
            const float prior_width  = prior_bbox[2] - prior_bbox[0];
            const float prior_height = prior_bbox[3] - prior_bbox[1];

            // Check if the prior width and height are greater than 0
            ARM_COMPUTE_ERROR_ON(prior_width <= 0.f);
            ARM_COMPUTE_ERROR_ON(prior_height <= 0.f);

            decode_bbox[0] = prior_bbox[0] + (variance_encoded_in_target ? bbox[0] : prior_variance[0] * bbox[0]) * prior_width;
            decode_bbox[1] = prior_bbox[1] + (variance_encoded_in_target ? bbox[1] : prior_variance[1] * bbox[1]) * prior_height;
            decode_bbox[2] = prior_bbox[2] + (variance_encoded_in_target ? bbox[2] : prior_variance[2] * bbox[2]) * prior_width;
            decode_bbox[3] = prior_bbox[3] + (variance_encoded_in_target ? bbox[3] : prior_variance[3] * bbox[3]) * prior_height;

            break;
        }
        default:
            ARM_COMPUTE_ERROR("Unsupported Detection Output Code Type.");
    }

    if(clip_bbox)
    {
        for(auto &d_bbox : decode_bbox)
        {
            d_bbox = utility::clamp(d_bbox, 0.f, 1.f);
        }
    }
}

/** Do non maximum suppression given bboxes and scores.
 *
 * @param[in]  bboxes          The input bounding boxes.
 * @param[in]  scores          The corresponding input confidence.
 * @param[in]  score_threshold The threshold used to filter detection results.
 * @param[in]  nms_threshold   The threshold used in non maximum suppression.
 * @param[in]  eta             Adaptation rate for nms threshold.
 * @param[in]  top_k           If not -1, keep at most top_k picked indices.
 * @param[out] indices         The kept indices of bboxes after nms.
 *
 */
void ApplyNMSFast(const std::vector<BBox> &bboxes,
                  const std::vector<float> &scores, const float score_threshold,
                  const float nms_threshold, const float eta, const int top_k,
                  std::vector<int> &indices)
{
    ARM_COMPUTE_ERROR_ON_MSG(bboxes.size() != scores.size(), "bboxes and scores have different size.");

    // Get top_k scores (with corresponding indices).
    std::list<std::pair<float, int>> score_index_vec;

    // Generate index score pairs.
    for(size_t i = 0; i < scores.size(); ++i)
    {
        if(scores[i] > score_threshold)
        {
            score_index_vec.emplace_back(std::make_pair(scores[i], i));
        }
    }

    // Sort the score pair according to the scores in descending order
    score_index_vec.sort(SortScorePairDescend<int>);

    // Keep top_k scores if needed.
    const int score_index_vec_size = score_index_vec.size();
    if(top_k > -1 && top_k < score_index_vec_size)
    {
        score_index_vec.resize(top_k);
    }

    // Do nms.
    float adaptive_threshold = nms_threshold;
    indices.clear();

    while(!score_index_vec.empty())
    {
        const int idx  = score_index_vec.front().second;
        bool      keep = true;
        for(int kept_idx : indices)
        {
            if(keep)
            {
                // Compute the jaccard (intersection over union IoU) overlap between two bboxes.
                BBox intersect_bbox = std::array<float, 4>({ 0, 0, 0, 0 });
                if(bboxes[kept_idx][0] > bboxes[idx][2] || bboxes[kept_idx][2] < bboxes[idx][0] || bboxes[kept_idx][1] > bboxes[idx][3] || bboxes[kept_idx][3] < bboxes[idx][1])
                {
                    intersect_bbox = std::array<float, 4>({ { 0, 0, 0, 0 } });
                }
                else
                {
                    intersect_bbox = std::array<float, 4>({ {
                            std::max(bboxes[idx][0], bboxes[kept_idx][0]),
                            std::max(bboxes[idx][1], bboxes[kept_idx][1]),
                            std::min(bboxes[idx][2], bboxes[kept_idx][2]),
                            std::min(bboxes[idx][3], bboxes[kept_idx][3])
                        }
                    });
                }

                float intersect_width  = intersect_bbox[2] - intersect_bbox[0];
                float intersect_height = intersect_bbox[3] - intersect_bbox[1];

                float overlap = 0.f;
                if(intersect_width > 0 && intersect_height > 0)
                {
                    float intersect_size = intersect_width * intersect_height;
                    float bbox1_size     = (bboxes[idx][2] < bboxes[idx][0]
                                            || bboxes[idx][3] < bboxes[idx][1]) ?
                                           0.f :
                                           (bboxes[idx][2] - bboxes[idx][0]) * (bboxes[idx][3] - bboxes[idx][1]); //BBoxSize(bboxes[idx]);
                    float bbox2_size = (bboxes[kept_idx][2] < bboxes[kept_idx][0]
                                        || bboxes[kept_idx][3] < bboxes[kept_idx][1]) ?
                                       0.f :
                                       (bboxes[kept_idx][2] - bboxes[kept_idx][0]) * (bboxes[kept_idx][3] - bboxes[kept_idx][1]); // BBoxSize(bboxes[kept_idx]);
                    overlap = intersect_size / (bbox1_size + bbox2_size - intersect_size);
                }
                keep = (overlap <= adaptive_threshold);
            }
            else
            {
                break;
            }
        }
        if(keep)
        {
            indices.push_back(idx);
        }
        score_index_vec.erase(score_index_vec.begin());
        if(keep && eta < 1.f && adaptive_threshold > 0.5f)
        {
            adaptive_threshold *= eta;
        }
    }
}
} // namespace

CPPDetectionOutputLayer::CPPDetectionOutputLayer()
    : _input_loc(nullptr), _input_conf(nullptr), _input_priorbox(nullptr), _output(nullptr), _info(), _num_priors(), _num(), _all_location_predictions(), _all_confidence_scores(), _all_prior_bboxes(),
      _all_prior_variances(), _all_decode_bboxes(), _all_indices()
{
}

void CPPDetectionOutputLayer::configure(const ITensor *input_loc, const ITensor *input_conf, const ITensor *input_priorbox,
                                        ITensor *output, DetectionOutputLayerInfo info)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input_loc, input_conf, input_priorbox, output);
    ARM_COMPUTE_LOG_PARAMS(input_loc, input_conf, input_priorbox, output, info);

    // Output auto initialization if not yet initialized
    // Since the number of bboxes to kept is unknown before nms, the shape is set to the maximum
    // The maximum is keep_top_k * input_loc_size[1]
    // Each row is a 7 dimension std::vector, which stores [image_id, label, confidence, xmin, ymin, xmax, ymax]
    const unsigned int max_size = info.keep_top_k() * (input_loc->info()->num_dimensions() > 1 ? input_loc->info()->dimension(1) : 1);
    auto_init_if_empty(*output->info(), input_loc->info()->clone()->set_tensor_shape(TensorShape(7U, max_size)));

    // Perform validation step
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input_loc->info(), input_conf->info(), input_priorbox->info(), output->info(), info));

    _input_loc      = input_loc;
    _input_conf     = input_conf;
    _input_priorbox = input_priorbox;
    _output         = output;
    _info           = info;
    _num_priors     = input_priorbox->info()->dimension(0) / 4;
    _num            = (_input_loc->info()->num_dimensions() > 1 ? _input_loc->info()->dimension(1) : 1);

    _all_location_predictions.resize(_num);
    _all_confidence_scores.resize(_num);
    _all_prior_bboxes.resize(_num_priors);
    _all_prior_variances.resize(_num_priors);
    _all_decode_bboxes.resize(_num);

    for(int i = 0; i < _num; ++i)
    {
        for(int c = 0; c < _info.num_loc_classes(); ++c)
        {
            const int label = _info.share_location() ? -1 : c;
            if(label == _info.background_label_id())
            {
                // Ignore background class.
                continue;
            }
            _all_decode_bboxes[i][label].resize(_num_priors);
        }
    }
    _all_indices.resize(_num);

    Coordinates coord;
    coord.set_num_dimensions(output->info()->num_dimensions());
    output->info()->set_valid_region(ValidRegion(coord, output->info()->tensor_shape()));
}

Status CPPDetectionOutputLayer::validate(const ITensorInfo *input_loc, const ITensorInfo *input_conf, const ITensorInfo *input_priorbox, const ITensorInfo *output, DetectionOutputLayerInfo info)
{
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input_loc, input_conf, input_priorbox, output, info));
    return Status{};
}

void CPPDetectionOutputLayer::run()
{
    // Retrieve all location predictions.
    retrieve_all_loc_predictions(_input_loc, _num, _num_priors, _info.num_loc_classes(), _info.share_location(), _all_location_predictions);

    // Retrieve all confidences.
    retrieve_all_conf_scores(_input_conf, _num, _num_priors, _info.num_classes(), _all_confidence_scores);

    // Retrieve all prior bboxes.
    retrieve_all_priorbox(_input_priorbox, _num_priors, _all_prior_bboxes, _all_prior_variances);

    // Decode all loc predictions to bboxes
    const bool clip_bbox = false;
    for(int i = 0; i < _num; ++i)
    {
        for(int c = 0; c < _info.num_loc_classes(); ++c)
        {
            const int label = _info.share_location() ? -1 : c;
            if(label == _info.background_label_id())
            {
                // Ignore background class.
                continue;
            }
            ARM_COMPUTE_ERROR_ON_MSG_VAR(_all_location_predictions[i].find(label) == _all_location_predictions[i].end(), "Could not find location predictions for label %d.", label);

            const std::vector<BBox> &label_loc_preds = _all_location_predictions[i].find(label)->second;

            const int num_bboxes = _all_prior_bboxes.size();
            ARM_COMPUTE_ERROR_ON(_all_prior_variances[i].size() != 4);

            for(int j = 0; j < num_bboxes; ++j)
            {
                DecodeBBox(_all_prior_bboxes[j], _all_prior_variances[j], _info.code_type(), _info.variance_encoded_in_target(), clip_bbox, label_loc_preds[j], _all_decode_bboxes[i][label][j]);
            }
        }
    }

    int num_kept = 0;

    for(int i = 0; i < _num; ++i)
    {
        const LabelBBox &decode_bboxes = _all_decode_bboxes[i];
        const std::map<int, std::vector<float>> &conf_scores = _all_confidence_scores[i];

        std::map<int, std::vector<int>> indices;
        int num_det = 0;
        for(int c = 0; c < _info.num_classes(); ++c)
        {
            if(c == _info.background_label_id())
            {
                // Ignore background class
                continue;
            }
            const int label = _info.share_location() ? -1 : c;
            if(conf_scores.find(c) == conf_scores.end() || decode_bboxes.find(label) == decode_bboxes.end())
            {
                ARM_COMPUTE_ERROR_VAR("Could not find predictions for label %d.", label);
            }
            const std::vector<float> &scores = conf_scores.find(c)->second;
            const std::vector<BBox> &bboxes = decode_bboxes.find(label)->second;

            ApplyNMSFast(bboxes, scores, _info.confidence_threshold(), _info.nms_threshold(), _info.eta(), _info.top_k(), indices[c]);

            num_det += indices[c].size();
        }

        int num_to_add = 0;
        if(_info.keep_top_k() > -1 && num_det > _info.keep_top_k())
        {
            std::vector<std::pair<float, std::pair<int, int>>> score_index_pairs;
            for(auto const &it : indices)
            {
                const int               label         = it.first;
                const std::vector<int> &label_indices = it.second;

                if(conf_scores.find(label) == conf_scores.end())
                {
                    ARM_COMPUTE_ERROR_VAR("Could not find predictions for label %d.", label);
                }

                const std::vector<float> &scores = conf_scores.find(label)->second;
                for(auto idx : label_indices)
                {
                    ARM_COMPUTE_ERROR_ON(idx > static_cast<int>(scores.size()));
                    score_index_pairs.emplace_back(std::make_pair(scores[idx], std::make_pair(label, idx)));
                }
            }

            // Keep top k results per image.
            std::sort(score_index_pairs.begin(), score_index_pairs.end(), SortScorePairDescend<std::pair<int, int>>);
            score_index_pairs.resize(_info.keep_top_k());

            // Store the new indices.

            std::map<int, std::vector<int>> new_indices;
            for(auto score_index_pair : score_index_pairs)
            {
                int label = score_index_pair.second.first;
                int idx   = score_index_pair.second.second;
                new_indices[label].push_back(idx);
            }
            _all_indices[i] = new_indices;
            num_to_add      = _info.keep_top_k();
        }
        else
        {
            _all_indices[i] = indices;
            num_to_add      = num_det;
        }
        num_kept += num_to_add;
    }

    //Update the valid region of the ouput to mark the exact number of detection
    _output->info()->set_valid_region(ValidRegion(Coordinates(0, 0), TensorShape(7, num_kept)));

    int count = 0;
    for(int i = 0; i < _num; ++i)
    {
        const std::map<int, std::vector<float>> &conf_scores = _all_confidence_scores[i];
        const LabelBBox &decode_bboxes = _all_decode_bboxes[i];
        for(auto &it : _all_indices[i])
        {
            const int                 label     = it.first;
            const std::vector<float> &scores    = conf_scores.find(label)->second;
            const int                 loc_label = _info.share_location() ? -1 : label;
            if(conf_scores.find(label) == conf_scores.end() || decode_bboxes.find(loc_label) == decode_bboxes.end())
            {
                // Either if there are no confidence predictions
                // or there are no location predictions for current label.
                ARM_COMPUTE_ERROR_VAR("Could not find predictions for the label %d.", label);
            }
            const std::vector<BBox> &bboxes  = decode_bboxes.find(loc_label)->second;
            const std::vector<int> &indices = it.second;

            for(auto idx : indices)
            {
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7))))     = i;
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 1)))) = label;
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 2)))) = scores[idx];
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 3)))) = bboxes[idx][0];
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 4)))) = bboxes[idx][1];
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 5)))) = bboxes[idx][2];
                *(reinterpret_cast<float *>(_output->ptr_to_element(Coordinates(count * 7 + 6)))) = bboxes[idx][3];

                ++count;
            }
        }
    }
}
} // namespace arm_compute
