1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
9 #include "inference_engine.hpp"
10 #include "details/caseless.hpp"
11 #include "ie_algorithm.hpp"
14 namespace GNAPluginNS {
17 * @brief detecting of const pointer for dynamic cast operations
21 struct is_const_pointer : public std::false_type{
25 struct is_const_pointer<const T *> : public std::true_type{
30 * similar to type traits determined in standard library this trait provides details per layer type, with some attributes specific for GNA
31 * we don't need to have compile time performance for this yet
34 InferenceEngine::CNNLayer * layer;
36 #define IS_VALID() if (nullptr == layer) return false
39 explicit LayerInfo(InferenceEngine::CNNLayer & layer)
42 explicit LayerInfo(const InferenceEngine::CNNLayerPtr & layer)
43 : LayerInfo(layer.get()) {
45 explicit LayerInfo(InferenceEngine::CNNLayer * layer)
48 bool has16BOutput() const noexcept {
50 static InferenceEngine::details::caseless_set<std::string> layersWith16BOutputs = {"memory", "input", "split", "slice", "concat", "copy"};
51 return layersWith16BOutputs.find(layer->type) != layersWith16BOutputs.end() ||
53 (isCrop() && !isCropAffined());
55 bool has32BOutput() const noexcept {
57 static InferenceEngine::details::caseless_set<std::string> layersWith32BOutputs =
58 {"FullyConnected", "InnerProduct", "AffineFilter", "Eltwise", "ScaleShift", "Convolution", "Pooling"};
59 return (layersWith32BOutputs.find(layer->type) != layersWith32BOutputs.end()) ||
60 (isCrop() && isCropAffined());
62 static bool isBatchSizeConstrained(const std::string name) {
63 static InferenceEngine::details::caseless_set<std::string> layersWithConstrains = {"memory", "convolution"};
64 return layersWithConstrains.find(name) != layersWithConstrains.end();
66 bool isActivation() const noexcept {
68 static InferenceEngine::details::caseless_set<std::string> activations = {"clamp", "sigmoid", "identity", "relu", "leakyrelu", "tanh", "prelu"};
69 return activations.find(layer->type) != activations.end();
71 bool isRelu() const noexcept {
73 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "relu");
75 bool isConvolution() const noexcept {
77 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "convolution");
79 bool isPower() const noexcept {
81 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "power");
83 bool has32BInput() const noexcept {
85 return isActivation() || isPooling();
87 bool isInput() const noexcept {
89 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "input");
91 bool isScaleShift() const noexcept {
93 return nullptr != as<const InferenceEngine::ScaleShiftLayer*>();
96 bool isEltwise() const noexcept {
98 return nullptr != as<const InferenceEngine::EltwiseLayer*>();
100 bool isEltwiseSum() const noexcept {
102 if (!isEltwise()) return false;
103 return dynamic_cast<const InferenceEngine::EltwiseLayer*>(layer)->_operation ==
104 InferenceEngine::EltwiseLayer::Sum;
106 bool isEltwiseMul() const noexcept {
108 if (!isEltwise()) return false;
109 return dynamic_cast<const InferenceEngine::EltwiseLayer*>(layer)->_operation ==
110 InferenceEngine::EltwiseLayer::Prod;
112 bool isIdentity() const noexcept {
114 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "identity");
116 bool isFullyConnected() const noexcept {
117 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "FullyConnected") ||
118 InferenceEngine::details::CaselessEq<std::string>()(layer->type, "InnerProduct");
120 bool isSplit() const noexcept {
122 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "split");
124 bool isSlice() const noexcept {
126 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "slice");
128 bool isConcat() const noexcept {
130 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "concat");
132 bool isReshape() const noexcept {
134 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "reshape");
136 bool isPermute() const noexcept {
138 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "permute");
140 bool isPooling() const noexcept {
142 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "Pooling");
144 bool isMaxPooling() const noexcept {
146 if (!isPooling()) return false;
147 return as<const InferenceEngine::PoolingLayer*>()->_type == InferenceEngine::PoolingLayer::MAX;
149 bool isMemory() const noexcept {
151 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "memory");
153 bool isCrop() const noexcept {
155 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "crop");
157 bool isCropAffined() const noexcept {
158 auto cropLayer = dynamic_cast<InferenceEngine::CropLayer *> (layer);
159 size_t cropOffset = cropLayer->offset.back() * cropLayer->precision.size();
160 return (ALIGN64(cropOffset) != cropOffset);
162 bool isCopy() const noexcept {
164 return InferenceEngine::details::CaselessEq<std::string>()(layer->type, "copy");
166 size_t paddingSize() const noexcept {
167 static InferenceEngine::details::caseless_set<std::string> layersWithPossiblePadding = {"FullyConnected",
171 if (layersWithPossiblePadding.find(layer->type) != layersWithPossiblePadding.end()) {
172 size_t size_without_padding = 0;
173 auto inputs = layer->insData.begin()->lock();
175 size_without_padding = InferenceEngine::details::product(begin(inputs->dims),
178 return ALIGN(size_without_padding, 8) - size_without_padding;
183 typename std::enable_if<!is_const_pointer<T>::value, T>::type as() noexcept {
184 return dynamic_cast<T>(layer);
187 typename std::enable_if<is_const_pointer<T>::value, T>::type as() const noexcept {
188 return dynamic_cast<T>(layer);
190 operator InferenceEngine::CNNLayer *() noexcept {
193 operator const InferenceEngine::CNNLayer *() const noexcept {
196 operator InferenceEngine::CNNLayerPtr () const noexcept {
197 return std::shared_ptr<InferenceEngine::CNNLayer>(layer, [] (InferenceEngine::CNNLayer * p) {});
203 inline std::ostream & operator <<(std::ostream &os, const LayerInfo & info) {
204 os << static_cast<const InferenceEngine::CNNLayer*>(info)->name;
208 } // namespace GNAPluginNS