[conformance] Enable local cache using in SubgraphsDumper tool (#18850)

* [conformance] Fix same name for models

* add model name

* Update hash wwith input_info and graph_priority

* Fix double cache

* Read meta from file

* temp to check

* Move loop with caches and add attr to rename

* [conformance] Enable local cache using in SubgraphsDumper tool
This commit is contained in:
Sofya Balandina 2023-08-24 16:05:37 +01:00 committed by GitHub
parent e0a75b78d1
commit b607c00c95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 102 additions and 71 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:21a6f0c136a6861e74e60088090e70146e161b0126fd7917aba8b6f960f23dae
size 263795
oid sha256:caa4f76ba61548d1b60d7de1f78fb48dccbf5337117240353a9581f23c88bfa9
size 216595

View File

@ -17,8 +17,10 @@ namespace subgraph_dumper {
class ICache {
public:
std::string m_cache_subdir = ".";
virtual void update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& source_model, bool extract_body = true) {};
const std::string& source_model, bool extract_body = true, bool from_cache = false) {};
virtual void serialize_cache() {};
virtual void reset_cache() {};

View File

@ -19,7 +19,7 @@ class GraphCache : public ICache {
public:
void update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& model_meta_data,
bool extract_body) override;
bool extract_body, bool from_cache = false) override;
void serialize_cache() override;
static std::shared_ptr<GraphCache>& get() {
@ -53,11 +53,12 @@ protected:
{ "repeat_pattern", RepeatPatternExtractor::Ptr(new RepeatPatternExtractor) },
};
m_manager.set_extractors(matchers);
m_cache_subdir = "subgraph";
}
void update_cache(const std::shared_ptr<ov::Model>& model, const std::string& model_path,
std::map<std::string, InputInfo>& input_info, const std::string& extractor_name,
size_t model_op_cnt);
size_t model_op_cnt, bool from_cache = false);
};
} // namespace subgraph_dumper

View File

@ -16,7 +16,7 @@ namespace subgraph_dumper {
class OpCache : public ICache {
public:
void update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& model_path, bool extract_body) override;
const std::string& model_path, bool extract_body, bool from_cache = false) override;
void serialize_cache() override;
static std::shared_ptr<OpCache> get() {
@ -47,9 +47,10 @@ protected:
{ "convolutions", ConvolutionsMatcher::Ptr(new ConvolutionsMatcher) },
};
m_manager.set_matchers(matchers);
m_cache_subdir = "operation";
}
void update_cache(const std::shared_ptr<ov::Node>& node, const std::string& model_path, size_t model_op_cnt = 1);
void update_cache(const std::shared_ptr<ov::Node>& node, const std::string& model_path, size_t model_op_cnt = 1, bool from_cache = false);
bool serialize_op(const std::pair<std::shared_ptr<ov::Node>, MetaInfo>& op_info);
std::string get_rel_serilization_dir(const std::shared_ptr<ov::Node>& node);
};

View File

@ -63,9 +63,9 @@ find_models(const std::vector<std::string> &dirs, const std::string& regexp = ".
// model_cache_status: model_list
std::map<ModelCacheStatus, std::vector<std::string>> cache_models(
std::vector<std::shared_ptr<ICache>>& caches,
std::shared_ptr<ICache>& cache,
const std::vector<std::string>& models,
bool extract_body);
bool extract_body, bool from_cache = false);
void save_model_status_to_file(const std::map<ModelCacheStatus, std::vector<std::string>>& caching_status,
const std::string& output_dir);

View File

@ -22,7 +22,7 @@ std::shared_ptr<GraphCache> GraphCache::m_cache_instance = nullptr;
void GraphCache::update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& model_meta_data,
bool extract_body) {
bool extract_body, bool from_cache) {
std::cout << "[ INFO ][ GRAPH CACHE ] Processing model: " << model_meta_data << std::endl;
auto model_total_op = model->get_ops().size() - model->get_output_size() - model->inputs().size();
auto extracted_patterns = m_manager.extract(model, extract_body);
@ -38,7 +38,7 @@ void GraphCache::update_cache(const std::shared_ptr<ov::Model>& model,
}
void GraphCache::update_cache(const std::shared_ptr<ov::Model>& extracted_model, const std::string& model_path,
std::map<std::string, InputInfo>& input_info, const std::string& extractor_name, size_t model_op_cnt) {
std::map<std::string, InputInfo>& input_info, const std::string& extractor_name, size_t model_op_cnt, bool from_cache) {
// todo: check the number 8GB
if (m_graph_cache_bytesize >> 33 > 0) {
std::cout << "[ GRAPH CACHE ][ WARNING ] Cache size > 8 GB. Serialize graph cache" << std::endl;
@ -50,7 +50,7 @@ void GraphCache::update_cache(const std::shared_ptr<ov::Model>& extracted_model,
auto graph_name = extracted_model->get_friendly_name();
std::string serialized_model_path = "";
for (const auto& extractor : m_manager.get_extractors()) {
auto tmp_serialized_model_path = ov::util::path_join({ m_serialization_dir, "subgraph", extractor.first, graph_name + ".xml" });
auto tmp_serialized_model_path = ov::util::path_join({ m_serialization_dir, m_cache_subdir, extractor.first, graph_name + ".xml" });
if (ov::util::file_exists(serialized_model_path)) {
serialized_model_path = tmp_serialized_model_path;
break;
@ -87,7 +87,13 @@ void GraphCache::update_cache(const std::shared_ptr<ov::Model>& extracted_model,
auto this_op_cnt = extracted_model->get_ops().size() -
extracted_model->get_parameters().size() - extracted_model->get_results().size();
if (model_to_update == nullptr) {
auto meta = MetaInfo(model_path, input_info, model_op_cnt, this_op_cnt, extractor_name);
MetaInfo meta;
if (from_cache) {
auto meta_path = ov::test::utils::replaceExt(model_path, "meta");
meta = MetaInfo::read_meta_from_file(meta_path);
} else {
meta = MetaInfo(model_path, input_info, model_op_cnt, this_op_cnt, extractor_name);
}
m_graph_cache.insert({ extracted_model, meta });
m_graph_cache_bytesize += extracted_model->get_graph_size();
return;
@ -107,7 +113,7 @@ void GraphCache::serialize_cache() {
// for (const auto& cache_item : m_graph_cache) {
auto it = m_graph_cache.begin();
while (it != m_graph_cache.end()) {
auto rel_dir = ov::util::path_join({ "subgraph", it->second.get_any_extractor() });
auto rel_dir = ov::util::path_join({m_cache_subdir, it->second.get_any_extractor() });
serialize_model(*it, rel_dir);
m_graph_cache.erase(it->first);
it = m_graph_cache.begin();

View File

@ -56,6 +56,7 @@ MetaInfo MetaInfo::read_meta_from_file(const std::string& meta_path) {
ModelInfo tmp_model_info;
tmp_model_info.this_op_cnt = model_child.attribute("this_op_count").as_uint();
tmp_model_info.total_op_cnt = model_child.attribute("total_op_count").as_uint();
tmp_model_info.model_priority = model_child.attribute("priority") ? model_child.attribute("priority").as_uint() : 1;
for (const auto& path : model_child.child("path")) {
tmp_model_info.model_paths.insert(std::string(path.attribute("path").value()));
}
@ -77,7 +78,7 @@ MetaInfo MetaInfo::read_meta_from_file(const std::string& meta_path) {
if (std::string(input.attribute("max").value()) != "undefined") {
in_info.ranges.max = input.attribute("max").as_double();
} else {
in_info.ranges.min = DEFAULT_MAX_VALUE;
in_info.ranges.max = DEFAULT_MAX_VALUE;
}
input_info.insert({in_name, in_info});
}
@ -103,6 +104,7 @@ void MetaInfo::serialize(const std::string& serialization_path) {
model_node.append_attribute("name").set_value(model.first.c_str());
model_node.append_attribute("this_op_count").set_value(static_cast<unsigned long long>(model.second.this_op_cnt));
model_node.append_attribute("total_op_count").set_value(static_cast<unsigned long long>(model.second.total_op_cnt));
model_node.append_attribute("priority").set_value(static_cast<unsigned long long>(model.second.model_priority));
for (const auto& model_path : model.second.model_paths) {
model_node.append_child("path").append_child("model").append_attribute("path").set_value(model_path.c_str());
}
@ -160,7 +162,7 @@ void MetaInfo::update(const std::string& _model_path,
if (input_info.find(in.first) == input_info.end()) {
throw std::runtime_error("Incorrect Input Info!");
} else if (input_info[in.first].is_const != in.second.is_const) {
throw std::runtime_error("Try to cast parameter ro constant!");
throw std::runtime_error("Try to cast parameter to constant!");
} else {
input_info[in.first] = in.second;
}

View File

@ -9,6 +9,8 @@
#include "openvino/op/ops.hpp"
#include "openvino/util/file_util.hpp"
#include "common_test_utils/file_utils.hpp"
#include "cache/op_cache.hpp"
#include "utils/node.hpp"
@ -19,7 +21,7 @@ std::shared_ptr<OpCache> OpCache::m_cache_instance = nullptr;
void OpCache::update_cache(const std::shared_ptr<ov::Model>& model,
const std::string& model_path,
bool extract_body) {
bool extract_body, bool from_cache) {
std::cout << "[ INFO ][ OP CACHE ] Processing model: " << model_path << std::endl;
size_t model_op_cnt = model->get_ops().size() - model->get_output_size() - model->inputs().size();
for (const auto& op : model->get_ordered_ops()) {
@ -37,25 +39,25 @@ void OpCache::update_cache(const std::shared_ptr<ov::Model>& model,
auto if_op = std::dynamic_pointer_cast<ov::op::v8::If>(op);
for (size_t i = 0; i < if_op->get_internal_subgraphs_size(); i++) {
auto if_body = if_op->get_function(i);
update_cache(if_body, model_path, extract_body);
update_cache(if_body, model_path, extract_body, from_cache);
}
} else if (std::dynamic_pointer_cast<ov::op::v5::Loop>(op)) {
auto loop = std::dynamic_pointer_cast<ov::op::v5::Loop>(op);
auto loop_body = loop->get_function();
update_cache(loop_body, model_path, extract_body);
update_cache(loop_body, model_path, extract_body, from_cache);
} else if (std::dynamic_pointer_cast<ov::op::v0::TensorIterator>(op)) {
auto ti = std::dynamic_pointer_cast<ov::op::v0::TensorIterator>(op);
auto ti_body = ti->get_function();
update_cache(ti_body, model_path, extract_body);
update_cache(ti_body, model_path, extract_body, from_cache);
}
}
update_cache(op, model_path, model_op_cnt);
update_cache(op, model_path, model_op_cnt, from_cache);
}
}
void OpCache::update_cache(const std::shared_ptr<ov::Node>& node,
const std::string& model_path,
size_t model_op_cnt) {
size_t model_op_cnt, bool from_cache) {
std::shared_ptr<ov::Node> find_op_in_cache = nullptr;
// Clone node to get node with Parameter/Constants input only
auto cloned_node = clone_node(node, true);
@ -82,19 +84,28 @@ void OpCache::update_cache(const std::shared_ptr<ov::Node>& node,
}
}
size_t priority = get_node_priority_by_version(cloned_node);
auto meta = MetaInfo(model_path, get_input_info_by_node(cloned_node), model_op_cnt, 1, "", priority);
MetaInfo meta;
if (from_cache) {
auto meta_path = ov::test::utils::replaceExt(model_path, "meta");
meta = MetaInfo::read_meta_from_file(meta_path);
} else {
size_t priority = get_node_priority_by_version(cloned_node);
meta = MetaInfo(model_path, get_input_info_by_node(cloned_node), model_op_cnt, 1, "", priority);
}
if (find_op_in_cache != nullptr) {
// std::cout << "[ INFO ][ OP CACHE ] Update cache node: " << cloned_node->get_type_info().name << cloned_node->get_friendly_name() <<
// " " << find_op_in_cache->get_friendly_name() << std::endl;
m_ops_cache[find_op_in_cache].update(
model_path, get_input_info_by_node(cloned_node), model_op_cnt, 1, "", ignored_input_names);
}
if (find_op_in_cache > cloned_node) {
meta = m_ops_cache[find_op_in_cache];
m_ops_cache.erase(find_op_in_cache);
find_op_in_cache = nullptr;
}
if (find_op_in_cache == nullptr) {
// std::cout << "[ INFO ][ OP CACHE ] Insert node: " << cloned_node->get_type_info().name <<
// " " << cloned_node->get_friendly_name() << " to Cache" << std::endl;
@ -118,7 +129,7 @@ std::string OpCache::get_rel_serilization_dir(const std::shared_ptr<ov::Node>& n
std::string op_folder_name = ov::test::functional::get_node_version(node);
auto op_el_type = node->get_output_element_type(0).get_type_name();
return ov::util::path_join({"operation", get_node_type(node), op_folder_name, op_el_type});
return ov::util::path_join({m_cache_subdir, get_node_type(node), op_folder_name, op_el_type});
}
} // namespace subgraph_dumper

View File

@ -7,6 +7,11 @@
#include "cache/graph_cache.hpp"
#include "utils/model.hpp"
#include "openvino/util/file_util.hpp"
#include "common_test_utils/file_utils.hpp"
using namespace ov::tools::subgraph_dumper;
int main(int argc, char *argv[]) {
@ -48,34 +53,41 @@ int main(int argc, char *argv[]) {
for (auto& cache : caches) {
cache->set_serialization_dir(FLAGS_output_folder);
}
// Upload previously cached graphs to cache
if (!FLAGS_local_cache.empty()) {
auto cached_ops = find_models(local_cache_dirs);
// todo: add normal caching with meta info reading
auto this_cache_model_status = cache_models(caches, cached_ops.first, FLAGS_extract_body);
auto not_read_model = cached_ops.second;
for (auto& model_status : cache_model_status) {
auto& key = model_status.first;
auto& value = model_status.second;
if (not_read_model.first == key) {
value.insert(value.end(), not_read_model.second.begin(), not_read_model.second.end());
// Upload previously cached graphs to cache
if (!FLAGS_local_cache.empty()) {
std::vector<std::string> tmp_paths;
for (auto& dir : local_cache_dirs) {
tmp_paths.push_back(ov::util::path_join({dir, cache->m_cache_subdir}));
}
if (this_cache_model_status.count(key)) {
value.insert(value.end(), this_cache_model_status[key].begin(), this_cache_model_status[key].end());
auto cached_ops = find_models(tmp_paths, FLAGS_path_regex);
auto this_cache_model_status = cache_models(cache, cached_ops.first, FLAGS_extract_body, true);
auto not_read_model = cached_ops.second;
for (auto& model_status : cache_model_status) {
auto& key = model_status.first;
auto& value = model_status.second;
if (not_read_model.first == key) {
value.insert(value.end(), not_read_model.second.begin(), not_read_model.second.end());
}
if (this_cache_model_status.count(key)) {
value.insert(value.end(), this_cache_model_status[key].begin(), this_cache_model_status[key].end());
}
}
}
}
{
auto this_cache_model_status = cache_models(caches, models, FLAGS_extract_body);
for (auto& model_status : cache_model_status) {
auto& key = model_status.first;
auto& value = model_status.second;
if (this_cache_model_status.count(key)) {
value.insert(value.end(), this_cache_model_status[key].begin(), this_cache_model_status[key].end());
{
auto this_cache_model_status = cache_models(cache, models, FLAGS_extract_body);
for (auto& model_status : cache_model_status) {
auto& key = model_status.first;
auto& value = model_status.second;
if (this_cache_model_status.count(key)) {
value.insert(value.end(), this_cache_model_status[key].begin(), this_cache_model_status[key].end());
}
}
}
cache->serialize_cache();
cache->reset_cache();
}
save_model_status_to_file(cache_model_status, FLAGS_output_folder);
return cache_model_status[ModelCacheStatus::NOT_FULLY_CACHED].empty() && cache_model_status[ModelCacheStatus::NOT_READ].empty();
}

View File

@ -25,7 +25,7 @@ void save_model_status_to_file(const std::map<ModelCacheStatus, std::vector<std:
// { models, { not_read_model }}
std::pair<std::vector<std::string>, std::pair<ModelCacheStatus, std::vector<std::string>>>
find_models(const std::vector<std::string> &dirs, const std::string& regexp) {
std::vector<std::string> models, full_content;
std::vector<std::string> models, full_content, not_read_model;
for (const auto& dir : dirs) {
std::vector<std::string> dir_content;
if (ov::util::directory_exists(dir)) {
@ -33,15 +33,13 @@ find_models(const std::vector<std::string> &dirs, const std::string& regexp) {
} else if (ov::util::file_exists(dir) && std::regex_match(dir, std::regex(".*" + std::string(ov::test::utils::LST_EXTENSION)))) {
dir_content = ov::test::utils::readListFiles({dir});
} else {
std::string msg = "Input directory (" + dir + ") doesn't not exist!";
throw std::runtime_error(msg);
std::cout << "[ ERROR ] Input directory (" << dir << ") doesn't not exist!" << std::endl;
}
if (!dir_content.empty()) {
full_content.insert(full_content.end(), dir_content.begin(), dir_content.end());
}
}
std::multimap<size_t, std::string> models_sorted_by_size;
std::vector<std::string> not_read_model;
auto in_regex = std::regex(regexp);
for (const auto& model_file : full_content) {
if (std::regex_match(model_file, in_regex)) {
@ -73,9 +71,9 @@ find_models(const std::vector<std::string> &dirs, const std::string& regexp) {
}
std::map<ModelCacheStatus, std::vector<std::string>> cache_models(
std::vector<std::shared_ptr<ICache>>& caches,
std::shared_ptr<ICache>& cache,
const std::vector<std::string>& models,
bool extract_body) {
bool extract_body, bool from_cache) {
std::map<ModelCacheStatus, std::vector<std::string>> cache_status = {
{ ModelCacheStatus::SUCCEED, {} },
{ ModelCacheStatus::NOT_FULLY_CACHED, {} },
@ -84,30 +82,28 @@ std::map<ModelCacheStatus, std::vector<std::string>> cache_models(
auto core = ov::test::utils::PluginCache::get().core();
auto models_size = models.size();
for (auto& cache : caches) {
for (size_t i = 0; i < models_size; ++i) {
const auto& model = models[i];
if (ov::util::file_exists(model)) {
std::cout << "[ INFO ] [ " << i << "/" << models_size << " ] model will be processed" << std::endl;
ModelCacheStatus model_status = ModelCacheStatus::SUCCEED;
for (size_t i = 0; i < models_size; ++i) {
const auto& model = models[i];
if (ov::util::file_exists(model)) {
std::cout << "[ INFO ] [ " << i << "/" << models_size << " ] model will be processed" << std::endl;
ModelCacheStatus model_status = ModelCacheStatus::SUCCEED;
try {
std::shared_ptr<ov::Model> function = core->read_model(model);
try {
std::shared_ptr<ov::Model> function = core->read_model(model);
try {
cache->update_cache(function, model, extract_body);
} catch (std::exception &e) {
std::cout << "[ ERROR ] Model processing failed with exception:" << std::endl << e.what() << std::endl;
model_status = ModelCacheStatus::NOT_FULLY_CACHED;
}
cache->update_cache(function, model, extract_body, from_cache);
} catch (std::exception &e) {
model_status = ModelCacheStatus::NOT_READ;
std::cout << "[ ERROR ] Model reading failed with exception:" << std::endl << e.what() << std::endl;
std::cout << "[ ERROR ] Model processing failed with exception:" << std::endl << e.what() << std::endl;
model_status = ModelCacheStatus::NOT_FULLY_CACHED;
}
cache_status[model_status].push_back(model);
} catch (std::exception &e) {
model_status = ModelCacheStatus::NOT_READ;
std::cout << "[ ERROR ] Model reading failed with exception:" << std::endl << e.what() << std::endl;
}
cache_status[model_status].push_back(model);
}
cache->serialize_cache();
cache->reset_cache();
}
return cache_status;
}