class_docstr: Applies layer normalization over each individual example in a batch
  of heterogeneous features as described in the `"Layer Normalization"
  <https://arxiv.org/abs/1607.06450>`_ paper.
  Compared to :class:`LayerNorm`, :class:`HeteroLayerNorm` applies
  normalization individually for each node or edge type.
  
  Args:
      in_channels (int): Size of each input sample.
      num_types (int): The number of types.
      eps (float, optional): A value added to the denominator for numerical
          stability. (default: :obj:`1e-5`)
      affine (bool, optional): If set to :obj:`True`, this module has
          learnable affine parameters :math:`\gamma` and :math:`\beta`.
          (default: :obj:`True`)
      mode (str, optinal): The normalization mode to use for layer
          normalization (:obj:`"node"`). If `"node"` is used, each node will
          be considered as an element to be normalized.
          (default: :obj:`"node"`)
class_docstr_tok: ["Applies","layer","normalization","over","each","individual","example","in","a","batch","of","heterogeneous","features","as","described","in","the","`","``","Layer","Normalization","''","<","https",":","\/\/arxiv.org\/abs\/1607.06450",">","`","_","paper",".","Compared","to",":","class",":","`","LayerNorm","`",",",":","class",":","`","HeteroLayerNorm","`","applies","normalization","individually","for","each","node","or","edge","type",".","Args",":","in_channels","(","int",")",":","Size","of","each","input","sample",".","num_types","(","int",")",":","The","number","of","types",".","eps","(","float",",","optional",")",":","A","value","added","to","the","denominator","for","numerical","stability",".","(","default",":",":","obj",":","`","1e-5","`",")","affine","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","True","`",",","this","module","has","learnable","affine","parameters",":","math",":","`","\\gamma","`","and",":","math",":","`","\\beta","`",".","(","default",":",":","obj",":","`","True","`",")","mode","(","str",",","optinal",")",":","The","normalization","mode","to","use","for","layer","normalization","(",":","obj",":","`","``","node","''","`",")",".","If","`","``","node","''","`","is","used",",","each","node","will","be","considered","as","an","element","to","be","normalized",".","(","default",":",":","obj",":","`","``","node","''","`",")"]
docstr: Forward pass.
  
  .. note::
      Either :obj:`type_vec` or :obj:`type_ptr` needs to be specified.
      In general, relying on :obj:`type_ptr` is more efficient in case
      the input tensor is sorted by types.
  
  Args:
      x (torch.Tensor): The input features.
      type_vec (torch.Tensor, optional): A vector that maps each entry to
          a type. (default: :obj:`None`)
      type_ptr (torch.Tensor or List[int]): A vector denoting the
          boundaries of types. (default: :obj:`None`)
docstr_tok: ["Forward","pass",".","..","note",":",":","Either",":","obj",":","`","type_vec","`","or",":","obj",":","`","type_ptr","`","needs","to","be","specified",".","In","general",",","relying","on",":","obj",":","`","type_ptr","`","is","more","efficient","in","case","the","input","tensor","is","sorted","by","types",".","Args",":","x","(","torch.Tensor",")",":","The","input","features",".","type_vec","(","torch.Tensor",",","optional",")",":","A","vector","that","maps","each","entry","to","a","type",".","(","default",":",":","obj",":","`","None","`",")","type_ptr","(","torch.Tensor","or","List","[","int","]",")",":","A","vector","denoting","the","boundaries","of","types",".","(","default",":",":","obj",":","`","None","`",")"]
code: def forward(
      self,
      x: Tensor,
      type_vec: OptTensor = None,
      type_ptr: Optional[Union[Tensor, List[int]]] = None,
  ) -> Tensor:
      r"""Forward pass.
  
      .. note::
          Either :obj:`type_vec` or :obj:`type_ptr` needs to be specified.
          In general, relying on :obj:`type_ptr` is more efficient in case
          the input tensor is sorted by types.
  
      Args:
          x (torch.Tensor): The input features.
          type_vec (torch.Tensor, optional): A vector that maps each entry to
              a type. (default: :obj:`None`)
          type_ptr (torch.Tensor or List[int]): A vector denoting the
              boundaries of types. (default: :obj:`None`)
      """
      if type_vec is None and type_ptr is None:
          raise ValueError(
              "Either 'type_vec' or 'type_ptr' must be given"
          )
  
      out = F.layer_norm(x, (self.in_channels,), None, None, self.eps)
  
      if self.affine:
          # TODO Revisit this logic completely as it performs worse than just
          # operating on a dictionary of tensors
          # (especially the `type_vec` code path)
          if type_ptr is not None:
              h = torch.empty_like(out)
              for i, (s, e) in enumerate(
                  zip(type_ptr[:-1], type_ptr[1:])
              ):
                  h[s:e] = out[s:e] * self.weight[i] + self.bias[i]
              out = h
          else:
              out = out * self.weight[type_vec] + self.bias[type_vec]
  
      return out
  
file_path: pytorch_geometric/torch_geometric/nn/norm/layer_norm.py
imports: from typing import List, Optional, Union
  import torch
  import torch.nn.functional
  from torch import Tensor
  from torch.nn import Parameter
  from torch_geometric.nn.inits import ones, zeros
  from torch_geometric.typing import OptTensor
  from torch_geometric.utils import degree, scatter
label_desc: Use image node_id 3 for calling the HeteroLayerNorm obj's underlying member method code with example usage: obj.forward(x, type_vec, type_ptr) and returns: out