Skip to content

Commit

Permalink
Add DynamicSlice experimental op (#1377)
Browse files Browse the repository at this point in the history
* Add DynamicSlice experimental op

* Address comments

* Address comment
  • Loading branch information
James Reed committed Sep 6, 2018
1 parent 91a7b8e commit bff0b88
Show file tree
Hide file tree
Showing 36 changed files with 650 additions and 6 deletions.
70 changes: 69 additions & 1 deletion docs/Changelog.md
Expand Up @@ -4114,7 +4114,7 @@ This version of the operator has been available since version 1 of the default O
### <a name="ScaledTanh-1"></a>**ScaledTanh-1**</a>

Calculates the scaled hyperbolic tangent of the given input tensor element-wise,
alpha * tanh(beta * x).
alpha * tanh(beta * x).


#### Version
Expand Down Expand Up @@ -8376,3 +8376,71 @@ This version of the operator has been available since version 8 of the default O
<dd>Constrain input and output types to float tensors.</dd>
</dl>

## Version 9 of the default ONNX operator set
### <a name="DynamicSlice-9"></a>**DynamicSlice-9**</a>

Produces a slice of the input tensor along multiple axes. Similar to numpy:
https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
Slices uses `axes`, `starts` and `ends` inputs to specify the start and end
dimension for each axis in the list of axes, it uses this information to
slice the input `data` tensor. If a negative value is passed for any of the
start or end indices, it represent number of elements before the end of that
dimension. If the value passed to start or end is larger than the `n` (the
number of elements in this dimension), it represents `n`. For slicing to the
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`.
If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
Example 1:
data = [
[1, 2, 3, 4],
[5, 6, 7, 8],
]
axes = [0, 1]
starts = [1, 0]
ends = [2, 3]
result = [
[5, 6, 7],
]
Example 2:
data = [
[1, 2, 3, 4],
[5, 6, 7, 8],
]
starts = [0, 1]
ends = [-1, 1000]
result = [
[2, 3, 4],
]

#### Version

This version of the operator has been available since version 9 of the default ONNX operator set.

#### Inputs (3 - 4)

<dl>
<dt><tt>data</tt> : T</dt>
<dd>Tensor of data to extract slices from.</dd>
<dt><tt>starts</tt> : Tind</dt>
<dd>1-D tensor of starting indices of corresponding axis in `axes`</dd>
<dt><tt>ends</tt> : Tind</dt>
<dd>1-D tensor of ending indices (exclusive) of corresponding axis in axes</dd>
<dt><tt>axes</tt> (optional) : Tind</dt>
<dd>1-D tensor of axes that `starts` and `ends` apply to.</dd>
</dl>

#### Outputs

<dl>
<dt><tt>output</tt> : T</dt>
<dd>Sliced data tensor.</dd>
</dl>

#### Type Constraints

<dl>
<dt><tt>T</tt> : tensor(uint8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(int8), tensor(int16), tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double), tensor(string), tensor(bool), tensor(complex64), tensor(complex128)</dt>
<dd>Constrain input and output types to all tensor types.</dd>
<dt><tt>Tind</tt> : tensor(int32), tensor(int64)</dt>
<dd>Constrain indices to integer types</dd>
</dl>

187 changes: 186 additions & 1 deletion docs/Operators.md
Expand Up @@ -112,6 +112,7 @@
* <sub>experimental</sub> <a href="#Affine">Affine</a>
* <sub>experimental</sub> <a href="#ConstantFill">ConstantFill</a>
* <sub>experimental</sub> <a href="#Crop">Crop</a>
* <sub>experimental</sub> <a href="#DynamicSlice">DynamicSlice</a>
* <sub>experimental</sub> <a href="#GRUUnit">GRUUnit</a>
* <sub>experimental</sub> <a href="#GivenTensorFill">GivenTensorFill</a>
* <sub>experimental</sub> <a href="#ImageScaler">ImageScaler</a>
Expand Down Expand Up @@ -10982,6 +10983,190 @@ This version of the operator has been available since version 1 of the default O
</dl>


### <sub>experimental</sub> <a name="DynamicSlice"></a><a name="dynamicslice">**DynamicSlice**</a>

Produces a slice of the input tensor along multiple axes. Similar to numpy:
https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
Slices uses `axes`, `starts` and `ends` inputs to specify the start and end
dimension for each axis in the list of axes, it uses this information to
slice the input `data` tensor. If a negative value is passed for any of the
start or end indices, it represent number of elements before the end of that
dimension. If the value passed to start or end is larger than the `n` (the
number of elements in this dimension), it represents `n`. For slicing to the
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`.
If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
Example 1:
data = [
[1, 2, 3, 4],
[5, 6, 7, 8],
]
axes = [0, 1]
starts = [1, 0]
ends = [2, 3]
result = [
[5, 6, 7],
]
Example 2:
data = [
[1, 2, 3, 4],
[5, 6, 7, 8],
]
starts = [0, 1]
ends = [-1, 1000]
result = [
[2, 3, 4],
]

#### Version

This version of the operator has been available since version 9 of the default ONNX operator set.

#### Inputs (3 - 4)

<dl>
<dt><tt>data</tt> : T</dt>
<dd>Tensor of data to extract slices from.</dd>
<dt><tt>starts</tt> : Tind</dt>
<dd>1-D tensor of starting indices of corresponding axis in `axes`</dd>
<dt><tt>ends</tt> : Tind</dt>
<dd>1-D tensor of ending indices (exclusive) of corresponding axis in axes</dd>
<dt><tt>axes</tt> (optional) : Tind</dt>
<dd>1-D tensor of axes that `starts` and `ends` apply to.</dd>
</dl>

#### Outputs

<dl>
<dt><tt>output</tt> : T</dt>
<dd>Sliced data tensor.</dd>
</dl>

#### Type Constraints

<dl>
<dt><tt>T</tt> : tensor(uint8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(int8), tensor(int16), tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double), tensor(string), tensor(bool), tensor(complex64), tensor(complex128)</dt>
<dd>Constrain input and output types to all tensor types.</dd>
<dt><tt>Tind</tt> : tensor(int32), tensor(int64)</dt>
<dd>Constrain indices to integer types</dd>
</dl>


#### Examples

<details>
<summary>dynamic_slice</summary>

```python
node = onnx.helper.make_node(
'DynamicSlice',
inputs=['x', 'starts', 'ends', 'axes'],
outputs=['y'],
)

x = np.random.randn(20, 10, 5).astype(np.float32)
y = x[0:3, 0:10]
starts = np.array([0, 0], dtype=np.long)
ends = np.array([3, 10], dtype=np.long)
axes = np.array([0, 1], dtype=np.long)

expect(node, inputs=[x, starts, ends, axes], outputs=[y],
name='test_dynamic_slice')
```

</details>


<details>
<summary>dynamic_slice_default_axes</summary>

```python
node = onnx.helper.make_node(
'DynamicSlice',
inputs=['x', 'starts', 'ends'],
outputs=['y'],
)

x = np.random.randn(20, 10, 5).astype(np.float32)
starts = np.array([0, 0, 3], dtype=np.long)
ends = np.array([20, 10, 4], dtype=np.long)
y = x[:, :, 3:4]

expect(node, inputs=[x, starts, ends], outputs=[y],
name='test_dynamic_slice_default_axes')
```

</details>


<details>
<summary>dynamic_slice_end_out_of_bounds</summary>

```python
node = onnx.helper.make_node(
'DynamicSlice',
inputs=['x', 'starts', 'ends', 'axes'],
outputs=['y'],
)

x = np.random.randn(20, 10, 5).astype(np.float32)
starts = np.array([1], dtype=np.long)
ends = np.array([1000], dtype=np.long)
axes = np.array([1], dtype=np.long)
y = x[:, 1:1000]

expect(node, inputs=[x, starts, ends, axes], outputs=[y],
name='test_dynamic_slice_end_out_of_bounds')
```

</details>


<details>
<summary>dynamic_slice_neg</summary>

```python
node = onnx.helper.make_node(
'DynamicSlice',
inputs=['x', 'starts', 'ends', 'axes'],
outputs=['y'],
)

x = np.random.randn(20, 10, 5).astype(np.float32)
starts = np.array([0], dtype=np.long)
ends = np.array([-1], dtype=np.long)
axes = np.array([1], dtype=np.long)
y = x[:, 0:-1]

expect(node, inputs=[x, starts, ends, axes], outputs=[y],
name='test_dynamic_slice_neg')
```

</details>


<details>
<summary>dynamic_slice_start_out_of_bounds</summary>

```python
node = onnx.helper.make_node(
'DynamicSlice',
inputs=['x', 'starts', 'ends', 'axes'],
outputs=['y'],
)

x = np.random.randn(20, 10, 5).astype(np.float32)
starts = np.array([1000], dtype=np.long)
ends = np.array([1000], dtype=np.long)
axes = np.array([1], dtype=np.long)
y = x[:, 1000:1000]

expect(node, inputs=[x, starts, ends, axes], outputs=[y],
name='test_dynamic_slice_start_out_of_bounds')
```

</details>


### <sub>experimental</sub> <a name="GRUUnit"></a><a name="gruunit">**GRUUnit**</a>

GRUUnit computes the activations of a standard GRU,
Expand Down Expand Up @@ -11232,7 +11417,7 @@ This version of the operator has been available since version 1 of the default O
### <sub>experimental</sub> <a name="ScaledTanh"></a><a name="scaledtanh">**ScaledTanh**</a>

Calculates the scaled hyperbolic tangent of the given input tensor element-wise,
alpha * tanh(beta * x).
alpha * tanh(beta * x).


#### Version
Expand Down

0 comments on commit bff0b88

Please sign in to comment.