From d7aca775c5bc5b9d914435cd4b4648c2e7cbd687 Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Thu, 22 Jun 2017 16:31:03 +0800 Subject: [PATCH 1/3] Update API --- doc/design/scope.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/design/scope.md b/doc/design/scope.md index 695426b2f2..6694e275b6 100644 --- a/doc/design/scope.md +++ b/doc/design/scope.md @@ -30,7 +30,7 @@ class Scope { public: Scope(const std::shared_ptr& scope): parent_(scope) {} - Variable* Get(const std::string& name) const { + Variable* GetVar(const std::string& name) const { Variable* var = GetVarLocally(name); if (var != nullptr) { return var; From 2d5507fab26fe990e88cbe3569b5a1f1a810b6b8 Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Thu, 22 Jun 2017 16:46:41 +0800 Subject: [PATCH 2/3] Add interfaces --- doc/design/scope.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/doc/design/scope.md b/doc/design/scope.md index 6694e275b6..68395435dd 100644 --- a/doc/design/scope.md +++ b/doc/design/scope.md @@ -50,6 +50,44 @@ In `Scope` class, there is a private data member called `parent_`. `parent_` is A local scope is very useful when we implement Recurrent Neural Network. Each timestep of an RNN should be a `Net`. Each `Net` of timestep (`StepNet` for short) should use an independent local scope. Just like variables in a while loop is inside a local scope in programming languages. By using a single `StepNet` and changing local scope, we can implement an RNN easily. -# 接口实现 +# Interface Design -# 各个接口是啥意思,为啥这么设计 +```cpp +class Variable { +private: + Variable() = default; + friend class Scope; +}; + +using VariablePtr = std::weak_ptr; + +class Scope { +public: + Scope(const std::shared_ptr& parent = nullptr); + + // return nullptr if not found. + VariablePtr GetVariable(const std::string& name) const; + + // return Error if already contains same name variable. + Error CreateVariable(const std::string& name); + +private: + std::shared_ptr parent_; + std::unordered_map> attrs_; +}; +``` +## Only scope can create a variable + +To ensure `only scope can create a variable`, we should mark `Variable`'s constructor as a private member function, and Scope is a friend class of Variable. And then only `CreateVariable` can construct `Variable`. + +## When scope destroyed, all variables inside this scope should be destroyed together + +The `VariablePtr` is a `weak_ptr`. `Net` and `Op` can only get a Variable from `Scope`, but cannot hold it. When scope is destroyed, all `VariablePtr`s belong to this Scope will be changed to `nullptr`. + +## Sharing a parent scope + +Local scope contains a `parent_` pointer. It is a linked-list for scopes. Using a `shared_ptr` because when a local scope is using, its parents cannot be destroyed. + +## Orthogonal interface + +`GetVariable` will return `nullptr` when `name` is not found. It can be used as `Contains` method. `CreateVariable` will return a `Error` when there is a name conflict locally. Combine `GetVariable` and `CreateVariable`, we can implement `CreateOrGetVariable` easily. From 1f0056b242f79f34fa472dcf93014866a787753c Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Thu, 22 Jun 2017 16:52:35 +0800 Subject: [PATCH 3/3] Update interface --- doc/design/scope.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/design/scope.md b/doc/design/scope.md index 74bb6242e4..76af6c30c1 100644 --- a/doc/design/scope.md +++ b/doc/design/scope.md @@ -76,9 +76,12 @@ private: using VariablePtr = std::weak_ptr; class Scope { -public: +private: Scope(const std::shared_ptr& parent = nullptr); +public: + static std::shared_ptr Create(const std::shared_ptr& parent = nullptr); + // return nullptr if not found. VariablePtr GetVariable(const std::string& name) const; @@ -102,6 +105,8 @@ The `VariablePtr` is a `weak_ptr`. `Net` and `Op` can only get a Variable from ` Local scope contains a `parent_` pointer. It is a linked-list for scopes. Using a `shared_ptr` because when a local scope is using, its parents cannot be destroyed. +Also, as the parent scope is a `shared_ptr`, we can only `Create()` a scope shared pointer. We cannot construct a scope variable, because it cannot be passed to other scope as `parent` pointer. + ## Orthogonal interface `GetVariable` will return `nullptr` when `name` is not found. It can be used as `Contains` method. `CreateVariable` will return a `Error` when there is a name conflict locally. Combine `GetVariable` and `CreateVariable`, we can implement `CreateOrGetVariable` easily.