def test_compare_coarse_cpu_vs_cuda(self): torch.manual_seed(231) N = 1 image_size = 512 blur_radius = 0.0 bin_size = 32 max_faces_per_bin = 20 device = torch.device("cpu") meshes = ico_sphere(2, device) faces = meshes.faces_packed() verts = meshes.verts_packed() faces_verts = verts[faces] num_faces_per_mesh = meshes.num_faces_per_mesh() mesh_to_face_first_idx = meshes.mesh_to_faces_packed_first_idx() args = ( faces_verts, mesh_to_face_first_idx, num_faces_per_mesh, image_size, blur_radius, bin_size, max_faces_per_bin, ) bin_faces_cpu = _C._rasterize_meshes_coarse(*args) device = torch.device("cuda:0") meshes = ico_sphere(2, device) faces = meshes.faces_packed() verts = meshes.verts_packed() faces_verts = verts[faces] num_faces_per_mesh = meshes.num_faces_per_mesh() mesh_to_face_first_idx = meshes.mesh_to_faces_packed_first_idx() args = ( faces_verts, mesh_to_face_first_idx, num_faces_per_mesh, image_size, blur_radius, bin_size, max_faces_per_bin, ) bin_faces_cuda = _C._rasterize_meshes_coarse(*args) # Bin faces might not be the same: CUDA version might write them in # any order. But if we sort the non-(-1) elements of the CUDA output # then they should be the same. for n in range(N): for by in range(bin_faces_cpu.shape[1]): for bx in range(bin_faces_cpu.shape[2]): K = (bin_faces_cuda[n, by, bx] != -1).sum().item() idxs_cpu = bin_faces_cpu[n, by, bx].tolist() idxs_cuda = bin_faces_cuda[n, by, bx].tolist() idxs_cuda[:K] = sorted(idxs_cuda[:K]) self.assertEqual(idxs_cpu, idxs_cuda)
def _test_coarse_rasterize(self, device): image_size = 16 blur_radius = 0.2**2 bin_size = 8 max_faces_per_bin = 3 # fmt: off verts = torch.tensor( [ [-0.5, 0.0, 0.1], # noqa: E241, E201 [0.0, 0.6, 0.1], # noqa: E241, E201 [0.5, 0.0, 0.1], # noqa: E241, E201 [-0.3, 0.0, 0.4], # noqa: E241, E201 [0.3, 0.5, 0.4], # noqa: E241, E201 [0.75, 0.0, 0.4], # noqa: E241, E201 [-0.4, -0.3, 0.9], # noqa: E241, E201 [0.2, -0.7, 0.9], # noqa: E241, E201 [0.4, -0.3, 0.9], # noqa: E241, E201 [-0.4, 0.0, -1.5], # noqa: E241, E201 [0.6, 0.6, -1.5], # noqa: E241, E201 [0.8, 0.0, -1.5], # noqa: E241, E201 ], device=device, ) faces = torch.tensor( [ [1, 0, 2], # noqa: E241, E201 bin 00 and bin 01 [4, 3, 5], # noqa: E241, E201 bin 00 and bin 01 [7, 6, 8], # noqa: E241, E201 bin 10 and bin 11 [10, 9, 11 ], # noqa: E241, E201 negative z, should not appear. ], dtype=torch.int64, device=device, ) # fmt: on meshes = Meshes(verts=[verts], faces=[faces]) faces_verts = verts[faces] num_faces_per_mesh = meshes.num_faces_per_mesh() mesh_to_face_first_idx = meshes.mesh_to_faces_packed_first_idx() bin_faces_expected = (torch.ones( (1, 2, 2, max_faces_per_bin), dtype=torch.int32, device=device) * -1) bin_faces_expected[0, 0, 0, 0:2] = torch.tensor([0, 1]) bin_faces_expected[0, 0, 1, 0:2] = torch.tensor([0, 1]) bin_faces_expected[0, 1, 0, 0:3] = torch.tensor([0, 1, 2]) bin_faces_expected[0, 1, 1, 0:3] = torch.tensor([0, 1, 2]) bin_faces = _C._rasterize_meshes_coarse( faces_verts, mesh_to_face_first_idx, num_faces_per_mesh, image_size, blur_radius, bin_size, max_faces_per_bin, ) bin_faces_same = (bin_faces.squeeze().flip( dims=[0]) == bin_faces_expected).all() self.assertTrue(bin_faces_same.item() == 1)
def _test_coarse_rasterize(self, device): image_size = 16 # No blurring. This test checks that the XY directions are # correctly oriented. blur_radius = 0.0 bin_size = 8 max_faces_per_bin = 3 # fmt: off verts = torch.tensor( [ [-0.5, 0.1, 0.1], # noqa: E241, E201 [-0.3, 0.6, 0.1], # noqa: E241, E201 [-0.1, 0.1, 0.1], # noqa: E241, E201 [-0.3, -0.1, 0.4], # noqa: E241, E201 [ 0.3, 0.5, 0.4], # noqa: E241, E201 [0.75, -0.1, 0.4], # noqa: E241, E201 [ 0.2, -0.3, 0.9], # noqa: E241, E201 [ 0.3, -0.7, 0.9], # noqa: E241, E201 [ 0.6, -0.3, 0.9], # noqa: E241, E201 [-0.4, 0.0, -1.5], # noqa: E241, E201 [ 0.6, 0.6, -1.5], # noqa: E241, E201 [ 0.8, 0.0, -1.5], # noqa: E241, E201 ], device=device, ) # Expected faces using axes convention +Y down, + X right, +Z in # Non symmetrical triangles i.e face 0 and 3 are in one bin only faces = torch.tensor( [ [ 1, 0, 2], # noqa: E241, E201 bin 01 only [ 4, 3, 5], # noqa: E241, E201 all bins [ 7, 6, 8], # noqa: E241, E201 bin 10 only [10, 9, 11], # noqa: E241, E201 negative z, should not appear. ], dtype=torch.int64, device=device, ) # fmt: on meshes = Meshes(verts=[verts], faces=[faces]) faces_verts = verts[faces] num_faces_per_mesh = meshes.num_faces_per_mesh() mesh_to_face_first_idx = meshes.mesh_to_faces_packed_first_idx() # Expected faces using axes convention +Y down, + X right, + Z in bin_faces_expected = ( torch.ones( (1, 2, 2, max_faces_per_bin), dtype=torch.int32, device=device ) * -1 ) bin_faces_expected[0, 0, 0, 0] = torch.tensor([1]) bin_faces_expected[0, 1, 0, 0:2] = torch.tensor([1, 2]) bin_faces_expected[0, 0, 1, 0:2] = torch.tensor([0, 1]) bin_faces_expected[0, 1, 1, 0] = torch.tensor([1]) # +Y up, +X left, +Z in bin_faces = _C._rasterize_meshes_coarse( faces_verts, mesh_to_face_first_idx, num_faces_per_mesh, image_size, blur_radius, bin_size, max_faces_per_bin, ) # Flip x and y axis of output before comparing to expected bin_faces_same = (bin_faces.squeeze() == bin_faces_expected).all() self.assertTrue(bin_faces_same.item() == 1)