code: def test_builder_to_backend_smoke(
      self,
      use_cpu_only,
      backend,
      seq_len,
      batch_size,
      input_size,
      hidden_size,
      has_bias,
      output_sequence,
      direction,
      symbolic,
  ):
      torch.manual_seed(5)
      rnn = torch.nn.GRU(input_size, hidden_size, 1, bias=has_bias)
      state_dict = rnn.state_dict()
  
      state_dict["weight_ih_l0"] /= state_dict["weight_ih_l0"]
      state_dict["weight_hh_l0"] /= state_dict["weight_hh_l0"]
  
      ih_wt = state_dict["weight_ih_l0"].detach().numpy()
      hh_wt = state_dict["weight_hh_l0"].detach().numpy()
  
      # Make weight compatible to CoreML format
      def rzo_to_zro(x):
          r, z, o = np.split(x, 3)
          return np.concatenate([z, r, o], axis=0)
  
      w = np.concatenate([ih_wt, hh_wt], axis=1)
      w = rzo_to_zro(w).transpose()
  
      b = None
      if has_bias:
          ih_b = state_dict["bias_ih_l0"].detach().numpy()
          hh_b = state_dict["bias_hh_l0"].detach().numpy()
          ih_b = rzo_to_zro(ih_b)
          hh_b = rzo_to_zro(hh_b)
          b = np.stack([ih_b, hh_b], axis=0)
  
      t = torch.randn(seq_len, batch_size, input_size)
      h0 = torch.randn(1, batch_size, hidden_size)
  
      n_t = t
      if direction == "reverse":
          n_t = torch.flip(n_t, [0])
  
      output, hn = rnn(n_t, h0)
      if output_sequence == False:
          output = output[-1].unsqueeze(0)
  
      output = output.detach().numpy()
      hn = hn.detach().numpy().squeeze(0)
  
      t = np.reshape(
          t.detach().numpy(), [seq_len, batch_size, input_size]
      )
      h = np.reshape(
          h0.detach().numpy().squeeze(0), [batch_size, hidden_size]
      )
  
      if symbolic:
          batch_size = get_new_symbol()
          seq_len = get_new_symbol()
  
      input_shape = [seq_len, batch_size, input_size]
      h_shape = [batch_size, hidden_size]
  
      expected_output_types = [
          (
              seq_len if output_sequence else 1,
              batch_size,
              hidden_size,
              types.fp32,
          ),
          (batch_size, hidden_size, types.fp32),
      ]
      expected_outputs = [output, hn]
  
      input_placeholders = {
          "x": mb.placeholder(shape=input_shape),
          "initial_h": mb.placeholder(shape=h_shape),
      }
      input_values = {"x": t, "initial_h": h}
  
      def build(x, initial_h):
          arguments = {
              "x": x,
              "initial_h": initial_h,
              "weight": w,
              "direction": direction,
              "output_sequence": output_sequence,
          }
          # If bias is provided, add in arguments
          if b is not None:
              arguments["bias"] = b
          return mb.gru(**arguments)
  
      run_compare_builder(
          build,
          input_placeholders,
          input_values,
          expected_output_types,
          expected_outputs,
          use_cpu_only=use_cpu_only,
          frontend_only=False,
          backend=backend,
      )
  
file_path: turicreate/src/external/coremltools_wrap/coremltools/coremltools/converters/mil/mil/ops/tests/test_recurrent.py
imports: from coremltools.converters.mil import testing_reqs
  from coremltools.converters.mil.mil import get_new_symbol
  from coremltools.converters.mil.testing_reqs import *
  from .testing_utils import run_compare_builder
label_desc: Use image node_id 1 for calling the TestGRU obj's underlying member method code with example usage: obj.test_builder_to_backend_smoke(use_cpu_only, backend, seq_len, batch_size, input_size, hidden_size, has_bias, output_sequence, direction, symbolic) and returns: np, mb