class_docstr: Beam search for Encoder-Decoder models.
  
  Arguments:
      seq2seq (Object): Seq2Seq container object with a trained model to use for inference
docstr: Arguments:
      t (int): time step
      z_list (list of tensors) : fprop outputs for all beams
docstr_tok: ["Arguments",":","t","(","int",")",":","time","step","z_list","(","list","of","tensors",")",":","fprop","outputs","for","all","beams"]
code: def _beamsearch_step(self, t, z_list_t, init_state_lists):
      """
      Arguments:
          t (int): time step
          z_list (list of tensors) : fprop outputs for all beams
      """
      num_out = self.layers.out_shape[0]
  
      # bring init_state_lists list of lists over to CPU
      # init_state_lists_in, init_state_lists_out
      init_state_lists_in = []
      for isl in init_state_lists:
          init_state_lists_in.append([state.get() for state in isl])
  
      # num_beams x num_layers x layer_hidden_shape
      init_state_lists_out = [
          [np.zeros(tnsr.shape) for tnsr in init_state_lists[0]]
          for _ in range(len(init_state_lists_in))
      ]
  
      # pick highest scoring across all beams
      z_list = [z_list_t[bb].get() for bb in range(self.num_live)]
      scores_list = [
          np.log(z) + score for z, score in zip(z_list, self.scores)
      ]
      scores = np.vstack(scores_list)
      self.num_live = num_live = self.num_beams - self.num_dead
      ind = scores.argsort(axis=0)[
          -num_live:
      ]  # top scores across both old beams and new tokens
      self.scores_list = scores_list  # for testing
  
      # store candidates and scores for all beams and samples in batch
      hyp_num = (ind // num_out).astype(np.int32)  # hypothesis number
      word_num = ind % num_out  # onehot word index
  
      # create a copy of candidates buffer to read from so it does not get overwritten
      old_candidates = [can.copy() for can in self.candidates]
  
      for bb in range(num_live):
          for hyp in range(len(scores_list)):
              ex_with_hyp = np.where(hyp_num[bb, :] == hyp)[0]
              self.candidates[bb][:, ex_with_hyp] = old_candidates[hyp][
                  :, ex_with_hyp
              ]
              wnum = word_num[bb, ex_with_hyp]
              self.scores[bb][ex_with_hyp] = scores_list[hyp][
                  wnum, ex_with_hyp
              ]
          self.candidates[bb][t, :] = word_num[bb, :]
  
      # get decoder hidden states for each beam
      for bb in range(num_live):
          for hyp in range(len(scores_list)):
              ex_with_hyp = np.where(hyp_num[bb, :] == hyp)[0]
  
              # transfer hidden state from DECODER to next step
              for ii in range(len(self.layers.decoder._recurrent)):
                  init_state_lists_out[bb][ii][
                      :, ex_with_hyp
                  ] = init_state_lists_in[hyp][ii][:, ex_with_hyp]
  
      # get inputs for next step for each beam
      for bb in range(num_live):
          # create input for next time step
          if self.hasLUT:
              # use index. TODO: Backend needs to catch these striding mismatches
              inputs = self.be.array(
                  self.candidates[bb][t, :].reshape(1, -1)
              )
              self.z_list[bb][:] = inputs
          else:
              # convoluted softmax -> index -> onehot scheme
              inputs = self.be.array(
                  self.candidates[bb][t, :], dtype=np.int32
              )
              self.z_list[bb][:] = self.be.onehot(inputs, axis=0)
  
      # copy list of lists of numpy matrices into list of lists of GPU tensors
      for ii, isl in enumerate(init_state_lists_out):
          for jj, state in enumerate(isl):
              self.init_state_lists[ii][jj][:] = state
  
file_path: neon/neon/util/beamsearch.py
imports: import numpy
  from neon import NervanaObject
  import logging
label_desc: Use image node_id 3 for calling the BeamSearch obj's underlying member method code with example usage: obj._beamsearch_step(t, z_list_t, init_state_lists) without return types