code: def type_inference(self):
      if self.x.rank != 3:
          raise ValueError(
              "Invalid input shape. Expecting Rank 3 input, got {}".format(
                  len(self.x.shape)
              )
          )
  
      sequence_length, batch_size, input_size = self.x.shape
  
      if self.weight.rank != 2:
          raise ValueError(
              "Invalid weight shape. Expecting Rank 2 input, got {}".format(
                  len(self.weight.shape)
              )
          )
  
      _, hidden_size = self.weight.shape
  
      direction = self.direction.val
      valid_directions = {"forward", "reverse"}
      if direction not in valid_directions:
          raise ValueError(
              "Direction {} not supported. Supported directions: {}".format(
                  direction, valid_directions
              )
          )
  
      out_seq_len = sequence_length if self.output_sequence.val else 1
      output_shape = [out_seq_len, batch_size, hidden_size]
      output_h_shape = [batch_size, hidden_size]
      return (
          types.tensor(self.x.dtype, tuple(output_shape)),
          types.tensor(self.x.dtype, tuple(output_h_shape)),
      )
  
file_path: turicreate/src/external/coremltools_wrap/coremltools/coremltools/converters/mil/mil/ops/defs/recurrent.py
imports: from coremltools.converters.mil.mil import get_new_symbol
  from ._op_reqs import *
label_desc: Use image node_id 2 for calling the rnn obj's underlying member method code with example usage: obj.type_inference() and returns: types,  types