code: def _forward_kernel(self, F, inputs, states, **kwargs):
          
          if self._layout == 'NTC':
              inputs = F.swapaxes(inputs, dim1=0, dim2=1)
          if self._projection_size is None:
              params = (kwargs['{}{}_{}_{}'.format(d, l, g, t)].reshape(-1)
                        for t in ['weight', 'bias']
                        for l in range(self._num_layers)
                        for d in ['l', 'r'][:self._dir]
                        for g in ['i2h', 'h2h'])
          else:
              params = (kwargs['{}{}_{}_{}'.format(d, l, g, t)].reshape(-1)
                        for t in ['weight', 'bias']
                        for l in range(self._num_layers)
                        for d in ['l', 'r'][:self._dir]
                        for g in ['i2h', 'h2h', 'h2r']
                        if g != 'h2r' or t != 'bias')
  
          params = F._internal._rnn_param_concat(*params, dim=0)
  
          rnn = F.RNN(inputs, params, *states, state_size=self._hidden_size,
                      projection_size=self._projection_size,
                      num_layers=self._num_layers, bidirectional=self._dir == 2,
                      p=self._dropout, state_outputs=True, mode=self._mode,
                      lstm_state_clip_min=self._lstm_state_clip_min,
                      lstm_state_clip_max=self._lstm_state_clip_max,
                      lstm_state_clip_nan=self._lstm_state_clip_nan)
  
          if self._mode == 'lstm':
              outputs, states = rnn[0], [rnn[1], rnn[2]]
          else:
              outputs, states = rnn[0], [rnn[1]]
  
          if self._layout == 'NTC':
              outputs = F.swapaxes(outputs, dim1=0, dim2=1)
  
          return outputs, states
docs: forward using CUDNN or CPU kenrel