1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
7 #include <details/caseless.hpp>
8 #include <ie_network.hpp>
9 #include <ie_builders.hpp>
10 #include <ie_layers.h>
17 namespace InferenceEngine {
22 inline std::string convertParameter2String(const Parameter& parameter) {
23 if (parameter.is<std::vector<T>>()) {
24 std::vector<T> params = parameter.as<std::vector<T>>();
26 for (const auto& param : params) {
29 result += convertParameter2String<T>(param);
33 return std::to_string(parameter.as<T>());
36 inline std::string convertParameter2String<std::string>(const Parameter& parameter) {
37 return parameter.as<std::string>();
40 std::map<std::string, std::string> convertParameters2Strings(const std::map<std::string, Parameter>& parameters);
41 Layer builderFromCNNLayer(const CNNLayerPtr& cnnLayer);
43 struct ConvertersHolder {
44 details::caseless_map<std::string, std::function<void(const CNNLayerPtr& cnnLayer, Layer&)>> converters;
48 * @brief This class registers layer validators
50 class ConverterRegister {
53 * @brief The constructor registers new layer validator
54 * @param type Layer type
55 * @param validator Layer validator
57 explicit ConverterRegister(const std::string& type, const std::function<void(const CNNLayerPtr&, Layer&)>& converter);
59 static void convert(const CNNLayerPtr& cnnLayer, Layer& layer) {
60 if (getConvertersHolder().converters.find(layer.getType()) != getConvertersHolder().converters.end())
61 getConvertersHolder().converters[layer.getType()](cnnLayer, layer);
65 static ConvertersHolder& getConvertersHolder();
68 #define REG_CONVERTER_FOR(__type, __converter) \
69 static InferenceEngine::Builder::ConverterRegister _reg_converter_##__type(#__type, __converter)
73 explicit BaseConverter(const std::string& type): type(type) {}
75 virtual CNNLayer::Ptr createLayer(const std::shared_ptr<const ILayer>& layer, Precision precision) = 0;
76 virtual bool canCreate(const std::string& nodeType) const = 0;
83 class LayerConverter: public BaseConverter {
85 explicit LayerConverter(const std::string& type): BaseConverter(type) {}
87 CNNLayer::Ptr createLayer(const std::shared_ptr<const ILayer>& layer, Precision precision) override {
88 LayerParams params = {layer->getName(), layer->getType(), precision};
89 auto res = std::make_shared<CLT>(params);
91 auto * weightLayerPtr = dynamic_cast<WeightableLayer *>(res.get());
93 for (const auto& port : layer->getInputPorts()) {
94 if (port.getParameters().find("type") == port.getParameters().end() ||
95 port.getData()->getData()->cbuffer() == nullptr)
97 res->blobs[port.getParameters().at("type")] = port.getData()->getData();
98 if (weightLayerPtr == nullptr)
100 if (port.getParameters().at("type").as<std::string>() == "weights") {
101 weightLayerPtr->_weights = port.getData()->getData();
102 } else if (port.getParameters().at("type").as<std::string>() == "biases") {
103 weightLayerPtr->_biases = port.getData()->getData();
107 // For constant layers
108 for (auto& it : layer->getParameters()) {
109 if (it.second.is<Blob::CPtr>()) {
110 res->blobs[it.first] = std::const_pointer_cast<Blob>(it.second.as<Blob::CPtr>());
111 } else if (it.second.is<Blob::Ptr>()) {
112 res->blobs[it.first] = it.second.as<Blob::Ptr>();
116 res->params = convertParameters2Strings(layer->getParameters());
120 bool canCreate(const std::string& nodeType) const override {
121 details::CaselessEq<std::string> comparator;
122 return comparator(nodeType, type);
126 class ActivationConverter: public BaseConverter {
128 ActivationConverter(): BaseConverter("Activation") {}
130 CNNLayer::Ptr createLayer(const std::shared_ptr<const ILayer>& layer, Precision precision) override {
131 LayerParams params = {layer->getName(), layer->getType(), precision};
132 static details::caseless_map<std::string, std::shared_ptr<BaseConverter>> activationCreators = {
133 {"relu", std::make_shared<LayerConverter<InferenceEngine::ReLULayer>>("ReLU")},
134 {"prelu", std::make_shared<LayerConverter<InferenceEngine::PReLULayer>>("PReLU")},
135 {"clamp", std::make_shared<LayerConverter<InferenceEngine::ClampLayer>>("Clamp")},
136 {"elu", std::make_shared<LayerConverter<InferenceEngine::CNNLayer>>("ELU")},
137 {"sigmoid", std::make_shared<LayerConverter<InferenceEngine::CNNLayer>>("Sigmoid")},
138 {"tanh", std::make_shared<LayerConverter<InferenceEngine::CNNLayer>>("TanH")},
141 auto typeIt = layer->getParameters().find("type");
142 if (typeIt == layer->getParameters().end())
143 THROW_IE_EXCEPTION << "Unsupported Activation layer. Type is unknown.";
145 auto activationBuilder = activationCreators.find(typeIt->second);
146 if (activationBuilder == activationCreators.end()) {
147 THROW_IE_EXCEPTION << "Unsupported Activation layer type: " << typeIt->second.as<std::string>();
150 auto activation = activationBuilder->second->createLayer(layer, precision);
152 activation->type = activationBuilder->first;
153 activation->params.erase("type");
154 activation->validateLayer();
158 bool canCreate(const std::string& nodeType) const override {
159 details::CaselessEq<std::string> comparator;
160 return comparator(nodeType, type);
164 class RNNSequenceConverter: public BaseConverter {
166 RNNSequenceConverter(): BaseConverter("RNN") {}
168 CNNLayer::Ptr createLayer(const std::shared_ptr<const ILayer>& layer, Precision precision) override {
169 auto rnnLayer = LayerConverter<InferenceEngine::RNNSequenceLayer>("RNN").createLayer(layer, precision);
170 rnnLayer->type = "RNN";
171 std::string type = layer->getType();
172 size_t pos = type.find("Sequence");
173 if (pos != std::string::npos)
175 rnnLayer->params["cell_type"] = type;
179 bool canCreate(const std::string& nodeType) const override {
180 static const details::caseless_set<std::string> supportedRnnTypes {
181 "LSTMSequence", "GRUSequence", "RNNSequence"
183 return supportedRnnTypes.find(nodeType) != supportedRnnTypes.end();
187 } // namespace Builder
188 } // namespace InferenceEngine