Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
a-sidorova committed May 10, 2023
1 parent eac7afa commit af947cb
Show file tree
Hide file tree
Showing 46 changed files with 240 additions and 332 deletions.
4 changes: 1 addition & 3 deletions src/common/snippets/include/snippets/lowered/expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Expression : public std::enable_shared_from_this<Expression> {
void set_loop_id(size_t id, size_t idx);
void remove_loop_id(size_t id);

void validate() const;
void init_emitter(const std::shared_ptr<const TargetMachine>& target);

ExpressionPort get_input_port(size_t i);
Expand All @@ -57,10 +58,7 @@ class Expression : public std::enable_shared_from_this<Expression> {
// Note: The constructor and tensor initialization are private since an expression can be created only by Linear IR.
// These methods must be used only by Linear IR builder of expressions!
explicit Expression(const std::shared_ptr<Node>& n);
void init_inputs(const std::vector<TensorPtr>& inputs) { m_input_tensors = inputs; }
void init_outputs(const std::vector<TensorPtr>& outputs) { m_output_tensors = outputs; }

// Note: These methods don't control availability of the current expression in this Tensor (as Consumer or Source)
void replace_input(size_t port, TensorPtr to);

std::shared_ptr<Node> m_source_node{nullptr};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,14 @@ class LinearIR::ExpressionFactory {
const std::shared_ptr<ov::Model>& model);

/* -- Input Builders - get input tensors from method parameters and create new output tensors themselves */
static ExpressionPtr create(const std::shared_ptr<op::LoopBegin>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs);
static ExpressionPtr create(const std::shared_ptr<op::LoopEnd>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs);
static ExpressionPtr create(const std::shared_ptr<ov::Node>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs);
static ExpressionPtr create(const std::shared_ptr<op::LoopBegin>& n, const std::vector<TensorPtr>& inputs);
static ExpressionPtr create(const std::shared_ptr<op::LoopEnd>& n, const std::vector<TensorPtr>& inputs);
static ExpressionPtr create(const std::shared_ptr<ov::Node>& n, const std::vector<TensorPtr>& inputs);

// Creates inputs for expression using parent output tensors
static void create_expression_inputs(const LinearIR& linear_ir, const ExpressionPtr& expr);
// Creates new output tensors
static void create_expression_outputs(const LinearIR& linear_ir, const ExpressionPtr& expr);
static void create_expression_outputs(const ExpressionPtr& expr);
// The method verifies of input tensors to availability of the expression as consumer and add it if missed
static void init_expression_inputs(const ExpressionPtr& expr, const std::vector<TensorPtr>& inputs);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ class ExpressionPort {
Type get_type() const { return m_type; }
size_t get_index() const { return m_port_index; }

std::vector<size_t> get_tensor() const;
std::vector<size_t> get_shape() const;
std::vector<size_t> get_layout() const;
std::vector<size_t> get_subtensor() const;
PortDescriptorPtr get_port_descriptor() const;
const std::shared_ptr<Tensor>& get_tensor_ptr() const;
// Returns connected ports to the current:
// - Input port returns one source (parent) port
// - Output port returns all consumer ports (children)
std::set<ExpressionPort> get_connected_ports() const;

void set_tensor(const std::vector<size_t>& tensor);
void set_shape(const std::vector<size_t>& tensor);
void set_layout(const std::vector<size_t>& layout);
void set_subtensor(const std::vector<size_t>& subtensor);

Expand Down
7 changes: 2 additions & 5 deletions src/common/snippets/include/snippets/lowered/linear_ir.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LinearIR {
LinearIR() = default;
explicit LinearIR(const std::shared_ptr<ov::Model>& m, Config config = {});

ExpressionPtr create_expression(const std::shared_ptr<Node>& n, const std::vector<TensorPtr> inputs);
ExpressionPtr create_expression(const std::shared_ptr<Node>& n, const std::vector<TensorPtr>& inputs);

LinearIR deep_copy() const;
static LinearIR::container deep_copy_range(LinearIR::container::const_iterator begin, LinearIR::container::const_iterator end);
Expand All @@ -46,7 +46,6 @@ class LinearIR {

void replace_input(std::set<ExpressionPort> consumers, const TensorPtr& to);
void replace_input(const ExpressionPort& expr_port, const TensorPtr& to);
void replace_input(const ExpressionPtr& expr, size_t port, const TensorPtr& to);

/**
* @brief Move an expression from the position "from" to the position immediately before "to".
Expand Down Expand Up @@ -98,9 +97,7 @@ class LinearIR {
// Default ctor - can be called only from Linear IR initialization as default way
ExpressionPtr create_expression(const std::shared_ptr<Node>& n, const std::shared_ptr<ov::Model>& model = nullptr);

void register_expression(const ExpressionPtr& expr);
// Like register_expression, but doesn't allow Parameter or Result registration. You can do it only through ctor
void register_regular_expression(const ExpressionPtr& expr);
void register_expression(const ExpressionPtr& expr, bool io_allowed = false);
void unregister_expression(const ExpressionPtr& expr);

container m_lowered_ops{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ class FuseLoops : public Transformation {
private:
static bool can_be_fused(const LinearIR::LoopManager::LoopInfoPtr& loop_current,
const LinearIR::LoopManager::LoopInfoPtr& loop_target);
static bool fuse_upper_into_current(LinearIR& linear_ir, const LinearIR::LoopManagerPtr& loop_manager,
const ExpressionPort& current_entry_point, const ExpressionPort& target_exit_point,
static bool fuse_upper_into_current(LinearIR& linear_ir, const LinearIR::LoopManagerPtr& loop_manager, const ExpressionPort& current_entry_point,
size_t current_loop_id, size_t target_loop_id, size_t dim_idx,
LinearIR::constExprIt& current_loop_begin_pos, LinearIR::constExprIt& current_loop_end_pos);
static bool fuse_lower_into_current(LinearIR& linear_ir, const LinearIR::LoopManagerPtr& loop_manager,
const ExpressionPort& current_entry_point, const ExpressionPort& target_exit_point,
static bool fuse_lower_into_current(LinearIR& linear_ir, const LinearIR::LoopManagerPtr& loop_manager, const ExpressionPort& current_entry_point,
size_t current_loop_id, size_t target_loop_id, size_t dim_idx,
LinearIR::constExprIt& current_loop_begin_pos, LinearIR::constExprIt& current_loop_end_pos);
static void fuse_points(std::vector<ExpressionPort>& exit_points, std::vector<ExpressionPort>& entry_points,
Expand Down
4 changes: 2 additions & 2 deletions src/common/snippets/include/snippets/lowered/tensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Expression;
class Tensor {
public:
Tensor() = default;
explicit Tensor(const ExpressionPort& source_descriptor, const std::set<ExpressionPort>& consumer_descriptors = {});
explicit Tensor(ExpressionPort source_descriptor, const std::set<ExpressionPort>& consumer_descriptors = {});

const ExpressionPort& get_source() const { return m_source_port; }
std::set<ExpressionPort> get_consumers() const { return m_consumer_ports; }
Expand All @@ -33,7 +33,7 @@ class Tensor {
std::set<ExpressionPort>::iterator find_consumer(const ExpressionPort& consumer);

// The scheduling params of Tensor is controlled by source expression port
std::vector<size_t> get_tensor() const { return m_source_port.get_tensor(); }
std::vector<size_t> get_shape() const { return m_source_port.get_shape(); }
std::vector<size_t> get_layout() const { return m_source_port.get_layout(); }
std::vector<size_t> get_subtensor() const { return m_source_port.get_subtensor(); }

Expand Down
2 changes: 1 addition & 1 deletion src/common/snippets/include/snippets/op/brgemm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Brgemm : public MemoryAccess {
bool has_evaluate() const override { return false; }

protected:
void constructor_validate_and_infer_types();
void custom_constructor_validate_and_infer_types();
void validate_inputs() const;

ov::element::Type get_output_type() const;
Expand Down
2 changes: 1 addition & 1 deletion src/common/snippets/include/snippets/op/subgraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static inline auto build_subgraph(const std::shared_ptr<ngraph::Node>& node, con
return subgraph;
};

// Need to update tensor name manually, since intel_cpu::Graph::Replicate() looks at input.get_tensor().get_name();
// Need to update tensor name manually, since intel_cpu::Graph::Replicate() looks at input.get_shape().get_name();
// If subgraph->get_output_size() == 1, then the name will be restored correctly from the node name
auto inline update_out_tensor_name(const std::shared_ptr<ngraph::snippets::op::Subgraph>& subgraph) -> void {
bool not_set = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ namespace snippets {
namespace pass {

/**
* @interface ScheduleSoftmax
* @brief The pass updates port descriptors for Softmax to show by which axes there is reducing
* @interface SetSoftmaxPorts
* @brief The pass updates port descriptors in accordance with the Softmax reduction axis
* @ingroup snippets
*/
class ScheduleSoftmax: public ngraph::pass::MatcherPass {
class SetSoftmaxPorts: public ngraph::pass::MatcherPass {
public:
ScheduleSoftmax();
SetSoftmaxPorts();
};

} // namespace pass
Expand Down
14 changes: 6 additions & 8 deletions src/common/snippets/include/snippets/port_descriptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
namespace ngraph {
namespace snippets {

class PortDescriptor;
using PortDescriptorPtr = std::shared_ptr<PortDescriptor>;
class PortDescriptor {
public:
// The structure with service values for scheduling parameters
Expand All @@ -34,17 +36,17 @@ class PortDescriptor {
PortDescriptor(std::vector<size_t> shape, std::vector<size_t> subtensor_shape, std::vector<size_t> layout = {});
PortDescriptor() = default;

std::vector<size_t> get_tensor() const {return m_tensor_shape;}
std::vector<size_t> get_shape() const {return m_tensor_shape;}
std::vector<size_t> get_subtensor() const {return m_subtensor_shape;}
std::vector<size_t> get_layout() const {return m_layout;}

void set_tensor(const std::vector<size_t>& tensor) { m_tensor_shape = tensor; }
void set_shape(const std::vector<size_t>& tensor) { m_tensor_shape = tensor; }
void set_layout(const std::vector<size_t>& layout) { m_layout = layout; }
void set_subtensor(const std::vector<size_t>& subtensor) { m_subtensor_shape = subtensor; }

static PortDescriptor deserialize(const std::string& serialized_info);
std::string serialize() const;
bool empty() const { return m_layout.empty() && m_subtensor_shape.empty();}
PortDescriptorPtr clone() const;

friend bool operator==(const PortDescriptor& lhs, const PortDescriptor& rhs);
friend bool operator!=(const PortDescriptor& lhs, const PortDescriptor& rhs) {return !(lhs == rhs);}
Expand All @@ -58,7 +60,6 @@ class PortDescriptor {
/// \brief Minimal tensor size that could be processed in one call
std::vector<size_t> m_subtensor_shape{};
};
using PortDescriptorPtr = std::shared_ptr<PortDescriptor>;

class PortManager {
public:
Expand All @@ -76,15 +77,12 @@ class PortManager {

class PortDescriptorVectorAttribute : public ov::RuntimeAttribute {
public:
OPENVINO_RTTI("PortDescriptorVectorAttribute", "0");
OPENVINO_RTTI("PortDescriptorVectorAttribute", "", ov::RuntimeAttribute);

PortDescriptorVectorAttribute() = default;
explicit PortDescriptorVectorAttribute(std::vector<PortDescriptorPtr> in_descs = {}, std::vector<PortDescriptorPtr> out_descs = {})
: inputs(std::move(in_descs)), outputs(std::move(out_descs)) {}

void set_input_port_descriptor(const PortDescriptorPtr& desc, size_t index);
void set_output_port_descriptor(const PortDescriptorPtr& desc, size_t index);

std::vector<PortDescriptorPtr> inputs{};
std::vector<PortDescriptorPtr> outputs{};
};
Expand Down
3 changes: 0 additions & 3 deletions src/common/snippets/include/snippets/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ inline auto is_scalar_constant(const std::shared_ptr<ngraph::Node>& source_outpu
ov::PartialShape get_port_planar_shape(const Input<Node>& out);
ov::PartialShape get_port_planar_shape(const Output<Node>& out);
ov::PartialShape get_reordered_planar_shape(const ov::PartialShape& shape, const std::vector<size_t>& layout);
ov::Shape get_reordered_shape(const ov::Shape& shape, const std::vector<size_t>& layout);
std::vector<size_t> get_node_output_layout(const std::shared_ptr<Node>& node);
std::vector<size_t> get_node_output_layout(const Node* node);

inline auto normalize_rank(int32_t allocation_rank, const size_t shape_rank) -> int32_t {
return allocation_rank < 0 ? allocation_rank + static_cast<int32_t>(shape_rank) + 1 : allocation_rank;
Expand Down
6 changes: 6 additions & 0 deletions src/common/snippets/src/lowered/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ void Expression::init_emitter(const std::shared_ptr<const TargetMachine>& target
m_emitter = target->get(m_source_node->get_type_info())(m_source_node);
}

void Expression::validate() const {
OPENVINO_ASSERT(m_input_port_descriptors.size() == m_input_tensors.size(), "The count of input ports and input tensors must be equal");
OPENVINO_ASSERT(m_output_port_descriptors.size() == m_output_tensors.size(), "The count of output ports and output tensors must be equal");
OPENVINO_ASSERT(m_source_node != nullptr, "The expression has null source node");
}

void Expression::replace_input(size_t port, TensorPtr to) {
OPENVINO_ASSERT(port < m_input_tensors.size(), "Failed to replace: target input port must be less than input count!");
m_input_tensors[port] = std::move(to);
Expand Down
53 changes: 31 additions & 22 deletions src/common/snippets/src/lowered/expression_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void LinearIR::ExpressionFactory::create_expression_inputs(const LinearIR& linea
}
}

void LinearIR::ExpressionFactory::create_expression_outputs(const LinearIR& linear_ir, const ExpressionPtr& expr) {
void LinearIR::ExpressionFactory::create_expression_outputs(const ExpressionPtr& expr) {
OPENVINO_ASSERT(expr != nullptr, "Failed expression outputs creation: expression is null");
const auto& node = expr->get_node();

Expand Down Expand Up @@ -57,59 +57,68 @@ ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<ngraph::
const LinearIR& linear_ir, const std::shared_ptr<ov::Model>& model) {
// Note: ctor of shared_ptr isn't friend class for Expression -> we cannot use directly make_shared<Expression>(args)
OPENVINO_ASSERT(model != nullptr, "To create IOExpression from Parameter there must be inited model!");
const auto expr = std::make_shared<IOExpression>(IOExpression(par, model->get_parameter_index(par)));
create_expression_outputs(linear_ir, expr);
auto expr = std::make_shared<IOExpression>(IOExpression(par, model->get_parameter_index(par)));
create_expression_outputs(expr);
expr->validate();
return expr;
}

ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<ngraph::op::v0::Result>& res,
const LinearIR& linear_ir, const std::shared_ptr<ov::Model>& model) {
// Note: ctor of shared_ptr isn't friend class for Expression -> we cannot use directly make_shared<Expression>(args)
OPENVINO_ASSERT(model != nullptr, "To create IOExpression from Result there must be inited model!");
const auto expr = std::make_shared<IOExpression>(IOExpression(res, model->get_result_index(res)));
auto expr = std::make_shared<IOExpression>(IOExpression(res, model->get_result_index(res)));
create_expression_inputs(linear_ir, expr);
// The Result node don't need output port (because of sense of the node). But each node in ngraph must have one output at least.
// The port descriptors are automatically created in constructor. We manually clean output ports.
expr->m_output_port_descriptors.clear();
expr->validate();
return expr;
}

ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<ov::Node>& n, const LinearIR& linear_ir,
const std::shared_ptr<ov::Model>& model) {
OPENVINO_ASSERT(!ov::is_type<op::LoopBase>(n), "Default expression builder doesn't support LoopBegin and LoopEnd");
// Note: ctor of shared_ptr isn't friend class for Expression
const auto expr = std::make_shared<Expression>(Expression(n));
auto expr = std::make_shared<Expression>(Expression(n));
create_expression_inputs(linear_ir, expr);
create_expression_outputs(linear_ir, expr);
create_expression_outputs(expr);
expr->validate();
return expr;
}

ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<op::LoopBegin>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs) {
ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<op::LoopBegin>& n, const std::vector<TensorPtr>& inputs) {
OPENVINO_ASSERT(inputs.empty(), "LoopBegin cannot have inputs");
const auto expr = std::make_shared<Expression>(Expression(n));
auto expr = std::make_shared<Expression>(Expression(n));
init_expression_inputs(expr, inputs);
create_expression_outputs(linear_ir, expr);
create_expression_outputs(expr);
expr->validate();
return expr;
}

ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<op::LoopEnd>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs) {
const auto expr = std::make_shared<Expression>(Expression(n));
// Copy port descriptor shared pointers to LoopEnd
expr->m_input_port_descriptors.resize(inputs.size());
for (size_t i = 0; i < inputs.size(); ++i) {
expr->m_input_port_descriptors[i] = inputs[i]->get_source().get_port_descriptor();
}
ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<op::LoopEnd>& n, const std::vector<TensorPtr>& inputs) {
auto expr = std::make_shared<Expression>(Expression(n));
// LoopEnd doesn't have port descriptors on inputs (except input from LoopBegin)
expr->m_input_port_descriptors.resize(inputs.size(), nullptr);
const auto& last_input = inputs.back()->get_source();
OPENVINO_ASSERT(ov::is_type<op::LoopBegin>(last_input.get_expr()->get_node()), "LoopEnd expression expects LoopBegin on last input");
expr->m_input_port_descriptors[inputs.size() - 1] = last_input.get_port_descriptor()->clone();
init_expression_inputs(expr, inputs);
// The LoopEnd node don't need output port (because of sense of the node). But each node in ngraph must have one output at least.
// The port descriptors are automatically created in constructor. We manually clean output ports.
expr->m_output_port_descriptors.clear();
expr->validate();
return expr;
}

ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<ov::Node>& n, const LinearIR& linear_ir,
const std::vector<TensorPtr>& inputs) {
ExpressionPtr LinearIR::ExpressionFactory::create(const std::shared_ptr<ov::Node>& n, const std::vector<TensorPtr>& inputs) {
OPENVINO_ASSERT(!ov::is_type<ngraph::op::v0::Parameter>(n) &&
!ov::is_type<ngraph::op::v0::Result>(n),
"Expression builder with inputs doesn't support Result and Parameter");
const auto expr = std::make_shared<Expression>(Expression(n));
auto expr = std::make_shared<Expression>(Expression(n));
init_expression_inputs(expr, inputs);
create_expression_outputs(linear_ir, expr);
create_expression_outputs(expr);
expr->validate();
return expr;
}
}// namespace lowered
Expand Down
Loading

0 comments on commit af947cb

Please sign in to comment.