code: def lstm_layer_static_for_tflite(
      inputs,
      num_units,
      bidirectional,
      is_training,
      lengths=None,
      stack_size=1,
      dropout_keep_prob=1,
  ):
      """Create a LSTM layer using bidirectional static RNNs."""
      # Uses tflite compatible LSTM cell. The graph is name-compatible
      # with the graph created by lstm_layer.
  
      assert (
          dropout_keep_prob == 1
      )  # Dropout not implemented for this mode.
      del is_training  # Only used for dropout.
  
      # Static RNNs will take a list of input tensors instead of a single block
      # tensor. I.e. we need to convert from Tensor(size=[batch, time, width]) to
      # a list=[Tensor(size=[batch, width])] of length 'time'
      split_inputs = [
          tf.squeeze(t, axis=1)
          for t in tf.split(
              inputs, num_or_size_splits=inputs.shape[1], axis=1
          )
      ]
  
      # Here we use the basic LSTMCell which tflite knows about and fudging it so
      # that it sets it's scopes as if it was a
      # tf.contrib.cudnn_rnn.BasicLSTMCell
      cell_type = tf.nn.rnn_cell.LSTMCell
      cells_fw = [
          cell_type(num_units, name="basic_lstm_cell")
          for _ in range(stack_size)
      ]
  
      prev_layer = split_inputs
      if bidirectional:
          cells_bw = [
              cell_type(num_units, name="basic_lstm_cell")
              for _ in range(stack_size)
          ]
  
          # This emulates the scoping that contrib.rnn.stack_bidirectional_dynamic_rnn
          # does.
          with tf.variable_scope("lstm"):
              with tf.variable_scope("stack_bidirectional_rnn"):
                  for i, (cell_fw, cell_bw) in enumerate(
                      zip(cells_fw, cells_bw)
                  ):
                      with tf.variable_scope("cell_%d" % i):
                          (
                              prev_layer,
                              _,
                              _,
                          ) = tf.nn.static_bidirectional_rnn(
                              cell_fw,
                              cell_bw,
                              inputs=prev_layer,
                              sequence_length=lengths,
                              dtype=tf.float32,
                          )
          outputs = prev_layer
  
      else:  # not bidirectional
          with tf.variable_scope("lstm"):
              outputs, unused_state = tf.nn.static_rnn(
                  cell=tf.nn.rnn_cell.MultiRNNCell(cells_fw),
                  inputs=prev_layer,
                  sequence_length=lengths,
                  dtype=tf.float32,
              )
  
      # We gotta undo our earlier split and fuse it back into a single tensor.
      outputs = tf.stack(outputs, axis=1)
      return outputs
  
file_path: magenta/magenta/models/onsets_frames_transcription/model_tpu.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from magenta.contrib import rnn
  from magenta.contrib import training
  from magenta.models.onsets_frames_transcription import constants
  from magenta.models.onsets_frames_transcription import estimator_spec_util
  import tensorflow.compat.v1
  from tensorflow.compat.v1 import estimator
  import tf_slim
label_desc: Use image node_id 3 for calling a global function with example usage: lstm_layer_static_for_tflite(inputs, num_units, bidirectional, is_training, lengths, stack_size, dropout_keep_prob) and returns: outputs