The basic structure of a PaddlePaddle program is some nested blocks, as a C++ or Java program.
As described in [graph.md](./graph.md), the first five lines of the following PaddlePaddle program
```python
x = layer.data("images")
l = layer.data("label")
y = layer.fc(x)
cost = layer.mse(y, l)
optimize(cost)
train(cost, reader=mnist.train())
```
generates, or compiles, a PaddelPaddle program, which is represented by the following protobuf message:
```protobuf
message ProgramDesc {
repeated BlockDesc blocks = 1;
}
message BlockDesc {
required int32 parent = 1;
repeated VarDesc vars = 2;
repeated OpDesc ops = 3;
}
message OpDesc {
AttrDesc attrs = 1;
...
}
message AttrDesc {
required AttrType type = 1;
// index into ProgramDesc::blocks when type==BLOCK
optional int32 block = 2;
...
}
```
When each of the first five lines runs, related Python function, e.g., `layer.fc`, calls C++ InferShape functions. This InferShape function needs to access the properties of VarDesc's accessed by the current OpDesc. These VarDesc's might not be defined in the current block, but in some ancestor blocks. This requires that we can trace the parent of a block.
A nested block is often an attribute of an operator, most likely, an IfElseOp or a WhileOp. In above solution, all blocks are in `ProgramDesc::blocks`, this implicitly assigns a zero-based ID to each block -- the index of the block in `ProgramDesc::blocks`. So that `AttrDesc::block` could be an integer block ID.
With this design, the InferShape function should take the following parameters:
```c++
void InferShape(int current_block,
int current_operator,
ProgramDesc* program // might change VarDesc values.
) {
...
}
```
where
- `current_block` indices into `ProgramDesc::blocks`,
- `current_operator` indices into `BlockDesc::ops`.
<liclass="toctree-l2"><aclass="reference internal"href="../getstarted/build_and_install/index_en.html">Install and Build</a><ul>
<liclass="toctree-l3"><aclass="reference internal"href="../getstarted/build_and_install/docker_install_en.html">PaddlePaddle in Docker Containers</a></li>
<liclass="toctree-l3"><aclass="reference internal"href="../getstarted/build_and_install/build_from_source_en.html">Installing from Sources</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/usage/k8s/k8s_en.html">Paddle On Kubernetes</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/usage/k8s/k8s_aws_en.html">Distributed PaddlePaddle Training on AWS with Kubernetes</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/dev/build_en.html">Build PaddlePaddle from Source Code and Run Unit Test</a></li>
<liclass="toctree-l2"><aclass="reference internal"href="../howto/dev/new_layer_en.html">Write New Layers</a></li>
<spanid="design-doc-programdesc"></span><h1>Design Doc: ProgramDesc<aclass="headerlink"href="#design-doc-programdesc"title="Permalink to this headline">¶</a></h1>
<p>The basic structure of a PaddlePaddle program is some nested blocks, as a C++ or Java program.</p>
<p>As described in <aclass="reference internal"href="graph.html"><spanclass="doc">graph.md</span></a>, the first five lines of the following PaddlePaddle program</p>
<p>When each of the first five lines runs, related Python function, e.g., <codeclass="docutils literal"><spanclass="pre">layer.fc</span></code>, calls C++ InferShape functions. This InferShape function needs to access the properties of VarDesc’s accessed by the current OpDesc. These VarDesc’s might not be defined in the current block, but in some ancestor blocks. This requires that we can trace the parent of a block.</p>
<p>A nested block is often an attribute of an operator, most likely, an IfElseOp or a WhileOp. In above solution, all blocks are in <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>, this implicitly assigns a zero-based ID to each block – the index of the block in <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>. So that <codeclass="docutils literal"><spanclass="pre">AttrDesc::block</span></code> could be an integer block ID.</p>
<p>With this design, the InferShape function should take the following parameters:</p>
<li><codeclass="docutils literal"><spanclass="pre">current_block</span></code> indices into <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>,</li>
<li><codeclass="docutils literal"><spanclass="pre">current_operator</span></code> indices into <codeclass="docutils literal"><spanclass="pre">BlockDesc::ops</span></code>.</li>
Built with <ahref="http://sphinx-doc.org/">Sphinx</a> using a <ahref="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <ahref="https://readthedocs.org">Read the Docs</a>.
The basic structure of a PaddlePaddle program is some nested blocks, as a C++ or Java program.
As described in [graph.md](./graph.md), the first five lines of the following PaddlePaddle program
```python
x = layer.data("images")
l = layer.data("label")
y = layer.fc(x)
cost = layer.mse(y, l)
optimize(cost)
train(cost, reader=mnist.train())
```
generates, or compiles, a PaddelPaddle program, which is represented by the following protobuf message:
```protobuf
message ProgramDesc {
repeated BlockDesc blocks = 1;
}
message BlockDesc {
required int32 parent = 1;
repeated VarDesc vars = 2;
repeated OpDesc ops = 3;
}
message OpDesc {
AttrDesc attrs = 1;
...
}
message AttrDesc {
required AttrType type = 1;
// index into ProgramDesc::blocks when type==BLOCK
optional int32 block = 2;
...
}
```
When each of the first five lines runs, related Python function, e.g., `layer.fc`, calls C++ InferShape functions. This InferShape function needs to access the properties of VarDesc's accessed by the current OpDesc. These VarDesc's might not be defined in the current block, but in some ancestor blocks. This requires that we can trace the parent of a block.
A nested block is often an attribute of an operator, most likely, an IfElseOp or a WhileOp. In above solution, all blocks are in `ProgramDesc::blocks`, this implicitly assigns a zero-based ID to each block -- the index of the block in `ProgramDesc::blocks`. So that `AttrDesc::block` could be an integer block ID.
With this design, the InferShape function should take the following parameters:
```c++
void InferShape(int current_block,
int current_operator,
ProgramDesc* program // might change VarDesc values.
) {
...
}
```
where
- `current_block` indices into `ProgramDesc::blocks`,
- `current_operator` indices into `BlockDesc::ops`.
<p>The basic structure of a PaddlePaddle program is some nested blocks, as a C++ or Java program.</p>
<p>As described in <aclass="reference internal"href="graph.html"><spanclass="doc">graph.md</span></a>, the first five lines of the following PaddlePaddle program</p>
<p>When each of the first five lines runs, related Python function, e.g., <codeclass="docutils literal"><spanclass="pre">layer.fc</span></code>, calls C++ InferShape functions. This InferShape function needs to access the properties of VarDesc’s accessed by the current OpDesc. These VarDesc’s might not be defined in the current block, but in some ancestor blocks. This requires that we can trace the parent of a block.</p>
<p>A nested block is often an attribute of an operator, most likely, an IfElseOp or a WhileOp. In above solution, all blocks are in <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>, this implicitly assigns a zero-based ID to each block – the index of the block in <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>. So that <codeclass="docutils literal"><spanclass="pre">AttrDesc::block</span></code> could be an integer block ID.</p>
<p>With this design, the InferShape function should take the following parameters:</p>
<li><codeclass="docutils literal"><spanclass="pre">current_block</span></code> indices into <codeclass="docutils literal"><spanclass="pre">ProgramDesc::blocks</span></code>,</li>
<li><codeclass="docutils literal"><spanclass="pre">current_operator</span></code> indices into <codeclass="docutils literal"><spanclass="pre">BlockDesc::ops</span></code>.</li>
Built with <ahref="http://sphinx-doc.org/">Sphinx</a> using a <ahref="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <ahref="https://readthedocs.org">Read the Docs</a>.