This reverts commit 7877287301
.
This commit is contained in:
parent
7877287301
commit
7f3d715f5d
@ -35,7 +35,6 @@ protected:
|
|||||||
ngraph::pass::low_precision::Subgraph& subgraph,
|
ngraph::pass::low_precision::Subgraph& subgraph,
|
||||||
std::function<void(
|
std::function<void(
|
||||||
std::shared_ptr<ngraph::Node> layer,
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
std::shared_ptr<ngraph::Node> child,
|
|
||||||
const std::string originalLayerName,
|
const std::string originalLayerName,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate)> getLayerDequantizationCallback) const;
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate)> getLayerDequantizationCallback) const;
|
||||||
|
|
||||||
@ -43,15 +42,6 @@ protected:
|
|||||||
const TransformationContext& context,
|
const TransformationContext& context,
|
||||||
const std::vector<std::shared_ptr<ngraph::Node>>& quantizationOperations);
|
const std::vector<std::shared_ptr<ngraph::Node>>& quantizationOperations);
|
||||||
|
|
||||||
void fillDequantizationNodes(
|
|
||||||
const std::vector<FakeQuantizeDequantization>& layerDequantizations,
|
|
||||||
const std::shared_ptr<Node> layer,
|
|
||||||
NodeVector& convertNodes,
|
|
||||||
NodeVector& subtractNodes,
|
|
||||||
NodeVector& multiplyNodes) const;
|
|
||||||
|
|
||||||
std::shared_ptr<Node> concatenateDeqNodes(NodeVector& nodes) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t getMinQuantizationLevels(
|
size_t getMinQuantizationLevels(
|
||||||
const DataPrecision& dataPrecision,
|
const DataPrecision& dataPrecision,
|
||||||
|
@ -27,9 +27,12 @@ public:
|
|||||||
bool isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept override;
|
bool isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Go through the parent elements of the layer and fill dequantization collection
|
|
||||||
// with Dq operations that should be inserted before the layer.
|
|
||||||
void fillDequantization(
|
void fillDequantization(
|
||||||
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
|
std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
||||||
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) const;
|
||||||
|
|
||||||
|
void fillQuantization(
|
||||||
const std::shared_ptr<ngraph::Node> layer,
|
const std::shared_ptr<ngraph::Node> layer,
|
||||||
const std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
const std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantization) const;
|
std::vector<FakeQuantizeDequantization>& dequantization) const;
|
||||||
@ -43,6 +46,8 @@ private:
|
|||||||
const FakeQuantizeDequantization& dequantization,
|
const FakeQuantizeDequantization& dequantization,
|
||||||
const size_t sourceOutputIdx);
|
const size_t sourceOutputIdx);
|
||||||
|
|
||||||
|
static FakeQuantizeDequantization broadcastDequantiationConstant(const FakeQuantizeDequantization& deq);
|
||||||
|
|
||||||
bool isMultiChannel(const std::vector<std::shared_ptr<ngraph::opset1::Concat>>& concatLayers) const noexcept;
|
bool isMultiChannel(const std::vector<std::shared_ptr<ngraph::opset1::Concat>>& concatLayers) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,12 +50,6 @@ public:
|
|||||||
template <typename OperationType>
|
template <typename OperationType>
|
||||||
static std::shared_ptr<Node> setOutDataPrecision(std::shared_ptr<OperationType> operation, const element::Type& precision);
|
static std::shared_ptr<Node> setOutDataPrecision(std::shared_ptr<OperationType> operation, const element::Type& precision);
|
||||||
|
|
||||||
// applies constant folding of operation to constant and returns the specified output
|
|
||||||
static std::shared_ptr<opset1::Constant> foldDequantizationConstant(
|
|
||||||
const std::shared_ptr<opset1::Constant>& foldingConstant,
|
|
||||||
const std::shared_ptr<Node>& operation,
|
|
||||||
const size_t outIdx = 0);
|
|
||||||
|
|
||||||
static size_t getOutputChannelsCount(std::shared_ptr<const Node> layer, bool isOnWeights = false);
|
static size_t getOutputChannelsCount(std::shared_ptr<const Node> layer, bool isOnWeights = false);
|
||||||
|
|
||||||
static std::vector<std::shared_ptr<Node>> getParentsRecursivelyExceptTypes(
|
static std::vector<std::shared_ptr<Node>> getParentsRecursivelyExceptTypes(
|
||||||
|
@ -24,6 +24,15 @@ public:
|
|||||||
TransformationContext& context,
|
TransformationContext& context,
|
||||||
std::vector<std::shared_ptr<ngraph::Node>> lastNodes,
|
std::vector<std::shared_ptr<ngraph::Node>> lastNodes,
|
||||||
std::shared_ptr<ngraph::Node> originalNode) const;
|
std::shared_ptr<ngraph::Node> originalNode) const;
|
||||||
|
protected:
|
||||||
|
ngraph::Shape getConstSplitShape(
|
||||||
|
const std::vector<size_t>& constSplitLengths,
|
||||||
|
const ngraph::Shape& constShape, const size_t axis,
|
||||||
|
const size_t idx) const;
|
||||||
|
virtual std::vector<size_t> getConstSplitLengths(
|
||||||
|
const OutputVector& inputs,
|
||||||
|
const ngraph::Shape& constShape,
|
||||||
|
const size_t outputSize) const;
|
||||||
};
|
};
|
||||||
} // namespace low_precision
|
} // namespace low_precision
|
||||||
} // namespace pass
|
} // namespace pass
|
||||||
|
@ -17,6 +17,11 @@ class TRANSFORMATIONS_API VariadicSplitTransformation : public SplitTransformati
|
|||||||
public:
|
public:
|
||||||
VariadicSplitTransformation(const Params& params);
|
VariadicSplitTransformation(const Params& params);
|
||||||
void registerMatcherIn(GraphRewrite& pass, TransformationContext& context) const override;
|
void registerMatcherIn(GraphRewrite& pass, TransformationContext& context) const override;
|
||||||
|
protected:
|
||||||
|
std::vector<size_t> getConstSplitLengths(
|
||||||
|
const OutputVector& inputs,
|
||||||
|
const ngraph::Shape& constShape,
|
||||||
|
const size_t outputSize) const override;
|
||||||
};
|
};
|
||||||
} // namespace low_precision
|
} // namespace low_precision
|
||||||
} // namespace pass
|
} // namespace pass
|
||||||
|
@ -201,7 +201,6 @@ bool ConcatTransformation::transform(TransformationContext& context, ngraph::pat
|
|||||||
|
|
||||||
auto dequantizationValuesCallback = [&](
|
auto dequantizationValuesCallback = [&](
|
||||||
std::shared_ptr<ngraph::Node> layer,
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
std::shared_ptr<ngraph::Node> child,
|
|
||||||
const std::string originalLayerName,
|
const std::string originalLayerName,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) {
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) {
|
||||||
dequantizationsToConcatenate.push_back(dequantization);
|
dequantizationsToConcatenate.push_back(dequantization);
|
||||||
@ -235,97 +234,15 @@ bool ConcatTransformation::isPrecisionPreserved(std::shared_ptr<Node>) const noe
|
|||||||
|
|
||||||
bool ConcatTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
|
bool ConcatTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
|
||||||
std::shared_ptr<opset1::Concat> concat = as_type_ptr<opset1::Concat>(layer);
|
std::shared_ptr<opset1::Concat> concat = as_type_ptr<opset1::Concat>(layer);
|
||||||
if (concat == nullptr) {
|
return concat && concat->get_axis() == 1ul;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto axis = concat->get_axis();
|
|
||||||
const size_t normalizedAxis = ngraph::normalize_axis(concat->get_friendly_name(), axis, concat->get_output_partial_shape(0).rank());
|
|
||||||
return normalizedAxis == 1ul;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcatTransformation::fillDequantizationNodes(
|
|
||||||
const std::vector<FakeQuantizeDequantization>& layerDequantizations,
|
|
||||||
const std::shared_ptr<Node> layer,
|
|
||||||
NodeVector& convertNodes,
|
|
||||||
NodeVector& subtractNodes,
|
|
||||||
NodeVector& multiplyNodes) const {
|
|
||||||
if (layerDequantizations.size() > 1ul) {
|
|
||||||
auto broadcastElementWiseConst = [](
|
|
||||||
// FakeQuantize constant shape must be broadcastable to the shape on data.
|
|
||||||
std::shared_ptr<ngraph::opset1::Constant> operation,
|
|
||||||
const ngraph::Shape targetShape) -> std::shared_ptr<Node> {
|
|
||||||
auto targetShapeConst = std::make_shared<ngraph::opset1::Constant>(
|
|
||||||
element::i64, ngraph::Shape{ targetShape.size() },
|
|
||||||
targetShape);
|
|
||||||
|
|
||||||
auto broadcast = ngraph::pass::low_precision::fold<ngraph::opset1::Broadcast>(
|
|
||||||
operation,
|
|
||||||
targetShapeConst,
|
|
||||||
ngraph::op::AutoBroadcastType::NUMPY);
|
|
||||||
|
|
||||||
return broadcast;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool allDequantizationShiftAreZero = true;
|
|
||||||
bool allDequantizationMultiplyAreZero = true;
|
|
||||||
for (const auto& dequantization : layerDequantizations) {
|
|
||||||
if (dequantization.subtract != nullptr) {
|
|
||||||
allDequantizationShiftAreZero = false;
|
|
||||||
}
|
|
||||||
if (dequantization.multiply != nullptr) {
|
|
||||||
allDequantizationMultiplyAreZero = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < layerDequantizations.size(); ++i) {
|
|
||||||
const auto& dequantization = layerDequantizations[i];
|
|
||||||
const ngraph::element::Type precision = deqPrecision;
|
|
||||||
ngraph::Shape targetShape(layer->get_input_shape(i).size(), 1ul);
|
|
||||||
targetShape[1] = layer->get_input_shape(i)[1];
|
|
||||||
|
|
||||||
if (dequantization.convert != nullptr) {
|
|
||||||
convertNodes.push_back(dequantization.convert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allDequantizationShiftAreZero) {
|
|
||||||
subtractNodes.push_back(dequantization.subtract == nullptr ?
|
|
||||||
std::make_shared<ngraph::opset1::Constant>(precision, targetShape, std::vector<float>({ 0.f })) :
|
|
||||||
broadcastElementWiseConst(dequantization.subtractConstant, targetShape));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allDequantizationMultiplyAreZero) {
|
|
||||||
multiplyNodes.push_back(dequantization.multiply == nullptr ?
|
|
||||||
std::make_shared<ngraph::opset1::Constant>(precision, targetShape, std::vector<float>({ 1.0f })) :
|
|
||||||
broadcastElementWiseConst(dequantization.multiplyConstant, targetShape));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: check constant shapes here - has to be scalar
|
|
||||||
if (layerDequantizations[0].convert != nullptr) {
|
|
||||||
convertNodes.push_back(layerDequantizations[0].convert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layerDequantizations[0].subtract != nullptr) {
|
|
||||||
subtractNodes.push_back(layerDequantizations[0].subtract->input_value(1).get_node_shared_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layerDequantizations[0].multiply != nullptr) {
|
|
||||||
multiplyNodes.push_back(layerDequantizations[0].multiply->input_value(1).get_node_shared_ptr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Node> ConcatTransformation::concatenateDeqNodes(NodeVector& nodes) const {
|
|
||||||
return nodes.size() == 1ul ? nodes[0] : fold<ngraph::opset1::Concat>(nodes, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcatTransformation::addDequantizationLayers(
|
void ConcatTransformation::addDequantizationLayers(
|
||||||
TransformationContext& context,
|
TransformationContext& context,
|
||||||
ngraph::pass::low_precision::Subgraph& subgraph,
|
ngraph::pass::low_precision::Subgraph& subgraph,
|
||||||
std::function<void(
|
std::function<void(
|
||||||
std::shared_ptr<ngraph::Node> layer,
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
std::shared_ptr<ngraph::Node> child,
|
|
||||||
const std::string originalLayerName,
|
const std::string originalLayerName,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate)> getLayerDequantizationCallback) const {
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate)> getLayerDequantizationCallback) const {
|
||||||
std::unordered_map<std::string, ngraph::Node*> outputs;
|
std::unordered_map<std::string, ngraph::Node*> outputs;
|
||||||
@ -352,28 +269,95 @@ void ConcatTransformation::addDequantizationLayers(
|
|||||||
ngraph::Node& child = *childInput.get_node();
|
ngraph::Node& child = *childInput.get_node();
|
||||||
|
|
||||||
if (subgraph.layers.find(child.get_friendly_name()) == subgraph.layers.end()) {
|
if (subgraph.layers.find(child.get_friendly_name()) == subgraph.layers.end()) {
|
||||||
std::shared_ptr<ngraph::Node> source = layer;
|
|
||||||
const std::shared_ptr<ngraph::Node> destination = child.shared_from_this();
|
|
||||||
|
|
||||||
if (layerDequantizations.size() == 0ul) {
|
if (layerDequantizations.size() == 0ul) {
|
||||||
// fill layerDequantizations collection
|
// fill layerDequantizations collection
|
||||||
getLayerDequantizationCallback(source, destination, source->get_friendly_name(), layerDequantizations);
|
getLayerDequantizationCallback(layer, layer->get_friendly_name(), layerDequantizations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Node> source = layer->shared_from_this();
|
||||||
{
|
{
|
||||||
NodeVector convertNodes;
|
std::vector<std::shared_ptr<ngraph::Node>> convertNodes;
|
||||||
NodeVector subtractNodes;
|
std::vector<std::shared_ptr<ngraph::Node>> subtractNodes;
|
||||||
NodeVector multiplyNodes;
|
std::vector<std::shared_ptr<ngraph::Node>> multiplyNodes;
|
||||||
|
|
||||||
// forming nodes for concatenation
|
// forming nodes for concatenation
|
||||||
fillDequantizationNodes(layerDequantizations, layer, convertNodes, subtractNodes, multiplyNodes);
|
if (layerDequantizations.size() > 1ul) {
|
||||||
|
auto broadcastElementWiseConst = [](
|
||||||
|
// FakeQuantize constant shape must be broadcastable to the shape on data.
|
||||||
|
std::shared_ptr<ngraph::opset1::Constant> operation,
|
||||||
|
const ngraph::Shape targetShape) -> std::shared_ptr<Node> {
|
||||||
|
auto targetShapeConst = std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
element::i64, ngraph::Shape{ targetShape.size() },
|
||||||
|
targetShape);
|
||||||
|
|
||||||
|
auto broadcast = ngraph::pass::low_precision::fold<ngraph::opset1::Broadcast>(
|
||||||
|
operation,
|
||||||
|
targetShapeConst,
|
||||||
|
ngraph::op::AutoBroadcastType::NUMPY);
|
||||||
|
|
||||||
|
return broadcast;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool allDequantizationShiftAreZero = true;
|
||||||
|
bool allDequantizationMultiplyAreZero = true;
|
||||||
|
for (FakeQuantizeDequantization dequantization : layerDequantizations) {
|
||||||
|
if (dequantization.subtract != nullptr) {
|
||||||
|
allDequantizationShiftAreZero = false;
|
||||||
|
}
|
||||||
|
if (dequantization.multiply != nullptr) {
|
||||||
|
allDequantizationMultiplyAreZero = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < layerDequantizations.size(); ++i) {
|
||||||
|
const auto& dequantization = layerDequantizations[i];
|
||||||
|
|
||||||
|
if (dequantization.convert != nullptr) {
|
||||||
|
convertNodes.push_back(dequantization.convert);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ngraph::element::Type precision = deqPrecision;
|
||||||
|
ngraph::Shape targetShape(layer->get_input_shape(i).size(), 1ul);
|
||||||
|
targetShape[1] = layer->get_input_shape(i)[1];
|
||||||
|
|
||||||
|
if (!allDequantizationShiftAreZero) {
|
||||||
|
subtractNodes.push_back(dequantization.subtract == nullptr ?
|
||||||
|
std::make_shared<ngraph::opset1::Constant>(precision, targetShape, std::vector<float>({ 0.f })) :
|
||||||
|
broadcastElementWiseConst(
|
||||||
|
as_type_ptr<ngraph::opset1::Constant>(dequantization.subtract->input_value(1).get_node_shared_ptr()),
|
||||||
|
targetShape));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allDequantizationMultiplyAreZero) {
|
||||||
|
multiplyNodes.push_back(dequantization.multiply == nullptr ?
|
||||||
|
std::make_shared<ngraph::opset1::Constant>(precision, targetShape, std::vector<float>({ 1.0f })) :
|
||||||
|
broadcastElementWiseConst(
|
||||||
|
as_type_ptr<ngraph::opset1::Constant>(dequantization.multiply->input_value(1).get_node_shared_ptr()),
|
||||||
|
targetShape));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: check constant shapes here - has to be scalar
|
||||||
|
if (layerDequantizations[0].convert != nullptr) {
|
||||||
|
convertNodes.push_back(layerDequantizations[0].convert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layerDequantizations[0].subtract != nullptr) {
|
||||||
|
subtractNodes.push_back(layerDequantizations[0].subtract->input_value(1).get_node_shared_ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layerDequantizations[0].multiply != nullptr) {
|
||||||
|
multiplyNodes.push_back(layerDequantizations[0].multiply->input_value(1).get_node_shared_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: the second place (first is FQ decomposition) where dequantization operations are inserted
|
// TODO: the second place (first is FQ decomposition) where dequantization operations are inserted
|
||||||
|
const std::shared_ptr<ngraph::Node> destination = child.shared_from_this();
|
||||||
|
|
||||||
if (!convertNodes.empty()) {
|
if (!convertNodes.empty()) {
|
||||||
const size_t sourceOutputIdx = NetworkHelper::getChildInputIndex(source, destination);
|
const size_t sourceOutputIdx = NetworkHelper::getChildInputIndex(source, destination);
|
||||||
std::shared_ptr<ngraph::Node> convert =
|
std::shared_ptr<ngraph::Node> convert =
|
||||||
convertNodes[0]->clone_with_new_inputs({ destination->get_input_source_output(sourceOutputIdx) });
|
convertNodes[0]->clone_with_new_inputs({ destination->get_input_source_output(sourceOutputIdx) });
|
||||||
|
|
||||||
insert_new_node_between(source, destination, convert);
|
insert_new_node_between(source, destination, convert);
|
||||||
ngraph::copy_runtime_info({ layer, convert }, convert);
|
ngraph::copy_runtime_info({ layer, convert }, convert);
|
||||||
source = convert;
|
source = convert;
|
||||||
@ -384,8 +368,9 @@ void ConcatTransformation::addDequantizationLayers(
|
|||||||
const size_t sourceOutputIdx = NetworkHelper::getChildInputIndex(source, destination);
|
const size_t sourceOutputIdx = NetworkHelper::getChildInputIndex(source, destination);
|
||||||
std::shared_ptr<ngraph::opset1::Subtract> subtract = std::make_shared<DequantizationSubtract>(
|
std::shared_ptr<ngraph::opset1::Subtract> subtract = std::make_shared<DequantizationSubtract>(
|
||||||
destination->get_input_source_output(sourceOutputIdx),
|
destination->get_input_source_output(sourceOutputIdx),
|
||||||
NetworkHelper::toScalarIfPossible(concatenateDeqNodes(subtractNodes)));
|
NetworkHelper::toScalarIfPossible(subtractNodes.size() == 1ul ?
|
||||||
|
subtractNodes[0] :
|
||||||
|
ngraph::pass::low_precision::fold<ngraph::opset1::Concat>(subtractNodes, 1)));
|
||||||
insert_new_node_between(source, destination, subtract);
|
insert_new_node_between(source, destination, subtract);
|
||||||
ngraph::copy_runtime_info({ layer, subtract }, subtract);
|
ngraph::copy_runtime_info({ layer, subtract }, subtract);
|
||||||
source = subtract;
|
source = subtract;
|
||||||
@ -396,9 +381,10 @@ void ConcatTransformation::addDequantizationLayers(
|
|||||||
std::shared_ptr<ngraph::opset1::Multiply> multiply = std::make_shared<op::TypeRelaxed<DequantizationMultiply>>(
|
std::shared_ptr<ngraph::opset1::Multiply> multiply = std::make_shared<op::TypeRelaxed<DequantizationMultiply>>(
|
||||||
DequantizationMultiply(
|
DequantizationMultiply(
|
||||||
destination->get_input_source_output(sourceOutputIdx),
|
destination->get_input_source_output(sourceOutputIdx),
|
||||||
NetworkHelper::toScalarIfPossible(concatenateDeqNodes(multiplyNodes))),
|
NetworkHelper::toScalarIfPossible(multiplyNodes.size() == 1ul ?
|
||||||
|
multiplyNodes[0] :
|
||||||
|
ngraph::pass::low_precision::fold<ngraph::opset1::Concat>(multiplyNodes, 1))),
|
||||||
layerDequantizations[0].multiply->get_output_element_type(0));
|
layerDequantizations[0].multiply->get_output_element_type(0));
|
||||||
|
|
||||||
insert_new_node_between(source, destination, multiply);
|
insert_new_node_between(source, destination, multiply);
|
||||||
ngraph::copy_runtime_info({ layer, multiply }, multiply);
|
ngraph::copy_runtime_info({ layer, multiply }, multiply);
|
||||||
source = multiply;
|
source = multiply;
|
||||||
|
@ -137,7 +137,6 @@ bool ConcatMultiChannelsTransformation::transform(TransformationContext& context
|
|||||||
|
|
||||||
auto dequantizationValuesCallback = [&](
|
auto dequantizationValuesCallback = [&](
|
||||||
std::shared_ptr<ngraph::Node> layer,
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
std::shared_ptr<ngraph::Node> child,
|
|
||||||
const std::string originalLayerName,
|
const std::string originalLayerName,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) {
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) {
|
||||||
if (layer->get_friendly_name() != originalLayerName) {
|
if (layer->get_friendly_name() != originalLayerName) {
|
||||||
@ -158,15 +157,6 @@ bool ConcatMultiChannelsTransformation::transform(TransformationContext& context
|
|||||||
layer,
|
layer,
|
||||||
dequantizations,
|
dequantizations,
|
||||||
dequantizationsToConcatenate);
|
dequantizationsToConcatenate);
|
||||||
|
|
||||||
if (!is_type<ngraph::opset1::Concat>(layer)) {
|
|
||||||
// for intermediate layers we should get Dq operations to be inserted between layer and child
|
|
||||||
assert(dequantizationsToConcatenate.size() == 1ul);
|
|
||||||
const size_t sourceOutputIdx = NetworkHelper::getParentOutputIndex(layer, child);
|
|
||||||
if (layer->get_input_shape(0)[1] != layer->get_output_shape(sourceOutputIdx)[1]) {
|
|
||||||
dequantizationsToConcatenate[0] = getFoldedDequantization(layer, dequantizationsToConcatenate[0], sourceOutputIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
addDequantizationLayers(context, subgraph, dequantizationValuesCallback);
|
addDequantizationLayers(context, subgraph, dequantizationValuesCallback);
|
||||||
@ -195,66 +185,137 @@ bool ConcatMultiChannelsTransformation::isPrecisionPreserved(std::shared_ptr<Nod
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fill dequantizationsToMerge collection for layer with using dequantizationByFakeQuantize
|
||||||
void ConcatMultiChannelsTransformation::fillDequantization(
|
void ConcatMultiChannelsTransformation::fillDequantization(
|
||||||
|
std::shared_ptr<ngraph::Node> layer,
|
||||||
|
std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
||||||
|
std::vector<FakeQuantizeDequantization>& dequantizationsToConcatenate) const {
|
||||||
|
std::shared_ptr<ngraph::opset1::FakeQuantize> currentFakeQuantize = ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(layer);
|
||||||
|
if (currentFakeQuantize) {
|
||||||
|
const auto it = dequantizationByFakeQuantize.find(currentFakeQuantize->get_friendly_name());
|
||||||
|
if (it == dequantizationByFakeQuantize.end()) {
|
||||||
|
THROW_IE_LPT_EXCEPTION(*currentFakeQuantize) << "dequantization scale values are not found";
|
||||||
|
}
|
||||||
|
const FakeQuantizeDequantization& fakeQuantizeDequantization = it->second;
|
||||||
|
dequantizationsToConcatenate.push_back(broadcastDequantiationConstant(fakeQuantizeDequantization));
|
||||||
|
} else {
|
||||||
|
fillQuantization(layer, dequantizationByFakeQuantize, dequantizationsToConcatenate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConcatMultiChannelsTransformation::fillQuantization(
|
||||||
const std::shared_ptr<ngraph::Node> layer,
|
const std::shared_ptr<ngraph::Node> layer,
|
||||||
const std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
const std::unordered_map<std::string, FakeQuantizeDequantization>& dequantizationByFakeQuantize,
|
||||||
std::vector<FakeQuantizeDequantization>& dequantization) const {
|
std::vector<FakeQuantizeDequantization>& dequantization) const {
|
||||||
const auto fillDqByFakeQuantize = [&](const std::shared_ptr<ngraph::Node>& fq) {
|
for (size_t i = 0; i < layer->get_input_size(); ++i) {
|
||||||
const auto it = dequantizationByFakeQuantize.find(fq->get_friendly_name());
|
std::shared_ptr<ngraph::Node> parent = layer->get_input_node_shared_ptr(i);
|
||||||
if (it == dequantizationByFakeQuantize.end()) {
|
|
||||||
THROW_IE_LPT_EXCEPTION(*fq) << "dequantization scale values are not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
const FakeQuantizeDequantization& fakeQuantizeDequantization = it->second;
|
std::shared_ptr<ngraph::opset1::FakeQuantize> fakeQuantize = ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(parent);
|
||||||
dequantization.push_back(fakeQuantizeDequantization);
|
if (fakeQuantize) {
|
||||||
};
|
const auto it = dequantizationByFakeQuantize.find(fakeQuantize->get_friendly_name());
|
||||||
|
if (it == dequantizationByFakeQuantize.end()) {
|
||||||
if (is_type<ngraph::opset1::FakeQuantize>(layer)) {
|
THROW_IE_LPT_EXCEPTION(*fakeQuantize) << "dequantization scale values are not found";
|
||||||
fillDqByFakeQuantize(layer);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < layer->get_input_size(); ++i) {
|
|
||||||
std::shared_ptr<ngraph::Node> parent = layer->get_input_node_shared_ptr(i);
|
|
||||||
if (as_type_ptr<ngraph::opset1::Constant>(parent)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto fakeQuantize = ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(parent);
|
const FakeQuantizeDequantization& fakeQuantizeDequantization = it->second;
|
||||||
if (fakeQuantize) {
|
dequantization.push_back(broadcastDequantiationConstant(fakeQuantizeDequantization));
|
||||||
fillDqByFakeQuantize(fakeQuantize);
|
} else {
|
||||||
|
std::shared_ptr<ngraph::opset1::Concat> concat = ngraph::as_type_ptr<ngraph::opset1::Concat>(parent);
|
||||||
|
if (concat) {
|
||||||
|
std::vector<FakeQuantizeDequantization> dequantizationToConcatenate;
|
||||||
|
fillQuantization(concat, dequantizationByFakeQuantize, dequantizationToConcatenate);
|
||||||
|
|
||||||
|
// add concatenated dequantization operations to dequantization collection
|
||||||
|
dequantization.push_back(getConcatenatedDequantization(concat, dequantizationToConcatenate));
|
||||||
} else {
|
} else {
|
||||||
const auto concat = ngraph::as_type_ptr<ngraph::opset1::Concat>(parent);
|
std::shared_ptr<ngraph::opset1::StridedSlice> stridedSlice = ngraph::as_type_ptr<ngraph::opset1::StridedSlice>(parent);
|
||||||
if (concat) {
|
if (stridedSlice) {
|
||||||
std::vector<FakeQuantizeDequantization> dequantizationToConcatenate;
|
std::vector<FakeQuantizeDequantization> dequantizationToPropagate;
|
||||||
fillDequantization(concat, dequantizationByFakeQuantize, dequantizationToConcatenate);
|
fillQuantization(stridedSlice, dequantizationByFakeQuantize, dequantizationToPropagate);
|
||||||
|
|
||||||
// add concatenated dequantization operations to dequantization collection
|
|
||||||
dequantization.push_back(getConcatenatedDequantization(concat, dequantizationToConcatenate));
|
|
||||||
} else {
|
|
||||||
const size_t sourceOutputIdx = NetworkHelper::getParentOutputIndex(parent, layer);
|
const size_t sourceOutputIdx = NetworkHelper::getParentOutputIndex(parent, layer);
|
||||||
if (parent->get_input_shape(0)[1] != parent->get_output_shape(sourceOutputIdx)[1]) {
|
// add folded dequantization operations to dequantization colection
|
||||||
std::vector<FakeQuantizeDequantization> dequantizationToPropagate;
|
dequantization.push_back(getFoldedDequantization(stridedSlice, dequantizationToPropagate[0], sourceOutputIdx));
|
||||||
fillDequantization(parent, dequantizationByFakeQuantize, dequantizationToPropagate);
|
} else {
|
||||||
|
fillQuantization(parent, dequantizationByFakeQuantize, dequantization);
|
||||||
// add folded dequantization operations to dequantization colection
|
|
||||||
dequantization.push_back(getFoldedDequantization(parent, dequantizationToPropagate[0], sourceOutputIdx));
|
|
||||||
} else {
|
|
||||||
fillDequantization(parent, dequantizationByFakeQuantize, dequantization);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// broadcast of dequantization constants by channels
|
||||||
|
FakeQuantizeDequantization ConcatMultiChannelsTransformation::broadcastDequantiationConstant(const FakeQuantizeDequantization& deq) {
|
||||||
|
ngraph::Shape targetShape(deq.data.get_shape().size(), 1ul);
|
||||||
|
targetShape[1] = deq.data.get_shape()[1];
|
||||||
|
|
||||||
|
FakeQuantizeDequantization result;
|
||||||
|
result.data = deq.data;
|
||||||
|
result.convert = deq.convert;
|
||||||
|
|
||||||
|
const auto targetShapeConst = std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
element::i64, ngraph::Shape{ targetShape.size() },
|
||||||
|
targetShape);
|
||||||
|
|
||||||
|
if (deq.subtract) {
|
||||||
|
auto broadcast = ngraph::pass::low_precision::fold<ngraph::opset1::Broadcast>(
|
||||||
|
deq.subtractConstant,
|
||||||
|
targetShapeConst,
|
||||||
|
ngraph::op::AutoBroadcastType::NUMPY);
|
||||||
|
|
||||||
|
result.subtract = deq.subtract;
|
||||||
|
result.subtractConstant = as_type_ptr<ngraph::opset1::Constant>(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deq.multiply) {
|
||||||
|
auto broadcast = ngraph::pass::low_precision::fold<ngraph::opset1::Broadcast>(
|
||||||
|
deq.multiplyConstant,
|
||||||
|
targetShapeConst,
|
||||||
|
ngraph::op::AutoBroadcastType::NUMPY);
|
||||||
|
|
||||||
|
result.multiply = deq.multiply;
|
||||||
|
result.multiplyConstant = as_type_ptr<ngraph::opset1::Constant>(broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
FakeQuantizeDequantization ConcatMultiChannelsTransformation::getConcatenatedDequantization(
|
FakeQuantizeDequantization ConcatMultiChannelsTransformation::getConcatenatedDequantization(
|
||||||
const std::shared_ptr<ngraph::opset1::Concat> concat,
|
const std::shared_ptr<ngraph::opset1::Concat> concat,
|
||||||
const std::vector<FakeQuantizeDequantization>& dequantization) const {
|
const std::vector<FakeQuantizeDequantization>& dequantization) const {
|
||||||
NodeVector convertNodes;
|
bool allDequantizationShiftAreZero = true;
|
||||||
NodeVector subtractNodes;
|
bool allDequantizationMultiplyAreZero = true;
|
||||||
NodeVector multiplyNodes;
|
for (const auto& deq : dequantization) {
|
||||||
|
if (deq.subtract != nullptr) {
|
||||||
|
allDequantizationShiftAreZero = false;
|
||||||
|
}
|
||||||
|
if (deq.multiply != nullptr) {
|
||||||
|
allDequantizationMultiplyAreZero = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// forming nodes for concatenation
|
NodeVector convertNodes;
|
||||||
fillDequantizationNodes(dequantization, concat, convertNodes, subtractNodes, multiplyNodes);
|
NodeVector subNodes;
|
||||||
|
NodeVector mulNodes;
|
||||||
|
//preparing to concatenate dequantization nodes
|
||||||
|
for (const auto& deq : dequantization) {
|
||||||
|
ngraph::Shape targetShape(deq.data.get_shape().size(), 1ul);
|
||||||
|
targetShape[1] = deq.data.get_shape()[1];
|
||||||
|
|
||||||
|
if (deq.convert != nullptr) {
|
||||||
|
convertNodes.push_back(deq.convert);
|
||||||
|
}
|
||||||
|
if (!allDequantizationShiftAreZero) {
|
||||||
|
subNodes.push_back(deq.subtract == nullptr ?
|
||||||
|
std::make_shared<ngraph::opset1::Constant>(deqPrecision, targetShape, std::vector<float>({ 0.f })) :
|
||||||
|
deq.subtractConstant);
|
||||||
|
}
|
||||||
|
if (!allDequantizationMultiplyAreZero) {
|
||||||
|
mulNodes.push_back(deq.multiply == nullptr ?
|
||||||
|
std::make_shared<ngraph::opset1::Constant>(deqPrecision, targetShape, std::vector<float>({ 1.0f })) :
|
||||||
|
deq.multiplyConstant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<Node> parent = concat;
|
std::shared_ptr<Node> parent = concat;
|
||||||
std::shared_ptr<DequantizationConvert> convert;
|
std::shared_ptr<DequantizationConvert> convert;
|
||||||
@ -265,16 +326,20 @@ FakeQuantizeDequantization ConcatMultiChannelsTransformation::getConcatenatedDeq
|
|||||||
|
|
||||||
std::shared_ptr<DequantizationSubtract> subtract;
|
std::shared_ptr<DequantizationSubtract> subtract;
|
||||||
std::shared_ptr<ngraph::opset1::Constant> subConst;
|
std::shared_ptr<ngraph::opset1::Constant> subConst;
|
||||||
if (!subtractNodes.empty()) {
|
if (!subNodes.empty()) {
|
||||||
subConst = as_type_ptr<ngraph::opset1::Constant>(concatenateDeqNodes(subtractNodes));
|
subConst = as_type_ptr<ngraph::opset1::Constant>(
|
||||||
|
subNodes.size() == 1ul ? subNodes[0] : fold<ngraph::opset1::Concat>(subNodes, 1ul));
|
||||||
|
|
||||||
subtract = std::make_shared<DequantizationSubtract>(parent, subConst);
|
subtract = std::make_shared<DequantizationSubtract>(parent, subConst);
|
||||||
parent = subtract;
|
parent = subtract;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DequantizationMultiply> multiply;
|
std::shared_ptr<DequantizationMultiply> multiply;
|
||||||
std::shared_ptr<ngraph::opset1::Constant> mulConst;
|
std::shared_ptr<ngraph::opset1::Constant> mulConst;
|
||||||
if (!multiplyNodes.empty()) {
|
if (!mulNodes.empty()) {
|
||||||
mulConst = as_type_ptr<ngraph::opset1::Constant>(concatenateDeqNodes(multiplyNodes));
|
mulConst = as_type_ptr<ngraph::opset1::Constant>(
|
||||||
|
mulNodes.size() == 1ul ? mulNodes[0] : fold<ngraph::opset1::Concat>(mulNodes, 1ul));
|
||||||
|
|
||||||
multiply = std::make_shared<DequantizationMultiply>(parent, mulConst);
|
multiply = std::make_shared<DequantizationMultiply>(parent, mulConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,19 +352,24 @@ FakeQuantizeDequantization ConcatMultiChannelsTransformation::getFoldedDequantiz
|
|||||||
const size_t sourceOutputIdx) {
|
const size_t sourceOutputIdx) {
|
||||||
OutputVector inputs = operation->input_values();
|
OutputVector inputs = operation->input_values();
|
||||||
OutputVector outputs(operation->get_output_size());
|
OutputVector outputs(operation->get_output_size());
|
||||||
Output<Node> data = operation->output(sourceOutputIdx);
|
|
||||||
|
|
||||||
std::shared_ptr<Node> parent = operation;
|
std::shared_ptr<Node> parent = operation;
|
||||||
std::shared_ptr<DequantizationConvert> convert;
|
std::shared_ptr<DequantizationConvert> convert;
|
||||||
if (dequantization.convert) {
|
if (dequantization.convert) {
|
||||||
convert = as_type_ptr<DequantizationConvert>(dequantization.convert->clone_with_new_inputs({ data }));
|
convert = as_type_ptr<DequantizationConvert>(dequantization.convert->clone_with_new_inputs({ parent }));
|
||||||
parent = convert;
|
parent = convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DequantizationSubtract> subtract;
|
std::shared_ptr<DequantizationSubtract> subtract;
|
||||||
std::shared_ptr<ngraph::opset1::Constant> subConst;
|
std::shared_ptr<ngraph::opset1::Constant> subConst;
|
||||||
if (dequantization.subtract) {
|
if (dequantization.subtract) {
|
||||||
subConst = NetworkHelper::foldDequantizationConstant(dequantization.subtractConstant, operation, sourceOutputIdx);
|
inputs[0] = dequantization.subtractConstant;
|
||||||
|
const auto op = operation->clone_with_new_inputs(inputs);
|
||||||
|
|
||||||
|
// constant folding of subtract constant
|
||||||
|
op->constant_fold(outputs, inputs);
|
||||||
|
|
||||||
|
subConst = as_type_ptr<ngraph::opset1::Constant>(outputs[sourceOutputIdx].get_node_shared_ptr());
|
||||||
subtract = std::make_shared<DequantizationSubtract>(parent, subConst);
|
subtract = std::make_shared<DequantizationSubtract>(parent, subConst);
|
||||||
parent = subtract;
|
parent = subtract;
|
||||||
}
|
}
|
||||||
@ -307,11 +377,17 @@ FakeQuantizeDequantization ConcatMultiChannelsTransformation::getFoldedDequantiz
|
|||||||
std::shared_ptr<DequantizationMultiply> multiply;
|
std::shared_ptr<DequantizationMultiply> multiply;
|
||||||
std::shared_ptr<ngraph::opset1::Constant> mulConst;
|
std::shared_ptr<ngraph::opset1::Constant> mulConst;
|
||||||
if (dequantization.multiply) {
|
if (dequantization.multiply) {
|
||||||
mulConst = NetworkHelper::foldDequantizationConstant(dequantization.multiplyConstant, operation, sourceOutputIdx);
|
inputs[0] = dequantization.multiplyConstant;
|
||||||
|
const auto op = operation->clone_with_new_inputs(inputs);
|
||||||
|
|
||||||
|
// constant folding of multiply constant
|
||||||
|
op->constant_fold(outputs, inputs);
|
||||||
|
|
||||||
|
mulConst = as_type_ptr<ngraph::opset1::Constant>(outputs[sourceOutputIdx].get_node_shared_ptr());
|
||||||
multiply = std::make_shared<DequantizationMultiply>(parent, mulConst);
|
multiply = std::make_shared<DequantizationMultiply>(parent, mulConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FakeQuantizeDequantization(data, convert, subtract, nullptr, subConst, multiply, mulConst);
|
return FakeQuantizeDequantization(operation->output(sourceOutputIdx), convert, subtract, nullptr, subConst, multiply, mulConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace low_precision
|
} // namespace low_precision
|
||||||
|
@ -87,31 +87,6 @@ bool NetworkHelper::isConstantPath(const std::shared_ptr<Node>& op) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<opset1::Constant> NetworkHelper::foldDequantizationConstant(
|
|
||||||
const std::shared_ptr<opset1::Constant>& foldingConstant,
|
|
||||||
const std::shared_ptr<Node>& operation,
|
|
||||||
const size_t outIdx) {
|
|
||||||
OutputVector inputs = operation->input_values();
|
|
||||||
OutputVector outputs(operation->get_output_size());
|
|
||||||
|
|
||||||
if (shape_size(foldingConstant->get_shape()) == 1ul) {
|
|
||||||
return toScalar(foldingConstant);
|
|
||||||
} else {
|
|
||||||
inputs[0] = foldingConstant;
|
|
||||||
const auto op = operation->clone_with_new_inputs(inputs);
|
|
||||||
|
|
||||||
// constant folding of constant
|
|
||||||
op->constant_fold(outputs, inputs);
|
|
||||||
|
|
||||||
const auto result = as_type_ptr<opset1::Constant>(outputs[outIdx].get_node_shared_ptr());
|
|
||||||
if (result == nullptr) {
|
|
||||||
THROW_IE_LPT_EXCEPTION(*result) << "result of constant folding is not constant";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t NetworkHelper::getOutputChannelsCount(std::shared_ptr<const Node> layer, bool isOnWeights) {
|
size_t NetworkHelper::getOutputChannelsCount(std::shared_ptr<const Node> layer, bool isOnWeights) {
|
||||||
if (layer->outputs().size() == 0) {
|
if (layer->outputs().size() == 0) {
|
||||||
THROW_TRANSFORMATION_EXCEPTION << "Layer " << layer->get_friendly_name() << " doesn't have output tensors";
|
THROW_TRANSFORMATION_EXCEPTION << "Layer " << layer->get_friendly_name() << " doesn't have output tensors";
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "low_precision/split.hpp"
|
#include "low_precision/split.hpp"
|
||||||
#include "ngraph/node.hpp"
|
#include "ngraph/node.hpp"
|
||||||
#include "low_precision/network_helper.hpp"
|
#include "low_precision/network_helper.hpp"
|
||||||
#include "low_precision/common/dequantization_op.hpp"
|
|
||||||
|
|
||||||
namespace ngraph {
|
namespace ngraph {
|
||||||
namespace pass {
|
namespace pass {
|
||||||
@ -23,68 +22,81 @@ bool SplitTransformation::transform(TransformationContext& context, ngraph::patt
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto split = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
|
const std::shared_ptr<Node> split = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
|
||||||
const auto dequantization = NetworkHelper::getDequantization(split);
|
auto dequantization = NetworkHelper::getDequantization(split);
|
||||||
|
|
||||||
OutputVector inputs = split->input_values();
|
OutputVector inputs(split->get_input_size());
|
||||||
inputs[0] = dequantization.data;
|
for (size_t i = 0; i < split->get_input_size(); ++i) {
|
||||||
|
inputs[i] = split->get_input_node_shared_ptr(i);
|
||||||
|
}
|
||||||
|
|
||||||
const auto newSplit = split->clone_with_new_inputs(inputs);
|
const size_t dequantizationIndex = NetworkHelper::getChildInputIndex(dequantization.multiply, split);
|
||||||
|
inputs[dequantizationIndex] = dequantization.data;
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Node> newSplit = split->clone_with_new_inputs(inputs);
|
||||||
newSplit->set_friendly_name(split->get_friendly_name());
|
newSplit->set_friendly_name(split->get_friendly_name());
|
||||||
ngraph::copy_runtime_info(split, newSplit);
|
|
||||||
|
|
||||||
const int64_t axis = as_type_ptr<opset1::Constant>(split->get_input_node_shared_ptr(1))->cast_vector<int64_t>()[0];
|
const ngraph::Shape subConstShape = dequantization.subtract ?
|
||||||
const size_t normalizedAxis = normalize_axis(split->get_friendly_name(), axis, split->get_input_partial_shape(0).rank());
|
dequantization.subtract->get_input_node_shared_ptr(1)->get_shape() : Shape{};
|
||||||
const size_t outputSize = newSplit->get_output_size();
|
std::vector<float> subValues = dequantization.subtract ? as_type_ptr<opset1::Constant>(
|
||||||
|
dequantization.subtract->get_input_node_shared_ptr(1))->cast_vector<float>() : std::vector<float>();
|
||||||
|
|
||||||
const auto splitConstant = [&](const std::shared_ptr<Node> operation) {
|
const ngraph::Shape mulConstShape = dequantization.multiply->get_input_node_shared_ptr(1)->get_shape();
|
||||||
// if batch is absent in constant shape - add batch
|
std::vector<float> mulValues = as_type_ptr<opset1::Constant>(
|
||||||
const auto normalizedConstant = NetworkHelper::normalizeDequantizationShape(operation);
|
dequantization.multiply->get_input_node_shared_ptr(1))->cast_vector<float>();
|
||||||
const auto constantShape = normalizedConstant->get_shape();
|
|
||||||
|
|
||||||
OutputVector results(outputSize);
|
int64_t SplitedAxis = as_type_ptr<opset1::Constant>(split->get_input_node_shared_ptr(1))->cast_vector<int64_t>()[0];
|
||||||
if ((shape_size(constantShape) == 1ul) || (constantShape[normalizedAxis] == 1ul)) {
|
size_t axis = SplitedAxis > 0 ? SplitedAxis : split->get_input_shape(0).size() + SplitedAxis;
|
||||||
std::for_each(results.begin(), results.end(), [&](Output<Node>& elem) { elem = normalizedConstant->clone_with_new_inputs({}); });
|
size_t outputSize = newSplit->get_output_size();
|
||||||
} else {
|
|
||||||
// prepare new inputs for constant folding
|
|
||||||
OutputVector inputs = newSplit->input_values();
|
|
||||||
inputs[0] = normalizedConstant;
|
|
||||||
const auto foldSplit = newSplit->clone_with_new_inputs(inputs);
|
|
||||||
|
|
||||||
// fold and fill results
|
const auto subSplitLengths = getConstSplitLengths(inputs, subConstShape, outputSize);
|
||||||
foldSplit->constant_fold(results, inputs);
|
const auto mulSplitLengths = getConstSplitLengths(inputs, mulConstShape, outputSize);
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& result : results) {
|
std::vector<std::shared_ptr<ngraph::Node>> lastNodes(outputSize);
|
||||||
result = NetworkHelper::toScalarIfPossible(result.get_node_shared_ptr());
|
ngraph::OutputVector replacement;
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// get splited dequantization constants
|
|
||||||
OutputVector splitedSub = dequantization.subtract ? splitConstant(dequantization.subtract) : OutputVector{};
|
|
||||||
OutputVector splitedMul = splitConstant(dequantization.multiply);
|
|
||||||
|
|
||||||
NodeVector lastNodes;
|
|
||||||
OutputVector replacement;
|
|
||||||
for (size_t i = 0; i < outputSize; ++i) {
|
for (size_t i = 0; i < outputSize; ++i) {
|
||||||
Output<Node> parent = newSplit->output(i);
|
Output<Node> previous = newSplit->output(i);
|
||||||
|
|
||||||
if (dequantization.convert) {
|
if (dequantization.convert != nullptr) {
|
||||||
const auto convert = dequantization.convert->clone_with_new_inputs({ newSplit->output(i) });
|
const std::shared_ptr<ngraph::Node> convert =
|
||||||
copy_runtime_info({ newSplit, convert }, convert);
|
dequantization.convert->clone_with_new_inputs({ newSplit->output(i) });
|
||||||
parent = convert;
|
previous = convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dequantization.subtract) {
|
if (dequantization.subtract != nullptr) {
|
||||||
const auto subtract = std::make_shared<DequantizationSubtract>(parent, splitedSub[i]);
|
std::shared_ptr<ngraph::opset1::Constant> subConst;
|
||||||
copy_runtime_info({ newSplit, subtract }, subtract);
|
if (!subSplitLengths.empty()) {
|
||||||
parent = subtract;
|
const auto newSubConstShape = getConstSplitShape(subSplitLengths, subConstShape, axis, i);
|
||||||
|
|
||||||
|
std::vector<float> newSubValues(
|
||||||
|
subValues.begin() + subSplitLengths[i],
|
||||||
|
subValues.begin() + subSplitLengths[i + 1]);
|
||||||
|
|
||||||
|
subConst = as_type_ptr<ngraph::opset1::Constant>(std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
dequantization.subtract->get_input_element_type(1),
|
||||||
|
newSubConstShape,
|
||||||
|
newSubValues));
|
||||||
|
} else {
|
||||||
|
subConst = as_type_ptr<ngraph::opset1::Constant>(dequantization.subtract->get_input_node_shared_ptr(1)->clone_with_new_inputs({}));
|
||||||
|
}
|
||||||
|
const std::shared_ptr<ngraph::Node> subtract = std::make_shared<ngraph::opset1::Subtract>(previous, subConst);
|
||||||
|
previous = subtract;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto multiply = std::make_shared<DequantizationMultiply>(parent, splitedMul[i]);
|
std::shared_ptr<ngraph::opset1::Constant> mulConst;
|
||||||
copy_runtime_info({ newSplit, multiply }, multiply);
|
if (!mulSplitLengths.empty()) {
|
||||||
|
const auto newMulConstShape = getConstSplitShape(mulSplitLengths, mulConstShape, axis, i);
|
||||||
|
|
||||||
|
std::vector<float> newMulValues(
|
||||||
|
mulValues.begin() + mulSplitLengths[i],
|
||||||
|
mulValues.begin() + mulSplitLengths[i + 1]);
|
||||||
|
|
||||||
|
mulConst = as_type_ptr<ngraph::opset1::Constant>(std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
dequantization.multiply->get_input_element_type(1), newMulConstShape, newMulValues));
|
||||||
|
} else {
|
||||||
|
mulConst = as_type_ptr<ngraph::opset1::Constant>(dequantization.multiply->get_input_node_shared_ptr(1)->clone_with_new_inputs({}));
|
||||||
|
}
|
||||||
|
const std::shared_ptr<ngraph::Node> multiply = std::make_shared<ngraph::opset1::Multiply>(previous, mulConst);
|
||||||
|
|
||||||
lastNodes.push_back(multiply);
|
lastNodes.push_back(multiply);
|
||||||
replacement.push_back(multiply);
|
replacement.push_back(multiply);
|
||||||
@ -95,6 +107,33 @@ bool SplitTransformation::transform(TransformationContext& context, ngraph::patt
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<size_t> SplitTransformation::getConstSplitLengths(
|
||||||
|
const OutputVector& inputs,
|
||||||
|
const ngraph::Shape& constShape,
|
||||||
|
const size_t outputSize) const {
|
||||||
|
int64_t axis = as_type_ptr<opset1::Constant>(inputs[1].get_node_shared_ptr())->cast_vector<int64_t>()[0];
|
||||||
|
size_t splitedAxis = axis > 0 ? axis : inputs[0].get_shape().size() + axis;
|
||||||
|
|
||||||
|
if ((!constShape.empty()) && (constShape[splitedAxis] != 1)) {
|
||||||
|
std::vector<size_t> result(outputSize + 1);
|
||||||
|
result[0] = 0;
|
||||||
|
for (size_t i = 1; i < result.size(); ++i) {
|
||||||
|
result[i] = result[i - 1] + constShape[splitedAxis] / outputSize;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return std::vector<size_t>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngraph::Shape SplitTransformation::getConstSplitShape(
|
||||||
|
const std::vector<size_t>& constSplitLengths,
|
||||||
|
const ngraph::Shape& constShape, const size_t axis,
|
||||||
|
const size_t idx) const {
|
||||||
|
Shape result(constShape);
|
||||||
|
result[axis] = constSplitLengths[idx + 1] - constSplitLengths[idx];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void SplitTransformation::updateOutputs(
|
void SplitTransformation::updateOutputs(
|
||||||
TransformationContext& context,
|
TransformationContext& context,
|
||||||
|
@ -23,7 +23,7 @@ std::shared_ptr<Node> stridedSliceDeqConstant(
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
const auto stridedSliceShape = strSlice->get_input_shape(0);
|
const auto stridedSliceShape = strSlice->get_input_shape(0);
|
||||||
auto constantShape = constant->get_shape();
|
const auto constantShape = constant->get_shape();
|
||||||
if (stridedSliceShape.size() != constantShape.size()) {
|
if (stridedSliceShape.size() != constantShape.size()) {
|
||||||
ngraph::Shape newConstantShape;
|
ngraph::Shape newConstantShape;
|
||||||
if (ngraph::shape_size(constantShape) == 1) {
|
if (ngraph::shape_size(constantShape) == 1) {
|
||||||
@ -37,7 +37,6 @@ std::shared_ptr<Node> stridedSliceDeqConstant(
|
|||||||
newConstantShape.insert(newConstantShape.begin(), stridedSliceShape[0]);
|
newConstantShape.insert(newConstantShape.begin(), stridedSliceShape[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constantShape = newConstantShape;
|
|
||||||
|
|
||||||
const auto newConstant = fold<ngraph::opset1::Broadcast>(
|
const auto newConstant = fold<ngraph::opset1::Broadcast>(
|
||||||
constant,
|
constant,
|
||||||
@ -46,24 +45,13 @@ std::shared_ptr<Node> stridedSliceDeqConstant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto stridedSlice = as_type_ptr<ngraph::opset1::StridedSlice>(strSlice);
|
const auto stridedSlice = as_type_ptr<ngraph::opset1::StridedSlice>(strSlice);
|
||||||
|
|
||||||
auto beginMask = stridedSlice->get_begin_mask();
|
|
||||||
auto endMask = stridedSlice->get_end_mask();
|
|
||||||
for (size_t i = 0; i < constantShape.size(); ++i) {
|
|
||||||
// don't slice constant if current dimension is 1
|
|
||||||
if (constantShape[i] == 1ul) {
|
|
||||||
beginMask[i] = 1ul;
|
|
||||||
endMask[i] = 1ul;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto result = fold<ngraph::opset1::StridedSlice>(
|
const auto result = fold<ngraph::opset1::StridedSlice>(
|
||||||
constant,
|
constant,
|
||||||
stridedSlice->get_input_node_shared_ptr(1),
|
stridedSlice->get_input_node_shared_ptr(1),
|
||||||
stridedSlice->get_input_node_shared_ptr(2),
|
stridedSlice->get_input_node_shared_ptr(2),
|
||||||
stridedSlice->get_input_node_shared_ptr(3),
|
stridedSlice->get_input_node_shared_ptr(3),
|
||||||
beginMask,
|
stridedSlice->get_begin_mask(),
|
||||||
endMask,
|
stridedSlice->get_end_mask(),
|
||||||
stridedSlice->get_new_axis_mask(),
|
stridedSlice->get_new_axis_mask(),
|
||||||
stridedSlice->get_shrink_axis_mask(),
|
stridedSlice->get_shrink_axis_mask(),
|
||||||
stridedSlice->get_ellipsis_mask());
|
stridedSlice->get_ellipsis_mask());
|
||||||
|
@ -22,15 +22,16 @@ namespace ngraph {
|
|||||||
namespace pass {
|
namespace pass {
|
||||||
namespace low_precision {
|
namespace low_precision {
|
||||||
|
|
||||||
bool operationIsSupportedInConcat(const std::shared_ptr<ngraph::Node>& node) {
|
bool isQuantizationPerChannel(const std::shared_ptr<ngraph::Node>& node) {
|
||||||
// list of operations, which change channels, but supported in ConcatTransformation
|
if (node->outputs().size() > 1ul) {
|
||||||
if (ngraph::is_type<opset1::StridedSlice>(node) ||
|
return false;
|
||||||
ngraph::is_type<opset1::Split>(node) ||
|
}
|
||||||
ngraph::is_type<opset1::VariadicSplit>(node)) {
|
|
||||||
|
//WA to support StridedSlice in ConcatTransformation
|
||||||
|
if (ngraph::is_type<opset1::StridedSlice>(node)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operations, which change channels, usually don't support in ConcatTransformation
|
|
||||||
const auto inputs = node->input_values();
|
const auto inputs = node->input_values();
|
||||||
for (const auto& input : inputs) {
|
for (const auto& input : inputs) {
|
||||||
if (ngraph::is_type<opset1::Constant>(input.get_node())) {
|
if (ngraph::is_type<opset1::Constant>(input.get_node())) {
|
||||||
@ -81,7 +82,7 @@ bool Subgraph::fillSubgraphForQuantization(
|
|||||||
if (fakeQuantizeChild != nullptr) {
|
if (fakeQuantizeChild != nullptr) {
|
||||||
//
|
//
|
||||||
} else {
|
} else {
|
||||||
if (layerTransformationsManager->isPrecisionPreserved(child) && operationIsSupportedInConcat(child)) {
|
if (layerTransformationsManager->isPrecisionPreserved(child) && isQuantizationPerChannel(child)) {
|
||||||
if (!fillSubgraphForIntermediate(child, handledLayers)) {
|
if (!fillSubgraphForIntermediate(child, handledLayers)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -103,7 +104,7 @@ bool Subgraph::atLeastOneIsIntermediate(const std::shared_ptr<ngraph::Node>& nod
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layerTransformationsManager->isPrecisionPreserved(child) || !operationIsSupportedInConcat(child)) {
|
if (!layerTransformationsManager->isPrecisionPreserved(child) || !isQuantizationPerChannel(child)) {
|
||||||
// child branch is out of subgraph
|
// child branch is out of subgraph
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -143,6 +144,10 @@ bool Subgraph::fill(const std::shared_ptr<ngraph::Node>& layer, std::unordered_s
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// WA: issue #46906
|
||||||
|
if (parent->get_output_size() != 1ul) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(parent, 0, true);
|
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(parent, 0, true);
|
||||||
const std::shared_ptr<ngraph::opset1::FakeQuantize> fakeQuantizeParent = dequantization.empty() ?
|
const std::shared_ptr<ngraph::opset1::FakeQuantize> fakeQuantizeParent = dequantization.empty() ?
|
||||||
ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(parent) :
|
ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(parent) :
|
||||||
@ -156,7 +161,7 @@ bool Subgraph::fill(const std::shared_ptr<ngraph::Node>& layer, std::unordered_s
|
|||||||
if (constant != nullptr) {
|
if (constant != nullptr) {
|
||||||
//
|
//
|
||||||
} else {
|
} else {
|
||||||
if (layerTransformationsManager->isPrecisionPreserved(parent) && operationIsSupportedInConcat(parent)) {
|
if (layerTransformationsManager->isPrecisionPreserved(parent) && isQuantizationPerChannel(parent)) {
|
||||||
if (!fillSubgraphForIntermediate(parent, handledLayers)) {
|
if (!fillSubgraphForIntermediate(parent, handledLayers)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -192,7 +197,7 @@ bool Subgraph::fill(const std::shared_ptr<ngraph::Node>& layer, std::unordered_s
|
|||||||
const std::shared_ptr<ngraph::opset1::FakeQuantize> fakeQuantizeChild = ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(child);
|
const std::shared_ptr<ngraph::opset1::FakeQuantize> fakeQuantizeChild = ngraph::as_type_ptr<ngraph::opset1::FakeQuantize>(child);
|
||||||
if (fakeQuantizeChild != nullptr) {
|
if (fakeQuantizeChild != nullptr) {
|
||||||
//
|
//
|
||||||
} else if (layerTransformationsManager->isPrecisionPreserved(child) && operationIsSupportedInConcat(child)) {
|
} else if (layerTransformationsManager->isPrecisionPreserved(child) && isQuantizationPerChannel(child)) {
|
||||||
if (!fillSubgraphForIntermediate(child, handledLayers)) {
|
if (!fillSubgraphForIntermediate(child, handledLayers)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -216,13 +221,6 @@ bool Subgraph::empty() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Subgraph::fillSubgraphForConcat(const std::shared_ptr<ngraph::opset1::Concat>& concat, std::unordered_set<std::string>& handledLayers) {
|
bool Subgraph::fillSubgraphForConcat(const std::shared_ptr<ngraph::opset1::Concat>& concat, std::unordered_set<std::string>& handledLayers) {
|
||||||
const auto axis = concat->get_axis();
|
|
||||||
const size_t normalizedAxis = ngraph::normalize_axis(concat->get_friendly_name(), axis, concat->get_output_partial_shape(0).rank());
|
|
||||||
// supported only per-channel concat
|
|
||||||
if (normalizedAxis != 1ul) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
concatLayers.push_back(concat);
|
concatLayers.push_back(concat);
|
||||||
handledLayers.insert(concat->get_friendly_name());
|
handledLayers.insert(concat->get_friendly_name());
|
||||||
layers.emplace(concat->get_friendly_name(), concat);
|
layers.emplace(concat->get_friendly_name(), concat);
|
||||||
|
@ -229,11 +229,9 @@ LowPrecisionTransformations LowPrecisionTransformer::getAllTransformations(const
|
|||||||
add<ReluTransformation, opset1::Relu>(params).
|
add<ReluTransformation, opset1::Relu>(params).
|
||||||
add<ReshapeTransformation, opset1::Reshape>(params).
|
add<ReshapeTransformation, opset1::Reshape>(params).
|
||||||
add<SqueezeTransformation, opset1::Squeeze>(params).
|
add<SqueezeTransformation, opset1::Squeeze>(params).
|
||||||
add<SplitTransformation, opset1::Split>(params).
|
|
||||||
add<StridedSliceTransformation, opset1::StridedSlice>(params).
|
add<StridedSliceTransformation, opset1::StridedSlice>(params).
|
||||||
add<TransposeTransformation, opset1::Transpose>(params).
|
add<TransposeTransformation, opset1::Transpose>(params).
|
||||||
add<UnsqueezeTransformation, opset1::Unsqueeze>(params).
|
add<UnsqueezeTransformation, opset1::Unsqueeze>(params).
|
||||||
add<VariadicSplitTransformation, opset1::VariadicSplit>(params).
|
|
||||||
|
|
||||||
addCleanup<FoldConvertTransformation, opset1::Subtract>(params).
|
addCleanup<FoldConvertTransformation, opset1::Subtract>(params).
|
||||||
addCleanup<FuseConvertTransformation, opset1::Multiply>(params).
|
addCleanup<FuseConvertTransformation, opset1::Multiply>(params).
|
||||||
|
@ -20,6 +20,26 @@ void VariadicSplitTransformation::registerMatcherIn(GraphRewrite& pass, Transfor
|
|||||||
make_op_label<opset1::Constant>() }));
|
make_op_label<opset1::Constant>() }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<size_t> VariadicSplitTransformation::getConstSplitLengths(
|
||||||
|
const OutputVector& inputs,
|
||||||
|
const ngraph::Shape& constShape,
|
||||||
|
const size_t outputSize) const {
|
||||||
|
std::vector<size_t> lengths = as_type_ptr<opset1::Constant>(inputs[2].get_node_shared_ptr())->cast_vector<size_t>();
|
||||||
|
|
||||||
|
int64_t axis = as_type_ptr<opset1::Constant>(inputs[1].get_node_shared_ptr())->cast_vector<int64_t>()[0];
|
||||||
|
size_t splitedAxis = axis > 0 ? axis : inputs[0].get_shape().size() + axis;
|
||||||
|
|
||||||
|
if ((!constShape.empty()) && (constShape[splitedAxis] != 1)) {
|
||||||
|
std::vector<size_t> result(outputSize + 1);
|
||||||
|
result[0] = 0;
|
||||||
|
for (size_t i = 1; i < result.size(); ++i) {
|
||||||
|
result[i] = result[i - 1] + lengths[i - 1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return std::vector<size_t>();
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace low_precision
|
} // namespace low_precision
|
||||||
} // namespace pass
|
} // namespace pass
|
||||||
} // namespace ngraph
|
} // namespace ngraph
|
||||||
|
@ -74,7 +74,6 @@ class ConcatTransformationTestValues {
|
|||||||
public:
|
public:
|
||||||
ngraph::pass::low_precision::LayerTransformation::Params params;
|
ngraph::pass::low_precision::LayerTransformation::Params params;
|
||||||
bool multiChannels;
|
bool multiChannels;
|
||||||
std::int64_t axis;
|
|
||||||
ConcatTransformationActualValues actual;
|
ConcatTransformationActualValues actual;
|
||||||
ConcatTransformationResultValues result;
|
ConcatTransformationResultValues result;
|
||||||
};
|
};
|
||||||
@ -115,8 +114,7 @@ public:
|
|||||||
testValues.actual.convert2,
|
testValues.actual.convert2,
|
||||||
testValues.actual.dequantization2,
|
testValues.actual.dequantization2,
|
||||||
ngraph::element::undefined,
|
ngraph::element::undefined,
|
||||||
{},
|
{});
|
||||||
testValues.axis);
|
|
||||||
|
|
||||||
SimpleLowPrecisionTransformer transform;
|
SimpleLowPrecisionTransformer transform;
|
||||||
if (testValues.multiChannels) {
|
if (testValues.multiChannels) {
|
||||||
@ -148,8 +146,7 @@ public:
|
|||||||
testValues.result.convert2,
|
testValues.result.convert2,
|
||||||
testValues.result.dequantization2,
|
testValues.result.dequantization2,
|
||||||
testValues.result.precisionAfterOperation,
|
testValues.result.precisionAfterOperation,
|
||||||
testValues.result.dequantizationAfter,
|
testValues.result.dequantizationAfter);
|
||||||
testValues.axis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getTestCaseName(testing::TestParamInfo<ConcatTransformationParams> obj) {
|
static std::string getTestCaseName(testing::TestParamInfo<ConcatTransformationParams> obj) {
|
||||||
@ -161,7 +158,6 @@ public:
|
|||||||
result <<
|
result <<
|
||||||
LayerTransformation::getTestCaseNameByParams(precision, shape, testValues.params) << "_" <<
|
LayerTransformation::getTestCaseNameByParams(precision, shape, testValues.params) << "_" <<
|
||||||
(testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") <<
|
(testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") <<
|
||||||
"axis_" << testValues.axis << "_" <<
|
|
||||||
testValues.actual << "_" <<
|
testValues.actual << "_" <<
|
||||||
testValues.result << "_";
|
testValues.result << "_";
|
||||||
return result.str();
|
return result.str();
|
||||||
@ -184,7 +180,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -206,7 +201,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
|
||||||
{ ngraph::element::u8 },
|
{ ngraph::element::u8 },
|
||||||
@ -238,7 +232,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
|
||||||
{ ngraph::element::u8 },
|
{ ngraph::element::u8 },
|
||||||
@ -270,7 +263,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -298,7 +290,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -326,7 +317,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {{1}, {1}, {1}, {1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {{1}, {1}, {1}, {1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -350,7 +340,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -374,7 +363,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -398,7 +386,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {{1}, {1}, {1}, {1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {{1}, {1}, {1}, {1}}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -422,7 +409,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
256ul,
|
256ul,
|
||||||
@ -464,7 +450,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -492,7 +477,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsI8I8(),
|
LayerTransformation::createParamsI8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f} },
|
{ 256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f} },
|
||||||
{},
|
{},
|
||||||
@ -516,7 +500,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -540,7 +523,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
true,
|
true,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
@ -564,7 +546,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f} },
|
{ 256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f} },
|
||||||
{},
|
{},
|
||||||
@ -588,7 +569,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {-1.28f}, {1.27f}, {0.f}, {2.3007815f} },
|
{ 256ul, {}, {-1.28f}, {1.27f}, {0.f}, {2.3007815f} },
|
||||||
{},
|
{},
|
||||||
@ -608,61 +588,10 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{ ngraph::element::f32, { 128 }, { 0.0302619f } }
|
{ ngraph::element::f32, { 128 }, { 0.0302619f } }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// U8: concat multi channels with subtract, negative axis
|
|
||||||
{
|
|
||||||
LayerTransformation::createParamsU8I8(),
|
|
||||||
true,
|
|
||||||
-3,
|
|
||||||
{
|
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{ 256ul, {}, {1.275f}, {2.55f}, {1.275f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f}, ngraph::element::u8 },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{ 256ul, {}, {1.275f}, {2.55f}, {0.f}, {255.f}, ngraph::element::u8 },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
ngraph::element::u8,
|
|
||||||
{
|
|
||||||
ngraph::element::f32,
|
|
||||||
{{ 0.f, 0.f, 0.f, -255.f, -255.f, -255.f }},
|
|
||||||
{{ 0.01f, 0.01f, 0.01f, 0.005f, 0.005f, 0.005f }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// U8: concat multi channels with subtract, not supported axis
|
|
||||||
{
|
|
||||||
LayerTransformation::createParamsU8I8(),
|
|
||||||
true,
|
|
||||||
0,
|
|
||||||
{
|
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{ 256ul, {}, {1.275f}, {2.55f}, {1.275f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{ 256ul, {}, {1.275f}, {2.55f}, {1.275f}, {2.55f} },
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// not update precisions
|
// not update precisions
|
||||||
{
|
{
|
||||||
LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
|
LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
|
||||||
false,
|
false,
|
||||||
1,
|
|
||||||
{
|
{
|
||||||
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f} },
|
||||||
{},
|
{},
|
||||||
|
@ -217,40 +217,6 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
{ ngraph::element::f32, {}, { 0.005f } }
|
{ ngraph::element::f32, {}, { 0.005f } }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// U8: concat multi channels with per-channel quantization
|
|
||||||
{
|
|
||||||
{ 1, 6, 10, 10 },
|
|
||||||
LayerTransformation::createParamsU8I8(),
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape({}), {0.f}, {2.55f / 2.f}, {0.f}, {2.55f / 2.f} },
|
|
||||||
{
|
|
||||||
256ul,
|
|
||||||
ngraph::Shape({ 1, 6, 1, 1 }),
|
|
||||||
{0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
|
|
||||||
{255.f, 25.5f, 2.55f, 25.5f, 255.f, 2.55f},
|
|
||||||
{0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
|
|
||||||
{255.f, 25.5f, 2.55f, 25.5f, 255.f, 2.55f}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape({}), {0.f}, {2.55f / 2.f}, {0.f}, {255.f}},
|
|
||||||
{
|
|
||||||
256ul,
|
|
||||||
ngraph::Shape({ 1, 6, 1, 1 }),
|
|
||||||
{0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
|
|
||||||
{255.f, 25.5f, 2.55f, 25.5f, 255.f, 2.55f},
|
|
||||||
{0.f},
|
|
||||||
{255.f}
|
|
||||||
},
|
|
||||||
ngraph::element::u8,
|
|
||||||
{{}, {}, {}},
|
|
||||||
{{}, {}, {}},
|
|
||||||
ngraph::element::u8,
|
|
||||||
{ ngraph::element::f32, {}, {{ 0.005f, 0.005f, 0.005f, 1.f, 0.1f, 0.01f }} },
|
|
||||||
{ ngraph::element::f32, {}, {{ 0.1f, 1.f, 0.01f }} }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// I8: concat multi channels
|
// I8: concat multi channels
|
||||||
{
|
{
|
||||||
{ 1, 6, 10, 10 },
|
{ 1, 6, 10, 10 },
|
||||||
@ -293,8 +259,9 @@ const std::vector<ConcatTransformationTestValues> testValues = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Split/VariadicSplit operations are not supported in ConcatTransformation
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
smoke_LPT,
|
DISABLED_smoke_LPT,
|
||||||
ConcatWithSplitTransformation,
|
ConcatWithSplitTransformation,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::ValuesIn(precisions),
|
::testing::ValuesIn(precisions),
|
||||||
|
@ -160,30 +160,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {2.f}, {22.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}},
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
}
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
}
|
},
|
||||||
},
|
{
|
||||||
// U8 per channel quantization with different values (constants without batch)
|
{ngraph::element::f32},
|
||||||
{
|
{{2.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
ngraph::Shape({ 1, 3, 16, 16 }), std::int64_t{-3}, size_t{3},
|
{{22.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
LayerTransformation::createParamsU8I8(),
|
},
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32},
|
{{3.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
{{1.f, 2.f, 3.f}, ngraph::element::f32, {3, 1, 1}},
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
{{11.f, 22.f, 33.f}, ngraph::element::f32, {3, 1, 1}}}
|
},
|
||||||
},
|
|
||||||
{
|
|
||||||
ngraph::element::u8,
|
|
||||||
{},
|
|
||||||
ngraph::element::u8,
|
|
||||||
{
|
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
|
||||||
{{ngraph::element::f32}, {2.f}, {22.f}},
|
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -202,9 +193,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::i8,
|
ngraph::element::i8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {2.f}, {22.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}},
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{2.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{22.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{3.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -223,9 +226,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -244,9 +259,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::i8,
|
ngraph::element::i8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}}
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -331,9 +358,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {}, {22.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {}, {33.f}},
|
{},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{},
|
||||||
|
{{22.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{},
|
||||||
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -352,9 +391,21 @@ const std::vector<SplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::i8,
|
ngraph::element::i8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {}, {22.f}},
|
{ngraph::element::f32},
|
||||||
{{ngraph::element::f32}, {}, {33.f}},
|
{},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{},
|
||||||
|
{{22.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{},
|
||||||
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -150,17 +150,6 @@ StridedSliceTransformationTestValues::LayerParams specialDimensionSlice = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
StridedSliceTransformationTestValues::LayerParams specialDimensionEndSlice = {
|
|
||||||
{ 0, 0, 20, 0 },
|
|
||||||
{ 1, 3, 24, 24 },
|
|
||||||
{ 1, 1, 1, 1 },
|
|
||||||
{ 1, 1, 0, 1 },
|
|
||||||
{ 1, 1, 0, 1 },
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<StridedSliceTransformationTestValues> stridedSliceTransformationTestValues = {
|
const std::vector<StridedSliceTransformationTestValues> stridedSliceTransformationTestValues = {
|
||||||
// U8: channel slice, per-tensor quantization
|
// U8: channel slice, per-tensor quantization
|
||||||
{
|
{
|
||||||
@ -322,38 +311,6 @@ const std::vector<StridedSliceTransformationTestValues> stridedSliceTransformati
|
|||||||
{{ngraph::element::f32}, {{ 32.f, 64.f, 32.f }}, {{ 0.1f, 0.01f, 1.f }}}
|
{{ngraph::element::f32}, {{ 32.f, 64.f, 32.f }}, {{ 0.1f, 0.01f, 1.f }}}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// I8: special dimension end slice, per-channel quantization with different values
|
|
||||||
{
|
|
||||||
ngraph::Shape{1, 3, 24, 24},
|
|
||||||
LayerTransformation::createParamsI8I8(),
|
|
||||||
specialDimensionEndSlice,
|
|
||||||
{
|
|
||||||
ngraph::element::i8,
|
|
||||||
{{ngraph::element::f32}, {{ 32.f, 64.f, 32.f }}, {{ 0.1f, 0.01f, 1.f }}}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ngraph::element::i8,
|
|
||||||
{},
|
|
||||||
ngraph::element::i8,
|
|
||||||
{{ngraph::element::f32}, {{ 32.f, 64.f, 32.f }}, {{ 0.1f, 0.01f, 1.f }}}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// I8: special dimension end slice, per-tensor quantization with different values
|
|
||||||
{
|
|
||||||
ngraph::Shape{1, 3, 24, 24},
|
|
||||||
LayerTransformation::createParamsI8I8(),
|
|
||||||
specialDimensionEndSlice,
|
|
||||||
{
|
|
||||||
ngraph::element::i8,
|
|
||||||
{{ngraph::element::f32}, { 32.f }, { 0.1f }}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ngraph::element::i8,
|
|
||||||
{},
|
|
||||||
ngraph::element::i8,
|
|
||||||
{{ngraph::element::f32}, { 32.f }, { 0.1f }}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// I8: channel slice, quantization by special dimension
|
// I8: channel slice, quantization by special dimension
|
||||||
{
|
{
|
||||||
ngraph::Shape{1, 3, 4, 4},
|
ngraph::Shape{1, 3, 4, 4},
|
||||||
|
@ -177,31 +177,11 @@ const std::vector<VariadicSplitTransformationTestValues> testValues = {
|
|||||||
{{1.f, 2.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
{{1.f, 2.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
||||||
{{11.f, 22.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
{{11.f, 22.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
||||||
},
|
},
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// U8 per channel quantization with different values (constants without batch)
|
|
||||||
{
|
|
||||||
ngraph::Shape({ 1, 3, 16, 16 }), std::int64_t{ -3 }, std::vector<size_t>{ 2, 1 },
|
|
||||||
LayerTransformation::createParamsU8I8(),
|
|
||||||
{
|
|
||||||
ngraph::element::u8,
|
|
||||||
{{ngraph::element::f32},
|
|
||||||
{{1.f, 2.f, 3.f}, ngraph::element::f32, {3, 1, 1}},
|
|
||||||
{{11.f, 22.f, 33.f}, ngraph::element::f32, {3, 1, 1}}}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ngraph::element::u8,
|
|
||||||
{},
|
|
||||||
ngraph::element::u8,
|
|
||||||
{
|
|
||||||
{
|
{
|
||||||
{ngraph::element::f32},
|
{ngraph::element::f32},
|
||||||
{{1.f, 2.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
{{3.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
{{11.f, 22.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
},
|
}
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -225,7 +205,11 @@ const std::vector<VariadicSplitTransformationTestValues> testValues = {
|
|||||||
{{1.f, 2.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
{{1.f, 2.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
||||||
{{11.f, 22.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
{{11.f, 22.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
||||||
},
|
},
|
||||||
{{ngraph::element::f32}, {3.f}, {33.f}}
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{3.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{33.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -244,8 +228,16 @@ const std::vector<VariadicSplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}}
|
{ngraph::element::f32},
|
||||||
|
{{1.f, 1.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
||||||
|
{{11.f, 11.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -264,8 +256,16 @@ const std::vector<VariadicSplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::i8,
|
ngraph::element::i8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}}
|
{ngraph::element::f32},
|
||||||
|
{{1.f, 1.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
||||||
|
{{11.f, 11.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -322,13 +322,21 @@ const std::vector<VariadicSplitTransformationTestValues> testValues = {
|
|||||||
{},
|
{},
|
||||||
ngraph::element::i8,
|
ngraph::element::i8,
|
||||||
{
|
{
|
||||||
{{ngraph::element::f32}, {1.f}, {11.f}},
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{1.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{11.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{ngraph::element::f32},
|
{ngraph::element::f32},
|
||||||
{{2.f, 3.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
{{2.f, 3.f}, ngraph::element::f32, {1, 2, 1, 1}},
|
||||||
{{22.f, 33.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
{{22.f, 33.f}, ngraph::element::f32, {1, 2, 1, 1}}
|
||||||
},
|
},
|
||||||
{{ngraph::element::f32}, {4.f}, {44.f}}
|
{
|
||||||
|
{ngraph::element::f32},
|
||||||
|
{{4.f}, ngraph::element::f32, {1, 1, 1, 1}},
|
||||||
|
{{44.f}, ngraph::element::f32, {1, 1, 1, 1}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,8 @@ const std::vector<ConcatWithSplitTransformationParam> testValues = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, ConcatWithSplitTransformation,
|
// TODO: Split/VariadicSplit operations are not supported in ConcatTransformation
|
||||||
|
INSTANTIATE_TEST_CASE_P(DISABLED_smoke_LPT, ConcatWithSplitTransformation,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::ValuesIn(netPrecisions),
|
::testing::ValuesIn(netPrecisions),
|
||||||
::testing::Values(ngraph::Shape({ 1, 6, 10, 10 })),
|
::testing::Values(ngraph::Shape({ 1, 6, 10, 10 })),
|
||||||
|
@ -45,7 +45,8 @@ const std::vector<ConcatWithSplitTransformationParam> testValues = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, ConcatWithSplitTransformation,
|
// TODO: Split/VariadicSplit operations are not supported in ConcatTransformation
|
||||||
|
INSTANTIATE_TEST_CASE_P(DISABLED_smoke_LPT, ConcatWithSplitTransformation,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::ValuesIn(netPrecisions),
|
::testing::ValuesIn(netPrecisions),
|
||||||
::testing::Values(ngraph::Shape({ 1, 6, 10, 10 })),
|
::testing::Values(ngraph::Shape({ 1, 6, 10, 10 })),
|
||||||
|
@ -114,8 +114,7 @@ public:
|
|||||||
const DequantizationOperations::Convert& convert2,
|
const DequantizationOperations::Convert& convert2,
|
||||||
const DequantizationOperations& dequantization2,
|
const DequantizationOperations& dequantization2,
|
||||||
const ngraph::element::Type precisionAfterOperation,
|
const ngraph::element::Type precisionAfterOperation,
|
||||||
const DequantizationOperations& dequantizationAfter,
|
const DequantizationOperations& dequantizationAfter);
|
||||||
const std::int64_t& axis);
|
|
||||||
|
|
||||||
static std::shared_ptr<ngraph::Function> getReferenceWithNeighbors(
|
static std::shared_ptr<ngraph::Function> getReferenceWithNeighbors(
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
|
@ -752,8 +752,7 @@ std::shared_ptr<ngraph::Function> ConcatFunction::get(
|
|||||||
const DequantizationOperations::Convert& convert2,
|
const DequantizationOperations::Convert& convert2,
|
||||||
const DequantizationOperations& dequantization2,
|
const DequantizationOperations& dequantization2,
|
||||||
const ngraph::element::Type precisionAfterOperation,
|
const ngraph::element::Type precisionAfterOperation,
|
||||||
const DequantizationOperations& dequantizationAfter,
|
const DequantizationOperations& dequantizationAfter) {
|
||||||
const std::int64_t& axis) {
|
|
||||||
const auto input1 = std::make_shared<ngraph::opset1::Parameter>(inputPrecision, inputShape);
|
const auto input1 = std::make_shared<ngraph::opset1::Parameter>(inputPrecision, inputShape);
|
||||||
input1->set_friendly_name("input1");
|
input1->set_friendly_name("input1");
|
||||||
|
|
||||||
@ -776,7 +775,7 @@ std::shared_ptr<ngraph::Function> ConcatFunction::get(
|
|||||||
parent2 = makeDequantization(parent2, dequantization2);
|
parent2 = makeDequantization(parent2, dequantization2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(ngraph::OutputVector{ parent1, parent2 }, axis);
|
const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(ngraph::OutputVector{ parent1, parent2 }, 1);
|
||||||
|
|
||||||
auto& rtInfo = concat->get_rt_info();
|
auto& rtInfo = concat->get_rt_info();
|
||||||
rtInfo["Variant::std::string"] = std::make_shared<VariantWrapper<std::string>>("concat");
|
rtInfo["Variant::std::string"] = std::make_shared<VariantWrapper<std::string>>("concat");
|
||||||
@ -990,13 +989,6 @@ std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithSplitedInterme
|
|||||||
input2->set_friendly_name("input2");
|
input2->set_friendly_name("input2");
|
||||||
|
|
||||||
const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
|
const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
|
||||||
replace_node(
|
|
||||||
fakeQuantize2->get_input_node_shared_ptr(3),
|
|
||||||
ngraph::pass::low_precision::NetworkHelper::toScalarIfPossible(fakeQuantize2->get_input_node_shared_ptr(3)));
|
|
||||||
replace_node(
|
|
||||||
fakeQuantize2->get_input_node_shared_ptr(4),
|
|
||||||
ngraph::pass::low_precision::NetworkHelper::toScalarIfPossible(fakeQuantize2->get_input_node_shared_ptr(4)));
|
|
||||||
|
|
||||||
fakeQuantize2->set_friendly_name("fakeQuantize2");
|
fakeQuantize2->set_friendly_name("fakeQuantize2");
|
||||||
low_precision::NetworkHelper::setOutDataPrecisionForTypeRelaxed(fakeQuantize2, precisionAfterOperation);
|
low_precision::NetworkHelper::setOutDataPrecisionForTypeRelaxed(fakeQuantize2, precisionAfterOperation);
|
||||||
const auto deqBefore2 = makeDequantization(fakeQuantize2, dequantizationBefore1);
|
const auto deqBefore2 = makeDequantization(fakeQuantize2, dequantizationBefore1);
|
||||||
|
Loading…
Reference in New Issue
Block a user