class_docstr: Dimension allocator for internal use by :func:`~pyro.poutine.markov`.
  There is a single global instance.
  
  Note that dimensions are indexed from the right, e.g. -1, -2.
  Note that ids are simply nonnegative integers here.
docstr: Allocate a new recyclable dim and a unique id.
  
  If ``scope_dims`` is None, this allocates a global enumeration dim
  that will never be recycled. If ``scope_dims`` is specified, this
  allocates a local enumeration dim that can be reused by at any other
  local site whose scope excludes this site.
  
  :param set scope_dims: An optional set of (negative integer)
      local enumeration dims to avoid when allocating this dim.
  :return: A pair ``(dim, id)``, where ``dim`` is a negative integer
      and ``id`` is a nonnegative integer.
  :rtype: tuple
docstr_tok: ["Allocate","a","new","recyclable","dim","and","a","unique","id",".","If","``","scope_dims","``","is","None",",","this","allocates","a","global","enumeration","dim","that","will","never","be","recycled",".","If","``","scope_dims","``","is","specified",",","this","allocates","a","local","enumeration","dim","that","can","be","reused","by","at","any","other","local","site","whose","scope","excludes","this","site",".",":","param","set","scope_dims",":","An","optional","set","of","(","negative","integer",")","local","enumeration","dims","to","avoid","when","allocating","this","dim",".",":","return",":","A","pair","``","(","dim",",","id",")","``",",","where","``","dim","``","is","a","negative","integer","and","``","id","``","is","a","nonnegative","integer",".",":","rtype",":","tuple"]
code: def allocate(
      self, scope_dims: Optional[Set[int]] = None
  ) -> Tuple[int, int]:
      """
      Allocate a new recyclable dim and a unique id.
  
      If ``scope_dims`` is None, this allocates a global enumeration dim
      that will never be recycled. If ``scope_dims`` is specified, this
      allocates a local enumeration dim that can be reused by at any other
      local site whose scope excludes this site.
  
      :param set scope_dims: An optional set of (negative integer)
          local enumeration dims to avoid when allocating this dim.
      :return: A pair ``(dim, id)``, where ``dim`` is a negative integer
          and ``id`` is a nonnegative integer.
      :rtype: tuple
      """
      id_ = self.next_available_id
      self.next_available_id += 1
  
      dim = self.next_available_dim
      if dim == -float("inf"):
          raise ValueError(
              "max_plate_nesting must be set to a finite value for parallel enumeration"
          )
      if scope_dims is None:
          # allocate a new global dimension
          self.next_available_dim -= 1
          self.dim_to_id[dim] = id_
      else:
          # allocate a new local dimension
          while dim in scope_dims:
              dim -= 1
  
      return dim, id_
  
imports: import functools
  from typing import TYPE_CHECKING, Callable, Dict, Generic, List, Optional, Set, Tuple, TypeVar, Union, overload
  import torch
  from typing_extensions import Literal, ParamSpec, TypedDict
  from pyro.params.param_store import _MODULE_NAMESPACE_DIVIDER, ParamStoreDict
label_desc: Use image node_id 2 for calling the _EnumAllocator obj's underlying member method code with example usage: obj.allocate(scope_dims) and returns: dim,  id_