diff --git a/src/common/snippets/include/snippets/pass/assign_registers_old.hpp b/src/common/snippets/include/snippets/pass/assign_registers_old.hpp deleted file mode 100644 index 8be9329138626a..00000000000000 --- a/src/common/snippets/include/snippets/pass/assign_registers_old.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2018-2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#pragma once - -#include - -namespace ngraph { -namespace snippets { -namespace pass { - -/** - * @interface AssignRegisters - * @brief Assigns internal `vector` register indexes to operations. - * Changing order of variables or datafrow lead to invalidation of register assignment. - * @ingroup snippets - */ -class AssignRegistersOld : public ngraph::pass::FunctionPass { -public: - explicit AssignRegistersOld() { - set_property(ngraph::pass::PassProperty::REQUIRE_STATIC_SHAPE, true); - } - bool run_on_model(const std::shared_ptr& m) override; -}; - -} // namespace pass -} // namespace snippets -} // namespace ngraph diff --git a/src/common/snippets/src/op/subgraph.cpp b/src/common/snippets/src/op/subgraph.cpp index 3d12fe0275125f..178a1e97d555ed 100644 --- a/src/common/snippets/src/op/subgraph.cpp +++ b/src/common/snippets/src/op/subgraph.cpp @@ -11,7 +11,6 @@ #include "snippets/pass/insert_movebroadcast.hpp" #include "snippets/pass/load_movebroadcast_to_broadcastload.hpp" #include "snippets/pass/assign_registers.hpp" -#include "snippets/pass/assign_registers_old.hpp" #include "snippets/pass/convert_constants.hpp" #include "snippets/pass/convert_power_to_powerstatic.hpp" #include "snippets/pass/vector_to_scalar.hpp" diff --git a/src/common/snippets/src/pass/assign_registers_old.cpp b/src/common/snippets/src/pass/assign_registers_old.cpp deleted file mode 100644 index d702989c791335..00000000000000 --- a/src/common/snippets/src/pass/assign_registers_old.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2018-2022 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -// #include -#include -#include "snippets/remarks.hpp" - -#include "snippets/pass/assign_registers_old.hpp" -#include "snippets/snippets_isa.hpp" - -#include - -#include - -bool ngraph::snippets::pass::AssignRegistersOld::run_on_model(const std::shared_ptr& f) { - RUN_ON_MODEL_SCOPE(AssignRegistersOld); - OV_ITT_SCOPED_TASK(ngraph::pass::itt::domains::SnippetsTransform, "Snippets::op::AssignRegistersOld") - using Reg = size_t; - auto ops = f->get_ordered_ops(); - decltype(ops) stmts; - std::copy_if(ops.begin(), ops.end(), std::back_inserter(stmts), [](decltype(ops[0]) op) { - return !(std::dynamic_pointer_cast(op) || std::dynamic_pointer_cast(op)); - }); - - size_t rdx = 0; - std::map, Reg> regs; - for (const auto& op : stmts) { - for (const auto& output : op->outputs()) { - regs[output.get_tensor_ptr()] = rdx++; - } - } - - std::vector> used; // used = used as an input - std::vector> def; // defined = used as output - for (const auto& op : stmts) { - std::set u; - for (const auto& input : op->inputs()) { - if (regs.count(input.get_tensor_ptr())) { - u.insert(regs[input.get_tensor_ptr()]); - } - } - used.push_back(u); - - std::set d; - if (!std::dynamic_pointer_cast(op)) { - for (const auto& output : op->outputs()) { - d.insert(regs[output.get_tensor_ptr()]); - } - } - def.push_back(d); - } - - // define life intervals - std::vector> lifeIn(stmts.size(), std::set()); - std::vector> lifeOut(stmts.size(), std::set()); - - for (size_t i = 0; i < stmts.size(); i++) { - for (size_t n = 0; n < stmts.size(); n++) { - // copy regs from lifeOut to lifeIn while ignoring regs in def - std::set_difference(lifeOut[n].begin(), lifeOut[n].end(), def[n].begin(), def[n].end(), std::inserter(lifeIn[n], lifeIn[n].begin())); - lifeIn[n].insert(used[n].begin(), used[n].end()); - } - for (size_t n = 0; n < stmts.size(); n++) { - auto node = stmts[n]; - if (!std::dynamic_pointer_cast(node)) { - for (const auto& out : node->outputs()) { - for (const auto& port : out.get_target_inputs()) { - auto pos = std::find(stmts.begin(), stmts.end(), port.get_node()->shared_from_this()); - if (pos != stmts.end()) { - auto k = pos-stmts.begin(); - lifeOut[n].insert(lifeIn[k].begin(), lifeIn[k].end()); - } - } - } - } - } - } - - struct by_starting { - auto operator()(const std::pair& lhs, const std::pair& rhs) const -> bool { - return lhs.first < rhs.first|| (lhs.first == rhs.first && lhs.second < rhs.second); - } - }; - - struct by_ending { - auto operator()(const std::pair& lhs, const std::pair& rhs) const -> bool { - return lhs.second < rhs.second || (lhs.second == rhs.second && lhs.first < rhs.first); - } - }; - - std::set, by_starting> live_intervals; - - std::reverse(lifeIn.begin(), lifeIn.end()); - auto find_last_use = [lifeIn](int i) -> int { - int ln = static_cast(lifeIn.size()) - 1; - for (auto& x : lifeIn) { - if (x.find(i) != x.end()) { - return ln; - } - ln--; - } - return i; - }; - - for (size_t i = 0; i < stmts.size(); i++) { - // Here we employ the fact that output tensor id and op id is essentially - // the same due to the way we enumerate them. This won't work if we have an op with multiple outputs - live_intervals.insert(std::make_pair(static_cast(i), find_last_use(static_cast(i)))); - } - - // http://web.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf - std::multiset, by_ending> active; - std::map register_map; - std::stack bank; - for (int i = 0; i < 16; i++) bank.push(16-1-i); - - for (auto interval : live_intervals) { - // check expired - while (!active.empty()) { - auto x = *active.begin(); - if (x.second >= interval.first) { - break; - } - active.erase(x); - bank.push(register_map[x.first]); - } - // allocate - if (active.size() == 16) { - throw ngraph_error("caanot allocate registers for a snippet "); - } else { - register_map[interval.first] = bank.top(); - bank.pop(); - active.insert(interval); - } - } - - std::map, Reg> physical_regs; - - for (const auto& reg : regs) { - physical_regs[reg.first] = register_map[reg.second]; - } - const auto num_parameters = f->get_parameters().size(); - for (const auto& n : f->get_ordered_ops()) { - /* The main idea here is that each operation stores its output regs in rt["reginfo"]. Input and output regs are - * then derived by parsing node's and parent's rt["reginfo"], look into ngraph::snippets::getRegisters for details. - * Note also that Parameter and Result store general-purpose register index, because they work with memory - * (memory pointer is stored in gpr). All other "regular" ops store vector regs indexes, since calculations are - * performed on registers. - */ - if (is_type(n)) { - continue; - } else if (const auto& param = ov::as_type_ptr(n)) { - auto& rt = n->get_output_tensor(0).get_rt_info(); - rt["reginfo_old"] = static_cast(f->get_parameter_index(param)); - } else if (const auto& store = ov::as_type_ptr(n)) { - auto& rt = n->get_output_tensor(0).get_rt_info(); - rt["reginfo_old"] = static_cast(f->get_result_index(store) + num_parameters); - } else { - for (const auto& output : n->outputs()) { - auto out_tensor = output.get_tensor_ptr(); - auto& rt = out_tensor->get_rt_info(); - rt["reginfo_old"] = physical_regs[out_tensor]; - } - } - } - - return false; -}