Supports tensor names with delimiter (#4085)

* Supports tensor names with delimiter

* Fixed comments

* Allow to use different delimiters
This commit is contained in:
Ilya Churaev authored and GitHub committed 2021-02-04 06:38:05 +03:00
1 parent da9d42f63b
commit 748780e392
7 files changed
+46 -12

No files matched your search

@@ -628,7 +628,16 @@ V10Parser::GenericLayerParams V10Parser::XmlDeserializer::parseGenericParams(con
port.precision = type;
std::vector<std::string> names;
if (getParameters<std::string>(parentNode, "names", names)) {
for (const auto& name : names) {
for (size_t i = 0; i < names.size(); i++) {
std::string name = names[i];
// Restore original name if it contains delimiter
// getParameters(...) returns the vector of names which were split by delimiter ','
// but some names can contain ',' as a part of name, in this case we use '\' to escape delimiter
// the cycle below is needed in order to find names which contained delimiter and restore the original name
while (i < names.size() && names[i].at(names[i].length() - 1) == '\\') {
name.replace(names[i].length() - 1, 1, ",");
name += names[++i];
}
port.names.emplace(name);
}
}
@@ -472,6 +472,17 @@ std::string get_output_precision_name(ngraph::Output<Node>& o) {
}
}
std::string escape_delim(const std::string& name, const char delim = ',') {
std::string result_name = name;
const std::string escaped_delim = std::string("\\") + delim;
size_t index = result_name.find(delim, 0);
while (index != std::string::npos) {
result_name.replace(index, 1, escaped_delim);
index = result_name.find(delim, index + 2);
}
return result_name;
}
std::string generate_unique_name(
const std::unordered_set<std::string>& unique_names, std::string base_name,
int suffix) {
@@ -666,7 +677,7 @@ void ngfunction_2_irv10(pugi::xml_node& netXml,
for (const auto& name : o.get_tensor().get_names()) {
if (!names.empty())
names += ", ";
names += name;
names += escape_delim(name);
}
if (!names.empty()) {
port.append_attribute("names").set_value(names.c_str());
@@ -38,7 +38,7 @@ TEST_F(TensorNameSerializationTest, SerializeFunctionWithTensorNames) {
relu_prev->get_output_tensor(0).set_names({"relu_prev_t", "identity_prev_t"});
auto relu = std::make_shared<ngraph::opset6::Relu>(relu_prev);
relu->set_friendly_name("relu");
relu->get_output_tensor(0).set_names({"relu_t", "identity"});
relu->get_output_tensor(0).set_names({"relu,t", "identity"});
const ngraph::ResultVector results{std::make_shared<ngraph::opset6::Result>(relu)};
results[0]->set_friendly_name("out");
ngraph::ParameterVector params{parameter};
@@ -30,7 +30,7 @@ TEST_F(NGraphReaderTests, ReadNetworkWithTensorNames) {
</port>
</input>
<output>
<port id="2" precision="FP32" names="relu_t, identity_t">
<port id="2" precision="FP32" names="relu\,t, identity_t">
<dim>1</dim>
<dim>3</dim>
<dim>22</dim>
@@ -86,4 +86,5 @@ TEST_F(NGraphReaderTests, ReadNetworkWithTensorNames) {
for (const auto& name : result->get_input_tensor(0).get_names())
ASSERT_TRUE(outNames.count(network.getOVNameForTensor(name)));
}
ASSERT_NO_THROW(network.getOVNameForTensor("relu,t"));
}
@@ -115,7 +115,7 @@ TEST_P(TensorNamesTest, CheckAddOutput) {
// Check that relu_prev doesn't exist in output and input maps
ASSERT_THROW(cnnNetwork.getOVNameForOperation("relu_prev"), InferenceEngine::NotFound);
for (const std::string& tensor_name : {"relu_prev_t", "identity_prev_t"}) {
for (const std::string& tensor_name : {"relu,prev_t", "identity_prev_t"}) {
ASSERT_THROW(cnnNetwork.getOVNameForOperation(tensor_name), InferenceEngine::NotFound);
}
@@ -137,11 +137,11 @@ TEST_P(TensorNamesTest, CheckAddOutput) {
// Check that relu_prev exists in output map
ASSERT_FALSE(inNames.count(cnnNetwork.getOVNameForOperation("relu_prev")));
for (const std::string& tensor_name : {"relu_prev_t", "identity_prev_t"}) {
for (const std::string& tensor_name : {"relu,prev_t", "identity_prev_t"}) {
ASSERT_FALSE(inNames.count(cnnNetwork.getOVNameForTensor(tensor_name)));
}
ASSERT_TRUE(outNames.count(cnnNetwork.getOVNameForOperation("relu_prev")));
for (const std::string& tensor_name : {"relu_prev_t", "identity_prev_t"}) {
for (const std::string& tensor_name : {"relu,prev_t", "identity_prev_t"}) {
ASSERT_TRUE(outNames.count(cnnNetwork.getOVNameForTensor(tensor_name)));
}
@@ -22,10 +22,10 @@ void TensorNamesTest::SetUp() {
parameter->get_output_tensor(0).set_names({"input"});
auto relu_prev = std::make_shared<ngraph::opset5::Relu>(parameter);
relu_prev->set_friendly_name("relu_prev");
relu_prev->get_output_tensor(0).set_names({"relu_prev_t", "identity_prev_t"});
relu_prev->get_output_tensor(0).set_names({"relu,prev_t", "identity_prev_t"});
auto relu = std::make_shared<ngraph::opset5::Relu>(relu_prev);
relu->set_friendly_name("relu");
relu->get_output_tensor(0).set_names({"relu_t", "identity"});
relu->get_output_tensor(0).set_names({"relu,t", "identity"});
const ngraph::ResultVector results{std::make_shared<ngraph::opset3::Result>(relu)};
results[0]->set_friendly_name("out");
ngraph::ParameterVector params{parameter};
@@ -821,9 +821,22 @@ FunctionsComparator::Result FunctionsComparator::compare(
const auto& tensor2 = node2->output(i).get_tensor();
if (tensor1.get_names() != tensor2.get_names()) {
err_log << "Output tensors names are different for nodes: "
<< node1->get_friendly_name() << " and " << node2->get_friendly_name()
<< std::endl;
std::string names1 = "";
for (const auto& name : tensor1.get_names()) {
if (!names1.empty())
names1 += ", ";
names1 += name;
}
names1 = "\"" + names1 + "\"";
std::string names2 = "";
for (const auto& name : tensor2.get_names()) {
if (!names2.empty())
names2 += ", ";
names2 += name;
}
names2 = "\"" + names2 + "\"";
err_log << "Output tensors names " << names1 << " and " << names2 << " are different for nodes: "
<< node1->get_friendly_name() << " and " << node2->get_friendly_name() << std::endl;
}
if (!node1->output(i).get_partial_shape().same_scheme(
node2->output(i).get_partial_shape())) {