369 lines
15 KiB
Python
369 lines
15 KiB
Python
# Copyright (C) 2018-2021 Intel Corporation
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
import numpy as np
|
|
import onnx
|
|
import pytest
|
|
|
|
from tests.runtime import get_runtime
|
|
from tests.test_onnx.utils import (
|
|
run_node,
|
|
import_onnx_model,
|
|
)
|
|
|
|
reduce_data = np.array([[[5, 1], [20, 2]], [[30, 1], [40, 2]], [[55, 1], [60, 2]]], dtype=np.float32)
|
|
reduce_axis_parameters = [
|
|
(0,),
|
|
(1,),
|
|
(2,),
|
|
(0, 1),
|
|
(0, 2),
|
|
(1, 2),
|
|
(0, 1, 2)
|
|
]
|
|
|
|
reduce_operation_parameters_as_attr = [
|
|
("ReduceMax", np.max),
|
|
("ReduceMin", np.min),
|
|
("ReduceMean", np.mean),
|
|
("ReduceProd", np.prod)
|
|
]
|
|
|
|
reduce_operation_parameters_as_const = [
|
|
("ReduceSum", np.sum),
|
|
]
|
|
|
|
|
|
def import_and_compute(op_type, input_data, **node_attrs):
|
|
data_inputs = [np.array(input_data)]
|
|
node = onnx.helper.make_node(op_type, inputs=["x"], outputs=["y"], **node_attrs)
|
|
return run_node(node, data_inputs).pop()
|
|
|
|
|
|
def import_and_compute_with_axes_as_const(op_type, data, axes, **node_attrs):
|
|
data_input = np.array(data)
|
|
axes_input = np.array(axes, dtype=int)
|
|
axes_const_node = onnx.helper.make_node(
|
|
"Constant",
|
|
inputs=[],
|
|
outputs=["const_axes"],
|
|
value=onnx.helper.make_tensor(
|
|
name="const_axes",
|
|
data_type=onnx.TensorProto.INT64,
|
|
dims=axes_input.shape,
|
|
vals=axes_input.flatten(),
|
|
),
|
|
)
|
|
node = onnx.helper.make_node(
|
|
op_type, inputs=["x", "const_axes"], outputs=["y"], **node_attrs
|
|
)
|
|
graph = onnx.helper.make_graph(
|
|
[axes_const_node, node],
|
|
"test_graph",
|
|
[onnx.helper.make_tensor_value_info("x", onnx.TensorProto.FLOAT, data_input.shape)],
|
|
[onnx.helper.make_tensor_value_info("y", onnx.TensorProto.FLOAT, ())],
|
|
)
|
|
|
|
model = onnx.helper.make_model(graph, producer_name="ngraph ONNX Importer")
|
|
model.opset_import[0].version = 13
|
|
ng_model_function = import_onnx_model(model)
|
|
runtime = get_runtime()
|
|
computation = runtime.computation(ng_model_function)
|
|
return computation(data_input)[0]
|
|
|
|
|
|
@pytest.mark.parametrize("operation, ref_operation",
|
|
reduce_operation_parameters_as_attr + reduce_operation_parameters_as_const)
|
|
def test_reduce_operation_keepdims_none_axes(operation, ref_operation):
|
|
assert np.array_equal(import_and_compute(operation, reduce_data, keepdims=True),
|
|
ref_operation(reduce_data, keepdims=True))
|
|
|
|
|
|
@pytest.mark.parametrize("operation, ref_operation", reduce_operation_parameters_as_attr)
|
|
@pytest.mark.parametrize("axes", reduce_axis_parameters)
|
|
def test_reduce_operation_keepdims_with_axes_as_attr(operation, ref_operation, axes):
|
|
assert np.array_equal(import_and_compute(operation, reduce_data, axes=axes, keepdims=True),
|
|
ref_operation(reduce_data, keepdims=True, axis=axes))
|
|
|
|
|
|
@pytest.mark.parametrize("operation, ref_operation", reduce_operation_parameters_as_const)
|
|
@pytest.mark.parametrize("axes", reduce_axis_parameters)
|
|
def test_reduce_operation_keepdims_with_axes_as_const(operation, ref_operation, axes):
|
|
assert np.array_equal(import_and_compute_with_axes_as_const(operation, reduce_data, axes, keepdims=True),
|
|
ref_operation(reduce_data, keepdims=True, axis=axes))
|
|
|
|
|
|
@pytest.mark.parametrize("axes", [
|
|
None,
|
|
(0,),
|
|
(1,),
|
|
(2,),
|
|
(0, 1),
|
|
(0, 2),
|
|
(1, 2),
|
|
(0, 1, 2)])
|
|
@pytest.mark.parametrize("operation, ref_operation", reduce_operation_parameters_as_attr)
|
|
def test_reduce_operation_no_keepdims_axes_as_attr(operation, ref_operation, axes):
|
|
if axes:
|
|
assert np.array_equal(import_and_compute(operation, reduce_data, axes=axes, keepdims=False),
|
|
ref_operation(reduce_data, keepdims=False, axis=axes))
|
|
else:
|
|
assert np.array_equal(import_and_compute(operation, reduce_data, keepdims=False),
|
|
ref_operation(reduce_data, keepdims=False))
|
|
|
|
|
|
@pytest.mark.parametrize("axes", [
|
|
None,
|
|
(0,),
|
|
(1,),
|
|
(2,),
|
|
(0, 1),
|
|
(0, 2),
|
|
(1, 2),
|
|
(0, 1, 2)])
|
|
@pytest.mark.parametrize("operation, ref_operation", reduce_operation_parameters_as_const)
|
|
def test_reduce_operation_no_keepdims_axes_as_const(operation, ref_operation, axes):
|
|
if axes:
|
|
assert np.array_equal(import_and_compute_with_axes_as_const(operation,
|
|
reduce_data,
|
|
axes,
|
|
keepdims=False),
|
|
ref_operation(reduce_data, keepdims=False, axis=axes))
|
|
else:
|
|
assert np.array_equal(import_and_compute(operation, reduce_data, keepdims=False),
|
|
ref_operation(reduce_data, keepdims=False))
|
|
|
|
|
|
@pytest.mark.parametrize("reduction_axes", [(0,), (0, 2), (0, 1, 2)])
|
|
def test_reduce_l1(reduction_axes):
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sum(np.abs(input_data), keepdims=True, axis=reduction_axes)
|
|
node = onnx.helper.make_node("ReduceL1", inputs=["x"], outputs=["y"], axes=reduction_axes)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.sum(np.abs(input_data), keepdims=False, axis=reduction_axes)
|
|
node = onnx.helper.make_node("ReduceL1", inputs=["x"], outputs=["y"], keepdims=0, axes=reduction_axes)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_l1_default_axes():
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sum(np.abs(input_data), keepdims=True)
|
|
node = onnx.helper.make_node("ReduceL1", inputs=["x"], outputs=["y"])
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.array(np.sum(np.abs(input_data), keepdims=False))
|
|
node = onnx.helper.make_node("ReduceL1", inputs=["x"], outputs=["y"], keepdims=0)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
@pytest.mark.parametrize("reduction_axes", [(0,), (0, 2), (0, 1, 2)])
|
|
def test_reduce_l2(reduction_axes):
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sqrt(np.sum(np.square(input_data), keepdims=True, axis=reduction_axes))
|
|
node = onnx.helper.make_node("ReduceL2", inputs=["x"], outputs=["y"], axes=reduction_axes)
|
|
raw_result = run_node(node, [input_data])
|
|
ng_result = np.array(raw_result.pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.sqrt(np.sum(np.square(input_data), keepdims=False, axis=reduction_axes))
|
|
node = onnx.helper.make_node("ReduceL2", inputs=["x"], outputs=["y"], keepdims=0, axes=reduction_axes)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_l2_default_axes():
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sqrt(np.sum(np.square(input_data), keepdims=True))
|
|
node = onnx.helper.make_node("ReduceL2", inputs=["x"], outputs=["y"])
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.array(np.sqrt(np.sum(np.square(input_data), keepdims=False)))
|
|
node = onnx.helper.make_node("ReduceL2", inputs=["x"], outputs=["y"], keepdims=0)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
@pytest.mark.parametrize("reduction_axes", [(0,), (0, 2), (0, 1, 2)])
|
|
def test_reduce_log_sum(reduction_axes):
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(0, 1, shape).astype(np.float32)
|
|
|
|
expected = np.log(np.sum(input_data, keepdims=True, axis=reduction_axes))
|
|
node = onnx.helper.make_node("ReduceLogSum", inputs=["x"], outputs=["y"], axes=reduction_axes)
|
|
ng_result = run_node(node, [input_data]).pop()
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.log(np.sum(input_data, keepdims=False, axis=reduction_axes))
|
|
node = onnx.helper.make_node("ReduceLogSum", inputs=["x"], outputs=["y"], keepdims=0, axes=reduction_axes)
|
|
ng_result = run_node(node, [input_data]).pop()
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_log_sum_default_axes():
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(0, 1, shape).astype(np.float32)
|
|
|
|
expected = np.log(np.sum(input_data, keepdims=True))
|
|
node = onnx.helper.make_node("ReduceLogSum", inputs=["x"], outputs=["y"])
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.log(np.sum(input_data, keepdims=False))
|
|
node = onnx.helper.make_node("ReduceLogSum", inputs=["x"], outputs=["y"], keepdims=0)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_log_sum_exp():
|
|
def logsumexp(data, axis=None, keepdims=True):
|
|
return np.log(np.sum(np.exp(data), axis=axis, keepdims=keepdims))
|
|
|
|
data = np.array([[[5, 1], [20, 2]], [[30, 1], [40, 2]], [[55, 1], [60, 2]]], dtype=np.float32)
|
|
|
|
assert np.array_equal(import_and_compute("ReduceLogSumExp", data), logsumexp(data, keepdims=True))
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, keepdims=0), logsumexp(data, keepdims=False)
|
|
)
|
|
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(1,)), logsumexp(data, keepdims=True, axis=(1,))
|
|
)
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(1,), keepdims=0),
|
|
logsumexp(data, keepdims=False, axis=(1,)),
|
|
)
|
|
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(0, 2)), logsumexp(data, keepdims=True, axis=(0, 2))
|
|
)
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(0, 2), keepdims=0),
|
|
logsumexp(data, keepdims=False, axis=(0, 2)),
|
|
)
|
|
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(0, 1, 2)),
|
|
logsumexp(data, keepdims=True, axis=(0, 1, 2)),
|
|
)
|
|
assert np.array_equal(
|
|
import_and_compute("ReduceLogSumExp", data, axes=(0, 1, 2), keepdims=0),
|
|
logsumexp(data, keepdims=False, axis=(0, 1, 2)),
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("reduction_axes", [(0,), (0, 2), (0, 1, 2)])
|
|
def test_reduce_sum_square(reduction_axes):
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sum(np.square(input_data), keepdims=True, axis=reduction_axes)
|
|
node = onnx.helper.make_node("ReduceSumSquare", inputs=["x"], outputs=["y"], axes=reduction_axes)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.sum(np.square(input_data), keepdims=False, axis=reduction_axes)
|
|
node = onnx.helper.make_node(
|
|
"ReduceSumSquare", inputs=["x"], outputs=["y"], keepdims=0, axes=reduction_axes
|
|
)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_sum_square_default_axes():
|
|
shape = [2, 4, 3, 2]
|
|
np.random.seed(133391)
|
|
input_data = np.random.uniform(-100, 100, shape).astype(np.float32)
|
|
|
|
expected = np.sum(np.square(input_data), keepdims=True)
|
|
node = onnx.helper.make_node("ReduceSumSquare", inputs=["x"], outputs=["y"])
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
expected = np.sum(np.square(input_data), keepdims=False)
|
|
node = onnx.helper.make_node("ReduceSumSquare", inputs=["x"], outputs=["y"], keepdims=0)
|
|
ng_result = np.array(run_node(node, [input_data]).pop())
|
|
assert np.array_equal(expected.shape, ng_result.shape)
|
|
assert np.allclose(expected, ng_result)
|
|
|
|
|
|
def test_reduce_argmin():
|
|
def argmin(ndarray, axis, keepdims=False):
|
|
res = np.argmin(ndarray, axis=axis)
|
|
if keepdims:
|
|
res = np.expand_dims(res, axis=axis)
|
|
return res
|
|
|
|
data = np.array([[[5, 1], [20, 2]], [[30, 1], [40, 2]], [[55, 1], [60, 2]]], dtype=np.float32)
|
|
|
|
assert np.array_equal(import_and_compute("ArgMin", data, axis=0), argmin(data, keepdims=True, axis=0))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMin", data, axis=0, keepdims=0), argmin(data, keepdims=False, axis=0)
|
|
)
|
|
assert np.array_equal(import_and_compute("ArgMin", data, axis=1), argmin(data, keepdims=True, axis=1))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMin", data, axis=1, keepdims=0), argmin(data, keepdims=False, axis=1)
|
|
)
|
|
assert np.array_equal(import_and_compute("ArgMin", data, axis=2), argmin(data, keepdims=True, axis=2))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMin", data, axis=2, keepdims=0), argmin(data, keepdims=False, axis=2)
|
|
)
|
|
|
|
|
|
def test_reduce_argmax():
|
|
def argmax(ndarray, axis, keepdims=False):
|
|
res = np.argmax(ndarray, axis=axis)
|
|
if keepdims:
|
|
res = np.expand_dims(res, axis=axis)
|
|
return res
|
|
|
|
data = np.array([[[5, 1], [20, 2]], [[30, 1], [40, 2]], [[55, 1], [60, 2]]], dtype=np.float32)
|
|
|
|
assert np.array_equal(import_and_compute("ArgMax", data, axis=0), argmax(data, keepdims=True, axis=0))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMax", data, axis=0, keepdims=0), argmax(data, keepdims=False, axis=0)
|
|
)
|
|
assert np.array_equal(import_and_compute("ArgMax", data, axis=1), argmax(data, keepdims=True, axis=1))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMax", data, axis=1, keepdims=0), argmax(data, keepdims=False, axis=1)
|
|
)
|
|
assert np.array_equal(import_and_compute("ArgMax", data, axis=2), argmax(data, keepdims=True, axis=2))
|
|
assert np.array_equal(
|
|
import_and_compute("ArgMax", data, axis=2, keepdims=0), argmax(data, keepdims=False, axis=2)
|
|
)
|