[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:
parent
e0a75b78d1
commit
b607c00c95
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:21a6f0c136a6861e74e60088090e70146e161b0126fd7917aba8b6f960f23dae
|
||||
size 263795
|
||||
oid sha256:caa4f76ba61548d1b60d7de1f78fb48dccbf5337117240353a9581f23c88bfa9
|
||||
size 216595
|
||||
|
@ -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() {};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user