From e25bb7e6ab9826ec7481b1602bd8cb748d897b90 Mon Sep 17 00:00:00 2001 From: Maxim Vafin Date: Thu, 15 Jul 2021 18:03:51 +0300 Subject: [PATCH] Add AdaptivePool to ngraph python API (#6579) * Add AdaptivePool to ngraph python API * Disable tests until CPU implementation is ready * Change ticket number * Add create op tests * Fix quotes * Fix typo --- ngraph/python/src/ngraph/__init__.py | 2 + ngraph/python/src/ngraph/opset8/__init__.py | 2 + ngraph/python/src/ngraph/opset8/ops.py | 37 +++++++++++ ngraph/python/tests/__init__.py | 2 + .../tests/test_ngraph/test_adaptive_pool.py | 66 +++++++++++++++++++ .../tests/test_ngraph/test_create_op.py | 27 ++++++++ 6 files changed, 136 insertions(+) create mode 100644 ngraph/python/tests/test_ngraph/test_adaptive_pool.py diff --git a/ngraph/python/src/ngraph/__init__.py b/ngraph/python/src/ngraph/__init__.py index 5dca8a5c68a..8647878d8df 100644 --- a/ngraph/python/src/ngraph/__init__.py +++ b/ngraph/python/src/ngraph/__init__.py @@ -32,6 +32,8 @@ from ngraph.opset8 import absolute from ngraph.opset8 import absolute as abs from ngraph.opset8 import acos from ngraph.opset8 import acosh +from ngraph.opset8 import adaptive_avg_pool +from ngraph.opset8 import adaptive_max_pool from ngraph.opset8 import add from ngraph.opset8 import asin from ngraph.opset8 import asinh diff --git a/ngraph/python/src/ngraph/opset8/__init__.py b/ngraph/python/src/ngraph/opset8/__init__.py index 2e7acf0f3ce..0b089c345f3 100644 --- a/ngraph/python/src/ngraph/opset8/__init__.py +++ b/ngraph/python/src/ngraph/opset8/__init__.py @@ -5,6 +5,8 @@ from ngraph.opset1.ops import absolute from ngraph.opset1.ops import absolute as abs from ngraph.opset1.ops import acos from ngraph.opset4.ops import acosh +from ngraph.opset8.ops import adaptive_avg_pool +from ngraph.opset8.ops import adaptive_max_pool from ngraph.opset1.ops import add from ngraph.opset1.ops import asin from ngraph.opset4.ops import asinh diff --git a/ngraph/python/src/ngraph/opset8/ops.py b/ngraph/python/src/ngraph/opset8/ops.py index bcc294ad931..a5496ab1e49 100644 --- a/ngraph/python/src/ngraph/opset8/ops.py +++ b/ngraph/python/src/ngraph/opset8/ops.py @@ -101,6 +101,43 @@ def deformable_convolution( ) +@nameable_op +def adaptive_avg_pool( + data: NodeInput, + output_shape: NodeInput +) -> Node: + """Return a node which performs AdaptiveAvgPool operation. + + @param data: The list of input nodes + @param output_shape: the shape of spatial dimentions after operation + @return: The new node performing AdaptiveAvgPool operation on the data + """ + inputs = as_nodes(data, output_shape) + return _get_node_factory_opset8().create("AdaptiveAvgPool", inputs) + + +@nameable_op +def adaptive_max_pool( + data: NodeInput, + output_shape: NodeInput, + index_element_type: str = "i64" +) -> Node: + """Return a node which performs AdaptiveMaxPool operation. + + @param data: The list of input nodes + @param output_shape: the shape of spatial dimentions after operation + @param index_element_type: Type of indices output. + @return: The new node performing AdaptiveMaxPool operation on the data + """ + inputs = as_nodes(data, output_shape) + + attributes = { + "index_element_type": index_element_type, + } + + return _get_node_factory_opset8().create("AdaptiveMaxPool", inputs, attributes) + + @nameable_op def multiclass_nms( boxes: NodeInput, diff --git a/ngraph/python/tests/__init__.py b/ngraph/python/tests/__init__.py index edcdb43a750..109c150b1dd 100644 --- a/ngraph/python/tests/__init__.py +++ b/ngraph/python/tests/__init__.py @@ -145,3 +145,5 @@ xfail_issue_52463 = xfail_test(reason="test_operator_add_size1_singleton_broadca xfail_issue_58033 = xfail_test(reason="Einsum operation misses support for complex ellipsis equations") xfail_issue_58676 = xfail_test(reason="AssertionError: Not equal to tolerance rtol=0.001, atol=1e-07") xfail_issue_onnx_models_140 = xfail_test(reason="https://github.com/onnx/models/issues/140") + +xfail_issue_59935 = xfail_test(reason="AdaptivePool is not implemented in CPU plugin.") diff --git a/ngraph/python/tests/test_ngraph/test_adaptive_pool.py b/ngraph/python/tests/test_ngraph/test_adaptive_pool.py new file mode 100644 index 00000000000..7d662706f46 --- /dev/null +++ b/ngraph/python/tests/test_ngraph/test_adaptive_pool.py @@ -0,0 +1,66 @@ +import ngraph as ng +import numpy as np +from tests import xfail_issue_59935 +from tests.runtime import get_runtime + + +@xfail_issue_59935 +def test_adaptive_avg_pool(): + runtime = get_runtime() + input = np.reshape([0, 4, 1, 3, -2, -5, -2, + -2, 1, -3, 1, -3, -4, 0, + -2, 1, -1, -2, 3, -1, -3, + + -1, -2, 3, 4, -3, -4, 1, + 2, 0, -4, -5, -2, -2, -3, + 2, 3, 1, -5, 2, -4, -2], (2, 3, 7)) + input_tensor = ng.constant(input) + output_shape = ng.constant(np.array([3], dtype=np.int32)) + + adaptive_pool_node = ng.adaptive_avg_pool(input_tensor, output_shape) + computation = runtime.computation(adaptive_pool_node) + adaptive_pool_results = computation() + expected_results = np.reshape([1.66666663, 0.66666669, -3., + -1.33333337, -1.66666663, -2.33333325, + -0.66666669, 0., -0.33333334, + + 0., 1.33333337, -2., + -0.66666669, -3.66666675, -2.33333325, + 2., -0.66666669, -1.33333337], (2, 3, 3)) + + assert np.allclose(adaptive_pool_results, expected_results) + + +@xfail_issue_59935 +def test_adaptive_max_pool(): + runtime = get_runtime() + input = np.reshape([0, 4, 1, 3, -2, -5, -2, + -2, 1, -3, 1, -3, -4, 0, + -2, 1, -1, -2, 3, -1, -3, + + -1, -2, 3, 4, -3, -4, 1, + 2, 0, -4, -5, -2, -2, -3, + 2, 3, 1, -5, 2, -4, -2], (2, 3, 7)) + input_tensor = ng.constant(input) + output_shape = ng.constant(np.array([3], dtype=np.int32)) + + adaptive_pool_node = ng.adaptive_max_pool(input_tensor, output_shape) + computation = runtime.computation(adaptive_pool_node) + adaptive_pool_results = computation() + expected_results = np.reshape([4, 3, -2, + 1, 1, 0, + 1, 3, 3, + + 3, 4, 1, + 2, -2, -2, + 3, 2, 2], (2, 3, 3)) + + expected_indices = np.reshape([1, 3, 4, + 1, 3, 6, + 1, 4, 4, + + 2, 3, 6, + 0, 4, 4, + 1, 4, 4], (2, 3, 3)) + + assert np.allclose(adaptive_pool_results, [expected_results, expected_indices]) diff --git a/ngraph/python/tests/test_ngraph/test_create_op.py b/ngraph/python/tests/test_ngraph/test_create_op.py index e8770b08178..673d7a2ebf1 100644 --- a/ngraph/python/tests/test_ngraph/test_create_op.py +++ b/ngraph/python/tests/test_ngraph/test_create_op.py @@ -23,6 +23,33 @@ integral_np_types = [ ] +@pytest.mark.parametrize("dtype", [np.float32, np.float64]) +def test_adaptive_avg_pool(dtype): + data = ng.parameter([2, 24, 34, 62], name="input", dtype=dtype) + output_shape = ng.constant(np.array([16, 16], dtype=np.int32)) + + node = ng.adaptive_avg_pool(data, output_shape) + + assert node.get_type_name() == "AdaptiveAvgPool" + assert node.get_output_size() == 1 + assert list(node.get_output_shape(0)) == [2, 24, 16, 16] + + +@pytest.mark.parametrize("dtype", [np.float32, np.float64]) +@pytest.mark.parametrize("ind_type", ["i32", "i64"]) +def test_adaptive_max_pool(dtype, ind_type): + data = ng.parameter([2, 24, 34, 62], name="input", dtype=dtype) + output_shape = ng.constant(np.array([16, 16], dtype=np.int32)) + + node = ng.adaptive_max_pool(data, output_shape, ind_type) + + assert node.get_type_name() == "AdaptiveMaxPool" + assert node.get_output_size() == 2 + assert list(node.get_output_shape(0)) == [2, 24, 16, 16] + assert list(node.get_output_shape(1)) == [2, 24, 16, 16] + assert node.get_output_element_type(1) == Type.i32 if ind_type == "i32" else Type.i64 + + @pytest.mark.parametrize("dtype", [np.float32, np.float64]) def test_binary_convolution(dtype): strides = np.array([1, 1])