class_docstr: This layer adds sinusoidal positional embeddings to a 3D input tensor. The code has been adapted from
  `Pytorch tutorial <https://pytorch.org/tutorials/beginner/transformer_tutorial.html>`_
  
  Args:
      d_model (int): dimension of the input tensor
      dropout (Optional[float]): Dropout rate. Default: 0.0
      max_len (Optional[int]): Max. number of patches (or seq. length). Default: 5000
      channels_last (Optional[bool]): Channels dimension is the last in the input tensor
  
  Shape:
      - Input: :math:`(N, C, P)` or :math:`(N, P, C)` where :math:`N` is the batch size, :math:`C` is the embedding dimension,
          :math:`P` is the number of patches
      - Output: same shape as the input
class_docstr_tok: ["This","layer","adds","sinusoidal","positional","embeddings","to","a","3D","input","tensor",".","The","code","has","been","adapted","from","`","Pytorch","tutorial","<","https",":","\/\/pytorch.org\/tutorials\/beginner\/transformer_tutorial.html",">","`","_","Args",":","d_model","(","int",")",":","dimension","of","the","input","tensor","dropout","(","Optional","[","float","]",")",":","Dropout","rate",".","Default",":","0.0","max_len","(","Optional","[","int","]",")",":","Max",".","number","of","patches","(","or","seq",".","length",")",".","Default",":","5000","channels_last","(","Optional","[","bool","]",")",":","Channels","dimension","is","the","last","in","the","input","tensor","Shape",":","-","Input",":",":","math",":","`","(","N",",","C",",","P",")","`","or",":","math",":","`","(","N",",","P",",","C",")","`","where",":","math",":","`","N","`","is","the","batch","size",",",":","math",":","`","C","`","is","the","embedding","dimension",",",":","math",":","`","P","`","is","the","number","of","patches","-","Output",":","same","shape","as","the","input"]
code: def forward_patch_last(
      self, x, indices: Optional[Tensor] = None, *args, **kwargs
  ) -> Tensor:
      # seq_length should be the last dim
      if indices is None:
          x = x + self.pe[..., : x.shape[-1]]
      else:
          ndim = x.ndim
          repeat_size = [x.shape[0]] + [-1] * (ndim - 1)
  
          pe = self.pe.expand(repeat_size)
          selected_pe = torch.gather(pe, index=indices, dim=-1)
          x = x + selected_pe
      return self.dropout(x)
  
file_path: ml-cvnets/cvnets/layers/positional_encoding.py
imports: import math
  from typing import Optional
  import torch
  from torch import Tensor, nn
  from cvnets.layers.base_layer import BaseLayer
  from cvnets.layers.dropout import Dropout
label_desc: Use image node_id 2 for calling the SinusoidalPositionalEncoding obj's underlying member method code with example usage: obj.forward_patch_last(x, indices) and returns: self