Repository: ivy-llc/ivy

Issue:
pixel_shuffle



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/paddle/nn/functional/vision.py b/ivy/functional/frontends/paddle/nn/functional/vision.py
--- a/ivy/functional/frontends/paddle/nn/functional/vision.py
+++ b/ivy/functional/frontends/paddle/nn/functional/vision.py
@@ -5,6 +5,65 @@
 from ivy.functional.frontends.paddle.func_wrapper import (
     to_ivy_arrays_and_back,
 )
+from ivy.utils.assertions import check_equal
+
+
+@to_ivy_arrays_and_back
+def pixel_shuffle(x, upscale_factor, data_format="NCHW"):
+    input_shape = ivy.shape(x)
+    check_equal(
+        len(input_shape),
+        4,
+        message="pixel shuffle requires a 4D input, but got input size {}".format(
+            input_shape
+        ),
+    )
+
+    if not isinstance(upscale_factor, int):
+        raise ValueError("upscale factor must be int type")
+
+    if data_format not in ["NCHW", "NHWC"]:
+        raise ValueError(
+            "Attr(data_format) should be 'NCHW' or 'NHWC'."
+            "But recevie Attr(data_format): {} ".format(data_format)
+        )
+
+    b = input_shape[0]
+    c = input_shape[1] if data_format == "NCHW" else input_shape[3]
+    h = input_shape[2] if data_format == "NCHW" else input_shape[1]
+    w = input_shape[3] if data_format == "NCHW" else input_shape[2]
+
+    upscale_factor_squared = upscale_factor**2
+
+    check_equal(
+        c % upscale_factor_squared,
+        0,
+        message=(
+            "pixel shuffle expects input channel to be divisible by square of upscale"
+            " factor, but got input with sizes {}, upscale factor={}, and"
+            " self.size(1)={}, is not divisible by {}".format(
+                input_shape, upscale_factor, c, upscale_factor_squared
+            )
+        ),
+        as_array=False,
+    )
+
+    oc = int(c / upscale_factor_squared)
+    oh = h * upscale_factor
+    ow = w * upscale_factor
+
+    if data_format == "NCHW":
+        input_reshaped = ivy.reshape(x, (b, oc, upscale_factor, upscale_factor, h, w))
+    else:
+        input_reshaped = ivy.reshape(x, (b, h, w, upscale_factor, upscale_factor, oc))
+
+    if data_format == "NCHW":
+        return ivy.reshape(
+            ivy.permute_dims(input_reshaped, (0, 1, 4, 2, 5, 3)), (b, oc, oh, ow)
+        )
+    return ivy.reshape(
+        ivy.permute_dims(input_reshaped, (0, 1, 4, 2, 5, 3)), (b, oh, ow, oc)
+    )
 
 
 @to_ivy_arrays_and_back


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_vision.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_vision.py
--- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_vision.py
+++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_vision.py
@@ -1,11 +1,54 @@
 # global
-from hypothesis import strategies as st
+import ivy
+from hypothesis import assume, strategies as st
 
 # local
 import ivy_tests.test_ivy.helpers as helpers
 from ivy_tests.test_ivy.helpers import handle_frontend_test
 
 
+# pixel_shuffle
+@handle_frontend_test(
+    fn_tree="paddle.nn.functional.pixel_shuffle",
+    dtype_and_x=helpers.dtype_and_values(
+        available_dtypes=["float32", "float64"],
+        min_value=0,
+        min_num_dims=4,
+        max_num_dims=4,
+        min_dim_size=3,
+    ),
+    factor=helpers.ints(min_value=1),
+    data_format=st.sampled_from(["NCHW", "NHWC"]),
+)
+def test_paddle_pixel_shuffle(
+    *,
+    dtype_and_x,
+    factor,
+    data_format,
+    on_device,
+    fn_tree,
+    frontend,
+    test_flags,
+    backend_fw,
+):
+    input_dtype, x = dtype_and_x
+    if data_format == "NCHW":
+        assume(ivy.shape(x[0])[1] % (factor**2) == 0)
+    else:
+        assume(ivy.shape(x[0])[3] % (factor**2) == 0)
+    helpers.test_frontend_function(
+        input_dtypes=input_dtype,
+        frontend=frontend,
+        test_flags=test_flags,
+        fn_tree=fn_tree,
+        on_device=on_device,
+        x=x[0],
+        upscale_factor=factor,
+        data_format=data_format,
+        backend_to_test=backend_fw,
+    )
+
+
 @st.composite
 def _affine_grid_helper(draw):
     align_corners = draw(st.booleans())