docstr: Calculate the output from rasterizing a square image with the minimum of (H, W).
  Then compare this with the same square region in the non square image.
  The input points are contained within the [-1, 1] range of the image
  so all the relevant pixels will be within the square region.
  
  `nonsq_fragment_gradtensor_list` is a list of fragments and verts grad tensors
  from rasterizing non square images.
docstr_tok: ["Calculate","the","output","from","rasterizing","a","square","image","with","the","minimum","of","(","H",",","W",")",".","Then","compare","this","with","the","same","square","region","in","the","non","square","image",".","The","input","points","are","contained","within","the","[","-1",",","1","]","range","of","the","image","so","all","the","relevant","pixels","will","be","within","the","square","region",".","`","nonsq_fragment_gradtensor_list","`","is","a","list","of","fragments","and","verts","grad","tensors","from","rasterizing","non","square","images","."]
code: def _compare_square_with_nonsq(
      self,
      image_size,
      blur,
      device,
      points,
      nonsq_fragment_gradtensor_list,
      batch_size=1,
  ):
      """
      Calculate the output from rasterizing a square image with the minimum of (H, W).
      Then compare this with the same square region in the non square image.
      The input points are contained within the [-1, 1] range of the image
      so all the relevant pixels will be within the square region.
  
      `nonsq_fragment_gradtensor_list` is a list of fragments and verts grad tensors
      from rasterizing non square images.
      """
      # Rasterize the square version of the image
      H, W = image_size
      S = min(H, W)
      points_square, pointclouds_sq = self._clone_pointcloud(
          points, device, batch_size
      )
      square_fragments = self._rasterize(
          pointclouds_sq, image_size=(S, S), bin_size=0, blur=blur
      )
      # Save debug image
      _save_debug_image(square_fragments.idx, (S, S), 0, blur)
  
      # Extract the values in the square image which are non zero.
      square_mask = square_fragments.idx > -1
      square_dists = square_fragments.dists[square_mask]
      square_zbuf = square_fragments.zbuf[square_mask]
  
      # Retain gradients on the output of fragments to check
      # intermediate values with the non square outputs.
      square_fragments.dists.retain_grad()
      square_fragments.zbuf.retain_grad()
  
      # Calculate gradient for the square image
      torch.manual_seed(231)
      grad_zbuf = torch.randn_like(square_zbuf)
      grad_dist = torch.randn_like(square_dists)
      loss0 = (grad_dist * square_dists).sum() + (
          grad_zbuf * square_zbuf
      ).sum()
      loss0.backward()
  
      # Now compare against the non square outputs provided
      # in the nonsq_fragment_gradtensor_list list
      for (
          fragments,
          grad_tensor,
          _name,
      ) in nonsq_fragment_gradtensor_list:
          # Check that there are the same number of non zero pixels
          # in both the square and non square images.
          non_square_mask = fragments.idx > -1
          self.assertEqual(
              non_square_mask.sum().item(), square_mask.sum().item()
          )
  
          # Check dists, zbuf and bary match the square image
          non_square_dists = fragments.dists[non_square_mask]
          non_square_zbuf = fragments.zbuf[non_square_mask]
          self.assertClose(square_dists, non_square_dists)
          self.assertClose(square_zbuf, non_square_zbuf)
  
          # Retain gradients to compare values with outputs from
          # square image
          fragments.dists.retain_grad()
          fragments.zbuf.retain_grad()
          loss1 = (grad_dist * non_square_dists).sum() + (
              grad_zbuf * non_square_zbuf
          ).sum()
          loss1.sum().backward()
  
          # Get the non zero values in the intermediate gradients
          # and compare with the values from the square image
          non_square_grad_dists = fragments.dists.grad[non_square_mask]
          non_square_grad_zbuf = fragments.zbuf.grad[non_square_mask]
  
          self.assertClose(
              non_square_grad_dists,
              square_fragments.dists.grad[square_mask],
          )
          self.assertClose(
              non_square_grad_zbuf,
              square_fragments.zbuf.grad[square_mask],
          )
  
          # Finally check the gradients of the input vertices for
          # the square and non square case
          self.assertClose(
              points_square.grad, grad_tensor.grad, rtol=2e-4
          )
  
imports: import re
  import unittest
  from itertools import product
  import numpy
  import torch
  from PIL import Image
  from pytorch3d.io import load_obj
  from pytorch3d.renderer import BlendParams, FoVPerspectiveCameras, look_at_view_transform, Materials, MeshRasterizer, MeshRenderer, PointLights, RasterizationSettings, SoftPhongShader, SplatterPhongShader, TexturesUV
  from pytorch3d.renderer.mesh.rasterize_meshes import rasterize_meshes, rasterize_meshes_python
  from pytorch3d.renderer.mesh.rasterizer import Fragments
  from pytorch3d.renderer.opengl import MeshRasterizerOpenGL
  from pytorch3d.renderer.points import AlphaCompositor, PointsRasterizationSettings, PointsRasterizer, PointsRenderer
  from pytorch3d.renderer.points.rasterize_points import rasterize_points, rasterize_points_python
  from pytorch3d.renderer.points.rasterizer import PointFragments
  from pytorch3d.structures import Meshes, Pointclouds
  from pytorch3d.transforms.transform3d import Transform3d
  from pytorch3d.utils import torus
  from .common_testing import get_pytorch3d_dir, get_tests_dir, load_rgb_image, TestCaseMixin
label_desc: Use image node_id 4 for calling the TestRasterizeRectangleImagesPointclouds obj's underlying member method code with example usage: obj._compare_square_with_nonsq(image_size, blur, device, points, nonsq_fragment_gradtensor_list, batch_size) without return types