def test_points_image_size_arg(self): points = Pointclouds([verts0]) with self.assertRaises(ValueError) as cm: rasterize_points( points, (100, 200, 3), 0.0001, points_per_pixel=1, ) self.assertTrue("tuple/list of (H, W)" in cm.msg) with self.assertRaises(ValueError) as cm: rasterize_points( points, (0, 10), 0.0001, points_per_pixel=1, ) self.assertTrue("sizes must be positive" in cm.msg) with self.assertRaises(ValueError) as cm: rasterize_points( points, (100.5, 120.5), 0.0001, points_per_pixel=1, ) self.assertTrue("sizes must be integers" in cm.msg)
def _rasterize(self, meshes, image_size, bin_size, blur): """ Simple wrapper around the rasterize function to return the fragment data. """ idxs, zbuf, dists = rasterize_points( meshes, image_size, blur, points_per_pixel=1, bin_size=bin_size, ) return PointFragments( idx=idxs, zbuf=zbuf, dists=dists, )
def test_cpp_vs_naive_vs_binned(self): # Make sure that the backward pass runs for all pathways N = 2 P = 1000 image_size = 32 radius = 0.1 points_per_pixel = 3 points1 = torch.randn(P, 3, requires_grad=True) points2 = torch.randn(int(P / 2), 3, requires_grad=True) pointclouds = Pointclouds(points=[points1, points2]) grad_zbuf = torch.randn(N, image_size, image_size, points_per_pixel) grad_dists = torch.randn(N, image_size, image_size, points_per_pixel) # Option I: CPU, naive idx1, zbuf1, dists1 = rasterize_points( pointclouds, image_size, radius, points_per_pixel, bin_size=0 ) loss = (zbuf1 * grad_zbuf).sum() + (dists1 * grad_dists).sum() loss.backward() grad1 = points1.grad.data.clone() # Option II: CUDA, naive points1_cuda = points1.cuda().detach().clone().requires_grad_(True) points2_cuda = points2.cuda().detach().clone().requires_grad_(True) pointclouds = Pointclouds(points=[points1_cuda, points2_cuda]) grad_zbuf = grad_zbuf.cuda() grad_dists = grad_dists.cuda() idx2, zbuf2, dists2 = rasterize_points( pointclouds, image_size, radius, points_per_pixel, bin_size=0 ) loss = (zbuf2 * grad_zbuf).sum() + (dists2 * grad_dists).sum() loss.backward() idx2 = idx2.data.cpu().clone() zbuf2 = zbuf2.data.cpu().clone() dists2 = dists2.data.cpu().clone() grad2 = points1_cuda.grad.data.cpu().clone() # Option III: CUDA, binned points1_cuda = points1.cuda().detach().clone().requires_grad_(True) points2_cuda = points2.cuda().detach().clone().requires_grad_(True) pointclouds = Pointclouds(points=[points1_cuda, points2_cuda]) idx3, zbuf3, dists3 = rasterize_points( pointclouds, image_size, radius, points_per_pixel, bin_size=32 ) loss = (zbuf3 * grad_zbuf).sum() + (dists3 * grad_dists).sum() points1.grad.data.zero_() loss.backward() idx3 = idx3.data.cpu().clone() zbuf3 = zbuf3.data.cpu().clone() dists3 = dists3.data.cpu().clone() grad3 = points1_cuda.grad.data.cpu().clone() # Make sure everything was the same idx12_same = (idx1 == idx2).all().item() idx13_same = (idx1 == idx3).all().item() zbuf12_same = (zbuf1 == zbuf2).all().item() zbuf13_same = (zbuf1 == zbuf3).all().item() dists12_diff = (dists1 - dists2).abs().max().item() dists13_diff = (dists1 - dists3).abs().max().item() self.assertTrue(idx12_same) self.assertTrue(idx13_same) self.assertTrue(zbuf12_same) self.assertTrue(zbuf13_same) self.assertTrue(dists12_diff < 1e-6) self.assertTrue(dists13_diff < 1e-6) diff12 = (grad1 - grad2).abs().max().item() diff13 = (grad1 - grad3).abs().max().item() diff23 = (grad2 - grad3).abs().max().item() self.assertTrue(diff12 < 5e-6) self.assertTrue(diff13 < 5e-6) self.assertTrue(diff23 < 5e-6)
def test_bin_size_error(self): points = Pointclouds(points=torch.rand(5, 100, 3)) image_size = 1024 bin_size = 16 with self.assertRaisesRegex(ValueError, "bin_size too small"): rasterize_points(points, image_size, 0.0, 2, bin_size=bin_size)
def _bm_cuda_with_init(N, P, img_size=32, radius=0.1, pts_per_pxl=3): torch.manual_seed(231) points = torch.randn(N, P, 3, device=torch.device("cuda")) pointclouds = Pointclouds(points=points) args = (pointclouds, img_size, radius, pts_per_pxl) return lambda: rasterize_points(*args)
def fn(): rasterize_points(*args) if device == "cuda": torch.cuda.synchronize(device)