Skip to content

Commit

Permalink
Update Pow input types in Opset 12 (onnx#2666)
Browse files Browse the repository at this point in the history
* Update Pow input types in Opset 12

* gen doc and tests

* remove uints and 8 bit ints

* add tests

* remove uint int x tets
  • Loading branch information
lara-hdr authored Mar 20, 2020
1 parent ac1caf3 commit 46fe392
Show file tree
Hide file tree
Showing 52 changed files with 458 additions and 30 deletions.
36 changes: 36 additions & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14832,6 +14832,42 @@ This version of the operator has been available since version 12 of the default
<dd>Constrain target to integer types</dd>
</dl>

### <a name="Pow-12"></a>**Pow-12**</a>

Pow takes input data (Tensor<T>) and exponent Tensor, and
produces one output data (Tensor<T>) where the function `f(x) = x^exponent`,
is applied to the data tensor elementwise.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).

#### Version

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

#### Inputs

<dl>
<dt><tt>X</tt> : T</dt>
<dd>First operand, base of the exponent.</dd>
<dt><tt>Y</tt> : T1</dt>
<dd>Second operand, power of the exponent.</dd>
</dl>

#### Outputs

<dl>
<dt><tt>Z</tt> : T</dt>
<dd>Output tensor (same size as X)</dd>
</dl>

#### Type Constraints

<dl>
<dt><tt>T</tt> : tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double)</dt>
<dd>Constrain input X and output types to float/int tensors.</dd>
<dt><tt>T1</tt> : tensor(uint8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(int8), tensor(int16), tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double)</dt>
<dd>Constrain input Y types to float/int tensors.</dd>
</dl>

### <a name="ReduceMax-12"></a>**ReduceMax-12**</a>

Computes the max of the input tensor's element along the provided axes. The resulted
Expand Down
82 changes: 73 additions & 9 deletions docs/Operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -11954,16 +11954,16 @@ for mode in ['edge', 'reflect']:

#### Version

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

Other versions of this operator: <a href="Changelog.md#Pow-1">Pow-1</a>
Other versions of this operator: <a href="Changelog.md#Pow-1">Pow-1</a>, <a href="Changelog.md#Pow-7">Pow-7</a>

#### Inputs

<dl>
<dt><tt>X</tt> : T</dt>
<dd>First operand, base of the exponent.</dd>
<dt><tt>Y</tt> : T</dt>
<dt><tt>Y</tt> : T1</dt>
<dd>Second operand, power of the exponent.</dd>
</dl>

Expand All @@ -11977,8 +11977,10 @@ Other versions of this operator: <a href="Changelog.md#Pow-1">Pow-1</a>
#### Type Constraints

<dl>
<dt><tt>T</tt> : tensor(float16), tensor(float), tensor(double)</dt>
<dd>Constrain input and output types to float tensors.</dd>
<dt><tt>T</tt> : tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double)</dt>
<dd>Constrain input X and output types to float/int tensors.</dd>
<dt><tt>T1</tt> : tensor(uint8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(int8), tensor(int16), tensor(int32), tensor(int64), tensor(float16), tensor(float), tensor(double)</dt>
<dd>Constrain input Y types to float/int tensors.</dd>
</dl>


Expand All @@ -11996,13 +11998,13 @@ node = onnx.helper.make_node(

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.float32)
z = np.power(x, y) # expected output [1., 32., 729.]
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_example')

x = np.arange(60).reshape(3, 4, 5).astype(np.float32)
y = np.random.randn(3, 4, 5).astype(np.float32)
z = np.power(x, y)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow')
```
Expand All @@ -12022,7 +12024,7 @@ node = onnx.helper.make_node(

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array(2).astype(np.float32)
z = np.power(x, y) # expected output [1., 4., 9.]
z = pow(x, y) # expected output [1., 4., 9.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_scalar')

Expand All @@ -12034,14 +12036,76 @@ node = onnx.helper.make_node(
x = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
y = np.array([1, 2, 3]).astype(np.float32)
# expected output [[1, 4, 27], [4, 25, 216]]
z = np.power(x, y).astype(np.float32)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_array')
```

</details>


<details>
<summary>types</summary>

```python
node = onnx.helper.make_node(
'Pow',
inputs=['x', 'y'],
outputs=['z'],
)

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int64')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int32')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint64')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint32')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_int64')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_int32')
```

</details>


### <a name="QLinearConv"></a><a name="qlinearconv">**QLinearConv**</a>

The convolution operator consumes a quantized input tensor, its scale and zero point,
Expand Down
70 changes: 65 additions & 5 deletions docs/TestCoverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6967,7 +6967,7 @@ for mode in ['edge', 'reflect']:


### Pow
There are 2 test cases, listed as following:
There are 3 test cases, listed as following:
<details>
<summary>pow</summary>

Expand All @@ -6980,13 +6980,13 @@ node = onnx.helper.make_node(

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.float32)
z = np.power(x, y) # expected output [1., 32., 729.]
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_example')

x = np.arange(60).reshape(3, 4, 5).astype(np.float32)
y = np.random.randn(3, 4, 5).astype(np.float32)
z = np.power(x, y)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow')
```
Expand All @@ -7004,7 +7004,7 @@ node = onnx.helper.make_node(

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array(2).astype(np.float32)
z = np.power(x, y) # expected output [1., 4., 9.]
z = pow(x, y) # expected output [1., 4., 9.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_scalar')

Expand All @@ -7016,11 +7016,71 @@ node = onnx.helper.make_node(
x = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
y = np.array([1, 2, 3]).astype(np.float32)
# expected output [[1, 4, 27], [4, 25, 216]]
z = np.power(x, y).astype(np.float32)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_array')
```

</details>
<details>
<summary>types</summary>

```python
node = onnx.helper.make_node(
'Pow',
inputs=['x', 'y'],
outputs=['z'],
)

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int64')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int32')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint64')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint32')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_int64')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_int32')
```

</details>


Expand Down
69 changes: 65 additions & 4 deletions onnx/backend/test/case/node/pow.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
from . import expect


def pow(x, y): # type: ignore
z = np.power(x, y).astype(x.dtype)
return z


class Pow(Base):

@staticmethod
Expand All @@ -22,13 +27,13 @@ def export(): # type: () -> None

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.float32)
z = np.power(x, y) # expected output [1., 32., 729.]
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_example')

x = np.arange(60).reshape(3, 4, 5).astype(np.float32)
y = np.random.randn(3, 4, 5).astype(np.float32)
z = np.power(x, y)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow')

Expand All @@ -42,7 +47,7 @@ def export_pow_broadcast(): # type: () -> None

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array(2).astype(np.float32)
z = np.power(x, y) # expected output [1., 4., 9.]
z = pow(x, y) # expected output [1., 4., 9.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_scalar')

Expand All @@ -54,6 +59,62 @@ def export_pow_broadcast(): # type: () -> None
x = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
y = np.array([1, 2, 3]).astype(np.float32)
# expected output [[1, 4, 27], [4, 25, 216]]
z = np.power(x, y).astype(np.float32)
z = pow(x, y)
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_bcast_array')

@staticmethod
def export_types(): # type: () -> None
node = onnx.helper.make_node(
'Pow',
inputs=['x', 'y'],
outputs=['z'],
)

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int64')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_int32')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.float32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_float32')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint64)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint64')

x = np.array([1, 2, 3]).astype(np.float32)
y = np.array([4, 5, 6]).astype(np.uint32)
z = pow(x, y) # expected output [1., 32., 729.]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_float32_uint32')

x = np.array([1, 2, 3]).astype(np.int64)
y = np.array([4, 5, 6]).astype(np.int64)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int64_int64')

x = np.array([1, 2, 3]).astype(np.int32)
y = np.array([4, 5, 6]).astype(np.int32)
z = pow(x, y) # expected output [1, 32, 729]
expect(node, inputs=[x, y], outputs=[z],
name='test_pow_types_int32_int32')
Loading

0 comments on commit 46fe392

Please sign in to comment.