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)
示例#3
0
    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)