Loop operation: IE IR Reader update (#2766)
* ie_ir_reader update, Loop implementation update * fix ie ir reader
This commit is contained in:
parent
de686fce39
commit
735c8747b5
@ -668,8 +668,8 @@ std::shared_ptr<ngraph::Node>
|
||||
V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &inputs, const pugi::xml_node &node,
|
||||
std::istream &binStream,
|
||||
const V10Parser::GenericLayerParams &layerParsePrms,
|
||||
std::shared_ptr<ngraph::op::util::SubGraphOp> tensor_iterator) {
|
||||
tensor_iterator->set_friendly_name(GetStrAttr(node, "name"));
|
||||
std::shared_ptr<ngraph::op::util::SubGraphOp> subgraph_op) {
|
||||
subgraph_op->set_friendly_name(GetStrAttr(node, "name"));
|
||||
auto body_node = node.child("body");
|
||||
|
||||
if (body_node.empty()) {
|
||||
@ -696,12 +696,12 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
// Disabled reshape for generic operations in the TI body
|
||||
::ngraph::op::GenericIE::DisableReshape noReshape(ngraph_function);
|
||||
auto body = std::make_shared<ngraph::Function>(result_nodes, parameter_nodes);
|
||||
tensor_iterator->set_function(body);
|
||||
subgraph_op->set_function(body);
|
||||
|
||||
// Parse PortMap: inputs
|
||||
std::map<uint64_t, pugi::xml_node> input_map;
|
||||
FOREACH_CHILD(_input, node.child("port_map"), "input") {
|
||||
int64_t ext_port_id = GetUIntAttr(_input, "external_port_id");
|
||||
int64_t ext_port_id = GetInt64Attr(_input, "external_port_id");
|
||||
input_map[ext_port_id] = _input;
|
||||
}
|
||||
|
||||
@ -709,7 +709,8 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
for (const auto& input : input_map) {
|
||||
auto &_input = input.second;
|
||||
auto axis_attr = _input.attribute("axis");
|
||||
size_t ti_input_index = GetUIntAttr(_input, "external_port_id");
|
||||
auto purpose = GetStrAttr(_input, "purpose", "");
|
||||
int64_t ti_input_index = GetInt64Attr(_input, "external_port_id");
|
||||
size_t body_parameter_index = GetUIntAttr(_input, "internal_layer_id");
|
||||
|
||||
auto body_param = std::find_if(parameter_nodes.begin(), parameter_nodes.end(),
|
||||
@ -721,7 +722,8 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
THROW_IE_EXCEPTION << "PortMap input parsing error. Body parameter with id = " << body_parameter_index
|
||||
<< " not found.";
|
||||
}
|
||||
if (ti_input_index >= inputs.size())
|
||||
|
||||
if (ti_input_index >= static_cast<int64_t>(inputs.size()))
|
||||
THROW_IE_EXCEPTION << "TensorIterator " << layerParsePrms.name << " has incorrect number of inputs!";
|
||||
|
||||
// if axis is set, then slicing is enabled. Create ngraph::TensorIterator::SlicedInput.
|
||||
@ -731,7 +733,7 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
int64_t stride = GetInt64Attr(_input, "stride", 1);
|
||||
int64_t end = GetInt64Attr(_input, "end", -1);
|
||||
int64_t part_size = GetInt64Attr(_input, "part_size", 1);
|
||||
tensor_iterator->set_sliced_input(*body_param, inputs[ti_input_index], start, stride, part_size, end, axis);
|
||||
subgraph_op->set_sliced_input(*body_param, inputs.at(ti_input_index), start, stride, part_size, end, axis);
|
||||
is_sliced_input_exists = true;
|
||||
} else {
|
||||
// otherwise find corresponding back edge and create ngraph::TensorIterator::MergedInput
|
||||
@ -752,28 +754,40 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
<< " not found.";
|
||||
}
|
||||
|
||||
tensor_iterator->set_merged_input(*body_param, inputs[ti_input_index], *body_result);
|
||||
subgraph_op->set_merged_input(*body_param, inputs.at(ti_input_index), *body_result);
|
||||
is_back_edge_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_back_edge_exist) {
|
||||
tensor_iterator->set_invariant_input(*body_param, inputs[ti_input_index]);
|
||||
// ti_input_index = -1 means that Parameter of the body is not connected to inputs of TensorIterator
|
||||
// and is used only for internal needs.
|
||||
if (!is_back_edge_exist && ti_input_index >= 0) {
|
||||
subgraph_op->set_invariant_input(*body_param, inputs.at(ti_input_index));
|
||||
}
|
||||
|
||||
if (purpose == "current_iteration") {
|
||||
auto loop = std::dynamic_pointer_cast<ngraph::opset5::Loop>(subgraph_op);
|
||||
if (!loop)
|
||||
THROW_IE_EXCEPTION << "PortMap output parsing error. Purpose attribute is available only for Loop operation.";
|
||||
loop->set_special_body_ports(ngraph::opset5::Loop::SpecialBodyPorts{ngraph_function->get_parameter_index(*body_param),
|
||||
-1});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse PortMap: outputs
|
||||
std::map<uint32_t, pugi::xml_node> output_map;
|
||||
std::map<int64_t, pugi::xml_node> output_map;
|
||||
FOREACH_CHILD(_output, node.child("port_map"), "output") {
|
||||
uint32_t ext_port_id = GetUIntAttr(_output, "external_port_id");
|
||||
int64_t ext_port_id = GetInt64Attr(_output, "external_port_id");
|
||||
output_map[ext_port_id] = _output;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (const auto& output : output_map) {
|
||||
auto& _output = output.second;
|
||||
auto axis_attr = _output.attribute("axis");
|
||||
auto purpose = GetStrAttr(_output, "purpose", "");
|
||||
size_t body_result_index = GetUIntAttr(_output, "internal_layer_id");
|
||||
|
||||
auto body_result =
|
||||
@ -788,25 +802,38 @@ V10Parser::LayerBaseCreator::fillSubGraphLayer(const ngraph::OutputVector &input
|
||||
|
||||
// if axis is set, then concatenation is enabled. Create ngraph::TensorIterator::ConcatOutput.
|
||||
if (!axis_attr.empty()) {
|
||||
uint32_t axis = GetUIntAttr(_output, "axis");
|
||||
int64_t axis = GetInt64Attr(_output, "axis");
|
||||
int64_t start = GetInt64Attr(_output, "start", 0);
|
||||
int64_t stride = GetInt64Attr(_output, "stride", 1);
|
||||
int64_t end = GetInt64Attr(_output, "end", -1);
|
||||
int64_t part_size = GetInt64Attr(_output, "part_size", 1);
|
||||
tensor_iterator->get_concatenated_slices(*body_result, start, stride, part_size, end, axis);
|
||||
subgraph_op->get_concatenated_slices(*body_result, start, stride, part_size, end, axis);
|
||||
|
||||
if (!is_sliced_input_exists) {
|
||||
if (auto ti = std::dynamic_pointer_cast<ngraph::op::TensorIterator>(tensor_iterator))
|
||||
ti->set_num_iterations((std::abs(end - start)) / part_size);
|
||||
if (auto ti = std::dynamic_pointer_cast<ngraph::op::TensorIterator>(subgraph_op))
|
||||
// for Loop op we just skip this call
|
||||
if (ti)
|
||||
ti->set_num_iterations((std::abs(end - start)) / part_size);
|
||||
}
|
||||
} else if (purpose == "execution_condition") {
|
||||
auto loop = std::dynamic_pointer_cast<ngraph::opset5::Loop>(subgraph_op);
|
||||
if (!loop)
|
||||
THROW_IE_EXCEPTION << "PortMap output parsing error. Purpose attribute is available only for Loop operation.";
|
||||
loop->set_special_body_ports(ngraph::opset5::Loop::SpecialBodyPorts{loop->get_special_body_ports().current_iteration_input_idx,
|
||||
ngraph_function->get_result_index(*body_result)});
|
||||
// if external_port_id < 0,
|
||||
// it means that this body result isn't connected to the Loop output and is used only for internal needs.
|
||||
if (output.first >= 0) {
|
||||
subgraph_op->get_iter_value(*body_result, -1);
|
||||
}
|
||||
} else {
|
||||
// otherwise create ngraph::TensorIterator::BodyOutput. -1 means last iteration.
|
||||
tensor_iterator->get_iter_value(*body_result, -1);
|
||||
subgraph_op->get_iter_value(*body_result, -1);
|
||||
}
|
||||
}
|
||||
|
||||
tensor_iterator->validate_and_infer_types();
|
||||
return tensor_iterator;
|
||||
subgraph_op->validate_and_infer_types();
|
||||
return subgraph_op;
|
||||
}
|
||||
|
||||
|
||||
@ -824,7 +851,7 @@ template <>
|
||||
std::shared_ptr<ngraph::Node> V10Parser::LayerCreator<ngraph::opset5::Loop>::createLayer(
|
||||
const ngraph::OutputVector& inputs, const pugi::xml_node& node, std::istream& binStream,
|
||||
const GenericLayerParams& layerParsePrms) {
|
||||
auto loop = std::make_shared<ngraph::opset5::Loop>();
|
||||
auto loop = std::make_shared<ngraph::opset5::Loop>(inputs[0], inputs[1]);
|
||||
return fillSubGraphLayer(inputs, node, binStream, layerParsePrms, loop);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ private:
|
||||
static std::shared_ptr<ngraph::Node> fillSubGraphLayer(const ngraph::OutputVector& inputs, const pugi::xml_node& node,
|
||||
std::istream& binStream,
|
||||
const GenericLayerParams& layerParsePrms,
|
||||
std::shared_ptr<ngraph::op::util::SubGraphOp> sub_graph_node);
|
||||
std::shared_ptr<ngraph::op::util::SubGraphOp> subgraph_op);
|
||||
explicit LayerBaseCreator(const std::string& type): type(type) {}
|
||||
std::string getType() {
|
||||
return type;
|
||||
|
@ -0,0 +1,383 @@
|
||||
// Copyright (C) 2018-2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include "ngraph_reader_tests.hpp"
|
||||
#include "common_test_utils/data_utils.hpp"
|
||||
|
||||
TEST_F(NGraphReaderTests, ReadLoopNetwork) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="yolov3-10" version="10">
|
||||
<layers>
|
||||
<layer id="0" name="TFNodes/yolo_evaluation_layer_1/arange_4__77_trip_cnt/placeholder_port_0" type="Parameter" version="opset1">
|
||||
<data element_type="f32" shape=""/>
|
||||
<output>
|
||||
<port id="0" precision="FP32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="TFNodes/yolo_evaluation_layer_1/arange_4__77_trip_cnt" type="Convert" version="opset1">
|
||||
<data destination_type="i64"/>
|
||||
<input>
|
||||
<port id="0"/>
|
||||
</input>
|
||||
<output>
|
||||
<port id="1" precision="I64"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="2" name="TFNodes/yolo_evaluation_layer_1/arange__271_cond/Output_0/Data__const" type="Parameter" version="opset1">
|
||||
<data element_type="boolean" offset="0" shape="" size="1"/>
|
||||
<output>
|
||||
<port id="1" precision="BOOL"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="3" name="TFNodes/yolo_evaluation_layer_1/arange_5/start:0/Output_0/Data__const" type="Parameter" version="opset1">
|
||||
<data element_type="i32" offset="1" shape="" size="4"/>
|
||||
<output>
|
||||
<port id="1" precision="I32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="4" name="TFNodes/yolo_evaluation_layer_1/arange_5/delta:0/Output_0/Data__const" type="Parameter" version="opset1">
|
||||
<data element_type="i32" offset="5" shape="" size="4"/>
|
||||
<output>
|
||||
<port id="1" precision="I32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="5" name="TFNodes/yolo_evaluation_layer_1/arange_4__77_loop" type="Loop" version="opset5">
|
||||
<input>
|
||||
<port id="0"/>
|
||||
<port id="1"/>
|
||||
<port id="2"/>
|
||||
<port id="3"/>
|
||||
</input>
|
||||
<output>
|
||||
<port id="4" precision="I32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
<port_map>
|
||||
<input external_port_id="3" internal_layer_id="6"/>
|
||||
<input external_port_id="1" internal_layer_id="0"/>
|
||||
<input external_port_id="2" internal_layer_id="2"/>
|
||||
<output external_port_id="-1" internal_layer_id="1" purpose="execution_condition"/>
|
||||
<output axis="0" external_port_id="4" internal_layer_id="5"/>
|
||||
</port_map>
|
||||
<back_edges>
|
||||
<edge from-layer="1" from-port="0" to-layer="0" to-port="0"/>
|
||||
<edge from-layer="8" from-port="0" to-layer="2" to-port="0"/>
|
||||
</back_edges>
|
||||
<body>
|
||||
<layers>
|
||||
<layer id="0" name="cond" type="Parameter" version="opset1">
|
||||
<data element_type="boolean" shape=""/>
|
||||
<output>
|
||||
<port id="0" precision="BOOL"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="Identity__82/sink_port_0" type="Result" version="opset1">
|
||||
<data order="0"/>
|
||||
<input>
|
||||
<port id="0"/>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="2" name="prev" type="Parameter" version="opset1">
|
||||
<data element_type="i32" shape=""/>
|
||||
<output>
|
||||
<port id="0" precision="I32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="3" name="11_input_port_1/value/Output_0/Data__const" type="Const" version="opset1">
|
||||
<data element_type="i64" offset="0" shape="1" size="8"/>
|
||||
<output>
|
||||
<port id="1" precision="I64">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="4" name="11" type="Unsqueeze" version="opset1">
|
||||
<input>
|
||||
<port id="0"/>
|
||||
<port id="1">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="I32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="5" name="Identity__84/sink_port_0" type="Result" version="opset1">
|
||||
<data order="2"/>
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="6" name="TFNodes/yolo_evaluation_layer_1/arange_5/delta:0" type="Parameter" version="opset1">
|
||||
<data element_type="i32" shape=""/>
|
||||
<output>
|
||||
<port id="0" precision="I32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="7" name="add__83" type="Add" version="opset1">
|
||||
<input>
|
||||
<port id="0"/>
|
||||
<port id="1"/>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="I32"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="8" name="add__83/sink_port_0" type="Result" version="opset1">
|
||||
<data order="1"/>
|
||||
<input>
|
||||
<port id="0"/>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
|
||||
<edge from-layer="2" from-port="0" to-layer="4" to-port="0"/>
|
||||
<edge from-layer="3" from-port="1" to-layer="4" to-port="1"/>
|
||||
<edge from-layer="4" from-port="2" to-layer="5" to-port="0"/>
|
||||
<edge from-layer="2" from-port="0" to-layer="7" to-port="0"/>
|
||||
<edge from-layer="6" from-port="0" to-layer="7" to-port="1"/>
|
||||
<edge from-layer="7" from-port="2" to-layer="8" to-port="0"/>
|
||||
</edges>
|
||||
</body>
|
||||
</layer>
|
||||
<layer id="8" name="TFNodes/yolo_evaluation_layer_1/Reshape_13/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
<dim>1</dim>
|
||||
<dim>1</dim>
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
|
||||
<edge from-layer="1" from-port="1" to-layer="5" to-port="0"/>
|
||||
<edge from-layer="2" from-port="1" to-layer="5" to-port="1"/>
|
||||
<edge from-layer="3" from-port="1" to-layer="5" to-port="2"/>
|
||||
<edge from-layer="4" from-port="1" to-layer="5" to-port="3"/>
|
||||
<edge from-layer="5" from-port="4" to-layer="8" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
|
||||
)V0G0N";
|
||||
|
||||
Core reader;
|
||||
Blob::Ptr weights;
|
||||
weights = make_shared_blob<uint8_t>(TensorDesc(Precision::U8, {8}, Layout::C));
|
||||
weights->allocate();
|
||||
weights->buffer().as<int64_t*>()[0] = 0;
|
||||
EXPECT_NO_THROW(reader.ReadNetwork(model, weights));
|
||||
}
|
||||
|
||||
TEST_F(NGraphReaderTests, ReadLoopNetwork_2) {
|
||||
std::string model = R"V0G0N(
|
||||
<?xml version="1.0" ?>
|
||||
<net name="loop_2d_add" version="10">
|
||||
<layers>
|
||||
<layer id="0" name="trip_count/Output_0/Data__const" type="Parameter" version="opset1">
|
||||
<data element_type="i64" offset="0" shape="1" size="8"/>
|
||||
<output>
|
||||
<port id="1" precision="I64">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="a_final5/execution_cond/Output_0/Data__const" type="Parameter" version="opset1">
|
||||
<data element_type="boolean" offset="8" shape="" size="1"/>
|
||||
<output>
|
||||
<port id="1" precision="BOOL"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="2" name="a_init" type="Parameter" version="opset1">
|
||||
<data element_type="f32" shape="1,2"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="3" name="a_final5" type="Loop" version="opset5">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
<port id="1"/>
|
||||
<port id="2">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="3" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
<port id="4" precision="FP32">
|
||||
<dim>3</dim>
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
<port_map>
|
||||
<input external_port_id="1" internal_layer_id="0"/>
|
||||
<input external_port_id="2" internal_layer_id="2"/>
|
||||
<output external_port_id="-1" internal_layer_id="1" purpose="execution_condition"/>
|
||||
<output external_port_id="3" internal_layer_id="5"/>
|
||||
<output axis="0" external_port_id="4" internal_layer_id="8"/>
|
||||
</port_map>
|
||||
<back_edges>
|
||||
<edge from-layer="1" from-port="0" to-layer="0" to-port="0"/>
|
||||
<edge from-layer="5" from-port="0" to-layer="2" to-port="0"/>
|
||||
</back_edges>
|
||||
<body>
|
||||
<layers>
|
||||
<layer id="0" name="cond_in" type="Parameter" version="opset1">
|
||||
<data element_type="boolean" shape=""/>
|
||||
<output>
|
||||
<port id="0" precision="BOOL"/>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="cond_identity/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0"/>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="2" name="a_in" type="Parameter" version="opset1">
|
||||
<data element_type="f32" shape="1,2"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="3" name="b/Output_0/Data__const" type="Const" version="opset1">
|
||||
<data element_type="f32" offset="0" shape="1,2" size="8"/>
|
||||
<output>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="4" name="loop_body_add" type="Add" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
<port id="1">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="5" name="loop_body_add/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="6" name="11_input_port_1/value/Output_0/Data__const" type="Const" version="opset1">
|
||||
<data element_type="i64" offset="0" shape="1" size="8"/>
|
||||
<output>
|
||||
<port id="1" precision="I64">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="7" name="11" type="Unsqueeze" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
<port id="1">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<dim>3</dim>
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="8" name="output_accumulator/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>3</dim>
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
|
||||
<edge from-layer="2" from-port="0" to-layer="4" to-port="0"/>
|
||||
<edge from-layer="3" from-port="1" to-layer="4" to-port="1"/>
|
||||
<edge from-layer="4" from-port="2" to-layer="5" to-port="0"/>
|
||||
<edge from-layer="4" from-port="2" to-layer="7" to-port="0"/>
|
||||
<edge from-layer="6" from-port="1" to-layer="7" to-port="1"/>
|
||||
<edge from-layer="7" from-port="2" to-layer="8" to-port="0"/>
|
||||
</edges>
|
||||
</body>
|
||||
</layer>
|
||||
<layer id="6" name="a_final/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
<layer id="9" name="a_values/sink_port_0" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>3</dim>
|
||||
<dim>1</dim>
|
||||
<dim>2</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="1" to-layer="3" to-port="0"/>
|
||||
<edge from-layer="1" from-port="1" to-layer="3" to-port="1"/>
|
||||
<edge from-layer="2" from-port="0" to-layer="3" to-port="2"/>
|
||||
<edge from-layer="3" from-port="3" to-layer="6" to-port="0"/>
|
||||
<edge from-layer="3" from-port="4" to-layer="9" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
|
||||
)V0G0N";
|
||||
|
||||
Core reader;
|
||||
Blob::Ptr weights;
|
||||
weights = make_shared_blob<uint8_t>(TensorDesc(Precision::U8, {8}, Layout::C));
|
||||
weights->allocate();
|
||||
weights->buffer().as<float*>()[0] = 0;
|
||||
weights->buffer().as<float*>()[1] = 0;
|
||||
EXPECT_NO_THROW(reader.ReadNetwork(model, weights));
|
||||
}
|
@ -111,6 +111,36 @@ void op::v5::Loop::validate_and_infer_types()
|
||||
m_num_iterations = 1; // condition_always_false, do_while mode
|
||||
}
|
||||
}
|
||||
else if (const auto& cond_param = std::dynamic_pointer_cast<const ngraph::opset5::Parameter>(
|
||||
body_execution_condition.get_node_shared_ptr()))
|
||||
{
|
||||
// Const(true or false) -> Loop (body: Parameter -> execution_condition output)
|
||||
for (const auto& desc : get_input_descriptions())
|
||||
{
|
||||
if (m_body->get_parameters().at(desc->m_body_parameter_index) == cond_param)
|
||||
{
|
||||
if (const auto& cond_value =
|
||||
std::dynamic_pointer_cast<const ngraph::opset5::Constant>(
|
||||
input_value(desc->m_input_index).get_node_shared_ptr()))
|
||||
{
|
||||
auto val = cond_value->cast_vector<bool>();
|
||||
NODE_VALIDATION_CHECK(
|
||||
this,
|
||||
val.size() == 1,
|
||||
"The number of values in the Condition constant is greater than 1");
|
||||
|
||||
if (val[0])
|
||||
{
|
||||
condition_always_true = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_num_iterations = 1; // condition_always_false, do_while mode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto& trip_count = input_value(0);
|
||||
const auto& trip_count_rank = trip_count.get_partial_shape().rank();
|
||||
|
Loading…
Reference in New Issue
Block a user