docstr: SSIM loss function.
  
  Args:
      kernel_size: size of the Gaussian kernel
      max_val: constant scaling factor
      sigma: sigma of the Gaussian kernel
      eps: constant for division by zero
      use_padding: whether to pad the input tensor such that we have a score for each pixel
code: def __init__(
      self,
      kernel_size: int = 11,
      max_val: float = 1.0,
      sigma: float = 1.5,
      eps: float = 1e-12,
      use_padding: bool = True,
  ) -> None:
      """SSIM loss function.
  
      Args:
          kernel_size: size of the Gaussian kernel
          max_val: constant scaling factor
          sigma: sigma of the Gaussian kernel
          eps: constant for division by zero
          use_padding: whether to pad the input tensor such that we have a score for each pixel
      """
      super().__init__()
  
      self.kernel_size = kernel_size
      self.max_val = max_val
      self.sigma = sigma
  
      gaussian_kernel = make_gaussian_kernel(kernel_size, sigma)
      self.register_buffer("gaussian_kernel", gaussian_kernel)
  
      self.c1 = (0.01 * self.max_val) ** 2
      self.c2 = (0.03 * self.max_val) ** 2
  
      self.use_padding = use_padding
      self.eps = eps
  
imports: from typing import List, Optional
  import torch
  from torch import nn, Tensor
  from torch.nn import functional
  from torchvision.prototype.models.depth.stereo.raft_stereo import grid_sample, make_coords_grid
label_desc: Use image node_id 1 to create a new SSIM object from inherited base classes: nn with example: obj = SSIM(kernel_size, max_val, sigma, eps, use_padding)