diff --git a/docs/doxygen/ie_docs.xml b/docs/doxygen/ie_docs.xml index 120b5e17e800eb..5ea61f802a3f9c 100644 --- a/docs/doxygen/ie_docs.xml +++ b/docs/doxygen/ie_docs.xml @@ -175,6 +175,7 @@ + diff --git a/docs/ops/infrastructure/Loop_5.md b/docs/ops/infrastructure/Loop_5.md new file mode 100644 index 00000000000000..3b6ad094e44eec --- /dev/null +++ b/docs/ops/infrastructure/Loop_5.md @@ -0,0 +1,181 @@ +## Loop {#openvino_docs_ops_infrastructure_Loop_5} + +**Versioned name**: *Loop-5* + +**Category**: Infrastructure + +**Short description**: *Loop* operation performs recurrent execution of the network, which is described in the `body`, iterating through the data. +The operation has similar semantic to the ONNX* Loop [operation](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Loop-13). + +**Detailed description** + +The body of the Loop can be executed 0 or more times depending on the values passed to the Loop operation inputs called "trip count", "execution condition" and input of the Loop body called "current iteration". + +These Loop operation inputs have the following meaning: +1. Trip count is an integer scalar or 1D tensor with 1 element input specifying maximum number of iterations. To simulate infinite loop Constant `-1` can be provided as input. +2. Loop execution condition input is a boolean scalar or 1D tensor with 1 element input specifying whether to run the first loop iteration or not. Note, that the body of the Loop must yield the condition value for the consecutive iterations. + +There are several combinations of these two inputs `(trip_count, execution condition)` which are described in the following code snippet: + +``` + input (-1, true) // infinite loop + bool cond = true; + for (int i = 0; cond; ++i) + { + cond = true; // sub-graph calculating condition must always return "true"! + } + + input (-1, cond) // while loop + bool cond = ...; + for (int i = 0; cond; ++i) + { + cond = ...; + } + + input (-1, true) // do-while loop + bool cond = true; + for (int i = 0; cond; ++i) + { + cond = ...; + } + + input (trip_count, true) // for loop + int trip_count = ...; + bool cond = true; + for (int i = 0; i < trip_count; ++i) + { + cond = true; // sub-graph calculating condition must always return "true"! + } + + input (trip_count, cond) // for with condition + int trip_count = ...; + bool cond = ...; + for (int i = 0; i < trip_count && cond; ++i) + { + cond = ...; + } +``` + +1. One of the body graph inputs called "current iteration" is an integer scalar or 1D integer tensor with 1 number specifying current iteration number. The iteration number starts from 0 and incremented by one for each iteration. This input is optional and may not exist if the iteration number value is not used in the body. +2. One of the body graph outputs is called "condition" is a boolean scalar or 1D tensor with 1 element. This value is used to decide whenever to perform the next iteration or not. + +Loop operation description in the IR has regular sections: `input` and `output`. They connect Loop body to the outer graph and specify condition(s). +Loop operation description in the IR also has several special sections: `body`, `port_map` and `back_edges` similar to the ones from the TensorIterator operation but having some important features described below. + +1. The body operation getting an input from the main graph should have an entry in the `port_map` section of the Loop operation. These edges connect input ports of the Loop with the body `Parameter`s. +2. The body operation producing tensor to be used in the subsequent iterations (like in RNN models) should have a back edge described in the `back_edges` section of the operation. The back edge connects the respective body `Parameter` and `Result` operations. For such a case the Loop operation node provides input for the first iteration, while corresponding Loop operation output produces the tensor computed during the last iteration. +3. Output tensors produced by a particular body operation across all iterations can be concatenated and returned as a Loop operation output (this is a "scan output" according to the ONNX* Loop operation [specification](https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Loop-13)). The corresponding `output` entry in the `port_map` should have `axis` attribute specifying the axis to concatenate. Therefore, outputs from operations corresponding to `output` entries in the `port_map` without `axis` attribute are returned "as is" (without concatenation). +4. There is one body `Parameter` operation not connected through the `port_map`. This is a "current iteration" input. The Loop operation is responsible for providing the appropriate value for each iteration. +5. Connection of nodes inside the Loop body with the main graph should be done through `Parameter` and `Result` body operations. No other ways to connect graphs are allowed. + +**Loop attributes**: + +* **Body**: + + `body` is a network that will be recurrently executed. The network is described operation by operation as a typical IR network. + + * **Body attributes**: + + No attributes available. + +* **Port map**: + + *port_map* is a set of rules to map input or output data tensors of `Loop` operation onto `body` data tensors. The `port_map` entries can be` input` and `output`. Each entry describes a corresponding mapping rule. + + * **Port map attributes**: + + * *external_port_id* + * **Description**: *external_port_id* is a port ID of the `Loop` operation. + * **Range of values**: IDs of the *Loop* outputs + * **Type**: `int` + * **Default value**: None + * **Required**: *yes* + + * *internal_layer_id* + + * **Description**: *internal_layer_id* is a `Parameter` or `Result` operation ID inside the `body` network to map to. + * **Range of values**: IDs of the `Parameter` operations inside in the *Loop* operation + * **Type**: `int` + * **Default value**: None + * **Required**: *yes* + + * *axis* + + * **Description**: *axis* is an axis to concatenate the body `Result` output across all iterations. Can be specified for `output` entry only. + * **Range of values**: an integer. Negative value means counting dimension from the end. + * **Type**: `int` + * **Default value**: None + * **Required**: *no* + +* **Back edges**: + + *back_edges* is a set of rules to transfer tensor values from `body` outputs at one iteration to `body` parameters at the next iteration. Back edge connects some `Result` operation in the `body` to `Parameter` operation in the same `body`. + + * **Back edge attributes**: + + * *from-layer* + + * **Description**: *from-layer* is a `Result` operation ID inside the `body` network. + * **Range of values**: IDs of the `Result` operations inside the *Loop* + * **Type**: `int` + * **Default value**: None + * **Required**: *yes* + + * *to-layer* + + * **Description**: *to-layer* is a `Parameter` operation ID inside the `body` network to end mapping. + * **Range of values**: IDs of the `Parameter` operations inside the *Loop* + * **Type**: `int` + * **Default value**: None + * **Required**: *yes* + +**Loop Inputs** + +* **Trip count**: A scalar or 1D tensor with 1 element of `int64` or `int32` type specifying maximum number of iterations. *Required*. + +* **ExecutionCondition**: A scalar or 1D tensor with 1 element of `boolean` type specifying whether to execute the first iteration or not. `True` value means to execute the 1st iteration. *Required*. + +* **Multiple other inputs**: tensors of different types and shapes. *Optional*. + +**Loop Outputs** + +* **Multiple outputs**: Results of execution of the `body`. Tensors of any type and shape. + + +**Body Inputs** + +* **Multiple inputs**: tensors of different types and shapes except the one corresponding to the current iteration number. This input is marked in the port_map with attribute `purpose = "current_iteration"` and produces a scalar or 1D tensor with 1 element of `int64` or `int32` type. *Optional*. + + +**Body Outputs** + +* **Multiple outputs**: Results of execution of the `body`. Tensors of any type and shape except the one corresponding to the output with execution condition. This output is marked in the port_map with attribute `purpose = "execution_condition"` and is mandatory and produces a scalar or 1D tensor with 1 element of `boolean` type. Other outputs are optional. + + +**Examples** + +*Example 1: a typical Loop structure* +```xml + + ... + ... + + + + + ... + + + + ... + + + + ... + + + ... + ... + + +``` diff --git a/docs/ops/opset5.md b/docs/ops/opset5.md index e75edf275dd157..75db70238f8ee6 100644 --- a/docs/ops/opset5.md +++ b/docs/ops/opset5.md @@ -76,6 +76,7 @@ declared in `namespace opset5`. * [LogicalOr](logical/LogicalOr_1.md) * [LogicalXor](logical/LogicalXor_1.md) * [LogSoftmax](activation/LogSoftmax_5.md) +* [Loop](infrastructure/Loop_5.md) * [LRN](normalization/LRN_1.md) * [LSTMCell](sequence/LSTMCell_1.md) * [LSTMSequence](sequence/LSTMSequence_1.md)