|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import torch |
|
|
import unittest |
|
|
|
|
|
from MinkowskiEngine import ( |
|
|
SparseTensor, |
|
|
MinkowskiConvolution, |
|
|
MinkowskiInterpolationFunction, |
|
|
MinkowskiInterpolation, |
|
|
) |
|
|
|
|
|
from utils.gradcheck import gradcheck |
|
|
from tests.python.common import data_loader |
|
|
|
|
|
LEAK_TEST_ITER = 10000000 |
|
|
|
|
|
|
|
|
class TestInterpolation(unittest.TestCase): |
|
|
def test(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=2) |
|
|
feats = feats.double() |
|
|
tfield = torch.Tensor( |
|
|
[ |
|
|
[0, 0.1, 2.7], |
|
|
[0, 0.3, 2], |
|
|
[1, 1.5, 2.5], |
|
|
] |
|
|
).double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
interp = MinkowskiInterpolation(return_kernel_map=True, return_weights=False) |
|
|
output, (in_map, out_map) = interp(input, tfield) |
|
|
print(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
output.sum().backward() |
|
|
fn = MinkowskiInterpolationFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
tfield, |
|
|
input.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
for i in range(LEAK_TEST_ITER): |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
tfield = torch.DoubleTensor( |
|
|
[ |
|
|
[0, 0.1, 2.7], |
|
|
[0, 0.3, 2], |
|
|
[1, 1.5, 2.5], |
|
|
], |
|
|
) |
|
|
output, _ = interp(input, tfield) |
|
|
output.sum().backward() |
|
|
|
|
|
def test_gpu(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=2) |
|
|
feats = feats.double() |
|
|
tfield = torch.cuda.DoubleTensor( |
|
|
[ |
|
|
[0, 0.1, 2.7], |
|
|
[0, 0.3, 2], |
|
|
[1, 1.5, 2.5], |
|
|
], |
|
|
) |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords, device="cuda") |
|
|
interp = MinkowskiInterpolation() |
|
|
output = interp(input, tfield) |
|
|
print(input) |
|
|
print(output) |
|
|
|
|
|
output.sum().backward() |
|
|
|
|
|
fn = MinkowskiInterpolationFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
tfield, |
|
|
input.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
for i in range(LEAK_TEST_ITER): |
|
|
input = SparseTensor(feats, coordinates=coords, device="cuda") |
|
|
tfield = torch.cuda.DoubleTensor( |
|
|
[ |
|
|
[0, 0.1, 2.7], |
|
|
[0, 0.3, 2], |
|
|
[1, 1.5, 2.5], |
|
|
], |
|
|
) |
|
|
output = interp(input, tfield) |
|
|
output.sum().backward() |
|
|
|
|
|
def test_zero(self): |
|
|
|
|
|
|
|
|
|
|
|
pc = torch.randint(-10, 10, size=(32, 4), dtype=torch.float32, device='cuda') |
|
|
pc[:, 0] = 0 |
|
|
feat = torch.randn(32, 3, dtype=torch.float32, device='cuda', requires_grad=True) |
|
|
|
|
|
|
|
|
x = SparseTensor(feat, pc, device='cuda') |
|
|
interp = MinkowskiInterpolation() |
|
|
|
|
|
|
|
|
samples = pc |
|
|
y = interp(x, samples) |
|
|
print(y.shape, y.stride()) |
|
|
torch.sum(y).backward() |
|
|
|
|
|
|
|
|
samples = torch.zeros_like(pc) |
|
|
samples[:, 0] = 0 |
|
|
y = interp(x, samples) |
|
|
print(y.shape, y.stride()) |
|
|
torch.sum(y).backward() |
|
|
|
|
|
def test_strided_tensor(self): |
|
|
in_channels, D = 2, 2 |
|
|
tfield = torch.Tensor( |
|
|
[ |
|
|
[0, 0.1, 2.7], |
|
|
[0, 0.3, 2], |
|
|
[1, 1.5, 2.5], |
|
|
] |
|
|
) |
|
|
|
|
|
coords = torch.IntTensor([[0, 0, 2], [0, 0, 4], [0, 2, 4]]) |
|
|
feats = torch.rand(len(coords), 1) |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, tensor_stride=2) |
|
|
interp = MinkowskiInterpolation() |
|
|
output = interp(input, tfield) |
|
|
print(input) |
|
|
print(output) |
|
|
|