class_docstr: Poly-encoder model.
  
  See https://arxiv.org/abs/1905.01969 for more details
class_docstr_tok: ["Poly-encoder","model",".","See","https",":","\/\/arxiv.org\/abs\/1905.01969","for","more","details"]
docstr: Encode a text sequence.
  
  :param ctxt_inputs:
      Dictionary of context inputs. If not empty, should contain at least
      'ctxt_tokens', a 2D long tensor of shape batchsize x sent_len
  :param cand_tokens:
      3D long tensor, batchsize x num_cands x sent_len
      Note this will actually view it as a 2D tensor
  :return:
      (ctxt_rep, ctxt_mask, cand_rep)
      - ctxt_rep 3D float tensor, batchsize x n_codes x dim
      - ctxt_mask byte:  batchsize x n_codes (all 1 in case
      of polyencoder with code. Which are the vectors to use
      in the ctxt_rep)
      - cand_rep (3D float tensor) batchsize x num_cands x dim
docstr_tok: ["Encode","a","text","sequence",".",":","param","ctxt_inputs",":","Dictionary","of","context","inputs",".","If","not","empty",",","should","contain","at","least","'ctxt_tokens","'",",","a","2D","long","tensor","of","shape","batchsize","x","sent_len",":","param","cand_tokens",":","3D","long","tensor",",","batchsize","x","num_cands","x","sent_len","Note","this","will","actually","view","it","as","a","2D","tensor",":","return",":","(","ctxt_rep",",","ctxt_mask",",","cand_rep",")","-","ctxt_rep","3D","float","tensor",",","batchsize","x","n_codes","x","dim","-","ctxt_mask","byte",":","batchsize","x","n_codes","(","all","1","in","case","of","polyencoder","with","code",".","Which","are","the","vectors","to","use","in","the","ctxt_rep",")","-","cand_rep","(","3D","float","tensor",")","batchsize","x","num_cands","x","dim"]
code: def encode(
      self,
      cand_tokens: Optional[torch.Tensor],
      **ctxt_inputs: torch.Tensor,
  ) -> Tuple[
      Optional[torch.Tensor],
      Optional[torch.Tensor],
      Optional[torch.Tensor],
  ]:
      """
      Encode a text sequence.
  
      :param ctxt_inputs:
          Dictionary of context inputs. If not empty, should contain at least
          'ctxt_tokens', a 2D long tensor of shape batchsize x sent_len
      :param cand_tokens:
          3D long tensor, batchsize x num_cands x sent_len
          Note this will actually view it as a 2D tensor
      :return:
          (ctxt_rep, ctxt_mask, cand_rep)
          - ctxt_rep 3D float tensor, batchsize x n_codes x dim
          - ctxt_mask byte:  batchsize x n_codes (all 1 in case
          of polyencoder with code. Which are the vectors to use
          in the ctxt_rep)
          - cand_rep (3D float tensor) batchsize x num_cands x dim
      """
      cand_embed = None
      ctxt_rep = None
      ctxt_rep_mask = None
  
      if cand_tokens is not None:
          assert len(cand_tokens.shape) == 3
          bsz = cand_tokens.size(0)
          num_cands = cand_tokens.size(1)
          cand_embed = self.encoder_cand(
              cand_tokens.view(bsz * num_cands, -1)
          )
          cand_embed = cand_embed.view(bsz, num_cands, -1)
  
      if len(ctxt_inputs) > 0:
          assert "ctxt_tokens" in ctxt_inputs
          if ctxt_inputs["ctxt_tokens"] is not None:
              assert len(ctxt_inputs["ctxt_tokens"].shape) == 2
          bsz = self._get_context_batch_size(**ctxt_inputs)
          # get context_representation. Now that depends on the cases.
          ctxt_out, ctxt_mask = self.encoder_ctxt(
              **self._context_encoder_input(ctxt_inputs)
          )
          dim = ctxt_out.size(2)
  
          if self.type == "codes":
              ctxt_rep = self.attend(
                  self.code_attention,
                  queries=self.codes.repeat(bsz, 1, 1),
                  keys=ctxt_out,
                  values=ctxt_out,
                  mask=ctxt_mask,
              )
              ctxt_rep_mask = ctxt_rep.new_ones(
                  bsz, self.n_codes
              ).byte()
  
          elif self.type == "n_first":
              # Expand the output if it is not long enough
              if ctxt_out.size(1) < self.n_codes:
                  difference = self.n_codes - ctxt_out.size(1)
                  extra_rep = ctxt_out.new_zeros(bsz, difference, dim)
                  ctxt_rep = torch.cat([ctxt_out, extra_rep], dim=1)
                  extra_mask = ctxt_mask.new_zeros(bsz, difference)
                  ctxt_rep_mask = torch.cat(
                      [ctxt_mask, extra_mask], dim=1
                  )
              else:
                  ctxt_rep = ctxt_out[:, 0 : self.n_codes, :]
                  ctxt_rep_mask = ctxt_mask[:, 0 : self.n_codes]
  
      return ctxt_rep, ctxt_rep_mask, cand_embed
  
imports: from parlai.core.params import ParlaiParser
  from typing import Any, Dict, Optional, Tuple
  import torch
  from parlai.core.opt import Opt
  from parlai.core.torch_ranker_agent import TorchRankerAgent
  from parlai.core.torch_agent import Batch
  from parlai.utils.misc import recursive_getattr
  from parlai.utils.logging import logging
  from .biencoder import AddLabelFixedCandsTRA
  from .modules import BasicAttention, MultiHeadAttention, TransformerEncoder
  from .transformer import TransformerRankerAgent
label_desc: Use image node_id 5 for calling the PolyEncoderModule obj's underlying member method code with example usage: obj.encode(cand_tokens) and returns: ctxt_rep,  ctxt_rep_mask,  cand_embed