Source code for torch_lattice.utils.to_dense
import torch
from torch.autograd import Function
# from torch.cuda.amp import custom_bwd, custom_fwd
from typing import Tuple
import torch_lattice.backend
from torch_lattice.utils.utils import make_tensor
__all__ = ["to_dense"]
class ToDenseFunction(Function):
@staticmethod
# @custom_fwd(cast_inputs=torch.half)
def forward(
ctx,
feats: torch.Tensor,
coords: torch.Tensor,
spatial_range: Tuple[int],
) -> torch.Tensor:
feats = feats.contiguous()
coords = coords.contiguous().int()
outputs = torch.zeros(
spatial_range + (feats.size(1),), dtype=feats.dtype, device=feats.device
)
spatial_range = make_tensor(spatial_range, dtype=torch.int, device=feats.device)
if feats.device.type == "cuda":
torch_lattice.backend.to_dense_forward_cuda(
feats, coords, spatial_range, outputs
)
else:
raise NotImplementedError
ctx.for_backwards = (coords, spatial_range)
return outputs.to(feats.dtype)
@staticmethod
# @custom_bwd
def backward(ctx, grad_output: torch.Tensor):
coords, spatial_range = ctx.for_backwards
grad_output = grad_output.contiguous()
grad_feats = torch.zeros(
coords.size(0),
grad_output.size(-1),
dtype=grad_output.dtype,
device=grad_output.device,
)
if grad_output.device.type == "cuda":
torch_lattice.backend.to_dense_backward_cuda(
grad_output, coords, spatial_range, grad_feats
)
else:
raise NotImplementedError
return grad_feats, None, None
[docs]
def to_dense(
feats: torch.Tensor, coords: torch.Tensor, spatial_range: Tuple[int]
) -> torch.Tensor:
return ToDenseFunction.apply(feats, coords, spatial_range)