!21137 Break ayalysis context loop, fix memleak problem

Merge pull request !21137 from zhangzhaoju/master_leak_ContextLoop
This commit is contained in:
i-robot 2021-08-02 06:06:54 +00:00 committed by Gitee
commit 528ce89c2f
4 changed files with 34 additions and 5 deletions

View File

@ -1336,6 +1336,7 @@ void ClearResAtexit() {
ReleaseGeTsd();
parse::python_adapter::ResetPythonScope();
abstract::AnalysisResultCacheMgr::GetInstance().Clear();
abstract::AnalysisContext::ClearContext();
#ifdef ENABLE_DEBUGGER
Debugger::GetInstance()->Reset();
#endif

View File

@ -350,6 +350,7 @@ void AnalysisEngine::ClearEvaluatorCache() {
void AnalysisEngine::Clear() {
AnalysisResultCacheMgr::GetInstance().Clear();
AnalysisContext::ClearContext();
anfnode_config_map_.clear();
eval_trace_.clear();
evaluators_.clear();

View File

@ -23,6 +23,7 @@
namespace mindspore {
namespace abstract {
std::list<AnalysisContextPtr> AnalysisContext::all_context_;
AnalysisContextPtr AnalysisContext::NewContext(const FuncGraphPtr &func_graph,
const AbstractBasePtrList &args_spec_list) {
// Find func graph's parent and its parent context firstly.
@ -56,7 +57,7 @@ AnalysisContextPtr AnalysisContext::NewContext(const FuncGraphPtr &func_graph,
}
// Create a new context for the func graph and its specific arguments.
AnalysisContextPtr new_context = std::make_shared<AnalysisContext>(parent_context, func_graph, args_spec_list);
AnalysisContextPtr new_context = CreateContext(parent_context, func_graph, args_spec_list);
// To avoid cycle-reference, use weak_ptr here.
auto weak_new_context = std::weak_ptr<AnalysisContext>(new_context);
new_context->extant_context_cache_[func_graph] = weak_new_context;
@ -102,7 +103,7 @@ AnalysisContextPtr AnalysisContext::FindOwnOrParentContext(const FuncGraphPtr &f
}
AnalysisContextPtr AnalysisContext::DummyContext() {
AnalysisContextPtr dummy_context = std::make_shared<AnalysisContext>(nullptr, nullptr, AbstractBasePtrList());
AnalysisContextPtr dummy_context = CreateContext(nullptr, nullptr, AbstractBasePtrList());
dummy_context->extant_context_cache_[nullptr] = std::weak_ptr<AnalysisContext>(dummy_context);
return dummy_context;
}
@ -112,7 +113,7 @@ bool AnalysisContext::IsDummyContext() {
}
const AnalysisContextPtr kDummyAnalysisContext =
std::make_shared<AnalysisContext>(nullptr, nullptr, AbstractBasePtrList());
AnalysisContext::CreateContext(nullptr, nullptr, AbstractBasePtrList());
bool AnalysisContext::operator==(const AnalysisContext &other) const {
if (func_graph_ != other.func_graph_) {
@ -174,7 +175,7 @@ AnalysisContextPtr AnalysisContext::SpecializeKey() const {
}
return arg;
});
AnalysisContextPtr context_new = std::make_shared<AnalysisContext>(nullptr, func_graph_, args_broad_shp);
AnalysisContextPtr context_new = CreateContext(nullptr, func_graph_, args_broad_shp);
context_new->parent_ = parent_;
return context_new;
}
@ -209,5 +210,23 @@ std::string AnalysisContext::ToString() const {
buffer << "}";
return buffer.str();
}
void AnalysisContext::ClearContext() {
for (auto &item : all_context_) {
item->parent_ = nullptr;
item->func_graph_ = nullptr;
item->args_spec_list_.clear();
item->extant_context_cache_.clear();
item->children_cache_.clear();
}
all_context_.clear();
}
AnalysisContextPtr AnalysisContext::CreateContext(const AnalysisContextPtr &parent, const FuncGraphPtr &fg,
const AbstractBasePtrList &args_spec_list) {
auto context = std::make_shared<AnalysisContext>(parent, fg, args_spec_list);
all_context_.emplace_back(context);
return context;
}
} // namespace abstract
} // namespace mindspore

View File

@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <list>
#include "abstract/abstract_value.h"
#include "ir/meta_func_graph.h"
@ -42,7 +43,6 @@ class AnalysisContext {
extant_context_cache_ = parent_->extant_context_cache_;
}
}
~AnalysisContext() = default;
// Extend this context with values for another graph.
@ -59,6 +59,9 @@ class AnalysisContext {
std::string ToString() const;
AnalysisContextPtr SpecializeKey() const;
AbstractBasePtrList args_spec_list() { return args_spec_list_; }
static void ClearContext();
static AnalysisContextPtr CreateContext(const AnalysisContextPtr &parent, const FuncGraphPtr &fg,
const AbstractBasePtrList &args_spec_list);
private:
AnalysisContextPtr parent_;
@ -70,6 +73,11 @@ class AnalysisContext {
// Record all created child contexts from this context.
// Like: key: [func_graph & arguments], value: [child_context]
std::unordered_map<FuncGraphPtr, ArgsSpecToAnalysisContextMap> children_cache_;
// There may may be shared_ptr loop like:
// FuncGraphAbstactClosur->AnalysisContext->children_cache_->ArgsSpec->FuncGraphAbstactClosur.
// For break the loop, using all_context_ to clear context_.
static std::list<AnalysisContextPtr> all_context_;
};
struct ContextHasher {