forked from openvinotoolkit/openvino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged list of tensor custom data type support and recent advances in…
… PT FE organization and new ops support (basically control flow)
- Loading branch information
Showing
20 changed files
with
2,014 additions
and
1,078 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
src/frontends/pytorch/include/openvino/frontend/pytorch/c_torchscript_decoder.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
182 changes: 182 additions & 0 deletions
182
src/frontends/pytorch/include/openvino/frontend/pytorch/node_context.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
#pragma once | ||
|
||
#include <openvino/frontend/exception.hpp> | ||
#include <openvino/frontend/node_context.hpp> | ||
#include <openvino/frontend/pytorch/decoder.hpp> | ||
#include <openvino/opsets/opset8.hpp> | ||
|
||
#include "exception.hpp" | ||
|
||
namespace ov { | ||
namespace frontend { | ||
namespace pytorch { | ||
|
||
typedef std::map<size_t, Output<Node>> TensorMap; | ||
|
||
class NodeContext : public frontend::NodeContext { | ||
public: | ||
NodeContext(std::shared_ptr<Decoder> decoder, | ||
TensorMap* tensor_map, | ||
ParameterVector* external_parameters, | ||
const TensorMap& ext_tensor_map) | ||
: // TODO: why the following ctor is explicit? | ||
frontend::NodeContext(decoder->get_op_type()), | ||
m_decoder(decoder), | ||
m_tensor_map(tensor_map), | ||
m_ext_tensor_map(ext_tensor_map), | ||
m_external_parameters(external_parameters) {} | ||
|
||
// Do not search for input in tensor map; try to access it as a constant of specified type T and return its value | ||
template <typename T> | ||
T const_input(size_t index) const; | ||
|
||
size_t get_input_size() const override { | ||
return m_decoder->inputs().size(); | ||
}; | ||
|
||
// Search for input in tensor map and return an output port for already converted op | ||
// TODO: int due to base class uses it, but naturally it should be size_t for PT | ||
Output<Node> get_input(int index) const override { | ||
// std::cerr << "Trying to map input to ngraph..."; | ||
OV_FRONTEND_REQUIRE(!m_decoder->input_is_none(index)); | ||
auto input = m_decoder->input(index); | ||
OV_FRONTEND_REQUIRE(m_tensor_map->count(input)); | ||
return m_tensor_map->at(input); | ||
} | ||
|
||
// TODO: upstream to base class | ||
OutputVector inputs() const { | ||
OutputVector res; | ||
for (size_t input : m_decoder->inputs()) { | ||
// std::cerr << "Searching for input: " << input->unique() << "\n"; | ||
OV_FRONTEND_REQUIRE(m_tensor_map->find(input) != m_tensor_map->end()); | ||
res.push_back(m_tensor_map->at(input)); | ||
} | ||
return res; | ||
} | ||
|
||
bool input_is_none(size_t index) const { | ||
return m_decoder->input_is_none(index); | ||
} | ||
|
||
// Convert the resulting value of this node to ngraph Constant; works correctly only for nodes that produce | ||
// constant value, naturally for prim::Constant | ||
OutputVector as_constant() const { | ||
return m_decoder->as_constant(); | ||
} | ||
|
||
/* | ||
TODO: Should be uncommented when explicit NodeContext ctor won't require passing op_type | ||
const std::string& get_op_type() const override { | ||
return m_decoder->get_op_type(); | ||
} | ||
*/ | ||
|
||
std::string get_schema() const { | ||
return m_decoder->get_schema(); | ||
} | ||
|
||
size_t num_of_outputs() const { | ||
return m_decoder->num_of_outputs(); | ||
} | ||
|
||
std::vector<size_t> outputs() const { | ||
return m_decoder->outputs(); | ||
} | ||
|
||
std::shared_ptr<Node> mark_node(std::shared_ptr<Node> ov_node) const { | ||
return m_decoder->mark_node(ov_node); | ||
} | ||
|
||
void mark_nodes(std::vector<std::shared_ptr<Node>> ov_nodes) const { | ||
return m_decoder->mark_nodes(ov_nodes); | ||
} | ||
|
||
Output<Node> mark_output(Output<Node> ov_output) const { | ||
return m_decoder->mark_node(ov_output.get_node_shared_ptr()); | ||
} | ||
|
||
Any get_attribute_as_any(const std::string&) const override { | ||
throw std::runtime_error( | ||
"There is no any named attributes in Pytorch node, query by attribute name is not implemented"); | ||
} | ||
|
||
void mutate_input(size_t index, Output<Node> ov_output) { | ||
OV_FRONTEND_REQUIRE(!m_decoder->input_is_none(index)); | ||
auto input = m_decoder->input(index); | ||
OV_FRONTEND_REQUIRE(m_tensor_map->count(input)); | ||
m_tensor_map->at(input).get_tensor().set_names({std::to_string(input) + "_"}); | ||
// TODO: find out why this doesn't work | ||
ov_output.get_tensor().add_names({std::to_string(input)}); | ||
(*m_tensor_map)[input] = ov_output; | ||
m_mutated_tensors.insert(input); | ||
} | ||
|
||
std::set<size_t> get_mutated_tensors() const { | ||
return m_mutated_tensors; | ||
} | ||
|
||
std::shared_ptr<Decoder> get_decoder() const { | ||
return m_decoder; | ||
} | ||
|
||
void add_tensor_to_context(size_t index, Output<Node> ov_output) { | ||
if (m_tensor_map->count(index)) { | ||
std::cerr << "[ WARNING ] Current context has tensor. Rewriting." << std::endl; | ||
} | ||
ov_output.get_tensor().add_names({std::to_string(index)}); | ||
(*m_tensor_map)[index] = ov_output; | ||
} | ||
|
||
Output<Node> get_tensor_from_model(size_t index) { | ||
if (m_tensor_map->find(index) != m_tensor_map->end()) { | ||
return m_tensor_map->at(index); | ||
} else { | ||
return Output<Node>(); | ||
} | ||
} | ||
|
||
Output<Node> get_tensor_from_model_or_create_input(size_t index) { | ||
if (m_tensor_map->find(index) != m_tensor_map->end()) { | ||
return m_tensor_map->at(index); | ||
} else { | ||
// nested subgraphs case | ||
auto parameter = std::make_shared<opset8::Parameter>(element::dynamic, PartialShape::dynamic()); | ||
parameter->get_output_tensor(0).add_names({std::to_string(index)}); | ||
(*m_tensor_map)[index] = parameter; | ||
m_external_parameters->push_back(parameter); | ||
std::cout << "Nested case, created: " << parameter << std::endl; | ||
return parameter; | ||
} | ||
} | ||
|
||
Output<Node> get_input_from_visible_context(size_t index) { | ||
OV_FRONTEND_REQUIRE(index < get_input_size()); | ||
auto input_tensor = get_input(index); | ||
auto input_node = input_tensor.get_node_shared_ptr(); | ||
if (std::dynamic_pointer_cast<opset8::Parameter>(input_node)) { | ||
// We need to look into external context for inputs that would be feed into this parameter | ||
auto name = input_node->get_output_tensor(0).get_any_name(); | ||
size_t tensor_idx = (size_t)std::stoll(name); | ||
if (m_ext_tensor_map.count(tensor_idx)) { | ||
input_tensor = m_ext_tensor_map.at(tensor_idx); | ||
} | ||
} | ||
return input_tensor; | ||
} | ||
|
||
std::shared_ptr<ov::Model> convert_subgraph(size_t index); | ||
|
||
private: | ||
std::shared_ptr<opset8::Constant> get_constant_at_input(size_t index) const; | ||
|
||
std::shared_ptr<Decoder> m_decoder; | ||
std::set<size_t> m_mutated_tensors; | ||
TensorMap* m_tensor_map; | ||
const TensorMap& m_ext_tensor_map; | ||
ParameterVector* m_external_parameters; | ||
}; | ||
|
||
} // namespace pytorch | ||
} // namespace frontend | ||
} // namespace ov |
Oops, something went wrong.