.. _op_ai_onnx_Scan: Scan ==== - **Domain**: ``ai.onnx`` - **Since version**: 11 Scan can be used to iterate over one or more scan_input tensors, constructing zero or more scan_output tensors. It combines ideas from general recurrences, functional programming constructs such as scan, fold, map, and zip, and is intended to enable generalizations of RNN-like constructs for sequence-to-sequence processing. Other tensors (referred to as state_variables here) can be used to carry a state when iterating from one element to another (similar to hidden-state in RNNs, also referred to as loop-carried dependences in the context of loops). Many common usages involve a single scan_input tensor (where functionality similar to scan, fold and map can be obtained). When more than one scan_input is used, a behavior similar to zip is obtained. The attribute body must be a graph, specifying the computation to be performed in every iteration. It takes as input the current values of the state_variables and the current iterated element of the scan_inputs. It must return the (updated) values of the state_variables and zero or more scan_output_element tensors. The values of the scan_output_element tensors are concatenated over all the iterations to produce the scan_output values of the scan construct (similar to the concatenated intermediate hidden-state values of RNN-like constructs). All the output tensors (state_variables as well as scan_output_element tensors) are required to have the same shape in each iteration of the loop (a restriction imposed to enable efficient memory allocation). The operation supports batching, and the batch-axis is required to be 0. When multiple scan_input tensors are used, they must all have the same batch-size, and they must all have the same maximum-sequence-length (the dimensionality of the sequence axis or scan axis). **Inputs** - **initial_state_and_scan_inputs** (*V*): Initial values of the loop's N state variables followed by M scan_inputs **Outputs** - **final_state_and_scan_outputs** (*V*): Final values of the loop's N state variables followed by K scan_outputs **Attributes** - **body** (*graph*): The graph run each iteration. It has N+M inputs: (loop state variables..., scan_input_elts...). It has N+K outputs: (loop state variables..., scan_output_elts...). Each scan_output is created by concatenating the value of the specified scan_output_elt value at the end of each iteration of the loop. It is an error if the dimensions of these values change across loop iterations. - **num_scan_inputs** (*int*): An attribute specifying the number of scan_inputs M. - **scan_input_axes** (*int[]*): An optional list of M flags. The i-th element of the list specifies the axis to be scanned (the sequence axis) for the i-th scan_input. If omitted, 0 will be used as the scan axis for every scan_input. Negative value for an axis means counting dimensions from the back. Accepted range is [-r, r-1] where r = rank(input). - **scan_input_directions** (*int[]*): An optional list of M flags. The i-th element of the list specifies the direction to be scanned for the i-th scan_input tensor: 0 indicates forward direction and 1 indicates reverse direction. If omitted, all scan_input tensors will be scanned in the forward direction. - **scan_output_axes** (*int[]*): An optional list of K flags. The i-th element of the list specifies the axis for the i-th scan_output. The scan outputs are accumulated along the specified axis. If omitted, 0 will be used as the scan axis for every scan_output. Negative value for an axis means counting dimensions from the back. Accepted range is [-r, r-1]. - **scan_output_directions** (*int[]*): An optional list of K flags, one for each scan_output. The i-th element of the list specifies whether the i-th scan_output should be constructed by appending or prepending a new value in each iteration: 0 indicates appending and 1 indicates prepending. If omitted, all scan_output tensors will be produced by appending a value in each iteration. **Type Constraints** - **V**: All Tensor types Allowed types: tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8). Examples -------- **test_cc_scan_basic_trip_count** .. code-block:: text Node: Scan(X) -> (Y) Attributes: body = num_scan_inputs = 1 .. code-block:: text Inputs: X: shape=(3, 2), dtype=float32 [[0., 1.], [2., 3.], [4., 5.]] Outputs: Y: shape=(3, 2), dtype=float32 [[0., 1.], [2., 3.], [4., 5.]] **test_cc_scan_pairwise_distance** .. code-block:: text Node: Scan(X_state, X_scan) -> (state_X_final, dists) Attributes: body = num_scan_inputs = 1 .. code-block:: text Inputs: X_state: shape=(3, 2), dtype=float32 [[1., 2.], [3., 4.], [5., 6.]] X_scan: shape=(3, 2), dtype=float32 [[1., 2.], [3., 4.], [5., 6.]] Outputs: state_X_final: shape=(3, 2), dtype=float32 [[1., 2.], [3., 4.], [5., 6.]] dists: shape=(3, 3), dtype=float32 [[ 0., 8., 32.], [ 8., 0., 8.], [32., 8., 0.]] **test_cc_scan_zero_trip_count** .. code-block:: text Node: Scan(X) -> (Y) Attributes: body = num_scan_inputs = 1 .. code-block:: text Inputs: X: shape=(0, 2), dtype=float32 [] Outputs: Y: shape=(0, 2), dtype=float32 [] Differences with previous version (9) ------------------------------------- **SchemaDiff**: ``Scan`` (domain ``'ai.onnx'``) * old version: 9 * new version: 11 * breaking: no Version History --------------- - :doc:`Version 9 ` - :doc:`Version 8 `