def test_nested(self):
        """
        Two nested blocks that will each be transformed.
        """

        @mb.program(
            input_specs=[
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
                mb.TensorSpec(shape=(1, 2, 3, 4)),
            ]
        )
        def prog(x1, x2, x3, x4, x5, x6, x7, x8):
            ab = mb.concat(values=[x1, x2], axis=2, interleave=True)
            cd = mb.concat(values=[x3, x4], axis=2, interleave=True)
            x = mb.concat(values=[ab, cd], axis=3, interleave=True)

            ef = mb.concat(values=[x5, x6], axis=2, interleave=True)
            gh = mb.concat(values=[x7, x8], axis=2, interleave=True)
            y = mb.concat(values=[ef, gh], axis=3, interleave=True)

            z = mb.concat(values=[x, y], axis=1)

            return z

        prev_prog, prev_block, block = apply_pass_and_basic_check(
            prog, "common::concat_to_pixel_shuffle"
        )
        self.assertEqual(
            get_op_types_in_program(prev_prog),
            ["concat", "concat", "concat", "concat", "concat", "concat", "concat"],
        )
        self.assertEqual(
            get_op_types_in_program(prog),
            ["concat", "pixel_shuffle", "concat", "pixel_shuffle", "concat"],
        )

        inputs = {
            "x1": (1, 2, 3, 4),
            "x2": (1, 2, 3, 4),
            "x3": (1, 2, 3, 4),
            "x4": (1, 2, 3, 4),
            "x5": (1, 2, 3, 4),
            "x6": (1, 2, 3, 4),
            "x7": (1, 2, 3, 4),
            "x8": (1, 2, 3, 4),
        }
        assert_model_is_valid(
            prog,
            inputs,
            expected_output_shapes={block.outputs[0].name: (1, 4, 6, 8)},
        )

        input_dict = dict()
        for name, shape in inputs.items():
            input_dict[name] = np.random.rand(*shape)

        output_name = block.outputs[0].name

        ab = np.reshape(
            np.stack((input_dict["x1"], input_dict["x2"]), axis=3), newshape=[1, 2, 6, 4]
        )
        cd = np.reshape(
            np.stack((input_dict["x3"], input_dict["x4"]), axis=3), newshape=[1, 2, 6, 4]
        )
        x = np.reshape(np.stack((ab, cd), axis=4), newshape=[1, 2, 6, 8])

        ef = np.reshape(
            np.stack((input_dict["x5"], input_dict["x6"]), axis=3), newshape=[1, 2, 6, 4]
        )
        gh = np.reshape(
            np.stack((input_dict["x7"], input_dict["x8"]), axis=3), newshape=[1, 2, 6, 4]
        )
        y = np.reshape(np.stack((ef, gh), axis=4), newshape=[1, 2, 6, 8])

        old_prediction = np.concatenate((x, y), axis=1)

        mlmodel = ct.convert(
            prog,
            source="milinternal",
            convert_to="neuralnetwork",
            compute_units=ct.ComputeUnit.CPU_ONLY,
        )

        if _IS_MACOS:
            prediction = mlmodel.predict(input_dict)
            np.testing.assert_allclose(
                old_prediction, prediction[output_name], atol=1e-04, rtol=1e-05
            )

        Two nested blocks that will each be transformed.
        
coremltools/converters/mil/mil/passes/tests/test_passes.py