From 24f7306ba2dc44949ae155c1791dfd23d6f57d15 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sun, 13 Aug 2023 21:53:54 +0300 Subject: [PATCH 1/5] refactored avg pooling frontend functions and thier tests --- .../torch/nn/functional/pooling_functions.py | 49 +++++++++++-------- ivy/stateful/module.py | 2 +- .../test_functional/test_pooling_functions.py | 45 +++++++++-------- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py index b1bacd44fa103..b468c24588825 100644 --- a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py @@ -25,10 +25,18 @@ def _broadcast_pooling_helper(x, pool_dims: str = "2d", name: str = "padding"): ) +@to_ivy_arrays_and_back @to_ivy_arrays_and_back def avg_pool1d( - input, kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True + input, + kernel_size, + stride=None, + padding=0, + ceil_mode=False, + count_include_pad=True, ): + if stride is None: + stride = kernel_size kernel_size = _broadcast_pooling_helper(kernel_size, "1d", name="kernel_size") stride = _broadcast_pooling_helper(stride, "1d", name="stride") padding = _broadcast_pooling_helper(padding, "1d", name="padding") @@ -48,10 +56,15 @@ def avg_pool1d( padding_str = "VALID" return ivy.avg_pool1d( - input, kernel_size, stride, padding_str, data_format=data_format + input, + kernel_size, + stride, + padding_str, + data_format=data_format, + count_include_pad=count_include_pad, + ceil_mode=ceil_mode, ) - @to_ivy_arrays_and_back def avg_pool2d( input, @@ -62,16 +75,9 @@ def avg_pool2d( count_include_pad=True, divisor_override=None, ): - # Figure out input dims N - input_rank = input.ndim - - if input_rank == 3: - # CHW - data_format = "CHW" - elif input_rank == 4: - # NCHW - data_format = "NCHW" - + if stride is None: + stride = kernel_size + data_format = "NCHW" kernel_size = _broadcast_pooling_helper(kernel_size, "2d", name="kernel_size") stride = _broadcast_pooling_helper(stride, "2d", name="stride") padding = _broadcast_pooling_helper(padding, "2d", name="padding") @@ -271,14 +277,15 @@ def avg_pool3d( ): if stride is None: stride = kernel_size - if not isinstance(padding, int): - padding = [(padding[i],) * 2 for i in range(3)] - - if not all([pad <= kernel // 2 for kernel, pad in zip(kernel_size, padding)]): - raise ValueError( - "pad should be smaller than or equal to half of kernel size, " - f"but got padding={padding}, kernel_size={kernel_size}. " - ) + kernel_size = _broadcast_pooling_helper(kernel_size, "3d", name="kernel_size") + stride = _broadcast_pooling_helper(stride, "3d", name="stride") + padding = _broadcast_pooling_helper(padding, "3d", name="padding") + if all( + [pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)] + ): + padding = "SAME" + else: + padding = "VALID" return ivy.avg_pool3d( input, kernel_size, diff --git a/ivy/stateful/module.py b/ivy/stateful/module.py index fd2b41b58cf68..9c20e5717d402 100644 --- a/ivy/stateful/module.py +++ b/ivy/stateful/module.py @@ -5,7 +5,7 @@ import os import abc import copy -import dill +#import dill from typing import Optional, Tuple, Dict # local diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py index e0e5530b5f5da..82eec194cbf27 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py @@ -36,7 +36,7 @@ def calculate_same_padding(kernel_size, stride, shape): if all([kernel_size[i] / 2 >= padding[i] for i in range(len(kernel_size))]): if is_same_padding(padding, stride, kernel_size, shape): return padding - return (0, 0) + return [0] * len(shape) # avg_pool1d @@ -47,11 +47,16 @@ def calculate_same_padding(kernel_size, stride, shape): max_dims=3, min_side=1, max_side=3, + data_format="channel_first", ), + count_include_pad=st.just(False), + ceil_mode=st.booleans(), test_with_out=st.just(False), ) def test_torch_avg_pool1d( dtype_x_k_s, + count_include_pad, + ceil_mode, *, test_flags, frontend, @@ -60,21 +65,14 @@ def test_torch_avg_pool1d( on_device, ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s - - # Torch ground truth func expects input to be consistent - # with a channels first format i.e. NCW - x[0] = x[0].reshape((x[0].shape[0], x[0].shape[-1], x[0].shape[1])) - x_shape = list(x[0].shape[2]) + x_shape = [x[0].shape[2]] # Torch ground truth func also takes padding input as an integer # or a tuple of integers, not a string - padding = tuple( - [ - ivy.handle_padding(x_shape[i], stride[0], kernel_size[i], padding) - for i in range(len(x_shape)) - ] - ) - + if padding == "SAME": + padding = calculate_same_padding(kernel_size, stride, x_shape) + else: + padding = (0,) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -86,8 +84,8 @@ def test_torch_avg_pool1d( kernel_size=kernel_size, stride=stride, padding=padding, - ceil_mode=False, - count_include_pad=True, + ceil_mode=ceil_mode, + count_include_pad=count_include_pad, ) @@ -99,6 +97,7 @@ def test_torch_avg_pool1d( max_dims=4, min_side=1, max_side=4, + data_format="channel_first", ), ceil_mode=st.booleans(), count_include_pad=st.booleans(), @@ -125,8 +124,6 @@ def test_torch_avg_pool2d( else: padding = (0, 0) - x[0] = x[0].reshape((x[0].shape[0], x[0].shape[-1], *x[0].shape[1:-1])) - helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -144,19 +141,20 @@ def test_torch_avg_pool2d( ) +# avg_pool3d @handle_frontend_test( fn_tree="torch.nn.functional.avg_pool3d", dtype_x_k_s=helpers.arrays_for_pooling( min_dims=5, max_dims=5, - min_side=1, + min_side=2, max_side=4, + only_explicit_padding=False, data_format="channel_first", - only_explicit_padding=True, ), count_include_pad=st.booleans(), ceil_mode=st.booleans(), - divisor_override=st.one_of(st.none(), st.integers(min_value=1, max_value=4)), + divisor_override=st.just(None), test_with_out=st.just(False), ) def test_torch_avg_pool3d( @@ -173,7 +171,12 @@ def test_torch_avg_pool3d( ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s - padding = [padding[i][0] for i in range(len(padding))] + if len(stride) == 1: + stride = [stride[0]] * 3 + if padding == "SAME": + padding = calculate_same_padding(kernel_size, stride, x[0].shape[2:]) + elif padding == "VALID": + padding = (0, 0, 0) helpers.test_frontend_function( input_dtypes=input_dtype, From aad94009f278fa5454abe3700af1116fc78df1f9 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 15 Aug 2023 14:16:56 +0300 Subject: [PATCH 2/5] fixed errors --- ivy/stateful/module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/stateful/module.py b/ivy/stateful/module.py index 9c20e5717d402..fd2b41b58cf68 100644 --- a/ivy/stateful/module.py +++ b/ivy/stateful/module.py @@ -5,7 +5,7 @@ import os import abc import copy -#import dill +import dill from typing import Optional, Tuple, Dict # local From 4af873422251b0300e2158c3ef0875aea9afc138 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 15 Aug 2023 19:26:42 +0300 Subject: [PATCH 3/5] changes made --- .../torch/nn/functional/pooling_functions.py | 51 ++++--------------- .../test_functional/test_pooling_functions.py | 38 ++++++-------- 2 files changed, 25 insertions(+), 64 deletions(-) diff --git a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py index b468c24588825..dabde1f580c77 100644 --- a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py @@ -25,7 +25,6 @@ def _broadcast_pooling_helper(x, pool_dims: str = "2d", name: str = "padding"): ) -@to_ivy_arrays_and_back @to_ivy_arrays_and_back def avg_pool1d( input, @@ -37,29 +36,18 @@ def avg_pool1d( ): if stride is None: stride = kernel_size + data_format = "NCW" kernel_size = _broadcast_pooling_helper(kernel_size, "1d", name="kernel_size") - stride = _broadcast_pooling_helper(stride, "1d", name="stride") padding = _broadcast_pooling_helper(padding, "1d", name="padding") - kernel_pads = list(zip(kernel_size, padding)) - - data_format = "NCW" - - if not all([pad <= kernel / 2 for kernel, pad in kernel_pads]): - raise ValueError( - "pad should be smaller than or equal to half of kernel size, " - f"but got padding={padding}, kernel_size={kernel_size}. " - ) - # figure out whether to apply padding - if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in kernel_pads]): - padding_str = "SAME" + if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + padding = "SAME" else: - padding_str = "VALID" - + padding = "VALID" return ivy.avg_pool1d( input, kernel_size, stride, - padding_str, + padding, data_format=data_format, count_include_pad=count_include_pad, ceil_mode=ceil_mode, @@ -79,28 +67,16 @@ def avg_pool2d( stride = kernel_size data_format = "NCHW" kernel_size = _broadcast_pooling_helper(kernel_size, "2d", name="kernel_size") - stride = _broadcast_pooling_helper(stride, "2d", name="stride") padding = _broadcast_pooling_helper(padding, "2d", name="padding") - kernel_pads = list(zip(kernel_size, padding)) - - # Padding should be less than or equal to half of kernel size - if not all([pad <= kernel / 2 for kernel, pad in kernel_pads]): - raise ValueError( - "pad should be smaller than or equal to half of kernel size, " - f"but got padding={padding}, kernel_size={kernel_size}. " - ) - - # Figure out padding string - if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in kernel_pads]): - padding_str = "SAME" + if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + padding = "SAME" else: - padding_str = "VALID" - + padding = "VALID" return ivy.avg_pool2d( input, kernel_size, stride, - padding_str, + padding, data_format=data_format, ceil_mode=ceil_mode, count_include_pad=count_include_pad, @@ -277,15 +253,6 @@ def avg_pool3d( ): if stride is None: stride = kernel_size - kernel_size = _broadcast_pooling_helper(kernel_size, "3d", name="kernel_size") - stride = _broadcast_pooling_helper(stride, "3d", name="stride") - padding = _broadcast_pooling_helper(padding, "3d", name="padding") - if all( - [pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)] - ): - padding = "SAME" - else: - padding = "VALID" return ivy.avg_pool3d( input, kernel_size, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py index 82eec194cbf27..e95998da123d2 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py @@ -48,6 +48,7 @@ def calculate_same_padding(kernel_size, stride, shape): min_side=1, max_side=3, data_format="channel_first", + only_explicit_padding=True, ), count_include_pad=st.just(False), ceil_mode=st.booleans(), @@ -66,13 +67,11 @@ def test_torch_avg_pool1d( ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s x_shape = [x[0].shape[2]] - - # Torch ground truth func also takes padding input as an integer - # or a tuple of integers, not a string - if padding == "SAME": + padding = (padding[0][0], ) + # figuring out the exact kernel_size for SAME and VALID padding + # As ivy.avg_pool1d doesn't support explicit padding scheme + if not sum(padding) == 0: padding = calculate_same_padding(kernel_size, stride, x_shape) - else: - padding = (0,) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -97,6 +96,7 @@ def test_torch_avg_pool1d( max_dims=4, min_side=1, max_side=4, + only_explicit_padding=True, data_format="channel_first", ), ceil_mode=st.booleans(), @@ -114,16 +114,11 @@ def test_torch_avg_pool2d( fn_tree, on_device, ): - input_dtype, x, kernel_size, stride, pad_name = dtype_x_k_s - - if len(stride) == 1: - stride = (stride[0], stride[0]) - - if pad_name == "SAME": - padding = calculate_same_padding(kernel_size, stride, x[0].shape[2:]) - else: - padding = (0, 0) - + input_dtype, x, kernel_size, stride, padding = dtype_x_k_s + padding = (pad[i] for i, pad in enumerate(padding)) + x_shape = x[0].shape[2:] + if not sum(padding) == 0: + padding = calculate_same_padding(kernel_size, [stride[0]] * 2, x_shape) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -149,7 +144,7 @@ def test_torch_avg_pool2d( max_dims=5, min_side=2, max_side=4, - only_explicit_padding=False, + only_explicit_padding=True, data_format="channel_first", ), count_include_pad=st.booleans(), @@ -173,11 +168,10 @@ def test_torch_avg_pool3d( if len(stride) == 1: stride = [stride[0]] * 3 - if padding == "SAME": - padding = calculate_same_padding(kernel_size, stride, x[0].shape[2:]) - elif padding == "VALID": - padding = (0, 0, 0) - + x_shape = x[0].shape[2:] + padding = (pad[i] for i, pad in enumerate(padding)) + if not sum(padding) == 0: + padding = calculate_same_padding(kernel_size, [stride[0]] * 3, x_shape) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, From 10fdf9b77beb6f64171ac682d58fb8e2e4984103 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Wed, 16 Aug 2023 19:07:29 +0300 Subject: [PATCH 4/5] refactored avg_pooling functions --- .../torch/nn/functional/pooling_functions.py | 12 ++++++++++++ .../test_functional/test_pooling_functions.py | 16 ++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py index dabde1f580c77..7525ca908cbc3 100644 --- a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py @@ -37,6 +37,8 @@ def avg_pool1d( if stride is None: stride = kernel_size data_format = "NCW" + # TODO: remove the broadcasting and padding string specification when ivy.avg_pool + # support explicit padding kernel_size = _broadcast_pooling_helper(kernel_size, "1d", name="kernel_size") padding = _broadcast_pooling_helper(padding, "1d", name="padding") if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): @@ -66,6 +68,8 @@ def avg_pool2d( if stride is None: stride = kernel_size data_format = "NCHW" + # TODO: remove the broadcasting and padding string specification when ivy.avg_pool + # support explicit padding kernel_size = _broadcast_pooling_helper(kernel_size, "2d", name="kernel_size") padding = _broadcast_pooling_helper(padding, "2d", name="padding") if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): @@ -253,6 +257,14 @@ def avg_pool3d( ): if stride is None: stride = kernel_size + # TODO: remove the broadcasting and padding string specification when ivy.avg_pool + # support explicit padding + kernel_size = _broadcast_pooling_helper(kernel_size, "3d", name="kernel_size") + padding = _broadcast_pooling_helper(padding, "3d", name="padding") + if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + padding = "SAME" + else: + padding = "VALID" return ivy.avg_pool3d( input, kernel_size, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py index e95998da123d2..fd1615ea305d9 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py @@ -66,8 +66,10 @@ def test_torch_avg_pool1d( on_device, ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s + # TODO: remove the processing of padding attribute when ivy.avg_pool + # support explicit padding x_shape = [x[0].shape[2]] - padding = (padding[0][0], ) + padding = (pad[i] for i, pad in enumerate(padding)) # figuring out the exact kernel_size for SAME and VALID padding # As ivy.avg_pool1d doesn't support explicit padding scheme if not sum(padding) == 0: @@ -115,6 +117,8 @@ def test_torch_avg_pool2d( on_device, ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s + # TODO: remove the processing of padding attribute when ivy.avg_pool + # support explicit padding padding = (pad[i] for i, pad in enumerate(padding)) x_shape = x[0].shape[2:] if not sum(padding) == 0: @@ -165,13 +169,13 @@ def test_torch_avg_pool3d( on_device, ): input_dtype, x, kernel_size, stride, padding = dtype_x_k_s - - if len(stride) == 1: - stride = [stride[0]] * 3 + # TODO: remove the processing of padding and strides attributes when ivy.avg_pool + # support explicit padding x_shape = x[0].shape[2:] - padding = (pad[i] for i, pad in enumerate(padding)) + padding = [pad[0] for pad in padding] if not sum(padding) == 0: - padding = calculate_same_padding(kernel_size, [stride[0]] * 3, x_shape) + stride_broad = (stride[0],) * 3 if len(stride) == 1 else stride + padding = calculate_same_padding(kernel_size, stride_broad, x_shape) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, From 8e54af5817120de1f01e138227dde1627c272ce3 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Wed, 16 Aug 2023 19:13:47 +0300 Subject: [PATCH 5/5] refactored lp pooling functions --- .../torch/nn/functional/pooling_functions.py | 13 ++++++++++--- ivy_tests/array_api_testing/test_array_api | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py index ef936448549c0..1b25b4d441cb6 100644 --- a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py @@ -1,5 +1,6 @@ # global from functools import reduce + # local import ivy from ivy import with_unsupported_dtypes @@ -41,7 +42,9 @@ def avg_pool1d( # support explicit padding kernel_size = _broadcast_pooling_helper(kernel_size, "1d", name="kernel_size") padding = _broadcast_pooling_helper(padding, "1d", name="padding") - if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + if all( + [pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)] + ): padding = "SAME" else: padding = "VALID" @@ -72,7 +75,9 @@ def avg_pool2d( # support explicit padding kernel_size = _broadcast_pooling_helper(kernel_size, "2d", name="kernel_size") padding = _broadcast_pooling_helper(padding, "2d", name="padding") - if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + if all( + [pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)] + ): padding = "SAME" else: padding = "VALID" @@ -254,7 +259,9 @@ def avg_pool3d( # support explicit padding kernel_size = _broadcast_pooling_helper(kernel_size, "3d", name="kernel_size") padding = _broadcast_pooling_helper(padding, "3d", name="padding") - if all([pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)]): + if all( + [pad == ivy.ceil((kernel - 1) / 2) for kernel, pad in zip(kernel_size, padding)] + ): padding = "SAME" else: padding = "VALID" diff --git a/ivy_tests/array_api_testing/test_array_api b/ivy_tests/array_api_testing/test_array_api index 852a1ddfedb14..f82c7bc8627cc 160000 --- a/ivy_tests/array_api_testing/test_array_api +++ b/ivy_tests/array_api_testing/test_array_api @@ -1 +1 @@ -Subproject commit 852a1ddfedb14742ec94a9dfc6b3f3d4e89d0189 +Subproject commit f82c7bc8627cc2c3a44fa3e425f53a253a609aa8