'Apply the forward pass transformation to the input data.  The input
data is a list of inputs with an element for each time step of
model unrolling.
Arguments:
inputs (Tensor): input data as 2D tensors, then being converted into a
list of 2D slices. The dimension is
(input_size, sequence_length * batch_size)
init_state (Tensor, optional): starting cell values, if not None.
For sequence to sequence models.
inference (bool, optional): Set to true if you are running
inference (only care about forward
propagation without associated backward
propagation).  Default is False.
Returns:
Tensor: LSTM output for each model time step'

def fprop(self, inputs, inference=False, init_state=None):

    self.init_buffers(inputs)
    if self.reset_cells:
        self.h[(-1)][:] = 0
        self.c[(-1)][:] = 0
    if (init_state is not None):
        self.h[(-1)][:] = init_state
    params = (self.h, self.h_prev, self.ifog, self.ifo, self.i, self.f, self.o, self.g, self.c, self.c_prev, self.c_act)
    self.be.compound_dot(self.W_input, self.x, self.ifog_buffer)
    for (h, h_prev, ifog, ifo, i, f, o, g, c, c_prev, c_act) in zip(*params):
        self.be.compound_dot(self.W_recur, h_prev, ifog, beta=1.0)
        ifog[:] = (ifog + self.b)
        ifo[:] = self.gate_activation(ifo)
        g[:] = self.activation(g)
        c[:] = ((f * c_prev) + (i * g))
        c_act[:] = self.activation(c)
        h[:] = (o * c_act)
    self.final_state_buffer[:] = self.h[(-1)]
    return self.outputs
