code: def diagonal_conv_gru(x,
                        kernel_size,
                        filters,
                        dropout=0.0,
                        name=None,
                        reuse=None):
    
  
    # Let's make a shorthand for conv call first.
    def do_conv(args, name, bias_start):
      return conv(
          args,
          filters,
          kernel_size,
          padding="SAME",
          bias_initializer=tf.constant_initializer(bias_start),
          name=name)
  
    # Here comes the GRU gate.
    with tf.variable_scope(
        name, default_name="diagonal_conv_gru", values=[x], reuse=reuse):
      reset, reset_cost = hard_sigmoid(do_conv(x, "reset", 0.5))
      gate, gate_cost = hard_sigmoid(do_conv(x, "gate", 0.7))
      candidate = tf.tanh(do_conv(reset * x, "candidate", 0.0))
  
      if dropout > 0.0:
        candidate = tf.nn.dropout(candidate, 1.0 - dropout)
  
      # Diagonal shift.
      shift_filters = filters // 3
      base_filter = ([[0, 1, 0]] * (filters - 2 * shift_filters) +
                     [[1, 0, 0]] * shift_filters + [[0, 0, 1]] * shift_filters)
      shift_filter = tf.constant(np.transpose(base_filter), dtype=tf.float32)
      shift_filter = tf.expand_dims(tf.expand_dims(shift_filter, 0), 3)
      x_shifted = tf.nn.depthwise_conv2d(
          x, shift_filter, [1, 1, 1, 1], padding="SAME")
  
      # Return the gated result and cost.
      total_cost_avg = 0.5 * (reset_cost + gate_cost)
      return gate * x_shifted + (1 - gate) * candidate, total_cost_avg
docs: Diagonal Convolutional GRU as in https://arxiv.org/abs/1702.08727.