If¶
Versioned name: If-8
Category: Condition
Short description: If operation contains two internal networks(subgraphs) such as then_body and else_body,
and performs one of them depending on cond value. If cond is True, then_body is executed. If cond is False,
the operation executes the else_body subgraph.
Detailed description
If must not contain empty subgraphs. Each of them must have at least one operation Result.
Also the number of outputs from If always must be greater than zero and equal to the number of outputs from each subgraph.
If attributes:
Subgraphs:
then_body/else_bodyare subgraphs that are executed depending on thecondvalue. The subgraph is described operation by operation as a typical IR network. The subgraph has inputs (Parameteroperations) and outputs (Resultoperations).Subgraph’s inputs - inputs to the subgraph which associated with If inputs via port_map.
The subgraph can have any number of inputs (even zero).
Subgraph’s outputs - outputs from the subgraph which associated with If outputs via port_map.
The subgraph must contain at least one output. Each If output is associated with one output from the subgraph. Therefore the number of
then_bodyoutputs is equal to the number of outputs from If and the number ofelse_bodyoutputs. The type of the subgraph output and the type of the associated output from If must be equal.
Port maps:
port_map is a set of rules to map input or output data tensors of If operation onto the subgraph data tensors. The
port_mapentries can beinputandoutput. Each entry describes a corresponding mapping rule. If has two port_maps:then_port_mapforthen_bodyandelse_port_mapforelse_body.Port map attributes:
external_port_id
Description: external_port_id is a port ID of If operation.
Range of values: IDs of the If inputs and outputs
Type:
unsigned intDefault value: None
Required: yes
internal_layer_id
Description: internal_layer_id is a
ParameterorResultoperation ID inside
the subgraph to map to. * Range of values: IDs of the
ParameterorResultoperations in the subgraph * Type:unsigned int* Default value: None * Required: yes
If Inputs
cond: A scalar or 1D tensor with 1 element of
booleantype specifying which subgraph to execute.
True value means to execute the then_body, False - else_body. Required.
Multiple other inputs: Tensors of different types and shapes. Optional.
If Outputs
Multiple outputs: Results of execution of one of the subgraph. Tensors of any type and shape.
Body Inputs
Multiple inputs: Tensors of different types and shapes. Optional.
Body Outputs
Multiple outputs: Results of execution of the subgraph. Tensors of any type and shape.
Examples
Example 1: a typical If structure
<layer id="6" name="if/cond" type="If" version="opset8">
<input>
<port id="0"/>
<port id="1">
<dim>2</dim>
<dim>4</dim>
</port>
<port id="2">
<dim>2</dim>
<dim>4</dim>
</port>
<port id="3">
<dim>2</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="4" names="if/cond/Identity:0,if/cond:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
<then_port_map>
<input external_port_id="1" internal_layer_id="0"/>
<input external_port_id="2" internal_layer_id="1"/>
<output external_port_id="0" internal_layer_id="3"/>
</then_port_map>
<else_port_map>
<input external_port_id="1" internal_layer_id="0"/>
<input external_port_id="3" internal_layer_id="1"/>
<output external_port_id="0" internal_layer_id="3"/>
</else_port_map>
<then_body>
<layers>
<layer id="0" name="add_x" type="Parameter" version="opset1">
<data element_type="f32" shape="2,4"/>
<output>
<port id="0" names="add_x:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="add_z" type="Parameter" version="opset1">
<data element_type="f32" shape="2,4"/>
<output>
<port id="0" names="add_z:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="2" name="Add" type="Add" version="opset1">
<data auto_broadcast="numpy"/>
<input>
<port id="0">
<dim>2</dim>
<dim>4</dim>
</port>
<port id="1">
<dim>2</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="2" names="Add:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="3" name="Identity/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>2</dim>
<dim>4</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
<edge from-layer="2" from-port="2" to-layer="3" to-port="0"/>
</edges>
</then_body>
<else_body>
<layers>
<layer id="0" name="add_x" type="Parameter" version="opset1">
<data element_type="f32" shape="2,4"/>
<output>
<port id="0" names="add_x:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="1" name="add_w" type="Parameter" version="opset1">
<data element_type="f32" shape="2,4"/>
<output>
<port id="0" names="add_w:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="2" name="Add" type="Add" version="opset1">
<data auto_broadcast="numpy"/>
<input>
<port id="0">
<dim>2</dim>
<dim>4</dim>
</port>
<port id="1">
<dim>2</dim>
<dim>4</dim>
</port>
</input>
<output>
<port id="2" names="Add:0" precision="FP32">
<dim>2</dim>
<dim>4</dim>
</port>
</output>
</layer>
<layer id="3" name="Identity/sink_port_0" type="Result" version="opset1">
<input>
<port id="0">
<dim>2</dim>
<dim>4</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="0" to-layer="2" to-port="1"/>
<edge from-layer="2" from-port="2" to-layer="3" to-port="0"/>
</edges>
</else_body>
</layer>