human
Complete this python program:
def diagonal_conv_gru(x, kernel_size, filters, dropout=0.0, name=None, reuse=None):
assistant
#Here is the Python program you requested.

    """Diagonal Convolutional GRU as in https://arxiv.org/abs/1702.08727.
    """
    def do_conv(args, name, bias_start):
        return conv(args, filters, kernel_size, padding='SAME', bias_initializer=tf.constant_initializer(bias_start), name=name)
    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))
        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')
        total_cost_avg = (0.5 * (reset_cost + gate_cost))
        return (((gate * x_shifted) + ((1 - gate) * candidate)), total_cost_avg)