@@ -15,9 +15,9 @@ Please be aware that these Python classes need to maintain some construction-tim
### Program
A `ProgramDesc` describes a [DL program](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md), which is composed of an array of `BlockDesc`s. A `BlockDesc` refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator needs to be able to access variables in its ancessor blocks.
A `ProgramDesc` describes a [DL program](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md), which is composed of an array of `BlockDesc`s. The `BlockDesc`s in a `ProgramDesc` can have a tree-like hierarchical structure. However, the `ProgramDesc` onlys stores a flattened array of `BlockDesc`s. A `BlockDesc` refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator need to be able to access variables in its ancestor blocks.
Whenever we create a block, we need set its parent block to the current block, so the Python class `Program` needs to maintain a data member `current_block`.
Whenever we create a block, we need to set its parent block to the current block, hence the Python class `Program` needs to maintain a data member `current_block`.
```python
class Program(objects):
...
...
@@ -81,13 +81,13 @@ class Block(objects):
self.ops.prepend(Operator(self, ...))
```
`create_parameter` is necessary because parameters are global variables, those defined in the global block, but can be created in some sub-blocks, e.g., an FC layer in the step block of an RNN operator.
`create_parameter` is necessary because parameters are global variables, defined in the global block, but can be created in some sub-blocks. For example, an FC layer in the step block of an RNN operator.
`prepand_operator` is necessary because the constructor of `Parameter` needs to create the initialize (or load) operator of the parameter, and would like to put it in the *preamble* of the global block.
`prepend_operator` is necessary because the constructor of `Parameter` needs to create the initialize (or load) operator of the parameter, and would like to put it in the *preamble* of the global block.
### Operator
The `Operator` class fills in the `OpDesc` message and calls the C++ function `InferShape` to infer output shape from input shape.
The `Operator` class fills in the `OpDesc` message and calls the C++ function `InferShape` to infer the output shapes from the input shapes.
```python
class Operator(object):
...
...
@@ -105,7 +105,7 @@ class Operator(object):
return self.proto.type()
```
`Operator` creates the `OpDesc` message in C++ space, so could it call the `InferShape` function, which is in C++.
`Operator` creates the `OpDesc` message in C++ space, so that it can call the `InferShape` function, which is in C++.
### Variable
...
...
@@ -128,7 +128,7 @@ class Variable(object):
self.writer = None
```
Please be aware of `self.writer`, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each writes to a variable is represented by a Variable class. This is guaranteed by the fact that **`core.NewVarDesc` must NOT create a new `VarDesc` message if its name already exists in the specified block**.
Please be aware of `self.writer`, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each write to a variable is represented by a Variable class. This is guaranteed by the fact that **`core.NewVarDesc` must NOT create a new `VarDesc` message if its name already exists in the specified block**.
<spanid="core-concepts"></span><h2>Core Concepts<aclass="headerlink"href="#core-concepts"title="Permalink to this headline">¶</a></h2>
<divclass="section"id="program">
<spanid="program"></span><h3>Program<aclass="headerlink"href="#program"title="Permalink to this headline">¶</a></h3>
<p>A <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> describes a <aclass="reference external"href="https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md">DL program</a>, which is composed of an array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. A <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code> refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator needs to be able to access variables in its ancessor blocks.</p>
<p>Whenever we create a block, we need set its parent block to the current block, so the Python class <codeclass="docutils literal"><spanclass="pre">Program</span></code> needs to maintain a data member <codeclass="docutils literal"><spanclass="pre">current_block</span></code>.</p>
<p>A <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> describes a <aclass="reference external"href="https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md">DL program</a>, which is composed of an array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. The <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s in a <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> can have a tree-like hierarchical structure. However, the <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> onlys stores a flattened array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. A <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code> refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator need to be able to access variables in its ancestor blocks.</p>
<p>Whenever we create a block, we need to set its parent block to the current block, hence the Python class <codeclass="docutils literal"><spanclass="pre">Program</span></code> needs to maintain a data member <codeclass="docutils literal"><spanclass="pre">current_block</span></code>.</p>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">proto</span><spanclass="o">=</span><spanclass="n">core</span><spanclass="o">.</span><spanclass="n">NewProgram</span><spanclass="p">()</span><spanclass="c1"># a C++ ProgramDesc pointer.</span>
<p><codeclass="docutils literal"><spanclass="pre">create_parameter</span></code> is necessary because parameters are global variables, those defined in the global block, but can be created in some sub-blocks, e.g., an FC layer in the step block of an RNN operator.</p>
<p><codeclass="docutils literal"><spanclass="pre">prepand_operator</span></code> is necessary because the constructor of <codeclass="docutils literal"><spanclass="pre">Parameter</span></code> needs to create the initialize (or load) operator of the parameter, and would like to put it in the <em>preamble</em> of the global block.</p>
<p><codeclass="docutils literal"><spanclass="pre">create_parameter</span></code> is necessary because parameters are global variables, defined in the global block, but can be created in some sub-blocks. For example, an FC layer in the step block of an RNN operator.</p>
<p><codeclass="docutils literal"><spanclass="pre">prepend_operator</span></code> is necessary because the constructor of <codeclass="docutils literal"><spanclass="pre">Parameter</span></code> needs to create the initialize (or load) operator of the parameter, and would like to put it in the <em>preamble</em> of the global block.</p>
</div>
<divclass="section"id="operator">
<spanid="operator"></span><h3>Operator<aclass="headerlink"href="#operator"title="Permalink to this headline">¶</a></h3>
<p>The <codeclass="docutils literal"><spanclass="pre">Operator</span></code> class fills in the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message and calls the C++ function <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> to infer output shape from input shape.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">Operator</span></code> class fills in the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message and calls the C++ function <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> to infer the output shapes from the input shapes.</p>
<p><codeclass="docutils literal"><spanclass="pre">Operator</span></code> creates the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message in C++ space, so could it call the <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> function, which is in C++.</p>
<p><codeclass="docutils literal"><spanclass="pre">Operator</span></code> creates the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message in C++ space, so that it can call the <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> function, which is in C++.</p>
</div>
<divclass="section"id="variable">
<spanid="variable"></span><h3>Variable<aclass="headerlink"href="#variable"title="Permalink to this headline">¶</a></h3>
<p>Please be aware of <codeclass="docutils literal"><spanclass="pre">self.writer</span></code>, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each writes to a variable is represented by a Variable class. This is guaranteed by the fact that <strong><codeclass="docutils literal"><spanclass="pre">core.NewVarDesc</span></code> must NOT create a new <codeclass="docutils literal"><spanclass="pre">VarDesc</span></code> message if its name already exists in the specified block</strong>.</p>
<p>Please be aware of <codeclass="docutils literal"><spanclass="pre">self.writer</span></code>, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each write to a variable is represented by a Variable class. This is guaranteed by the fact that <strong><codeclass="docutils literal"><spanclass="pre">core.NewVarDesc</span></code> must NOT create a new <codeclass="docutils literal"><spanclass="pre">VarDesc</span></code> message if its name already exists in the specified block</strong>.</p>
</div>
<divclass="section"id="parameter">
<spanid="parameter"></span><h3>Parameter<aclass="headerlink"href="#parameter"title="Permalink to this headline">¶</a></h3>
@@ -15,9 +15,9 @@ Please be aware that these Python classes need to maintain some construction-tim
### Program
A `ProgramDesc` describes a [DL program](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md), which is composed of an array of `BlockDesc`s. A `BlockDesc` refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator needs to be able to access variables in its ancessor blocks.
A `ProgramDesc` describes a [DL program](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md), which is composed of an array of `BlockDesc`s. The `BlockDesc`s in a `ProgramDesc` can have a tree-like hierarchical structure. However, the `ProgramDesc` onlys stores a flattened array of `BlockDesc`s. A `BlockDesc` refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator need to be able to access variables in its ancestor blocks.
Whenever we create a block, we need set its parent block to the current block, so the Python class `Program` needs to maintain a data member `current_block`.
Whenever we create a block, we need to set its parent block to the current block, hence the Python class `Program` needs to maintain a data member `current_block`.
```python
class Program(objects):
...
...
@@ -81,13 +81,13 @@ class Block(objects):
self.ops.prepend(Operator(self, ...))
```
`create_parameter` is necessary because parameters are global variables, those defined in the global block, but can be created in some sub-blocks, e.g., an FC layer in the step block of an RNN operator.
`create_parameter` is necessary because parameters are global variables, defined in the global block, but can be created in some sub-blocks. For example, an FC layer in the step block of an RNN operator.
`prepand_operator` is necessary because the constructor of `Parameter` needs to create the initialize (or load) operator of the parameter, and would like to put it in the *preamble* of the global block.
`prepend_operator` is necessary because the constructor of `Parameter` needs to create the initialize (or load) operator of the parameter, and would like to put it in the *preamble* of the global block.
### Operator
The `Operator` class fills in the `OpDesc` message and calls the C++ function `InferShape` to infer output shape from input shape.
The `Operator` class fills in the `OpDesc` message and calls the C++ function `InferShape` to infer the output shapes from the input shapes.
```python
class Operator(object):
...
...
@@ -105,7 +105,7 @@ class Operator(object):
return self.proto.type()
```
`Operator` creates the `OpDesc` message in C++ space, so could it call the `InferShape` function, which is in C++.
`Operator` creates the `OpDesc` message in C++ space, so that it can call the `InferShape` function, which is in C++.
### Variable
...
...
@@ -128,7 +128,7 @@ class Variable(object):
self.writer = None
```
Please be aware of `self.writer`, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each writes to a variable is represented by a Variable class. This is guaranteed by the fact that **`core.NewVarDesc` must NOT create a new `VarDesc` message if its name already exists in the specified block**.
Please be aware of `self.writer`, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each write to a variable is represented by a Variable class. This is guaranteed by the fact that **`core.NewVarDesc` must NOT create a new `VarDesc` message if its name already exists in the specified block**.
<p>A <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> describes a <aclass="reference external"href="https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md">DL program</a>, which is composed of an array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. A <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code> refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator needs to be able to access variables in its ancessor blocks.</p>
<p>Whenever we create a block, we need set its parent block to the current block, so the Python class <codeclass="docutils literal"><spanclass="pre">Program</span></code> needs to maintain a data member <codeclass="docutils literal"><spanclass="pre">current_block</span></code>.</p>
<p>A <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> describes a <aclass="reference external"href="https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md">DL program</a>, which is composed of an array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. The <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s in a <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> can have a tree-like hierarchical structure. However, the <codeclass="docutils literal"><spanclass="pre">ProgramDesc</span></code> onlys stores a flattened array of <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code>s. A <codeclass="docutils literal"><spanclass="pre">BlockDesc</span></code> refers to its parent block by its index in the array. For example, operators in the step block of an RNN operator need to be able to access variables in its ancestor blocks.</p>
<p>Whenever we create a block, we need to set its parent block to the current block, hence the Python class <codeclass="docutils literal"><spanclass="pre">Program</span></code> needs to maintain a data member <codeclass="docutils literal"><spanclass="pre">current_block</span></code>.</p>
<spanclass="bp">self</span><spanclass="o">.</span><spanclass="n">proto</span><spanclass="o">=</span><spanclass="n">core</span><spanclass="o">.</span><spanclass="n">NewProgram</span><spanclass="p">()</span><spanclass="c1"># a C++ ProgramDesc pointer.</span>
<p><codeclass="docutils literal"><spanclass="pre">create_parameter</span></code> is necessary because parameters are global variables, those defined in the global block, but can be created in some sub-blocks, e.g., an FC layer in the step block of an RNN operator.</p>
<p><codeclass="docutils literal"><spanclass="pre">prepand_operator</span></code> is necessary because the constructor of <codeclass="docutils literal"><spanclass="pre">Parameter</span></code> needs to create the initialize (or load) operator of the parameter, and would like to put it in the <em>preamble</em> of the global block.</p>
<p><codeclass="docutils literal"><spanclass="pre">create_parameter</span></code> is necessary because parameters are global variables, defined in the global block, but can be created in some sub-blocks. For example, an FC layer in the step block of an RNN operator.</p>
<p><codeclass="docutils literal"><spanclass="pre">prepend_operator</span></code> is necessary because the constructor of <codeclass="docutils literal"><spanclass="pre">Parameter</span></code> needs to create the initialize (or load) operator of the parameter, and would like to put it in the <em>preamble</em> of the global block.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">Operator</span></code> class fills in the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message and calls the C++ function <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> to infer output shape from input shape.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">Operator</span></code> class fills in the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message and calls the C++ function <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> to infer the output shapes from the input shapes.</p>
<p><codeclass="docutils literal"><spanclass="pre">Operator</span></code> creates the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message in C++ space, so could it call the <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> function, which is in C++.</p>
<p><codeclass="docutils literal"><spanclass="pre">Operator</span></code> creates the <codeclass="docutils literal"><spanclass="pre">OpDesc</span></code> message in C++ space, so that it can call the <codeclass="docutils literal"><spanclass="pre">InferShape</span></code> function, which is in C++.</p>
<p>Please be aware of <codeclass="docutils literal"><spanclass="pre">self.writer</span></code>, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each writes to a variable is represented by a Variable class. This is guaranteed by the fact that <strong><codeclass="docutils literal"><spanclass="pre">core.NewVarDesc</span></code> must NOT create a new <codeclass="docutils literal"><spanclass="pre">VarDesc</span></code> message if its name already exists in the specified block</strong>.</p>
<p>Please be aware of <codeclass="docutils literal"><spanclass="pre">self.writer</span></code>, that tracks operator who creates the variable. It possible that there are more than one operators who write a variable, but in Python space, each write to a variable is represented by a Variable class. This is guaranteed by the fact that <strong><codeclass="docutils literal"><spanclass="pre">core.NewVarDesc</span></code> must NOT create a new <codeclass="docutils literal"><spanclass="pre">VarDesc</span></code> message if its name already exists in the specified block</strong>.</p>