'Time step unrolling portion of recurrent layer bprop.
Arguments:
W_recur (Tensor): Recurrent weight matrix.
delta_prev_s (Array): Array of per time step input delta tensors.
Each element in the array is a single time step view into one
tensor containing all of the time steps in sequence.
delta_s (Array): Array of per time step input delta tensors.
Each element in the array is a single time step view into one
tensor containing all of the time steps in sequence.
h_s (Tensor): Array of per time step hidden state tensors. Each
element in the array is a single time step view into one tensor
containing all of the time steps in sequence.
nout (integer): Number of output units for the layer.
num_steps (integer): Total number of time steps in the buffer.
num_used_steps (integer): Number of time steps being used for real
data.
activation (Transform): Activation function for the layer.
reverse (boolean): When true, unrolling will iterate over time steps
in reverse (default case for RNN).'

def compound_rnn_unroll_bprop(self, W_recur, delta_prev_s, delta_s, h_s, nout, num_steps, num_used_steps, activation, reverse=True):

    if ((nout <= 1152) and (self.bsz == 4) and ((nout % 48) == 0)):
        persistent_kernel = True
        num_blocks = (nout // 48)
    else:
        persistent_kernel = False
        num_blocks = ((- ((- delta_s[0].shape[0]) // 128)) * (- ((- delta_s[0].shape[1]) // 32)))
        num_blocks = (- ((- num_blocks) // 4))
    if ((activation.classnm == 'Rectlinclip') and (num_blocks <= self.sm_count) and (not self.use_cudac_kernels) and (activation.slope == 0)):
        if reverse:
            delta_s[(-1)][:] = (activation.bprop(h_s[(-1)]) * delta_s[(-1)])
        else:
            delta_s[0][:] = (activation.bprop(h_s[0]) * delta_s[0])
        if ((num_used_steps is not None) and (num_used_steps < num_steps)):
            num_steps = num_used_steps
        if reverse:
            B = delta_s[1]
            C = delta_s[0]
            H = h_s[0]
        else:
            B = delta_s[0]
            C = delta_s[1]
            H = h_s[1]
        if persistent_kernel:
            self._persistent_rnn_bprop(W_recur, B, C, H, nout, nout, self.bsz, (num_steps - 1), activation, reverse)
        else:
            self._compound_unrolled_gemm_bprop(W_recur, B, C, H, nout, nout, self.bsz, (num_steps - 1), activation, reverse)
        if reverse:
            self.compound_dot(W_recur, delta_s[0], delta_s[(-1)], beta=1.0)
        else:
            self.compound_dot(W_recur, delta_s[(-1)], delta_s[0], beta=1.0)
    else:
        if ((num_used_steps is not None) and (num_used_steps < num_steps)):
            h_s = h_s[:num_used_steps]
            h_prev_s = h_prev_s[:num_used_steps]
            h_ff_s = h_ff_s[:num_used_steps]
        if reverse:
            steps = reversed(list(zip(h_s, delta_s, delta_prev_s)))
        else:
            steps = list(zip(h_s, delta_s, delta_prev_s))
        for (hs, in_deltas, prev_in_deltas) in steps:
            in_deltas[:] = (activation.bprop(hs) * in_deltas)
            self.compound_dot(W_recur, in_deltas, prev_in_deltas, beta=1.0)
