Scan - version 8#
This page documents version 8 of operator Scan. See Scan for the latest version (since version 11).
Domain:
ai.onnxSince version: 8
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).
Note that the iterated element passed to the body subgraph does not have a sequence axis. It will have a rank one less than the rank of the corresponding scan_input.
Inputs
sequence_lens (I): Optional tensor specifying lengths of the sequences in a batch. If this input is not specified, all sequences are assumed to be of the maximum sequence length (the dimension of the sequence axis of the scan_input tensors).
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.
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.
num_scan_inputs (int): An attribute specifying the number of scan_inputs M.
Type Constraints
I: Int64 tensor Allowed types: tensor(int64).
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_scan_sum
Node:
Scan("", initial, x) -> (y, z)
Attributes:
body = <subgraph>
num_scan_inputs = 1
Inputs:
initial: shape=(1, 2), dtype=float32
[[0., 0.]]
x: shape=(1, 3, 2), dtype=float32
[[[1., 2.],
[3., 4.],
[5., 6.]]]
Outputs:
y: shape=(1, 2), dtype=float32
[[ 9., 12.]]
z: shape=(1, 3, 2), dtype=float32
[[[ 1., 2.],
[ 4., 6.],
[ 9., 12.]]]