docstr: What is the probability of a given set of scores producing the given
  list of permutations only considering the top `equiv_len` ranks?
  
  We may want to override the default equiv_len here when we know the having larger
  action space doesn't matter. i.e. in Reels
docstr_tok: ["What","is","the","probability","of","a","given","set","of","scores","producing","the","given","list","of","permutations","only","considering","the","top","`","equiv_len","`","ranks","?","We","may","want","to","override","the","default","equiv_len","here","when","we","know","the","having","larger","action","space","does","n't","matter",".","i.e",".","in","Reels"]
code: def log_prob(
      self,
      scores: torch.Tensor,
      action: torch.Tensor,
      equiv_len_override: Optional[torch.Tensor] = None,
  ) -> torch.Tensor:
      """
      What is the probability of a given set of scores producing the given
      list of permutations only considering the top `equiv_len` ranks?
  
      We may want to override the default equiv_len here when we know the having larger
      action space doesn't matter. i.e. in Reels
      """
      upto = self.upto
      if equiv_len_override is not None:
          assert equiv_len_override.shape == (
              scores.shape[0],
          ), f"Invalid shape {equiv_len_override.shape}, compared to scores {scores.shape}. equiv_len_override {equiv_len_override}"
          upto = equiv_len_override.long()
          if self.topk is not None and torch.any(
              equiv_len_override > self.topk
          ):
              raise ValueError(
                  f"Override {equiv_len_override} cannot exceed topk={self.topk}."
              )
  
      squeeze = False
      if len(scores.shape) == 1:
          squeeze = True
          scores = scores.unsqueeze(0)
          action = action.unsqueeze(0)
  
      assert (
          len(action.shape) == len(scores.shape) == 2
      ), "scores should be batch"
      if action.shape[1] > scores.shape[1]:
          raise ValueError(
              f"action cardinality ({action.shape[1]}) is larger than the number of scores ({scores.shape[1]})"
          )
      elif action.shape[1] < scores.shape[1]:
          raise NotImplementedError(
              f"This semantic is ambiguous. If you have shorter slate, pad it with scores.shape[1] ({scores.shape[1]})"
          )
  
      log_scores = scores if self.log_scores else torch.log(scores)
      n = log_scores.shape[-1]
      # Add scores for the padding value
      log_scores = torch.cat(
          [
              log_scores,
              torch.full(
                  (log_scores.shape[0], 1),
                  -math.inf,
                  device=log_scores.device,
              ),
          ],
          dim=1,
      )
      log_scores = torch.gather(log_scores, 1, action) * self.shape
  
      p = upto if upto is not None else n
      # We should unsqueeze here
      if isinstance(p, int):
          log_prob = sum(
              torch.nan_to_num(
                  F.log_softmax(log_scores[:, i:], dim=1)[:, 0],
                  neginf=0.0,
              )
              for i in range(p)
          )
      elif isinstance(p, torch.Tensor):
          # do masked sum
          log_prob = sum(
              torch.nan_to_num(
                  F.log_softmax(log_scores[:, i:], dim=1)[:, 0],
                  neginf=0.0,
              )
              * (i < p).float()
              for i in range(n)
          )
      else:
          raise RuntimeError(f"p is {p}")
  
      # pyre-fixme[16]: Item `int` of `Union[typing_extensions.Literal[0],
      #  Tensor]` has no attribute `isnan`.
      assert not torch.any(log_prob.isnan()), f"Nan in {log_prob}"
      # pyre-fixme[7]: Expected `Tensor` but got `Union[int, Tensor]`.
      return log_prob
  
file_path: ReAgent/reagent/samplers/frechet.py
imports: import logging
  import math
  from typing import Optional
  import reagent.core.types
  import torch
  import torch.nn.functional
  from reagent.core.configuration import resolve_defaults
  from reagent.gym.types import Sampler
  from torch.distributions import Gumbel
label_desc: Use image node_id 3 for calling the FrechetSort obj's underlying member method code with example usage: obj.log_prob(scores, action, equiv_len_override) and returns: log_prob