code: def test_builder_to_backend_smoke(
      self,
      compute_unit,
      backend,
      seq_len,
      batch_size,
      input_size,
      hidden_size,
      has_bias,
      output_sequence,
      direction,
      activation_functions,
      symbolic,
      dtype,
  ):
      torch.manual_seed(5)
  
      R_z = 2 * np.random.rand(hidden_size, hidden_size) - 1
      R_r = 2 * np.random.rand(hidden_size, hidden_size) - 1
      R_o = 2 * np.random.rand(hidden_size, hidden_size) - 1
      W_z = 2 * np.random.rand(hidden_size, input_size) - 1
      W_r = 2 * np.random.rand(hidden_size, input_size) - 1
      W_o = 2 * np.random.rand(hidden_size, input_size) - 1
      b_z = (
          2 * np.random.rand(hidden_size) - 1
          if has_bias
          else np.zeros((hidden_size))
      )
      b_r = (
          2 * np.random.rand(hidden_size) - 1
          if has_bias
          else np.zeros((hidden_size))
      )
      b_o = (
          2 * np.random.rand(hidden_size) - 1
          if has_bias
          else np.zeros((hidden_size))
      )
  
      def apply_act(x, option):
          if option == "tanh":
              return np.tanh(x)
          elif option == "sigmoid":
              return 1.0 / (1 + np.exp(-x))
          else:
              raise ValueError("activation invalid")
  
      def get_numpy_prediction_gru(
          X,
          H,
          return_seq,
          direction,
          inner_activation_str="sigmoid",
          activation_str="tanh",
      ):
          """
          shape of X : (B, Seq, input_size)
  
          shape of H : (B, hidden_size)
  
          shape of return = (B, 1, hidden_size) if return_seq=False else (B, Seq, hidden_size)
          """
          assert X.shape == (batch_size, seq_len, input_size)
          assert H.shape == (batch_size, hidden_size)
          out = []
          for i in range(batch_size):
              numpy_input = X[i]
              hidden_state = H[i]
              out.append(
                  get_numpy_prediction_gru_single_batch(
                      numpy_input,
                      hidden_state,
                      return_seq,
                      direction,
                      inner_activation_str=inner_activation_str,
                      activation_str=activation_str,
                  )
              )
          output = np.stack(out, axis=0)
          output = np.transpose(output, (1, 0, 2))
          return output, output[-1, :, :]
  
      def get_numpy_prediction_gru_single_batch(
          X,
          h,
          return_seq,
          direction,
          inner_activation_str="sigmoid",
          activation_str="tanh",
      ):
          np_out = np.zeros((seq_len, hidden_size))
          batch_x = X if direction == "forward" else X[::-1, :]
          for k in range(seq_len):
              x = batch_x[k, :]
              z = apply_act(
                  np.dot(W_z, x) + np.dot(R_z, h) + b_z,
                  inner_activation_str,
              )
              r = apply_act(
                  np.dot(W_r, x) + np.dot(R_r, h) + b_r,
                  inner_activation_str,
              )
              c = h * r
              o = apply_act(
                  np.dot(W_o, x) + np.dot(R_o, c) + b_o, activation_str
              )
              h = (1 - z) * o + z * h
              np_out[k, :] = h
  
          if return_seq:
              np_out_final = np_out
          else:
              np_out_final = np_out[-1:, :]
  
          return np_out_final
  
      x = np.random.rand(batch_size, seq_len, input_size).astype(dtype)
      h = np.random.rand(batch_size, hidden_size).astype(dtype)
  
      activation, inner_activation = activation_functions
      output, state = get_numpy_prediction_gru(
          x, h, output_sequence, direction, inner_activation, activation
      )
      expected_outputs = [output, state]
  
      if symbolic:
          batch_size = get_new_symbol()
          seq_len = get_new_symbol()
  
      hh_wt = np.concatenate([R_r, R_o, R_z], axis=0).astype(dtype)
      ih_wt = np.concatenate([W_r, W_o, W_z], axis=0).astype(dtype)
      b = np.concatenate([b_r, b_o, b_z], axis=0).astype(dtype)
  
      input_shape = [seq_len, batch_size, input_size]
      h_shape = [batch_size, hidden_size]
  
      builtin_dtype = numpy_type_to_builtin_type(dtype)
      input_placeholders = {
          "x": mb.placeholder(shape=input_shape, dtype=builtin_dtype),
          "initial_h": mb.placeholder(
              shape=h_shape, dtype=builtin_dtype
          ),
      }
  
      coreml_x = np.transpose(x, (1, 0, 2))
      input_values = {"x": coreml_x, "initial_h": h}
  
      expected_output_types = [
          (
              seq_len if output_sequence else 1,
              batch_size,
              hidden_size,
              builtin_dtype,
          ),
          (batch_size, hidden_size, builtin_dtype),
      ]
  
      def build(x, initial_h):
          arguments = {
              "x": x,
              "initial_h": initial_h,
              "weight_ih": ih_wt,
              "weight_hh": hh_wt,
              "direction": direction,
              "output_sequence": output_sequence,
              "activation": activation,
              "recurrent_activation": inner_activation,
          }
          # If bias is provided, add in arguments
          if has_bias:
              arguments["bias"] = b
          return mb.gru(**arguments)
  
      run_compare_builder(
          build,
          input_placeholders,
          input_values,
          expected_output_types,
          expected_outputs,
          inputs=construct_inputs_from_placeholders(
              input_placeholders, upper_bound=10
          )
          if symbolic and backend.backend == "mlprogram"
          else None,
          compute_unit=compute_unit,
          backend=backend,
      )
  
imports: import itertools
  import numpy
  import pytest
  import coremltools
  from coremltools._deps import _HAS_TORCH, MSG_TORCH_NOT_FOUND
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import get_new_symbol
  from coremltools.converters.mil.mil.ops.tests.iOS14 import backends
  from coremltools.converters.mil.mil.ops.tests.testing_utils import construct_inputs_from_placeholders, run_compare_builder
  from coremltools.converters.mil.mil.types.type_mapping import numpy_type_to_builtin_type
  from coremltools.converters.mil.testing_reqs import compute_units
  from coremltools.converters.mil.testing_utils import ssa_fn
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(compute_unit, backend, seq_len, batch_size, input_size, hidden_size, has_bias, output_sequence, direction, activation_functions, symbolic, dtype) and returns: output,  output, np_out_final, mb, np, unknown