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

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

        strides = (2,)
        pad = (1, 1)
        # MIL convolution with dynamic weights does not support dilations != 1
        # see coremltools/coremltools/converters/mil/mil/ops/defs/iOS15/conv.py
        dilations = (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, C_in, L)),
                mb.TensorSpec(shape=(C_out, C_in, K)),
            ]
        )
        def prog(x, weight):
            y = mb.conv(x=x, weight=weight, **conv_kwargs)
            return y

        assert get_op_types_in_program(prog) == ["conv"]

        prev_prog, prev_block, block = apply_pass_and_basic_check(
            prog, "nn_backend::decompose_conv1d"
        )
        assert get_op_types_in_program(prog) == ["expand_dims", "expand_dims", "conv", "squeeze"]

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

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

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

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