Skip to content

Commit

Permalink
[CONFORMANCE][TOOLS] Repeat pattern extractor API (openvinotoolkit#20293
Browse files Browse the repository at this point in the history
)

* Prepare API

* Refactor api

* Move model comparation to separate component

* Cover by tests

* Move align_in_info to utils

* Change arch diagram
  • Loading branch information
iefode authored Oct 12, 2023
1 parent 29475c7 commit 74690d0
Show file tree
Hide file tree
Showing 36 changed files with 1,315 additions and 770 deletions.
4 changes: 2 additions & 2 deletions docs/img/subgraphs_dumper_arch_diaram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "cache/cache.hpp"
#include "cache/meta/input_info.hpp"
#include "utils/model_comparator.hpp"
#include "matchers/subgraph/manager.hpp"
#include "matchers/subgraph/subgraph.hpp"
#include "matchers/subgraph/fused_names.hpp"
Expand Down Expand Up @@ -42,10 +43,12 @@ class GraphCache : public ICache {

protected:
std::map<std::shared_ptr<ov::Model>, MetaInfo> m_graph_cache;
ExtractorsManager m_manager = ExtractorsManager();
static std::shared_ptr<GraphCache> m_cache_instance;
// cache byte size
uint64_t m_graph_cache_bytesize = 0;
ExtractorsManager m_manager;
ModelComparator::Ptr m_model_comparator = ModelComparator::get();
std::shared_ptr<ov::Model> model_to_update = nullptr;
static std::shared_ptr<GraphCache> m_cache_instance;

GraphCache(const std::string& device = "") {
ExtractorsManager::ExtractorsMap matchers = {
Expand All @@ -59,7 +62,7 @@ class GraphCache : public ICache {

void update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& model_path,
std::map<std::string, InputInfo>& input_info,
const std::map<std::string, InputInfo>& input_info,
const std::string& extractor_name,
size_t model_op_cnt);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ struct InputInfo {
}

InputInfo operator=(const InputInfo& input_info) {
if (this->is_const != input_info.is_const) {
throw std::runtime_error("Cast Const to Parameter! Impossible to update Input Info!");
}
this->ranges = input_info.ranges;
if (ov::shape_size(this->max_shape.get_max_shape()) < ov::shape_size(input_info.max_shape.get_max_shape())) {
this->max_shape = input_info.max_shape;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ class MetaInfo {
const std::string& extractor = "",
const std::vector<std::string>& ignored_inputs = {});
std::map<std::string, InputInfo> get_input_info() const;
void set_input_info(const std::map<std::string, InputInfo>& new_in_info) { input_info = new_in_info; };
void set_input_info(const std::map<std::string, InputInfo>& new_in_info) {
input_info.clear();
input_info = new_in_info;
};
std::map<std::string, ModelInfo> get_model_info() const;
std::string get_any_extractor() const { return *extractors.begin(); }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class MatchersManager {
const std::shared_ptr<ov::Node> &ref) const;

void set_matchers(const MatchersMap& matchers = {}) { m_matchers = matchers; }
void set_shape_strict_match(bool shape_strict_match);

const MatchersMap& get_matchers() { return m_matchers; }
iMatcherConfig::Ptr get_config(const std::shared_ptr<ov::Node> &node) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class SingleOpMatcher {
const std::shared_ptr<ov::Node> &ref) const;

iMatcherConfig::Ptr get_config(const std::shared_ptr<ov::Node> &node) const;
void set_strict_shape_match(bool strict_shape_match);

protected:
virtual void configure(const pugi::xml_document &cfg) {};
Expand All @@ -35,6 +36,8 @@ class SingleOpMatcher {
const std::shared_ptr<ov::Node> &ref) const;

std::vector<iMatcherConfig::Ptr> default_configs;
// match only shape ranks by default;
bool is_strict_shape_match = false;
};

} // namespace subgraph_dumper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ class FusedNamesExtractor final : public SubgraphExtractor {
FusedNamesExtractor(const std::string& device = "");
~FusedNamesExtractor();

std::list<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model,
bool is_extract_body = true,
bool is_copy_constants = true) override;
std::vector<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &modele) override;

protected:
std::unordered_set<std::string> extract_compiled_model_names(const std::shared_ptr<ov::Model>& model);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,19 @@ namespace subgraph_dumper {

class ExtractorsManager {
public:
// { model, subgraph, model_in_info, subgraph_in_info }
using ExtractedSubgraphTuple = std::tuple<bool, std::shared_ptr<ov::Model>, std::shared_ptr<ov::Model>, std::map<std::string, InputInfo>, std::map<std::string, InputInfo>>;
using ExtractorsMap = std::map<std::string, SubgraphExtractor::Ptr>;

explicit ExtractorsManager(const ExtractorsMap& extractors = {}) : m_extractors(extractors) {}

bool match(const std::shared_ptr<ov::Model> &model,
const std::shared_ptr<ov::Model> &ref_model,
std::map<std::string, InputInfo> &in_info,
const std::map<std::string, InputInfo> &in_info_ref);
ExtractedSubgraphTuple is_subgraph(const std::shared_ptr<ov::Model> &model,
const std::shared_ptr<ov::Model> &ref_model,
const std::map<std::string, InputInfo> &in_info = {},
const std::map<std::string, InputInfo> &in_info_ref = {});
std::list<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model,
bool is_extract_body = true,
bool is_copy_constants = true);
std::vector<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model,
bool is_extract_body = true,
bool is_copy_constants = true);

void set_extractors(const ExtractorsMap& extractors = {}) { m_extractors = extractors; }
ExtractorsMap get_extractors() { return m_extractors; }

std::map<std::string, InputInfo> align_input_info(const std::shared_ptr<ov::Model>& model,
const std::shared_ptr<ov::Model>& model_ref,
const std::map<std::string, InputInfo> &in_info,
const std::map<std::string, InputInfo> &in_info_ref,
const std::map<std::string, std::string> &matched_op = {});

protected:
ExtractorsMap m_extractors = {};

bool match(const std::shared_ptr<ov::Model> &model,
const std::shared_ptr<ov::Model> &ref);
};

} // namespace subgraph_dumper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,45 @@
#pragma once

#include <utility>

#include "matchers/subgraph/subgraph.hpp"
#include "matchers/single_op/single_op.hpp"
#include "matchers/single_op/convolutions.hpp"
#include "matchers/single_op/manager.hpp"

namespace ov {
namespace tools {
namespace subgraph_dumper {

class RepeatPatternExtractor final : public SubgraphExtractor {
private:
using InputVector = std::vector<ov::Input<ov::Node>>;
using OutputVector = std::vector<ov::Output<ov::Node>>;

public:
RepeatPatternExtractor() {
MatchersManager::MatchersMap matchers = {
{ "generic_single_op", SingleOpMatcher::Ptr(new SingleOpMatcher) },
{ "convolutions", ConvolutionsMatcher::Ptr(new ConvolutionsMatcher) },
};
manager.set_matchers(matchers);
}

std::list<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model,
bool is_extract_body = true,
bool is_copy_constants = true) override;
using PatternBorders = std::pair<InputVector, OutputVector>;
ModelComparator::Ptr model_comparator = ModelComparator::get();

std::vector<std::vector<PatternBorders>>
get_repeat_pattern_borders(const std::shared_ptr<ov::Model> &model);
std::vector<std::vector<ov::NodeVector>>
get_repeat_node_vectors(const std::shared_ptr<ov::Model> &model);

void set_recursive_extraction(bool _is_recursive_extraction);
std::vector<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model) override;

protected:
// {subgraph, node_vector, input_info}
using ExtractedRepeatPattern = std::tuple<std::shared_ptr<ov::Model>, ov::NodeVector, std::map<std::string, InputInfo>>;
bool is_recursive_extraction = true;

std::list<std::vector<ExtractedRepeatPattern>>
find_repeat_patterns(const std::shared_ptr<ov::Model> &model,
bool is_save_borders_only = false);
void update_extractor_cache(std::list<std::vector<ExtractedRepeatPattern>>& extracted_patterns,
std::list<std::vector<ExtractedRepeatPattern>>& secondary_extracted_patterns);
void update_extractor_cache(std::list<std::vector<ExtractedRepeatPattern>>& extracted_patterns,
const std::shared_ptr<ov::Model>& pattern,
const ov::NodeVector& pattern_node_vector,
const std::map<std::string, InputInfo>& in_info);

private:
MatchersManager manager;
};

} // namespace subgraph_dumper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,28 @@
#include <utility>

#include "openvino/op/util/op_types.hpp"
#include "common_test_utils/graph_comparator.hpp"

#include "cache/meta/input_info.hpp"
#include "matchers/single_op/single_op.hpp"
#include "matchers/single_op/convolutions.hpp"
#include "matchers/single_op/manager.hpp"
#include "utils/model_comparator.hpp"

namespace ov {
namespace tools {
namespace subgraph_dumper {

class SubgraphExtractor {
public:
// { is_subgraph, model, subgraph, matched_ops{ model_op_name, graph_op_name }}
using IsSubgraphTuple = std::tuple<bool, std::shared_ptr<ov::Model>, std::shared_ptr<ov::Model>, std::map<std::string, std::string>>;
using Ptr = std::shared_ptr<SubgraphExtractor>;

SubgraphExtractor() {
MatchersManager::MatchersMap matchers = {
{ "generic_single_op", SingleOpMatcher::Ptr(new SingleOpMatcher) },
{ "convolutions", ConvolutionsMatcher::Ptr(new ConvolutionsMatcher) },
};
m_manager.set_matchers(matchers);
virtual std::vector<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model) {
return std::vector<ExtractedPattern>{};
}

bool match(const std::shared_ptr<ov::Model> &model,
const std::shared_ptr<ov::Model> &ref_model) const;
IsSubgraphTuple is_subgraph(const std::shared_ptr<ov::Model> &model,
const std::shared_ptr<ov::Model> &ref_model) const;

virtual std::list<ExtractedPattern> extract(const std::shared_ptr<ov::Model> &model,
bool is_extract_body = true,
bool is_copy_constants = true) {
return std::list<ExtractedPattern>{};
};

void set_extractor_name(const std::string& _extractor_name) { extractor_name = _extractor_name; }
void set_extract_body(bool _is_extract_body) { is_extract_body = _is_extract_body; }
void set_save_const(bool _is_save_const) { is_save_const = _is_save_const; }

protected:
std::string extractor_name = "";
FunctionsComparator comparator = FunctionsComparator::no_default()
.enable(FunctionsComparator::ATTRIBUTES)
.enable(FunctionsComparator::NODES)
.enable(FunctionsComparator::PRECISIONS);
MatchersManager m_manager = MatchersManager();

inline bool is_node_to_skip(const std::shared_ptr<ov::Node>& node) const {
return ov::op::util::is_parameter(node) ||
ov::op::util::is_constant(node) ||
ov::op::util::is_output(node);
}
bool is_extract_body = true, is_save_const = true;
};

} // namespace subgraph_dumper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static std::vector<std::regex> FROTEND_REGEXP = {
std::regex(R"(.*__model__)"),
#endif
#ifdef ENABLE_OV_TF_FRONTEND
std::regex(R"(.*\.pb)"),
std::regex(R"(.*\model.pb)"),
#endif
#ifdef ENABLE_OV_IR_FRONTEND
std::regex(R"(.*\.xml)"),
Expand Down Expand Up @@ -74,32 +74,24 @@ std::map<ModelCacheStatus, std::vector<std::string>> cache_models(
void save_model_status_to_file(const std::map<ModelCacheStatus, std::vector<std::string>>& caching_status,
const std::string& output_dir);

inline bool is_dynamic_model(const std::shared_ptr<ov::Model>& model) {
for (const auto& parameter : model->get_parameters()) {
if (is_dynamic_node(parameter)) {
return true;
}
}
for (const auto& result : model->get_results()) {
if (is_dynamic_node(result)) {
return true;
}
}
return false;
}
bool is_dynamic_model(const std::shared_ptr<ov::Model>& model);
std::string get_model_type(const std::shared_ptr<ov::Model>& model);

inline std::string get_model_type(const std::shared_ptr<ov::Model>& model) {
if (is_dynamic_model(model)) {
return "dynamic";
}
return "static";
}
std::map<std::string, InputInfo>
get_input_info_by_model(const std::shared_ptr<ov::Model>& model);

inline ExtractedPattern
generate_model(const std::set<std::shared_ptr<ov::Node>>& nodes,
std::map<std::string, InputInfo>
align_input_info(const std::shared_ptr<ov::Model>& model,
const std::shared_ptr<ov::Model>& model_ref,
const std::map<std::string, InputInfo> &in_info,
const std::map<std::string, InputInfo> &in_info_ref,
const std::map<std::string, std::string> &matched_op = {});

inline std::pair<std::shared_ptr<ov::Model>, std::map<std::string, InputInfo>>
generate_model(ov::NodeVector& nodes,
std::unordered_set<std::string>& checked_ops,
const std::string& extractor_name,
bool is_copy_constants = true) {
bool is_copy_constants = true,
bool is_save_only_borders = false) {
// map to recover graph using cloned nodes and original connections
// { original_node_name, cloned_node }
std::unordered_map<std::string, std::shared_ptr<ov::Node>> cloned_node_map;
Expand Down Expand Up @@ -214,27 +206,51 @@ generate_model(const std::set<std::shared_ptr<ov::Node>>& nodes,
// prepare unique model name based on operations from model
std::string string_to_hash;
for (const auto& op : model->get_ordered_ops()) {
bool is_erase_node = !is_save_only_borders;
std::ostringstream result;
result << op->get_type_info();
for (const auto& in : op->inputs()) {
for (size_t i = 0; i < op->inputs().size(); ++i) {
const auto& in = op->input(i);
if (!is_node_to_skip(op->get_input_node_shared_ptr(i))) {
is_erase_node |= true;
}
result << in.get_element_type();
result << in.get_partial_shape().rank();
result << in.get_partial_shape().is_static();
}
for (const auto& out : op->outputs()) {
for (const auto& target_input : out.get_target_inputs()) {
if (!is_node_to_skip(target_input.get_node()->shared_from_this())) {
is_erase_node |= true;
break;
}
}
result << out.get_element_type();
result << out.get_partial_shape().rank();
result << out.get_partial_shape().is_static();
}
string_to_hash += result.str();
if (is_erase_node) {
cloned_node_map.erase(op->get_friendly_name());
}
}
for (const auto& in : model_input_info) {
string_to_hash += (in.second.is_const ? "1" : "0");
}
auto h1 = std::hash<std::string>{}(string_to_hash);
model->set_friendly_name(std::to_string(h1));

return { model, model_input_info, extractor_name };
{
auto it = nodes.begin();
while (it != nodes.end()) {
if (cloned_node_map.count((*it)->get_friendly_name())) {
nodes.erase(it);
} else {
++it;
}
}
}

return { model, model_input_info };
}

} // namespace subgraph_dumper
Expand Down
Loading

0 comments on commit 74690d0

Please sign in to comment.