docstr: Test CUDA implementation for PointEdgeArrayDistanceForward
      &  PointEdgeArrayDistanceBackward
docstr_tok: ["Test","CUDA","implementation","for","PointEdgeArrayDistanceForward","&","PointEdgeArrayDistanceBackward"]
code: def test_point_edge_array_distance(self):
      """
      Test CUDA implementation for PointEdgeArrayDistanceForward
          &  PointEdgeArrayDistanceBackward
      """
      P, E = 16, 32
      device = get_random_cuda_device()
      points = torch.rand((P, 3), dtype=torch.float32, device=device)
      edges = torch.rand((E, 2, 3), dtype=torch.float32, device=device)
  
      # randomly make some edge points equal
      same = torch.rand((E,), dtype=torch.float32, device=device) > 0.5
      edges[same, 1] = edges[same, 0].clone().detach()
  
      points_cpu = points.clone().cpu()
      edges_cpu = edges.clone().cpu()
  
      points.requires_grad = True
      edges.requires_grad = True
      grad_dists = torch.rand(
          (P, E), dtype=torch.float32, device=device
      )
  
      # Naive python implementation
      dists_naive = torch.zeros(
          (P, E), dtype=torch.float32, device=device
      )
      for p in range(P):
          for e in range(E):
              dist = self._point_to_edge_distance(points[p], edges[e])
              dists_naive[p, e] = dist
  
      # Cuda Forward Implementation
      dists_cuda = _C.point_edge_array_dist_forward(points, edges)
      dists_cpu = _C.point_edge_array_dist_forward(
          points_cpu, edges_cpu
      )
  
      # Compare
      self.assertClose(dists_naive.cpu(), dists_cuda.cpu())
      self.assertClose(dists_naive.cpu(), dists_cpu)
  
      # CUDA Bacwkard Implementation
      (
          grad_points_cuda,
          grad_edges_cuda,
      ) = _C.point_edge_array_dist_backward(points, edges, grad_dists)
      (
          grad_points_cpu,
          grad_edges_cpu,
      ) = _C.point_edge_array_dist_backward(
          points_cpu, edges_cpu, grad_dists.cpu()
      )
  
      dists_naive.backward(grad_dists)
      grad_points_naive = points.grad.cpu()
      grad_edges_naive = edges.grad.cpu()
  
      # Compare
      self.assertClose(grad_points_naive, grad_points_cuda.cpu())
      self.assertClose(grad_edges_naive, grad_edges_cuda.cpu())
      self.assertClose(grad_points_naive, grad_points_cpu)
      self.assertClose(grad_edges_naive, grad_edges_cpu)
  
imports: import unittest
  import numpy
  import torch
  from pytorch3d import _C
  from pytorch3d.loss import point_mesh_edge_distance, point_mesh_face_distance
  from pytorch3d.structures import Meshes, packed_to_list, Pointclouds
  from .common_testing import get_random_cuda_device, TestCaseMixin
label_desc: Use image node_id 9 for calling the TestPointMeshDistance obj's underlying member method code with example usage: obj.test_point_edge_array_distance() without return types