docstr: Input graph:
  input -> expand_dims -> conv2d -> squeeze -> out
  
  Output graph:
  input -> conv1d -> out
docstr_tok: ["Input","graph",":","input","-",">","expand_dims","-",">","conv2d","-",">","squeeze","-",">","out","Output","graph",":","input","-",">","conv1d","-",">","out"]
code: 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,
      )
  
file_path: coremltools/coremltools/converters/mil/backend/nn/passes/test_passes.py
imports: import copy
  import itertools
  import numpy
  import pytest
  from coremltools.converters.mil import testing_reqs
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil.passes.pass_registry import PASS_REGISTRY
  from coremltools.converters.mil.testing_utils import apply_pass_and_basic_check, assert_model_is_valid, assert_same_output_names, get_op_types_in_program
label_desc: Use image node_id 2 for calling the TestConv1dDeompositionPasses obj's underlying member method code with example usage: obj.test_conv1d_decomposition_dynamic_weight(backend) and returns: y