Moved graph validation utils to ov (#7529)

This commit is contained in:
Ilya Churaev authored and GitHub committed 2021-09-20 10:40:14 +03:00
1 parent 9cfdad9afc
commit 850c526e3b
7 files changed
+516 -461

No files matched your search

+2 -4
View File
@@ -23,12 +23,10 @@ acos0->set_argument(0, add0);
add1->set_argument(0, acos0);
add1->set_argument(1, abs0);
// Run shape inference on the nodes
NodeVector ops{arg0, arg1, add0, abs0, acos0, add1};
validate_nodes_and_infer_types(ops);
// Create a graph with one output (add1) and four inputs (arg0, arg1)
auto ng_function = make_shared<Function>(OutputVector{add1}, ParameterVector{arg0, arg1});
// Run shape inference on the nodes
ng_function->validate_nodes_and_infer_types();
//! [part0]
+9 -257
View File
@@ -17,6 +17,7 @@
#include "ngraph/check.hpp"
#include "ngraph/function.hpp"
#include "ngraph/node.hpp"
#include "openvino/core/graph_util.hpp"
namespace ov {
namespace op {
@@ -33,249 +34,19 @@ using ov::op::v0::Parameter;
}
} // namespace op
NGRAPH_API
void traverse_nodes(const std::shared_ptr<const Function> p, std::function<void(std::shared_ptr<Node>)> f);
NGRAPH_API
void traverse_nodes(const Function* p, std::function<void(std::shared_ptr<Node>)> f);
/// \brief Visit each node in a sub-graph of the entire graph
/// \param subgraph_results The output nodes of the sub-graph
/// \param f Function to execute at each node in the traversal
/// \param subgraph_params Input nodes of the sub-graph (optional)
///
/// Traverses a sub-graph starting from subgraph_results moving up
/// towards parameter nodes. Traversal stops if it hits a node in
/// subgraph_params.
///
/// Most useful for finding parameters of a graph directly from the
/// result nodes and not from function parameters or extracting a
/// subgraph relevant to the computation of certain outputs
NGRAPH_API
void traverse_nodes(const NodeVector& subgraph_results,
std::function<void(std::shared_ptr<Node>)> f,
const NodeVector& subgraph_params = {});
/// \brief Replace the node `target` with the node `replacement`, i.e.,
/// redirect all users and control dependencies of `target` to
/// `replacement`.
///
/// \param target Node to be replaced.
/// \param replacement Node to replace `target` with.
/// \param output_order Vector determines order of replacement node's outputs.
///
/// This is primarily used in graph-rewriting passes. For example, we
/// might "fuse" two Concat operations as follows:
///
/// (Step 0: Original graph)
///
/// A B
/// | |
/// v v
/// N0[Concat, concatenation_axis=3] C
/// | |
/// v v
/// N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 1: Construct replacement)
///
/// shared_ptr<Node> new_N1 = make_shared<op::Concat>({A,B,C},3);
///
/// A----------------------------------------.
/// | |
/// | B----------------)--.
/// | | | |
/// v v | |
/// N0[Concat, concatenation_axis=3] C-----)--)--.
/// | | | | |
/// v v v v v
/// N1[Concat, concatenation_axis=3] new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 2: Replace N1 with new_N1)
///
/// replace_node(N1, new_N1);
///
/// A----------------------------------------.
/// | |
/// | B----------------)--.
/// | | | |
/// v v | |
/// N0[Concat, concatenation_axis=3] C-----)--)--.
/// | | | | |
/// v v v v v
/// N1[Concat, concatenation_axis=3] new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 3: N0 and N1 are now dead, nodes will be freed)
///
/// [happens automatically, once all shared_ptrs to N1 are released]
///
/// A----------------------------------------.
/// |
/// B----------------)--.
/// | |
/// | |
/// C-----)--)--.
/// | | |
/// v v v
/// new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// NOTE 1: replace_node is not type-safe (the graph is not revalidated).
/// For example, the following is allowed, even if node `some_user`
/// requires an input of shape 2x2:
///
/// (Before)
/// A(shape=2x2) B(shape=3x3)
/// |
/// v
/// some_user(requires 2x2 input)
///
/// (After -- graph is now invalid)
///
/// replace_node(A, B);
///
/// A(shape=2x2) B(shape=3x3)
/// |
/// v
/// some_user(requires 2x2 input)
///
/// NOTE 2: it is possible to insert a cycle into the graph with
/// replace_node, resulting in an invalid graph. Care must be taken to
/// avoid this. One common example is when you are attempting to insert a
/// new node `M` "after"` a node `N`. For example, you might expect this
/// to work:
///
/// shared_ptr<Node> M = make_shared<SomeUnaryOp>(N);
/// replace_node(M, N);
///
/// The problem is that at replacement time, N itself is a user of M. So
/// we end up introducing a cycle as follows:
///
/// N
/// |
/// v
/// other users...
///
/// |||
/// vvv
///
/// N------------>M
/// |
/// v
/// other users...
///
/// |||
/// vvv
///
/// .----.
/// | |
/// | |
/// N `----->M
/// |
/// v
/// other users...
///
/// To avoid the cycle, a valid way to perform the above desired insertion would be,
///
/// auto new_N = N->clone_with_new_inputs(N->input_values());
/// shared_ptr<Node> M = make_shared<SomeUnaryOp>(new_N);
/// replace_node(N, M);
NGRAPH_API
void replace_node(std::shared_ptr<Node> target,
std::shared_ptr<Node> replacement,
const std::vector<int64_t>& output_order);
/// Replace target.outputs[i] with replacement_values[i] and transfer control dependents and
/// provenance from target to the node(s) in replacement_values.
NGRAPH_API
void replace_node(const std::shared_ptr<Node>& target, const OutputVector& replacement_values);
NGRAPH_API
void replace_node(std::shared_ptr<Node> target, std::shared_ptr<Node> replacement);
/// \brief Replace multiple nodes in a function.
/// \param f Function where replacement is taking place.
/// \param parameter_replacement_map A mapping from parameter shared pointers to parameter
/// shared pointers. For each pair (k,v) in the map, parameter
/// k is replaced by parameter v, except if k==v or k is not a
/// parameter bound by f, in which case the pair (k,v) is
/// ignored.
/// \param body_replacement_map A mapping from node shared pointers to node shared pointers.
/// For each pair (k,v) in the map, node k is replaced by node v,
/// except if k==v, the pair (k,v) is ignored.
/// Note that if k is a parameter, its users will be redirected to
/// v, but k will _not_ be replaced in the function's parameter
/// list.
///
/// Limitations:
///
/// - No check is made that the replaced nodes in `parameter_replacement_map` are actually
/// among the bound parameters of `f`. (If a parameter appears in the map that is not
/// bound by `f`, it will be silently ignored.)
/// - If a parameter node appears as a key in both `parameter_replacement_map` _and_ in
/// `body_replacement_map`, behavior is unspecified.
NGRAPH_API
void replace_nodes(const std::shared_ptr<Function>& f,
const std::unordered_map<std::shared_ptr<op::v0::Parameter>, std::shared_ptr<op::v0::Parameter>>&
parameter_replacement_map,
const std::unordered_map<std::shared_ptr<Node>, std::shared_ptr<Node>>& body_replacement_map);
using ov::clone_function;
using ov::compare_constants;
using ov::replace_node;
using ov::replace_node_update_name;
using ov::replace_nodes;
using ov::replace_output_update_name;
using ov::topological_sort;
using ov::traverse_nodes;
NGRAPH_DEPRECATED("This method is deprecated and will be removed soon")
NGRAPH_API
NodeVector find_common_args(std::shared_ptr<Node> target, std::shared_ptr<Node> replacement);
/// Topological sort of nodes needed to compute root_nodes
template <typename T>
std::vector<std::shared_ptr<Node>> topological_sort(T root_nodes) {
std::stack<Node*, std::vector<Node*>> nodes_to_do;
std::unordered_set<Node*> nodes_done;
std::vector<std::shared_ptr<Node>> result;
for (auto& node : root_nodes) {
nodes_to_do.push(node.get());
}
while (nodes_to_do.size() > 0) {
Node* node = nodes_to_do.top();
if (nodes_done.count(node) == 0) {
bool can_add = true;
size_t arg_count = node->get_input_size();
for (size_t i = 0; i < arg_count; ++i) {
Node* dep = node->get_input_node_ptr(arg_count - i - 1);
if (nodes_done.count(dep) == 0) {
can_add = false;
nodes_to_do.push(dep);
}
}
for (auto& depptr : node->get_control_dependencies()) {
Node* dep = depptr.get();
if (nodes_done.count(dep) == 0) {
can_add = false;
nodes_to_do.push(dep);
}
}
if (can_add) {
result.push_back(node->shared_from_this());
nodes_to_do.pop();
nodes_done.insert(node);
}
} else {
nodes_to_do.pop();
}
}
return result;
}
/// Topological sort of just nodes
template <typename T>
std::vector<std::shared_ptr<Node>> subgraph_topological_sort(T nodes) {
@@ -356,16 +127,6 @@ NGRAPH_API
std::list<std::shared_ptr<ngraph::Node>> clone_nodes(const std::vector<std::shared_ptr<ngraph::Node>>& nodes,
RawNodeOutputMap& node_map);
// input function is cloned and returned
// NodeMap input may contain default node mapping i.e. pre-cloned nodes
// NodeMap output (by reference) fully maps input and cloned function ops
NGRAPH_API
std::shared_ptr<ngraph::Function> clone_function(const ngraph::Function& func, NodeMap& node_map);
// input function is cloned and returned
NGRAPH_API
std::shared_ptr<ngraph::Function> clone_function(const ngraph::Function& func);
NGRAPH_DEPRECATED("This method is deprecated and will be removed soon")
NGRAPH_API
std::pair<std::shared_ptr<op::Result>, std::shared_ptr<op::v0::Parameter>> insert_result_parameter_split(
@@ -406,9 +167,6 @@ NGRAPH_DEPRECATED("This method is deprecated and will be removed soon")
NGRAPH_API
bool is_one(const Output<Node>& reduce_constant);
NGRAPH_API
bool compare_constants(const std::shared_ptr<Node>& n1, const std::shared_ptr<Node>& n2);
// Returns true if `node` is live in the graph i.e. a result op
// transitively uses this `node`
NGRAPH_API
@@ -456,12 +214,6 @@ std::vector<Output<Node>> get_outputs_to(Node& src, Node& dst);
NGRAPH_DEPRECATED("This method is deprecated and will be removed soon")
NGRAPH_API
bool check_for_cycles(const ngraph::Function* func, ngraph::NodeVector& cycle_nodes, bool& is_bkwd_cycle);
NGRAPH_API
bool replace_output_update_name(Output<Node> node, const Output<Node>& node_input);
NGRAPH_API
bool replace_node_update_name(std::shared_ptr<Node> target, std::shared_ptr<Node> replacement);
} // namespace ngraph
using ngraph::replace_node;
+8 -104
View File
@@ -11,8 +11,16 @@
#include "ngraph/op/op.hpp"
#include "ngraph/op/util/attr_types.hpp"
#include "ngraph/op/util/variable_context.hpp"
#include "openvino/core/validation_util.hpp"
namespace ngraph {
using ov::evaluate_as_partial_shape;
using ov::get_constant_from_source;
using ov::infer_auto_padding;
using ov::infer_convolution_forward;
using ov::normalize_axes;
using ov::normalize_axis;
NGRAPH_API
Strides conv_default_strides(const Node* node, const PartialShape& data_batch_shape, const PartialShape& filters_shape);
@@ -63,16 +71,6 @@ PartialShape validate_and_infer_convolution_forward_output_shape(const Node* nod
CoordinateDiff& pads_begin,
CoordinateDiff& pads_end);
NGRAPH_API
PartialShape infer_convolution_forward(const Node* node,
const PartialShape& data_batch_shape,
const Strides& data_dilation,
const CoordinateDiff& data_padding_below,
const CoordinateDiff& data_padding_above,
const PartialShape& filters_shape,
const Strides& filter_strides,
const Strides& filter_dilation);
NGRAPH_API
PartialShape infer_batched_pooling_forward(const Node* node,
const PartialShape& data_batch_shape,
@@ -129,15 +127,6 @@ bool try_apply_auto_padding(const PartialShape& image_shape,
CoordinateDiff& padding_above,
CoordinateDiff& padding_below);
NGRAPH_API
void infer_auto_padding(const Shape& image_shape,
const Shape& filter_shape,
const Strides& filter_strides,
const Strides& filter_dilations,
const op::PadType pad_type,
CoordinateDiff& padding_above,
CoordinateDiff& padding_below);
NGRAPH_API
PartialShape infer_slice_shape(const Node* node,
const PartialShape& input_shape,
@@ -150,80 +139,6 @@ PartialShape infer_slice_shape(const Node* node,
const AxisSet& shrink_axis_mask,
const AxisSet& ellipsis_mask);
/// \brief Handle out of range axis.
///
/// \param[in] node The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return Checking if axis is in range [-tensor_rank, tensor_rank-1], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
NGRAPH_API
int64_t normalize_axis(const Node* node, std::int64_t axis, const Rank& tensor_rank);
/// \brief Handle out of range axes in vector.
///
/// \param[in] node_description The name of node with requested axes.
/// \param[in] axes The requested vector of axes.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return If any negative axis in vector, it counts from the last to the first
/// axis, by adding tensor_rank to axis.
///
NGRAPH_API
std::vector<size_t> normalize_axes(const std::string& node_description,
const std::vector<int64_t>& axes,
const Rank& tensor_rank);
/// \brief Handle out of range axis.
///
/// \param[in] node_description The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return Checking if axis is in range [-tensor_rank, tensor_rank-1], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
NGRAPH_API
int64_t normalize_axis(const std::string& node_description, std::int64_t axis, const Rank& tensor_rank);
/// \brief Handle out of range axis.
///
/// \param[in] node The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
/// \param[in] axis_range_min The min value of accepted range for axis.
/// \param[in] axis_range_max The max value of accepted range for axis.
///
/// \return Checking if axis is in range [axis_range_min, axis_range_max], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
NGRAPH_API
int64_t normalize_axis(const Node* node,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max);
/// \brief Handle out of range axis.
///
/// \param[in] node_description The name of node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
/// \param[in] axis_range_min The min value of accepted range for axis.
/// \param[in] axis_range_max The max value of accepted range for axis.
///
/// \return Checking if axis is in range [axis_range_min, axis_range_max], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
NGRAPH_API
int64_t normalize_axis(const std::string& node_description,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max);
/// \brief Try to compute the maximum value of value
/// \return (true, max_value) if can be determined, or (false, numeric_limits<uint64_t>::max())
/// if not.
@@ -263,13 +178,6 @@ NGRAPH_API HostTensorPtr evaluate_upper_bound(const Output<Node>& output);
/// could be HostTensorPtr to estimated value if particular bound can be determined, or nullptr.
NGRAPH_API std::pair<HostTensorPtr, HostTensorPtr> evaluate_both_bounds(const Output<Node>& output);
/// \brief Evaluates lower and upper value estimations for the output tensor. Estimation would
/// be represented as partial shape object using Dimension(min, max) for each element.
/// \param output Node output pointing to the tensor for estimation.
/// \param pshape Resulting estimation would be stored in this PartialShape.
/// \return boolean status if value evaluation was successful.
NGRAPH_API bool evaluate_as_partial_shape(const Output<Node>& output, PartialShape& pshape);
/// \brief Estimates upper bound for node output tensors using only upper bounds of the nodes
/// inputs.
/// \param node Operation to be performed
@@ -302,10 +210,6 @@ NGRAPH_API bool host_tensor_is_positive(const HostTensorPtr& bound);
/// only on pointers comparison.
NGRAPH_API bool has_and_set_equal_bounds(const Output<Node>& source);
/// \brief Runs an estimation of source tensor. If it succeeded to calculate both bounds and
/// they are the same returns Constant operation from the resulting bound, otherwise nullptr.
NGRAPH_API std::shared_ptr<op::Constant> get_constant_from_source(const Output<Node>& source);
/// \brief Returns a Constant storing scalar value equal to std::numeric_limits<t>::max()
NGRAPH_API std::shared_ptr<op::Constant> get_constant_max_of_type(element::Type_t t);
@@ -0,0 +1,282 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <deque>
#include <functional>
#include <list>
#include <memory>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "openvino/core/core_visibility.hpp"
#include "openvino/core/function.hpp"
#include "openvino/core/node.hpp"
#include "openvino/op/parameter.hpp"
namespace ov {
OPENVINO_API
void traverse_nodes(const std::shared_ptr<const Function>& p,
const std::function<void(const std::shared_ptr<Node>&)>& f);
OPENVINO_API
void traverse_nodes(const Function* p, const std::function<void(const std::shared_ptr<Node>&)>& f);
/// \brief Visit each node in a sub-graph of the entire graph
/// \param subgraph_results The output nodes of the sub-graph
/// \param f Function to execute at each node in the traversal
/// \param subgraph_params Input nodes of the sub-graph (optional)
///
/// Traverses a sub-graph starting from subgraph_results moving up
/// towards parameter nodes. Traversal stops if it hits a node in
/// subgraph_params.
///
/// Most useful for finding parameters of a graph directly from the
/// result nodes and not from function parameters or extracting a
/// subgraph relevant to the computation of certain outputs
OPENVINO_API
void traverse_nodes(const NodeVector& subgraph_results,
const std::function<void(const std::shared_ptr<Node>&)>& f,
const NodeVector& subgraph_params = {});
/// \brief Replace the node `target` with the node `replacement`, i.e.,
/// redirect all users and control dependencies of `target` to
/// `replacement`.
///
/// \param target Node to be replaced.
/// \param replacement Node to replace `target` with.
/// \param output_order Vector determines order of replacement node's outputs.
///
/// This is primarily used in graph-rewriting passes. For example, we
/// might "fuse" two Concat operations as follows:
///
/// (Step 0: Original graph)
///
/// A B
/// | |
/// v v
/// N0[Concat, concatenation_axis=3] C
/// | |
/// v v
/// N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 1: Construct replacement)
///
/// shared_ptr<Node> new_N1 = make_shared<op::Concat>({A,B,C},3);
///
/// A----------------------------------------.
/// | |
/// | B----------------)--.
/// | | | |
/// v v | |
/// N0[Concat, concatenation_axis=3] C-----)--)--.
/// | | | | |
/// v v v v v
/// N1[Concat, concatenation_axis=3] new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 2: Replace N1 with new_N1)
///
/// replace_node(N1, new_N1);
///
/// A----------------------------------------.
/// | |
/// | B----------------)--.
/// | | | |
/// v v | |
/// N0[Concat, concatenation_axis=3] C-----)--)--.
/// | | | | |
/// v v v v v
/// N1[Concat, concatenation_axis=3] new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// (Step 3: N0 and N1 are now dead, nodes will be freed)
///
/// [happens automatically, once all shared_ptrs to N1 are released]
///
/// A----------------------------------------.
/// |
/// B----------------)--.
/// | |
/// | |
/// C-----)--)--.
/// | | |
/// v v v
/// new_N1[Concat, concatenation_axis=3]
/// | |
/// v v
/// some_user another_user
///
/// NOTE 1: replace_node is not type-safe (the graph is not revalidated).
/// For example, the following is allowed, even if node `some_user`
/// requires an input of shape 2x2:
///
/// (Before)
/// A(shape=2x2) B(shape=3x3)
/// |
/// v
/// some_user(requires 2x2 input)
///
/// (After -- graph is now invalid)
///
/// replace_node(A, B);
///
/// A(shape=2x2) B(shape=3x3)
/// |
/// v
/// some_user(requires 2x2 input)
///
/// NOTE 2: it is possible to insert a cycle into the graph with
/// replace_node, resulting in an invalid graph. Care must be taken to
/// avoid this. One common example is when you are attempting to insert a
/// new node `M` "after"` a node `N`. For example, you might expect this
/// to work:
///
/// shared_ptr<Node> M = make_shared<SomeUnaryOp>(N);
/// replace_node(M, N);
///
/// The problem is that at replacement time, N itself is a user of M. So
/// we end up introducing a cycle as follows:
///
/// N
/// |
/// v
/// other users...
///
/// |||
/// vvv
///
/// N------------>M
/// |
/// v
/// other users...
///
/// |||
/// vvv
///
/// .----.
/// | |
/// | |
/// N `----->M
/// |
/// v
/// other users...
///
/// To avoid the cycle, a valid way to perform the above desired insertion would be,
///
/// auto new_N = N->clone_with_new_inputs(N->input_values());
/// shared_ptr<Node> M = make_shared<SomeUnaryOp>(new_N);
/// replace_node(N, M);
OPENVINO_API
void replace_node(const std::shared_ptr<Node>& target,
const std::shared_ptr<Node>& replacement,
const std::vector<int64_t>& output_order);
/// Replace target.outputs[i] with replacement_values[i] and transfer control dependents and
/// provenance from target to the node(s) in replacement_values.
OPENVINO_API
void replace_node(const std::shared_ptr<Node>& target, const OutputVector& replacement_values);
OPENVINO_API
void replace_node(const std::shared_ptr<Node>& target, const std::shared_ptr<Node>& replacement);
/// \brief Replace multiple nodes in a function.
/// \param f Function where replacement is taking place.
/// \param parameter_replacement_map A mapping from parameter shared pointers to parameter
/// shared pointers. For each pair (k,v) in the map, parameter
/// k is replaced by parameter v, except if k==v or k is not a
/// parameter bound by f, in which case the pair (k,v) is
/// ignored.
/// \param body_replacement_map A mapping from node shared pointers to node shared pointers.
/// For each pair (k,v) in the map, node k is replaced by node v,
/// except if k==v, the pair (k,v) is ignored.
/// Note that if k is a parameter, its users will be redirected to
/// v, but k will _not_ be replaced in the function's parameter
/// list.
///
/// Limitations:
///
/// - No check is made that the replaced nodes in `parameter_replacement_map` are actually
/// among the bound parameters of `f`. (If a parameter appears in the map that is not
/// bound by `f`, it will be silently ignored.)
/// - If a parameter node appears as a key in both `parameter_replacement_map` _and_ in
/// `body_replacement_map`, behavior is unspecified.
OPENVINO_API
void replace_nodes(const std::shared_ptr<Function>& f,
const std::unordered_map<std::shared_ptr<op::v0::Parameter>, std::shared_ptr<op::v0::Parameter>>&
parameter_replacement_map,
const std::unordered_map<std::shared_ptr<Node>, std::shared_ptr<Node>>& body_replacement_map);
/// Topological sort of nodes needed to compute root_nodes
template <typename T>
std::vector<std::shared_ptr<Node>> topological_sort(T root_nodes) {
std::stack<Node*, std::vector<Node*>> nodes_to_do;
std::unordered_set<Node*> nodes_done;
std::vector<std::shared_ptr<Node>> result;
for (auto& node : root_nodes) {
nodes_to_do.push(node.get());
}
while (nodes_to_do.size() > 0) {
Node* node = nodes_to_do.top();
if (nodes_done.count(node) == 0) {
bool can_add = true;
size_t arg_count = node->get_input_size();
for (size_t i = 0; i < arg_count; ++i) {
Node* dep = node->get_input_node_ptr(arg_count - i - 1);
if (nodes_done.count(dep) == 0) {
can_add = false;
nodes_to_do.push(dep);
}
}
for (auto& depptr : node->get_control_dependencies()) {
Node* dep = depptr.get();
if (nodes_done.count(dep) == 0) {
can_add = false;
nodes_to_do.push(dep);
}
}
if (can_add) {
result.push_back(node->shared_from_this());
nodes_to_do.pop();
nodes_done.insert(node);
}
} else {
nodes_to_do.pop();
}
}
return result;
}
// input function is cloned and returned
// NodeMap input may contain default node mapping i.e. pre-cloned nodes
// NodeMap output (by reference) fully maps input and cloned function ops
OPENVINO_API
std::shared_ptr<ov::Function> clone_function(const ov::Function& func, NodeMap& node_map);
// input function is cloned and returned
OPENVINO_API
std::shared_ptr<ov::Function> clone_function(const ov::Function& func);
OPENVINO_API
bool compare_constants(const std::shared_ptr<Node>& n1, const std::shared_ptr<Node>& n2);
OPENVINO_API
bool replace_output_update_name(Output<Node> node, const Output<Node>& node_input);
OPENVINO_API
bool replace_node_update_name(const std::shared_ptr<Node>& target, const std::shared_ptr<Node>& replacement);
} // namespace ov
@@ -0,0 +1,117 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "openvino/core/coordinate_diff.hpp"
#include "openvino/core/node.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/util/attr_types.hpp"
namespace ov {
OPENVINO_API
PartialShape infer_convolution_forward(const Node* node,
const PartialShape& data_batch_shape,
const Strides& data_dilation,
const CoordinateDiff& data_padding_below,
const CoordinateDiff& data_padding_above,
const PartialShape& filters_shape,
const Strides& filter_strides,
const Strides& filter_dilation);
OPENVINO_API
void infer_auto_padding(const Shape& image_shape,
const Shape& filter_shape,
const Strides& filter_strides,
const Strides& filter_dilations,
const op::PadType pad_type,
CoordinateDiff& padding_above,
CoordinateDiff& padding_below);
/// \brief Handle out of range axis.
///
/// \param[in] node The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return Checking if axis is in range [-tensor_rank, tensor_rank-1], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
OPENVINO_API
int64_t normalize_axis(const Node* node, std::int64_t axis, const Rank& tensor_rank);
/// \brief Handle out of range axes in vector.
///
/// \param[in] node_description The name of node with requested axes.
/// \param[in] axes The requested vector of axes.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return If any negative axis in vector, it counts from the last to the first
/// axis, by adding tensor_rank to axis.
///
OPENVINO_API
std::vector<size_t> normalize_axes(const std::string& node_description,
const std::vector<int64_t>& axes,
const Rank& tensor_rank);
/// \brief Handle out of range axis.
///
/// \param[in] node_description The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
///
/// \return Checking if axis is in range [-tensor_rank, tensor_rank-1], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
OPENVINO_API
int64_t normalize_axis(const std::string& node_description, std::int64_t axis, const Rank& tensor_rank);
/// \brief Handle out of range axis.
///
/// \param[in] node The node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
/// \param[in] axis_range_min The min value of accepted range for axis.
/// \param[in] axis_range_max The max value of accepted range for axis.
///
/// \return Checking if axis is in range [axis_range_min, axis_range_max], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
OPENVINO_API
int64_t normalize_axis(const Node* node,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max);
/// \brief Handle out of range axis.
///
/// \param[in] node_description The name of node with requested axis.
/// \param[in] axis The requested axis value.
/// \param[in] tensor_rank The corresponding tensor rank.
/// \param[in] axis_range_min The min value of accepted range for axis.
/// \param[in] axis_range_max The max value of accepted range for axis.
///
/// \return Checking if axis is in range [axis_range_min, axis_range_max], otherwise
/// returns error. If negative axis, it counts from the last to the first axis,
/// by adding tensor_rank to axis.
OPENVINO_API
int64_t normalize_axis(const std::string& node_description,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max);
/// \brief Evaluates lower and upper value estimations for the output tensor. Estimation would
/// be represented as partial shape object using Dimension(min, max) for each element.
/// \param output Node output pointing to the tensor for estimation.
/// \param pshape Resulting estimation would be stored in this PartialShape.
/// \return boolean status if value evaluation was successful.
OPENVINO_API bool evaluate_as_partial_shape(const Output<Node>& output, PartialShape& pshape);
/// \brief Runs an estimation of source tensor. If it succeeded to calculate both bounds and
/// they are the same returns Constant operation from the resulting bound, otherwise nullptr.
OPENVINO_API std::shared_ptr<op::v0::Constant> get_constant_from_source(const Output<Node>& source);
} // namespace ov
+57 -55
View File
@@ -7,6 +7,7 @@
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "ngraph/descriptor/input.hpp"
@@ -33,30 +34,31 @@ using namespace ngraph;
NGRAPH_SUPPRESS_DEPRECATED_START
void ngraph::traverse_nodes(const std::shared_ptr<const Function> p, std::function<void(std::shared_ptr<Node>)> f) {
void ov::traverse_nodes(const std::shared_ptr<const Function>& p,
const std::function<void(const std::shared_ptr<Node>&)>& f) {
traverse_nodes(p.get(), f);
}
void ngraph::traverse_nodes(const Function* p, std::function<void(std::shared_ptr<Node>)> f) {
void ov::traverse_nodes(const Function* p, const std::function<void(const std::shared_ptr<Node>&)>& f) {
NodeVector nodes;
for (auto r : p->get_results()) {
for (const auto& r : p->get_results()) {
nodes.push_back(r);
}
for (auto s : p->get_sinks()) {
nodes.emplace_back(s);
}
for (auto param : p->get_parameters()) {
for (const auto& param : p->get_parameters()) {
nodes.push_back(param);
}
traverse_nodes(nodes, f);
}
void ngraph::traverse_nodes(const NodeVector& subgraph_results,
std::function<void(std::shared_ptr<Node>)> f,
const NodeVector& subgraph_params) {
void ov::traverse_nodes(const NodeVector& subgraph_results,
const std::function<void(const std::shared_ptr<Node>&)>& f,
const NodeVector& subgraph_params) {
std::unordered_set<Node*> instances_seen;
std::stack<Node*, std::vector<Node*>> stack;
for (auto& node_ptr : subgraph_params) {
@@ -85,19 +87,19 @@ void ngraph::traverse_nodes(const NodeVector& subgraph_results,
NodeVector ngraph::find_common_args(std::shared_ptr<Node> node1, std::shared_ptr<Node> node2) {
std::unordered_set<std::shared_ptr<Node>> node1_args;
auto compute_node1_args = [&node1_args](const std::shared_ptr<Node> node) {
auto compute_node1_args = [&node1_args](const std::shared_ptr<Node>& node) {
node1_args.insert(node);
};
traverse_nodes({node1}, compute_node1_args, NodeVector{});
traverse_nodes({std::move(node1)}, compute_node1_args, NodeVector{});
std::unordered_set<std::shared_ptr<Node>> node2_args;
auto compute_node2_args = [&node2_args](const std::shared_ptr<Node> node) {
auto compute_node2_args = [&node2_args](const std::shared_ptr<Node>& node) {
node2_args.insert(node);
};
traverse_nodes({node2}, compute_node2_args, NodeVector{});
traverse_nodes({std::move(node2)}, compute_node2_args, NodeVector{});
NodeVector common_args;
for (const auto& e : node1_args) {
@@ -109,9 +111,9 @@ NodeVector ngraph::find_common_args(std::shared_ptr<Node> node1, std::shared_ptr
return common_args;
}
void ngraph::replace_node(std::shared_ptr<Node> target,
std::shared_ptr<Node> replacement,
const std::vector<int64_t>& output_order) {
void ov::replace_node(const std::shared_ptr<Node>& target,
const std::shared_ptr<Node>& replacement,
const std::vector<int64_t>& output_order) {
if (ngraph::op::is_output(target)) {
throw ngraph_error("Result nodes cannot be replaced.");
}
@@ -130,8 +132,8 @@ void ngraph::replace_node(std::shared_ptr<Node> target,
std::set<string> removed_subgraph_tags;
auto set_replacement_prov = [&removed_subgraph_tags](std::shared_ptr<Node> node) {
for (auto tag : node->get_provenance_tags()) {
auto set_replacement_prov = [&removed_subgraph_tags](const std::shared_ptr<Node>& node) {
for (const auto& tag : node->get_provenance_tags()) {
removed_subgraph_tags.insert(tag);
}
};
@@ -139,7 +141,7 @@ void ngraph::replace_node(std::shared_ptr<Node> target,
traverse_nodes({target}, set_replacement_prov, common_args);
replacement->add_provenance_tags(removed_subgraph_tags);
auto set_prov_new_nodes = [&removed_subgraph_tags](std::shared_ptr<Node> node) {
auto set_prov_new_nodes = [&removed_subgraph_tags](const std::shared_ptr<Node>& node) {
node->add_provenance_tags(removed_subgraph_tags);
};
@@ -158,7 +160,7 @@ void ngraph::replace_node(std::shared_ptr<Node> target,
target->clear_control_dependents();
}
void ngraph::replace_node(const std::shared_ptr<Node>& target, const OutputVector& replacement_values) {
void ov::replace_node(const std::shared_ptr<Node>& target, const OutputVector& replacement_values) {
if (ngraph::op::is_output(target)) {
throw ngraph_error("Result nodes cannot be replaced.");
}
@@ -183,16 +185,16 @@ void ngraph::replace_node(const std::shared_ptr<Node>& target, const OutputVecto
target->clear_control_dependents();
}
void ngraph::replace_node(std::shared_ptr<Node> target, std::shared_ptr<Node> replacement) {
void ov::replace_node(const std::shared_ptr<Node>& target, const std::shared_ptr<Node>& replacement) {
auto default_output_order = vector<int64_t>(target->get_output_size());
std::iota(default_output_order.begin(), default_output_order.end(), 0);
replace_node(target, replacement, default_output_order);
}
void ngraph::replace_nodes(
const std::shared_ptr<Function>& f,
const unordered_map<shared_ptr<op::Parameter>, shared_ptr<op::Parameter>>& parameter_replacement_map,
const unordered_map<shared_ptr<Node>, shared_ptr<Node>>& body_replacement_map) {
void ov::replace_nodes(const std::shared_ptr<Function>& f,
const unordered_map<shared_ptr<ov::op::v0::Parameter>, shared_ptr<ov::op::v0::Parameter>>&
parameter_replacement_map,
const unordered_map<shared_ptr<Node>, shared_ptr<Node>>& body_replacement_map) {
auto& params = f->get_parameters();
for (size_t i = 0; i < params.size(); i++) {
@@ -239,7 +241,7 @@ std::vector<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector
NodeMap& node_map) {
// for each node in topological order
auto sorted_nodes = topological_sort(nodes);
for (auto node : sorted_nodes) {
for (const auto& node : sorted_nodes) {
if (node_map.count(node.get()) == 0) {
// get (already) cloned arguments and clone the node
OutputVector cloned_args;
@@ -267,7 +269,7 @@ std::vector<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector
new_output.get_rt_info() = output_rt_info;
}
for (auto tag : node->get_provenance_tags()) {
for (const auto& tag : node->get_provenance_tags()) {
cloned_node->add_provenance_tag(tag);
}
cloned_node->set_op_annotations(node->get_op_annotations());
@@ -279,7 +281,7 @@ std::vector<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector
// create and return vector of cloned nodes
// order matches input vector (not necessarily topological)
std::vector<std::shared_ptr<ngraph::Node>> cloned_nodes;
for (auto node : nodes) {
for (const auto& node : nodes) {
cloned_nodes.push_back(node_map.at(node.get()));
}
return cloned_nodes;
@@ -290,19 +292,19 @@ std::list<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector<s
// for each node in topological order
auto sorted_nodes = topological_sort(nodes);
std::list<shared_ptr<Node>> cloned_nodes;
for (auto node : sorted_nodes) {
for (const auto& node : sorted_nodes) {
auto node_outputs = node->outputs();
for (auto value : node_outputs) {
for (const auto& value : node_outputs) {
if (output_map.count(value) == 0) {
// We need this node cloned
// get (already) cloned arguments and clone the node
OutputVector cloned_args;
for (auto value : node->input_values()) {
for (const auto& value : node->input_values()) {
cloned_args.push_back(output_map.at(value));
}
NodeVector cloned_dependencies;
for (auto& dependency : node->get_control_dependencies()) {
for (auto dependency_value : dependency->outputs()) {
for (const auto& dependency_value : dependency->outputs()) {
shared_ptr<Node> dependent = output_map.at(dependency_value).get_node_shared_ptr();
if (find(cloned_dependencies.begin(), cloned_dependencies.end(), dependent) ==
cloned_dependencies.end()) {
@@ -317,11 +319,11 @@ std::list<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector<s
auto rt_info = node->get_rt_info();
cloned_node->get_rt_info() = rt_info;
for (auto tag : node->get_provenance_tags()) {
for (const auto& tag : node->get_provenance_tags()) {
cloned_node->add_provenance_tag(tag);
}
cloned_node->set_op_annotations(node->get_op_annotations());
for (auto cloned_value : cloned_node->outputs()) {
for (const auto& cloned_value : cloned_node->outputs()) {
auto original_value = node_outputs.at(cloned_value.get_index());
if (output_map.count(original_value) == 0) {
output_map[original_value] = cloned_value;
@@ -334,12 +336,12 @@ std::list<std::shared_ptr<ngraph::Node>> ngraph::clone_nodes(const std::vector<s
return cloned_nodes;
}
std::shared_ptr<ngraph::Function> ngraph::clone_function(const ngraph::Function& func) {
std::shared_ptr<ngraph::Function> ov::clone_function(const ngraph::Function& func) {
NodeMap nm;
return clone_function(func, nm);
}
std::shared_ptr<ngraph::Function> ngraph::clone_function(const ngraph::Function& func, NodeMap& node_map) {
std::shared_ptr<ngraph::Function> ov::clone_function(const ngraph::Function& func, NodeMap& node_map) {
// clone function operations
clone_nodes(func.get_ops(), node_map);
@@ -365,7 +367,7 @@ std::shared_ptr<ngraph::Function> ngraph::clone_function(const ngraph::Function&
// get cloned function results and sinks and parameters
ResultVector cloned_results;
for (shared_ptr<Node> node : func.get_results()) {
auto result = ov::as_type_ptr<op::Result>(node_map.at(node.get()));
auto result = ov::as_type_ptr<op::v0::Result>(node_map.at(node.get()));
if (!result) {
throw ngraph_error("Results should be of type op::Result");
}
@@ -376,9 +378,9 @@ std::shared_ptr<ngraph::Function> ngraph::clone_function(const ngraph::Function&
cloned_sinks.push_back(static_pointer_cast<op::Sink>(node_map.at(node.get())));
}
std::vector<std::shared_ptr<op::Parameter>> cloned_params;
std::vector<std::shared_ptr<op::v0::Parameter>> cloned_params;
for (const auto& param : func.get_parameters()) {
cloned_params.push_back(ov::as_type_ptr<op::Parameter>(node_map.at(param.get())));
cloned_params.push_back(ov::as_type_ptr<op::v0::Parameter>(node_map.at(param.get())));
}
// create and return cloned function
@@ -543,7 +545,7 @@ NodeVector ngraph::get_subgraph_outputs(const NodeVector& nodes,
NodeVector outputs;
for (auto n : nodes) {
for (const auto& n : nodes) {
if (exclusions_set.count(n) != 0) {
continue;
}
@@ -564,7 +566,7 @@ NodeVector ngraph::extract_subgraph(const NodeVector& results, const NodeVector&
NodeVector subgraph;
traverse_nodes(
results,
[&](std::shared_ptr<Node> n) {
[&](const std::shared_ptr<Node>& n) {
subgraph.push_back(n);
},
args);
@@ -636,13 +638,13 @@ bool ngraph::is_valid_rank(const std::shared_ptr<Node>& node, std::vector<size_t
return false;
}
bool ngraph::compare_constants(const std::shared_ptr<Node>& n1, const std::shared_ptr<Node>& n2) {
if (!(op::is_constant(n1) && op::is_constant(n2))) {
bool ov::compare_constants(const std::shared_ptr<Node>& n1, const std::shared_ptr<Node>& n2) {
if (!(op::util::is_constant(n1) && op::util::is_constant(n2))) {
return false;
}
if (static_pointer_cast<op::Constant>(n1)->get_value_strings() !=
static_pointer_cast<op::Constant>(n2)->get_value_strings()) {
if (static_pointer_cast<op::v0::Constant>(n1)->get_value_strings() !=
static_pointer_cast<op::v0::Constant>(n2)->get_value_strings()) {
return false;
}
@@ -654,7 +656,7 @@ void ngraph::plot_graph(std::shared_ptr<Function> f,
std::function<void(const Node& node, std::vector<std::string>& attributes)> attributes) {
ngraph::pass::Manager pass_manager;
pass_manager.register_pass<ngraph::pass::VisualizeTree>(filename, attributes);
pass_manager.run_passes(f);
pass_manager.run_passes(std::move(f));
}
std::vector<Input<Node>> ngraph::get_inputs_from(Node& src, Node& dst) {
@@ -690,7 +692,7 @@ std::vector<Output<Node>> ngraph::get_outputs_to(Node& src, Node& dst) {
return result;
}
static bool check_for_cycles_bkwd(std::shared_ptr<ngraph::Node> node,
static bool check_for_cycles_bkwd(const std::shared_ptr<ngraph::Node>& node,
std::deque<std::shared_ptr<ngraph::Node>>& path,
std::unordered_set<std::shared_ptr<ngraph::Node>>& path_set,
ngraph::NodeVector& cycle_nodes) {
@@ -699,7 +701,7 @@ static bool check_for_cycles_bkwd(std::shared_ptr<ngraph::Node> node,
for (size_t i = 0; i < node->inputs().size(); i++) {
auto arg = node->get_input_node_shared_ptr(i);
if (path_set.find(arg) != path_set.end()) {
for (auto it : path) {
for (const auto& it : path) {
cycle_nodes.push_back(it);
}
// last node
@@ -715,7 +717,7 @@ static bool check_for_cycles_bkwd(std::shared_ptr<ngraph::Node> node,
return false;
}
static bool check_for_cycles_fwd(std::shared_ptr<ngraph::Node> node,
static bool check_for_cycles_fwd(const std::shared_ptr<ngraph::Node>& node,
std::deque<std::shared_ptr<ngraph::Node>>& path,
std::unordered_set<std::shared_ptr<ngraph::Node>>& path_set,
ngraph::NodeVector& cycle_nodes) {
@@ -723,7 +725,7 @@ static bool check_for_cycles_fwd(std::shared_ptr<ngraph::Node> node,
path_set.insert(node);
for (auto& arg : node->get_users()) {
if (path_set.find(arg) != path_set.end()) {
for (auto it : path) {
for (const auto& it : path) {
cycle_nodes.push_back(it);
}
// last node
@@ -740,7 +742,7 @@ static bool check_for_cycles_fwd(std::shared_ptr<ngraph::Node> node,
}
bool ngraph::check_for_cycles(const ngraph::Function* func, ngraph::NodeVector& cycle_nodes, bool& is_bkwd_cycle) {
for (auto res : func->get_results()) {
for (const auto& res : func->get_results()) {
std::deque<std::shared_ptr<Node>> path;
// mirror of path stack for faster cycle check
std::unordered_set<std::shared_ptr<Node>> path_set;
@@ -750,7 +752,7 @@ bool ngraph::check_for_cycles(const ngraph::Function* func, ngraph::NodeVector&
}
}
for (auto res : func->get_sinks()) {
for (const auto& res : func->get_sinks()) {
std::deque<std::shared_ptr<Node>> path;
// mirror of path stack for faster cycle check
std::unordered_set<std::shared_ptr<Node>> path_set;
@@ -760,7 +762,7 @@ bool ngraph::check_for_cycles(const ngraph::Function* func, ngraph::NodeVector&
}
}
for (auto param : func->get_parameters()) {
for (const auto& param : func->get_parameters()) {
std::deque<std::shared_ptr<Node>> path;
// mirror of path stack for faster cycle check
std::unordered_set<std::shared_ptr<Node>> path_set;
@@ -773,10 +775,10 @@ bool ngraph::check_for_cycles(const ngraph::Function* func, ngraph::NodeVector&
return false;
}
bool ngraph::replace_output_update_name(Output<Node> output, const Output<Node>& replacement) {
bool ov::replace_output_update_name(Output<Node> output, const Output<Node>& replacement) {
bool has_result_output = false;
for (auto& target_input : output.get_target_inputs()) {
if (ov::is_type<op::Result>(target_input.get_node())) {
if (ov::is_type<op::v0::Result>(target_input.get_node())) {
// ignore trivial elimination
has_result_output = true;
if (ov::is_type<ngraph::op::Parameter>(replacement.get_node())) {
@@ -807,10 +809,10 @@ bool ngraph::replace_output_update_name(Output<Node> output, const Output<Node>&
return false;
}
bool ngraph::replace_node_update_name(std::shared_ptr<Node> target, std::shared_ptr<Node> replacement) {
bool ov::replace_node_update_name(const std::shared_ptr<Node>& target, const std::shared_ptr<Node>& replacement) {
for (auto& output : target->output(0).get_target_inputs()) {
if (ov::as_type<ngraph::op::Parameter>(replacement->input_value(0).get_node()) &&
ov::as_type<op::Result>(output.get_node())) {
ov::as_type<op::v0::Result>(output.get_node())) {
return false;
}
}
+41 -41
View File
@@ -297,14 +297,14 @@ PartialShape ngraph::validate_and_infer_convolution_forward_output_shape(const N
//
// Infers the output batch shape and element type for convolution fprop.
//
PartialShape ngraph::infer_convolution_forward(const Node* node,
const PartialShape& data_batch_shape,
const Strides& data_dilation,
const CoordinateDiff& data_padding_below,
const CoordinateDiff& data_padding_above,
const PartialShape& filters_shape,
const Strides& filter_strides,
const Strides& filter_dilation) {
PartialShape ov::infer_convolution_forward(const Node* node,
const PartialShape& data_batch_shape,
const Strides& data_dilation,
const CoordinateDiff& data_padding_below,
const CoordinateDiff& data_padding_above,
const PartialShape& filters_shape,
const Strides& filter_strides,
const Strides& filter_dilation) {
Rank data_batch_filters_rank{Rank::dynamic()};
NODE_VALIDATION_CHECK(node,
@@ -643,13 +643,13 @@ std::tuple<element::Type, PartialShape, PartialShape> ngraph::infer_batch_norm_f
{{gamma_element_type, gamma_shape, "gamma"}, {beta_element_type, beta_shape, "beta"}});
}
void ngraph::infer_auto_padding(const Shape& image_shape,
const Shape& filter_shape,
const Strides& filter_strides,
const Strides& filter_dilations,
const op::PadType pad_type,
CoordinateDiff& padding_above,
CoordinateDiff& padding_below) {
void ov::infer_auto_padding(const Shape& image_shape,
const Shape& filter_shape,
const Strides& filter_strides,
const Strides& filter_dilations,
const op::PadType pad_type,
CoordinateDiff& padding_above,
CoordinateDiff& padding_below) {
const auto image_dims = std::vector<Dimension>(std::begin(image_shape), std::end(image_shape));
// because image_shape is fully known result of try_apply_infer_auto_padding is ignored
try_apply_auto_padding(image_dims,
@@ -676,9 +676,9 @@ bool ngraph::try_apply_auto_padding(const PartialShape& image_shape,
const auto image_dims = static_cast<std::vector<Dimension>>(image_shape);
for (size_t i = 0; i < static_cast<size_t>(filter_shape.size()); i++) {
if (image_dims[i + 2].is_static()) {
int64_t image_size = static_cast<int64_t>(image_dims[i + 2].get_length());
auto image_size = static_cast<int64_t>(image_dims[i + 2].get_length());
int64_t filter_size = (static_cast<int64_t>(filter_shape[i]) - 1) * filter_dilations[i] + 1;
int64_t filter_stride = static_cast<int64_t>(filter_strides[i]);
auto filter_stride = static_cast<int64_t>(filter_strides[i]);
auto output_size = (image_size + filter_stride - 1) / filter_stride;
auto padding_needed = std::max(int64_t(0), (output_size - 1) * filter_stride + filter_size - image_size);
@@ -847,9 +847,9 @@ PartialShape ngraph::infer_slice_shape(const Node* node,
return dim;
}
std::vector<size_t> ngraph::normalize_axes(const std::string& node_description,
const std::vector<int64_t>& axes,
const Rank& tensor_rank) {
std::vector<size_t> ov::normalize_axes(const std::string& node_description,
const std::vector<int64_t>& axes,
const Rank& tensor_rank) {
std::vector<size_t> new_axes;
for (const auto& axis : axes) {
@@ -859,11 +859,11 @@ std::vector<size_t> ngraph::normalize_axes(const std::string& node_description,
return new_axes;
}
int64_t ngraph::normalize_axis(const Node* node, std::int64_t axis, const Rank& tensor_rank) {
int64_t ov::normalize_axis(const Node* node, std::int64_t axis, const Rank& tensor_rank) {
return normalize_axis(node->description(), axis, tensor_rank);
}
int64_t ngraph::normalize_axis(const std::string& node_description, std::int64_t axis, const Rank& tensor_rank) {
int64_t ov::normalize_axis(const std::string& node_description, std::int64_t axis, const Rank& tensor_rank) {
if (axis < 0) {
// Handling negative axis requires static tensor rank
NGRAPH_CHECK(tensor_rank.is_static(),
@@ -883,19 +883,19 @@ int64_t ngraph::normalize_axis(const std::string& node_description, std::int64_t
tensor_rank_value ? (tensor_rank_value - 1) : 0);
}
int64_t ngraph::normalize_axis(const Node* node,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max) {
int64_t ov::normalize_axis(const Node* node,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max) {
return ngraph::normalize_axis(node->description(), axis, tensor_rank, axis_range_min, axis_range_max);
}
int64_t ngraph::normalize_axis(const std::string& node_description,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max) {
int64_t ov::normalize_axis(const std::string& node_description,
std::int64_t axis,
std::uint64_t tensor_rank,
std::int64_t axis_range_min,
std::int64_t axis_range_max) {
// Accepted range of value for axis is [axis_range_min, axis_range_max].
NGRAPH_CHECK(((axis >= axis_range_min) && (axis <= axis_range_max)),
node_description,
@@ -954,7 +954,7 @@ namespace {
/// For tensor values, we use the maximum value in the tensor
struct MaxValue {
/// \brief No information known about the output
MaxValue() {}
MaxValue() = default;
/// \brief uint64_t assoiated with the output
MaxValue(uint64_t value) : m_value(value) {}
MaxValue(const vector<uint64_t>& slices, int64_t slice_axis) : m_slices(slices), m_slice_axis(slice_axis) {
@@ -1027,7 +1027,7 @@ vector<MaxValue> exec_minimum(Node* node, vector<MaxValue>& inputs) {
vector<MaxValue> exec_concat(Node* node, vector<MaxValue>& inputs) {
auto op = ov::as_type<op::v0::Concat>(node);
vector<uint64_t> slice_maxen;
for (auto input : inputs) {
for (const auto& input : inputs) {
slice_maxen.push_back(input.m_value);
}
auto axis = op->get_concatenation_axis();
@@ -1039,7 +1039,7 @@ vector<MaxValue> exec_reduce_min(Node* node, vector<MaxValue>& inputs) {
if (data.m_slice_axis >= 0 && data.m_slices.size() > 1) {
if (auto indices_const = ov::as_type<op::v0::Constant>(node->get_input_node_ptr(1))) {
if (indices_const->get_output_element_type(0).is_integral()) {
auto indices_shape = indices_const->get_output_shape(0);
const auto& indices_shape = indices_const->get_output_shape(0);
if (indices_shape == Shape{1}) {
auto indices = indices_const->cast_vector<int64_t>();
auto axis = indices.at(0);
@@ -1254,13 +1254,13 @@ pair<HostTensorPtr, HostTensorPtr> ngraph::evaluate_both_bounds(const Output<Nod
return {evaluate_lower_bound(output), evaluate_upper_bound(output)};
}
bool ngraph::evaluate_as_partial_shape(const Output<Node>& output, PartialShape& pshape) {
bool ov::evaluate_as_partial_shape(const Output<Node>& output, PartialShape& pshape) {
HostTensorPtr lb, ub;
std::tie(lb, ub) = evaluate_both_bounds(output);
bool shape_defined = false;
if (lb && ub) {
const auto lower_bound = std::make_shared<op::Constant>(lb)->cast_vector<int64_t>();
const auto upper_bound = std::make_shared<op::Constant>(ub)->cast_vector<int64_t>();
const auto lower_bound = std::make_shared<op::v0::Constant>(lb)->cast_vector<int64_t>();
const auto upper_bound = std::make_shared<op::v0::Constant>(ub)->cast_vector<int64_t>();
NGRAPH_CHECK(lower_bound.size() == upper_bound.size());
vector<Dimension> resulting_pshape(lower_bound.size());
for (size_t i = 0; i < lower_bound.size(); ++i) {
@@ -1497,12 +1497,12 @@ bool ngraph::has_and_set_equal_bounds(const Output<Node>& source) {
return lb && lb == ub;
}
shared_ptr<op::Constant> ngraph::get_constant_from_source(const Output<Node>& source) {
shared_ptr<op::Constant> ov::get_constant_from_source(const Output<Node>& source) {
if (!has_and_set_equal_bounds(source))
return nullptr;
if (const auto& c = ov::as_type_ptr<op::Constant>(source.get_node_shared_ptr()))
if (const auto& c = ov::as_type_ptr<op::v0::Constant>(source.get_node_shared_ptr()))
return c;
return std::make_shared<op::Constant>(source.get_tensor().get_upper_value());
return std::make_shared<op::v0::Constant>(source.get_tensor().get_upper_value());
}
bool ngraph::validate_host_tensor_vector(const HostTensorVector& tensor_vector, const size_t& size) {