class_docstr: Spatial GRU layer.
  
  :param units: Number of SpatialGRU units.
  :param activation: Activation function to use. Default:
      hyperbolic tangent (`tanh`). If you pass `None`, no
      activation is applied (ie. "linear" activation: `a(x) = x`).
  :param recurrent_activation: Activation function to use for
      the recurrent step. Default: sigmoid (`sigmoid`).
      If you pass `None`, no activation is applied (ie. "linear"
      activation: `a(x) = x`).
  :param kernel_initializer: Initializer for the `kernel` weights
      matrix, used for the linear transformation of the inputs.
  :param recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix, used for the linear transformation of the
      recurrent state.
  :param direction: Scanning direction. `lt` (i.e., left top)
      indicates the scanning from left top to right bottom, and
      `rb` (i.e., right bottom) indicates the scanning from
      right bottom to left top.
  :param kwargs: Standard layer keyword arguments.
  
  Examples:
      >>> import matchzoo as mz
      >>> layer = mz.contrib.layers.SpatialGRU(units=10,
      ...                                      direction='lt')
      >>> num_batch, channel, left_len, right_len = 5, 5, 3, 2
      >>> layer.build([num_batch, channel, left_len, right_len])
class_docstr_tok: ["Spatial","GRU","layer",".",":","param","units",":","Number","of","SpatialGRU","units",".",":","param","activation",":","Activation","function","to","use",".","Default",":","hyperbolic","tangent","(","`","tanh","`",")",".","If","you","pass","`","None","`",",","no","activation","is","applied","(","ie",".","``","linear","''","activation",":","`","a","(","x",")","=","x","`",")",".",":","param","recurrent_activation",":","Activation","function","to","use","for","the","recurrent","step",".","Default",":","sigmoid","(","`","sigmoid","`",")",".","If","you","pass","`","None","`",",","no","activation","is","applied","(","ie",".","``","linear","''","activation",":","`","a","(","x",")","=","x","`",")",".",":","param","kernel_initializer",":","Initializer","for","the","`","kernel","`","weights","matrix",",","used","for","the","linear","transformation","of","the","inputs",".",":","param","recurrent_initializer",":","Initializer","for","the","`","recurrent_kernel","`","weights","matrix",",","used","for","the","linear","transformation","of","the","recurrent","state",".",":","param","direction",":","Scanning","direction",".","`","lt","`","(","i.e.",",","left","top",")","indicates","the","scanning","from","left","top","to","right","bottom",",","and","`","rb","`","(","i.e.",",","right","bottom",")","indicates","the","scanning","from","right","bottom","to","left","top",".",":","param","kwargs",":","Standard","layer","keyword","arguments",".","Examples",":",">",">",">","import","matchzoo","as","mz",">",">",">","layer","=","mz.contrib.layers.SpatialGRU","(","units=10",",","...","direction='lt","'",")",">",">",">","num_batch",",","channel",",","left_len",",","right_len","=","5",",","5",",","3",",","2",">",">",">","layer.build","(","[","num_batch",",","channel",",","left_len",",","right_len","]",")"]
docstr: The computation logic of SpatialGRU.
  
  :param inputs: input tensors.
docstr_tok: ["The","computation","logic","of","SpatialGRU",".",":","param","inputs",":","input","tensors","."]
code: def call(self, inputs: list, **kwargs) -> typing.Any:
      """
      The computation logic of SpatialGRU.
  
      :param inputs: input tensors.
      """
      batch_size = tf.shape(inputs)[0]
      # h0 = [B, U]
      self._bounder_state_h0 = tf.zeros([batch_size, self._units])
  
      # input_x = [L, R, B, C]
      input_x = tf.transpose(inputs, [2, 3, 0, 1])
      if self._direction == "rb":
          # input_x: [R, L, B, C]
          input_x = tf.reverse(input_x, [0, 1])
      elif self._direction != "lt":
          raise ValueError(
              f"Invalid direction. "
              f"`{self._direction}` received. "
              f"Must be in `lt`, `rb`."
          )
      # input_x = [L*R*B, C]
      input_x = tf.reshape(input_x, [-1, self._channel])
      # input_x = L*R * [B, C]
      input_x = tf.split(
          axis=0,
          num_or_size_splits=self._text1_maxlen * self._text2_maxlen,
          value=input_x,
      )
  
      # inputs = L*R * [B, C]
      inputs = tf.TensorArray(
          dtype=tf.float32,
          size=self._text1_maxlen * self._text2_maxlen,
          name="inputs",
      )
      inputs = inputs.unstack(input_x)
  
      # states = (L+1)*(R+1) * [B, U]
      states = tf.TensorArray(
          dtype=tf.float32,
          size=(self._text1_maxlen + 1) * (self._text2_maxlen + 1),
          name="states",
          clear_after_read=False,
      )
      # Initialize states
      for i in range(self._text2_maxlen + 1):
          states = states.write(i, self._bounder_state_h0)
      for i in range(1, self._text1_maxlen + 1):
          states = states.write(
              i * (self._text2_maxlen + 1), self._bounder_state_h0
          )
  
      # Calculate h_ij
      # h_ij = [B, U]
      _, _, _, h_ij = tf.while_loop(
          cond=lambda _0, _1, i, _3: tf.less(i, self._recurrent_step),
          body=self.calculate_recurrent_unit,
          loop_vars=(
              inputs,
              states,
              tf.constant(0, dtype=tf.int32),
              self._bounder_state_h0,
          ),
          parallel_iterations=1,
          swap_memory=True,
      )
      return h_ij
  
file_path: MatchZoo/matchzoo/contrib/layers/spatial_gru.py
imports: import typing
  import tensorflow
  from keras import backend
  from keras.engine import Layer
  from keras.layers import Permute
  from keras.layers import Reshape
  from keras import activations
  from keras import initializers
label_desc: Use image node_id 5 for calling the SpatialGRU obj's underlying member method code with example usage: obj.call(inputs) and returns: h_ij