code: def test_chamfer_pointcloud_object_withnormals(self):
      N = 5
      P1, P2 = 100, 100
      device = get_random_cuda_device()
  
      reductions = [
          ("sum", "sum"),
          ("mean", "sum"),
          ("sum", "mean"),
          ("mean", "mean"),
          ("sum", None),
          ("mean", None),
          (None, None),
      ]
      for point_reduction, batch_reduction in reductions:
          # Reinitialize all the tensors so that the
          # backward pass can be computed.
          points_normals = TestChamfer.init_pointclouds(
              N, P1, P2, device, allow_empty=False
          )
  
          # Chamfer with pointclouds as input.
          cham_cloud, norm_cloud = chamfer_distance(
              points_normals.cloud1,
              points_normals.cloud2,
              point_reduction=point_reduction,
              batch_reduction=batch_reduction,
          )
  
          # Chamfer with tensors as input.
          cham_tensor, norm_tensor = chamfer_distance(
              points_normals.p1,
              points_normals.p2,
              x_lengths=points_normals.p1_lengths,
              y_lengths=points_normals.p2_lengths,
              x_normals=points_normals.n1,
              y_normals=points_normals.n2,
              point_reduction=point_reduction,
              batch_reduction=batch_reduction,
          )
  
          if point_reduction is None:
              cham_tensor_bidirectional = torch.hstack(
                  [cham_tensor[0], cham_tensor[1]]
              )
              norm_tensor_bidirectional = torch.hstack(
                  [norm_tensor[0], norm_tensor[1]]
              )
              cham_cloud_bidirectional = torch.hstack(
                  [cham_cloud[0], cham_cloud[1]]
              )
              norm_cloud_bidirectional = torch.hstack(
                  [norm_cloud[0], norm_cloud[1]]
              )
              self.assertClose(
                  cham_cloud_bidirectional, cham_tensor_bidirectional
              )
              self.assertClose(
                  norm_cloud_bidirectional, norm_tensor_bidirectional
              )
              self._check_gradients(
                  cham_tensor_bidirectional,
                  norm_tensor_bidirectional,
                  cham_cloud_bidirectional,
                  norm_cloud_bidirectional,
                  points_normals.cloud1.points_list(),
                  points_normals.p1,
                  points_normals.cloud2.points_list(),
                  points_normals.p2,
                  points_normals.cloud1.normals_list(),
                  points_normals.n1,
                  points_normals.cloud2.normals_list(),
                  points_normals.n2,
                  points_normals.p1_lengths,
                  points_normals.p2_lengths,
              )
          else:
              self.assertClose(cham_cloud, cham_tensor)
              self.assertClose(norm_cloud, norm_tensor)
              self._check_gradients(
                  cham_tensor,
                  norm_tensor,
                  cham_cloud,
                  norm_cloud,
                  points_normals.cloud1.points_list(),
                  points_normals.p1,
                  points_normals.cloud2.points_list(),
                  points_normals.p2,
                  points_normals.cloud1.normals_list(),
                  points_normals.n1,
                  points_normals.cloud2.normals_list(),
                  points_normals.n2,
                  points_normals.p1_lengths,
                  points_normals.p2_lengths,
              )
  
imports: import unittest
  from collections import namedtuple
  import numpy
  import torch
  import torch.nn.functional
  from pytorch3d.loss import chamfer_distance
  from pytorch3d.structures.pointclouds import Pointclouds
  from .common_testing import get_random_cuda_device, TestCaseMixin
label_desc: Use image node_id 8 for calling the TestChamfer obj's underlying member method code with example usage: obj.test_chamfer_pointcloud_object_withnormals() without return types