~iliaplatone/spacedrone.eu/inova-sis-pack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright (C) 2018-2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "ext_list.hpp"
#include "ext_base.hpp"
#include <algorithm>
#include <cassert>
#include <vector>


namespace InferenceEngine {
namespace Extensions {
namespace Cpu {

class ExperimentalDetectronTopKROIsImpl: public ExtLayerBase {
private:
    // Inputs:
    //      rois, shape [n, 4]
    //      rois_probs, shape [n]
    // Outputs:
    //      top_rois, shape [max_rois, 4]

    const int INPUT_ROIS {0};
    const int INPUT_PROBS {1};

    const int OUTPUT_ROIS {0};

public:
    explicit ExperimentalDetectronTopKROIsImpl(const CNNLayer* layer) {
        try {
            if (layer->insData.size() != 2 || layer->outData.empty())
                THROW_IE_EXCEPTION << "Incorrect number of input/output edges!";

            if (layer->insData[INPUT_ROIS].lock()->getTensorDesc().getDims().size() != 2 ||
                layer->insData[INPUT_PROBS].lock()->getTensorDesc().getDims().size() != 1)
                THROW_IE_EXCEPTION << "Unsupported shape of input blobs!";

            max_rois_num_ = layer->GetParamAsInt("max_rois", 0);

            addConfig(layer,
                      {DataConfigurator(ConfLayout::PLN), DataConfigurator(ConfLayout::PLN)},
                      {DataConfigurator(ConfLayout::PLN)});
        } catch (InferenceEngine::details::InferenceEngineException &ex) {
            errorMsg = ex.what();
        }
    }

    StatusCode execute(std::vector<Blob::Ptr>& inputs, std::vector<Blob::Ptr>& outputs,
                       ResponseDesc *resp) noexcept override {
        const int input_rois_num = inputs[INPUT_ROIS]->getTensorDesc().getDims()[0];
        const int top_rois_num = std::min(max_rois_num_, input_rois_num);

        auto *input_rois = inputs[INPUT_ROIS]->buffer().as<const float *>();
        auto *input_probs = inputs[INPUT_PROBS]->buffer().as<const float *>();
        auto *output_rois = outputs[OUTPUT_ROIS]->buffer().as<float *>();

        std::vector<size_t> idx(input_rois_num);
        iota(idx.begin(), idx.end(), 0);
        // FIXME. partial_sort is enough here.
        sort(idx.begin(), idx.end(), [&input_probs](size_t i1, size_t i2) {return input_probs[i1] > input_probs[i2];});

        for (int i = 0; i < top_rois_num; ++i) {
            std::memcpy(output_rois + 4 * i, input_rois + 4 * idx[i], 4 * sizeof(float));
        }

        return OK;
    }

private:
    int max_rois_num_;
};

REG_FACTORY_FOR(ImplFactory<ExperimentalDetectronTopKROIsImpl>, ExperimentalDetectronTopKROIs);

}  // namespace Cpu
}  // namespace Extensions
}  // namespace InferenceEngine