pytorch3d icon indicating copy to clipboard operation
pytorch3d copied to clipboard

Running pytorch3d with theseus optimization

Open nea98 opened this issue 2 years ago • 5 comments

🐛 Bugs / Unexpected behaviors

I am trying to integrate theseus optimization library and pytorch3d for my application. When I am passing the variables from Theseus to pytorch3d for rendering it throws the following error.

*RuntimeError: vmap: inplace arithmetic(self, extra_args) is not possible because there exists a Tensor other in extra_args that has more elements than self. This happened due to other being vmapped over but self not being vmapped over in a vmap. Please try to use out-of-place operators instead of inplace arithmetic. If said operator is being called inside the PyTorch framework, please file a bug report instead.

I am using a silhouette_renderer to render an obj model. self.silhouette_renderer(meshes_world=self.mesh, R=R, T=T) The R and T is coming from Theseus while optimizing.

GradTrackingTensor(lvl=2, value=
    BatchedTensor(lvl=1, bdim=0, value=
        tensor([[[[ 0.9541,  0.2773, -0.1129],
                  [-0.1744,  0.8211,  0.5435],
                  [ 0.2434, -0.4988,  0.8318]]]], device='cuda:0', dtype=torch.float64)
    )
) GradTrackingTensor(lvl=2, value=
    BatchedTensor(lvl=1, bdim=0, value=
        tensor([[[-0.0891,  0.1401,  0.4739]]], device='cuda:0', dtype=torch.float64)
    )
)

These are the tensors passed by theseus while optimizing. When I pass normal tensors ie, while not in optimizing mode the renderer works perfectly.

Traceback (most recent call last):
  File "main.py", line 24, in <module>
    main()
  File "main.py", line 21, in main
    optimizer.optimization()   
  File "/home/nahar/6D-Pose-Estimation/learning-tools/multi-camera-tools/optimizer.py", line 350, in optimization
    print(cost_function.jacobians())
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/theseus/core/cost_function.py", line 355, in jacobians
    jacobians_full = self._compute_autograd_jacobian_vmap(
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/theseus/core/cost_function.py", line 341, in _compute_autograd_jacobian_vmap
    return vmap(jacrev(jac_fn, argnums=0))(optim_tensors, aux_tensors)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/vmap.py", line 434, in wrapped
    return _flat_vmap(
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/vmap.py", line 39, in fn
    return f(*args, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/vmap.py", line 619, in _flat_vmap
    batched_outputs = func(*batched_inputs, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/eager_transforms.py", line 489, in wrapper_fn
    vjp_out = _vjp_with_argnums(func, *args, argnums=argnums, has_aux=has_aux)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/vmap.py", line 39, in fn
    return f(*args, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/_functorch/eager_transforms.py", line 291, in _vjp_with_argnums
    primals_out = func(*primals)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/theseus/core/cost_function.py", line 314, in jac_fn
    return self._err_fn(optim_vars=tmp_optim_vars, aux_vars=tmp_aux_vars)[0]
  File "/home/nahar/6D-Pose-Estimation/learning-tools/multi-camera-tools/optimizer.py", line 301, in img_sim_error
    img1 = self.dr.render(c2.rotation().tensor, c2.translation().tensor)
  File "/home/nahar/6D-Pose-Estimation/learning-tools/multi-camera-tools/diff_render.py", line 106, in render
    silhouette = self.silhouette_renderer(meshes_world=self.mesh, R=R, T=T)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/renderer/mesh/renderer.py", line 61, in forward
    fragments = self.rasterizer(meshes_world, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/renderer/mesh/rasterizer.py", line 224, in forward
    meshes_proj = self.transform(meshes_world, **kwargs)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/renderer/mesh/rasterizer.py", line 198, in transform
    verts_view = cameras.get_world_to_view_transform(**kwargs).transform_points(
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/renderer/cameras.py", line 206, in get_world_to_view_transform
    world_to_view_transform = get_world_to_view_transform(R=R, T=T)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/renderer/cameras.py", line 1588, in get_world_to_view_transform
    T_ = Translate(T, device=T.device)
  File "/home/nahar/miniconda3/envs/theseus/lib/python3.8/site-packages/pytorch3d/transforms/transform3d.py", line 553, in __init__
    mat[:, 3, :3] = xyz
RuntimeError: vmap: inplace arithmetic(self, *extra_args) is not possible because there exists a Tensor `other` in extra_args that has more elements than `self`. This happened due to `other` being vmapped over but `self` not being vmapped over in a vmap. Please try to use out-of-place operators instead of inplace arithmetic. If said operator is being called inside the PyTorch framework, please file a bug report instead.

nea98 avatar Sep 14 '23 08:09 nea98

I'm afraid lots of pytorch3d ops are not written to be compatible with vmap. In https://github.com/facebookresearch/pytorch3d/issues/1533 you can see an example of how you might wrap a function to combine the vmap dimension with the batch dimension and therefore make it work. Can you do something similar for this case?

bottler avatar Sep 18 '23 19:09 bottler

My input R shape is torch.Size([1, 3, 3]). I Think I dont have a batch dimension. I think there are some inplace operations happening here. That maybe the issue. I can see that in the todo here you are planning to make the function take input of 4*4 matrix. If thats the case maybe it is not an issue.

nea98 avatar Sep 29 '23 01:09 nea98

This might be quite hard to solve. What is the silhouette_renderer function? Perhaps it could be rewritten specially for vmap compatibility.

bottler avatar Sep 29 '23 15:09 bottler

My code is just a slightly changed version of this example

cameras = FoVPerspectiveCameras(device=device)


blend_params = BlendParams(sigma=1e-4, gamma=1e-4)
raster_settings = RasterizationSettings(
    image_size=256, 
    blur_radius=np.log(1. / 1e-4 - 1.) * blend_params.sigma, 
    faces_per_pixel=100, 
)

silhouette_renderer = MeshRenderer(
    rasterizer=MeshRasterizer(
        cameras=cameras, 
        raster_settings=raster_settings
    ),
    shader=SoftSilhouetteShader(blend_params=blend_params)
)


raster_settings = RasterizationSettings(
    image_size=256, 
    blur_radius=0.0, 
    faces_per_pixel=1, 
)
lights = PointLights(device=device, location=((2.0, 2.0, -2.0),))
phong_renderer = MeshRenderer(
    rasterizer=MeshRasterizer(
        cameras=cameras, 
        raster_settings=raster_settings
    ),
    shader=HardPhongShader(device=device, cameras=cameras, lights=lights)
)

Here you can see the defenition of functions. Sorry I am new to vmap and couldn't understand what is happening in the error message.

nea98 avatar Oct 02 '23 02:10 nea98

What is the whole function you are passing to theseus?

bottler avatar Oct 02 '23 13:10 bottler