The variable in our design can hold variant types. Such as `LoDTensor` and `SelectedRows`. An operator should be able to inference the variable types of its output.
For example, a `lookup table` operator takes two `LoDTensor`; one is a float tensor as the embedding table, the other is an int tensor as word ID. The gradient operator of `lookup table` will generate a `SelectedRows` as its output. A `sum` operator can take both `LoDTensor` and `SelectedRows` as its inputs and will generate a `LoDTensor` if any of its inputs is `LoDTensor`, otherwise, the `sum` operator will generate `SelectedRows` as its output.
The variable type will be constant at runtime. Every variable's type can either be set by the user (input data and parameter) or be inferred by the operator in compile time.
## Proposed Solution
The `InferVarType` is a compile-time function which is registered to each operator. The inferface of that function is:
// set the output type of variable as `LoDTensor`.
// ...
}
struct OpInfo {
InferVarTypeFN infer_var_type_;
InferVarTypeFN GetInferVarType() const {
if (infer_var_type_) {
return infer_var_type_;
} else {
return DefaultInferVarType;
}
}
};
```
## Register InferVarType
We provide a thin base class for registering an `InferVarTypeFN`. To use a base class will ease the implementation of registry since we can detect the registry entry is an `InferVarTypeFN` or not.
<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-infervartype"></span><h1>Design Doc: InferVarType<aclass="headerlink"href="#design-doc-infervartype"title="Permalink to this headline">¶</a></h1>
<divclass="section"id="the-problem-posed">
<spanid="the-problem-posed"></span><h2>The Problem Posed<aclass="headerlink"href="#the-problem-posed"title="Permalink to this headline">¶</a></h2>
<p>The variable in our design can hold variant types. Such as <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> and <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code>. An operator should be able to inference the variable types of its output.</p>
<p>For example, a <codeclass="docutils literal"><spanclass="pre">lookup</span><spanclass="pre">table</span></code> operator takes two <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>; one is a float tensor as the embedding table, the other is an int tensor as word ID. The gradient operator of <codeclass="docutils literal"><spanclass="pre">lookup</span><spanclass="pre">table</span></code> will generate a <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its output. A <codeclass="docutils literal"><spanclass="pre">sum</span></code> operator can take both <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> and <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its inputs and will generate a <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> if any of its inputs is <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>, otherwise, the <codeclass="docutils literal"><spanclass="pre">sum</span></code> operator will generate <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its output.</p>
<p>The variable type will be constant at runtime. Every variable’s type can either be set by the user (input data and parameter) or be inferred by the operator in compile time.</p>
</div>
<divclass="section"id="proposed-solution">
<spanid="proposed-solution"></span><h2>Proposed Solution<aclass="headerlink"href="#proposed-solution"title="Permalink to this headline">¶</a></h2>
<p>The <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> is a compile-time function which is registered to each operator. The inferface of that function is:</p>
<p>It takes an operator description as its input and will write the output variable type and store them in block description.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code> will be registered in <codeclass="docutils literal"><spanclass="pre">OpInfo</span></code>, to replace <codeclass="docutils literal"><spanclass="pre">infer_var_type_</span></code> field. The <codeclass="docutils literal"><spanclass="pre">OpInfo</span></code> should be</p>
<p>The default <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> will set output type as <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>. It can be done by <codeclass="docutils literal"><spanclass="pre">GetInferVarType()</span></code>.</p>
<spanid="register-infervartype"></span><h2>Register InferVarType<aclass="headerlink"href="#register-infervartype"title="Permalink to this headline">¶</a></h2>
<p>We provide a thin base class for registering an <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code>. To use a base class will ease the implementation of registry since we can detect the registry entry is an <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code> or not.</p>
<p>Then user can register the <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> just like <codeclass="docutils literal"><spanclass="pre">GradOpDescMaker</span></code> and <codeclass="docutils literal"><spanclass="pre">OpInfoMaker</span></code>.</p>
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 variable in our design can hold variant types. Such as `LoDTensor` and `SelectedRows`. An operator should be able to inference the variable types of its output.
For example, a `lookup table` operator takes two `LoDTensor`; one is a float tensor as the embedding table, the other is an int tensor as word ID. The gradient operator of `lookup table` will generate a `SelectedRows` as its output. A `sum` operator can take both `LoDTensor` and `SelectedRows` as its inputs and will generate a `LoDTensor` if any of its inputs is `LoDTensor`, otherwise, the `sum` operator will generate `SelectedRows` as its output.
The variable type will be constant at runtime. Every variable's type can either be set by the user (input data and parameter) or be inferred by the operator in compile time.
## Proposed Solution
The `InferVarType` is a compile-time function which is registered to each operator. The inferface of that function is:
// set the output type of variable as `LoDTensor`.
// ...
}
struct OpInfo {
InferVarTypeFN infer_var_type_;
InferVarTypeFN GetInferVarType() const {
if (infer_var_type_) {
return infer_var_type_;
} else {
return DefaultInferVarType;
}
}
};
```
## Register InferVarType
We provide a thin base class for registering an `InferVarTypeFN`. To use a base class will ease the implementation of registry since we can detect the registry entry is an `InferVarTypeFN` or not.
<spanid="the-problem-posed"></span><h2>The Problem Posed<aclass="headerlink"href="#the-problem-posed"title="永久链接至标题">¶</a></h2>
<p>The variable in our design can hold variant types. Such as <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> and <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code>. An operator should be able to inference the variable types of its output.</p>
<p>For example, a <codeclass="docutils literal"><spanclass="pre">lookup</span><spanclass="pre">table</span></code> operator takes two <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>; one is a float tensor as the embedding table, the other is an int tensor as word ID. The gradient operator of <codeclass="docutils literal"><spanclass="pre">lookup</span><spanclass="pre">table</span></code> will generate a <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its output. A <codeclass="docutils literal"><spanclass="pre">sum</span></code> operator can take both <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> and <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its inputs and will generate a <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code> if any of its inputs is <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>, otherwise, the <codeclass="docutils literal"><spanclass="pre">sum</span></code> operator will generate <codeclass="docutils literal"><spanclass="pre">SelectedRows</span></code> as its output.</p>
<p>The variable type will be constant at runtime. Every variable’s type can either be set by the user (input data and parameter) or be inferred by the operator in compile time.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> is a compile-time function which is registered to each operator. The inferface of that function is:</p>
<p>It takes an operator description as its input and will write the output variable type and store them in block description.</p>
<p>The <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code> will be registered in <codeclass="docutils literal"><spanclass="pre">OpInfo</span></code>, to replace <codeclass="docutils literal"><spanclass="pre">infer_var_type_</span></code> field. The <codeclass="docutils literal"><spanclass="pre">OpInfo</span></code> should be</p>
<p>The default <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> will set output type as <codeclass="docutils literal"><spanclass="pre">LoDTensor</span></code>. It can be done by <codeclass="docutils literal"><spanclass="pre">GetInferVarType()</span></code>.</p>
<p>We provide a thin base class for registering an <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code>. To use a base class will ease the implementation of registry since we can detect the registry entry is an <codeclass="docutils literal"><spanclass="pre">InferVarTypeFN</span></code> or not.</p>
<p>Then user can register the <codeclass="docutils literal"><spanclass="pre">InferVarType</span></code> just like <codeclass="docutils literal"><spanclass="pre">GradOpDescMaker</span></code> and <codeclass="docutils literal"><spanclass="pre">OpInfoMaker</span></code>.</p>
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>.