/*
 * 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/common/utils/Log.h"
#include "src/core/helpers/AutoConfiguration.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
