## If <a name="If"></a> {#openvino_docs_ops_infrastructure_If_8}

**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_body` are subgraphs that are executed depending on the `cond` value. 
    The subgraph is described operation by operation as a typical IR network. 
    The subgraph has inputs (`Parameter` operations) and outputs (`Result` operations).
    
    * **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_body` outputs is equal to the number of outputs from *If* and 
    the number of `else_body` outputs.
    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_map` entries can be `input` and `output`. Each entry describes a corresponding mapping rule. 
    *If* has two *port_maps*: `then_port_map` for `then_body` and `else_port_map` for `else_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 int`
            * **Default value**: None
            * **Required**: *yes*

        * *internal_layer_id*

            * **Description**: *internal_layer_id* is a `Parameter` or `Result` operation ID inside 
            the subgraph to map to.
            * **Range of values**: IDs of the `Parameter` or `Result` operations in the subgraph
            * **Type**: `unsigned int`
            * **Default value**: None
            * **Required**: *yes* 

**If Inputs**


* **cond**: A scalar or 1D tensor with 1 element of `boolean` type 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*
```xml
    <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>
```
