SequenceMap#

SequenceMap - 17#

Version

  • name: SequenceMap (GitHub)

  • domain: main

  • since_version: 17

  • function: False

  • support_level: SupportType.COMMON

  • shape inference: True

This version of the operator has been available since version 17.

Summary

Applies a sub-graph to each sample in the input sequence(s).

Inputs can be either tensors or sequences, with the exception of the first input which must be a sequence. The length of the first input sequence will determine the number of samples in the outputs. Any other sequence inputs should have the same number of samples. The number of inputs and outputs, should match the one of the subgraph.

For each i-th element in the output, a sample will be extracted from the input sequence(s) at the i-th position and the sub-graph will be applied to it. The outputs will contain the outputs of the sub-graph for each sample, in the same order as in the input.

This operator assumes that processing each sample is independent and could executed in parallel or in any order. Users cannot expect any specific ordering in which each subgraph is computed.

Attributes

  • body (required): The graph to be run for each sample in the sequence(s). It should have as many inputs and outputs as inputs and outputs to the SequenceMap function.

Inputs

Between 1 and 2147483647 inputs.

  • input_sequence (heterogeneous) - S: Input sequence.

  • additional_inputs (variadic) - V: Additional inputs to the graph

Outputs

Between 1 and 2147483647 outputs.

  • out_sequence (variadic) - S: Output sequence(s)

Type Constraints

  • S in ( seq(tensor(bool)), seq(tensor(complex128)), seq(tensor(complex64)), seq(tensor(double)), seq(tensor(float)), seq(tensor(float16)), seq(tensor(int16)), seq(tensor(int32)), seq(tensor(int64)), seq(tensor(int8)), seq(tensor(string)), seq(tensor(uint16)), seq(tensor(uint32)), seq(tensor(uint64)), seq(tensor(uint8)) ): Constrain input types to any sequence type.

  • V in ( seq(tensor(bool)), seq(tensor(complex128)), seq(tensor(complex64)), seq(tensor(double)), seq(tensor(float)), seq(tensor(float16)), seq(tensor(int16)), seq(tensor(int32)), seq(tensor(int64)), seq(tensor(int8)), seq(tensor(string)), seq(tensor(uint16)), seq(tensor(uint32)), seq(tensor(uint64)), seq(tensor(uint8)), 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) ): Constrain to any tensor or sequence type.

Examples

_sequence_map_identity_1_sequence

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Identity', ['in0'], ['out0'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info(
        'in0', onnx.TensorProto.FLOAT, ['N'])],
    [onnx.helper.make_tensor_value_info(
        'out0', onnx.TensorProto.FLOAT, ['M'])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['x'],
    outputs=['y'],
    body=body
)

x = [np.random.uniform(0.0, 1.0, 10).astype(np.float32)
     for _ in range(3)]
y = x
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
]
expect(node, inputs=[x], outputs=[y],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_identity_1_sequence')

_sequence_map_identity_2_sequences

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Identity', ['in0'], ['out0']),
     onnx.helper.make_node('Identity', ['in1'], ['out1'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info('in0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info('in1', onnx.TensorProto.FLOAT, ['M'])],
    [onnx.helper.make_tensor_value_info('out0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info('out1', onnx.TensorProto.FLOAT, ['M'])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['x0', 'x1'],
    outputs=['y0', 'y1'],
    body=body
)

x0 = [np.random.uniform(0.0, 1.0, np.random.randint(
    1, 10)).astype(np.float32) for _ in range(3)]
x1 = [np.random.uniform(0.0, 1.0, np.random.randint(
    1, 10)).astype(np.float32) for _ in range(3)]
y0 = x0
y1 = x1
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['M'])),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['M'])),
]
expect(node, inputs=[x0, x1], outputs=[y0, y1],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_identity_2_sequences')

_sequence_map_identity_1_sequence_1_tensor

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Identity', ['in0'], ['out0']),
     onnx.helper.make_node('Identity', ['in1'], ['out1'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info('in0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info('in1', onnx.TensorProto.FLOAT, ['M'])],
    [onnx.helper.make_tensor_value_info(
        'out0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info(
        'out1', onnx.TensorProto.FLOAT, ['M'])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['x0', 'x1'],
    outputs=['y0', 'y1'],
    body=body
)

x0 = [np.random.uniform(0.0, 1.0, np.random.randint(
    1, 10)).astype(np.float32) for _ in range(3)]
x1 = np.random.uniform(0.0, 1.0, np.random.randint(
    1, 10)).astype(np.float32)
y0 = x0
y1 = [x1 for _ in range(3)]
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['M']),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['M'])),
]
expect(node, inputs=[x0, x1], outputs=[y0, y1],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_identity_1_sequence_1_tensor')

_sequence_map_add_2_sequences

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Add', ['in0', 'in1'], ['out0'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info('in0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info('in1', onnx.TensorProto.FLOAT, ['N'])],
    [onnx.helper.make_tensor_value_info(
        'out0', onnx.TensorProto.FLOAT, ['N'])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['x0', 'x1'],
    outputs=['y0'],
    body=body
)

N = [np.random.randint(1, 10) for _ in range(3)]
x0 = [np.random.uniform(0.0, 1.0, N[k]).astype(np.float32)
      for k in range(3)]
x1 = [np.random.uniform(0.0, 1.0, N[k]).astype(np.float32)
      for k in range(3)]
y0 = [x0[k] + x1[k] for k in range(3)]
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
]
expect(node, inputs=[x0, x1], outputs=[y0],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_add_2_sequences')

_sequence_map_add_1_sequence_1_tensor

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Add', ['in0', 'in1'], ['out0'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info('in0', onnx.TensorProto.FLOAT, ['N']),
     onnx.helper.make_tensor_value_info('in1', onnx.TensorProto.FLOAT, ['N'])],
    [onnx.helper.make_tensor_value_info(
        'out0', onnx.TensorProto.FLOAT, ['N'])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['x0', 'x1'],
    outputs=['y0'],
    body=body
)

x0 = [np.random.uniform(0.0, 1.0, 10).astype(np.float32) for k in range(3)]
x1 = np.random.uniform(0.0, 1.0, 10).astype(np.float32)
y0 = [x0[i] + x1 for i in range(3)]
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
    onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N']),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['N'])),
]
expect(node, inputs=[x0, x1], outputs=[y0],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_add_1_sequence_1_tensor')

_sequence_map_extract_shapes

body = onnx.helper.make_graph(
    [onnx.helper.make_node('Shape', ['x'], ['shape'])],
    'seq_map_body',
    [onnx.helper.make_tensor_value_info('x', onnx.TensorProto.FLOAT, ['H', 'W', 'C'])],
    [onnx.helper.make_tensor_value_info('shape', onnx.TensorProto.INT64, [3])]
)

node = onnx.helper.make_node(
    'SequenceMap',
    inputs=['in_seq'],
    outputs=['shapes'],
    body=body
)

shapes = [
    np.array([40, 30, 3], dtype=np.int64),
    np.array([20, 10, 3], dtype=np.int64),
    np.array([10, 5, 3], dtype=np.int64),
]
x0 = [np.zeros(shape, dtype=np.float32) for shape in shapes]
input_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.FLOAT, ['H', 'W', 'C'])),
]
output_type_protos = [
    onnx.helper.make_sequence_type_proto(
        onnx.helper.make_tensor_type_proto(onnx.TensorProto.INT64, [3])),
]
expect(node, inputs=[x0], outputs=[shapes],
       input_type_protos=input_type_protos,
       output_type_protos=output_type_protos,
       name='test_sequence_map_extract_shapes')