code: def expand_tf_lstm_block(op):
      if op.op_type != "tf_lstm_block":
          raise ValueError()
  
      with op.enclosing_block as block:
          x = op.x  # [s, b, input_dim]
          h_prev = op.h_prev  # [b, hidden_dim]
          cs_prev = op.c_prev  # [b, hidden_dim]
  
          # Allocate two lists: cs & h
          x_shape = mb.shape(x=x, before_op=op)
          length = mb.slice_by_index(
              x=x_shape, begin=[0], end=[1], before_op=op
          )
          h_shape = mb.shape(x=h_prev, before_op=op)
          list_shape = mb.concat(
              values=[length, h_shape], axis=0, before_op=op
          )
          cs_list = mb.fill(shape=list_shape, before_op=op)
          h_list = mb.fill(shape=list_shape, before_op=op)
  
          # append initial state at index 0
          cs_prev = mb.expand_dims(x=cs_prev, axes=[0], before_op=op)
          cs_list = mb.concat(
              values=[cs_prev, cs_list], axis=0, before_op=op
          )
          h_prev = mb.expand_dims(x=h_prev, axes=[0], before_op=op)
          h_list = mb.concat(
              values=[h_prev, h_list], axis=0, before_op=op
          )
  
          def cond(i, cs_list, h_list):
              return mb.less(x=i, y=length)
  
          def body(i, cs_list, h_list):
              xi = mb.gather(x=x, indices=i, axis=0)
              h_prev = mb.gather(x=h_list, indices=i, axis=0)
              cs_prev = mb.gather(x=cs_list, indices=i, axis=0)
  
              ig, cs, fg, og, ci, co, h = _lstm_cell_builder(
                  op, xi, h_prev, cs_prev
              )
  
              counter = mb.add(x=i, y=1)
  
              return (
                  counter,
                  mb.scatter(data=cs_list, indices=counter, updates=cs),
                  mb.scatter(data=h_list, indices=counter, updates=h),
              )
  
          _, cs_list, h_list = mb.while_loop(
              _cond=cond,
              _body=body,
              loop_vars=([0], cs_list, h_list),
              before_op=op,
          )
  
          # strip initial state or element at index 0
          begin, end = [1, 0, 0], [0, 0, 0]
          begin_mask = [False, True, True]
          end_mask = [True, True, True]
          cs = mb.slice_by_index(
              x=cs_list,
              begin=begin,
              end=end,
              begin_mask=begin_mask,
              end_mask=end_mask,
              before_op=op,
          )
          h = mb.slice_by_index(
              x=h_list,
              begin=begin,
              end=end,
              begin_mask=begin_mask,
              end_mask=end_mask,
              before_op=op,
          )
  
          # Replace all outputs
          new_outputs = [cs, h]
          for old_v, new_v in zip(
              [
                  ov
                  for index, ov in enumerate(op.outputs)
                  if index in [1, 6]
              ],
              new_outputs,
          ):
              block.replace_uses_of_var_after_op(
                  anchor_op=op, old_var=old_v, new_var=new_v
              )
          block.remove_ops([op])
  
file_path: turicreate/src/external/coremltools_wrap/coremltools/coremltools/converters/mil/frontend/tensorflow/ssa_passes/expand_tf_lstm.py
imports: from __future__ import print_function
  from __future__ import division
  from __future__ import absolute_import
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import types
  import numpy
  import logging
label_desc: Use image node_id 5 for calling a global function with example usage: expand_tf_lstm_block(op) and returns: mb, counter,  mb,  mb