def test_conv1d_channellast_composotion_dynamic_weight(self, backend):
        """
        Input graph:
        input -> expand_dims -> transpose -> conv2d -> transpose -> squeeze -> out

        Output graph:
        input -> transpose -> conv1d -> transpose -> out
        """
        N, L = 2, 9
        C_in, C_out = 4, 5
        K = 4

        strides = (1, 2)
        # The pad is specially designed to make sure the output of conv has dim_size=1 at axis 1.
        pad = (0, 0, 0, 1)
        # MIL convolution with dynamic weights does not support dilations != 1
        # see coremltools/coremltools/converters/mil/mil/ops/defs/iOS15/conv.py
        dilations = (1, 1)

        # infer L_out with pad_type fixed to custom
        L_out = (L + pad[-2] + pad[-1] - dilations[-1] * (K - 1) - 1) // strides[-1] + 1

        conv_kwargs = {
            "strides": strides,
            "pad_type": "custom",
            "pad": pad,
            "dilations": dilations,
        }

        @mb.program(
            input_specs=[
                mb.TensorSpec(shape=(N, L, C_in)),
                mb.TensorSpec(shape=(C_out, C_in, 1, K)),
            ]
        )
        def prog(x, weight):
            y_expand = mb.expand_dims(x=x, axes=(1,))
            y_transpose1 = mb.transpose(x=y_expand, perm=(0, 3, 1, 2))
            y_conv = mb.conv(x=y_transpose1, weight=weight, **conv_kwargs)
            y_transpose2 = mb.transpose(x=y_conv, perm=(0, 2, 3, 1))
            y_squeeze = mb.squeeze(x=y_transpose2, axes=(1,))
            return y_squeeze

        assert get_op_types_in_program(prog) == [
            "expand_dims",
            "transpose",
            "conv",
            "transpose",
            "squeeze",
        ]

        prev_prog, prev_block, block = apply_pass_and_basic_check(prog, "common::compose_conv1d")
        assert get_op_types_in_program(prog) == ["transpose", "squeeze", "conv", "transpose"]

        prev_prog, prev_block, block = apply_pass_and_basic_check(prog, "common::const_elimination")
        assert get_op_types_in_program(prog) == ["transpose", "squeeze", "conv", "transpose"]

        output_shape = (N, L_out, C_out)
        assert_model_is_valid(
            prog,
            {"x": (N, L, C_in), "weight": (C_out, C_in, 1, K)},
            expected_output_shapes={block.outputs[0].name: output_shape},
            backend=backend,
        )

        Input graph:
        input -> expand_dims -> transpose -> conv2d -> transpose -> squeeze -> out

        Output graph:
        input -> transpose -> conv1d -> transpose -> out
        
coremltools/converters/mil/mil/passes/tests/test_passes.py