test_basis.py 3.02 KB
Newer Older
rusty1s's avatar
rusty1s committed
1
2
3
4
from itertools import product

import pytest
import torch
rusty1s's avatar
rusty1s committed
5
6
7
from torch.autograd import Variable, gradcheck
from torch_spline_conv.basis import spline_basis, SplineBasis
from torch_spline_conv.utils.ffi import implemented_degrees
rusty1s's avatar
rusty1s committed
8

rusty1s's avatar
rusty1s committed
9
from .tensor import tensors
rusty1s's avatar
rusty1s committed
10

rusty1s's avatar
rusty1s committed
11
tests = [{
rusty1s's avatar
rusty1s committed
12
    'pseudo': [[0], [0.0625], [0.25], [0.75], [0.9375], [1]],
rusty1s's avatar
rusty1s committed
13
14
15
16
17
    'kernel_size': [5],
    'is_open_spline': [1],
    'basis': [[1, 0], [0.75, 0.25], [1, 0], [1, 0], [0.25, 0.75], [1, 0]],
    'weight_index': [[0, 1], [0, 1], [1, 2], [3, 4], [3, 4], [4, 0]],
}, {
rusty1s's avatar
rusty1s committed
18
    'pseudo': [[0], [0.0625], [0.25], [0.75], [0.9375], [1]],
rusty1s's avatar
rusty1s committed
19
20
21
22
23
24
25
26
27
28
29
    'kernel_size': [4],
    'is_open_spline': [0],
    'basis': [[1, 0], [0.75, 0.25], [1, 0], [1, 0], [0.25, 0.75], [1, 0]],
    'weight_index': [[0, 1], [0, 1], [1, 2], [3, 0], [3, 0], [0, 1]],
}, {
    'pseudo': [[0.125, 0.5], [0.5, 0.5], [0.75, 0.125]],
    'kernel_size': [5, 5],
    'is_open_spline': [1, 1],
    'basis': [[0.5, 0.5, 0, 0], [1, 0, 0, 0], [0.5, 0, 0.5, 0]],
    'weight_index': [[10, 11, 15, 16], [12, 13, 17, 18], [3, 4, 8, 9]]
}]
rusty1s's avatar
rusty1s committed
30
31


rusty1s's avatar
rusty1s committed
32
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(tests))))
rusty1s's avatar
rusty1s committed
33
def test_spline_basis_forward_cpu(tensor, i):
rusty1s's avatar
rusty1s committed
34
    data = tests[i]
rusty1s's avatar
rusty1s committed
35

rusty1s's avatar
rusty1s committed
36
37
38
    pseudo = getattr(torch, tensor)(data['pseudo'])
    kernel_size = torch.LongTensor(data['kernel_size'])
    is_open_spline = torch.ByteTensor(data['is_open_spline'])
rusty1s's avatar
rusty1s committed
39

rusty1s's avatar
rusty1s committed
40
    basis, weight_index = spline_basis(1, pseudo, kernel_size, is_open_spline)
rusty1s's avatar
rusty1s committed
41
42
    assert basis.tolist() == data['basis']
    assert weight_index.tolist() == data['weight_index']
rusty1s's avatar
rusty1s committed
43
44
45


@pytest.mark.skipif(not torch.cuda.is_available(), reason='no CUDA')
rusty1s's avatar
rusty1s committed
46
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(tests))))
rusty1s's avatar
rusty1s committed
47
def test_spline_basis_forward_gpu(tensor, i):  # pragma: no cover
rusty1s's avatar
rusty1s committed
48
    data = tests[i]
rusty1s's avatar
rusty1s committed
49

rusty1s's avatar
rusty1s committed
50
51
52
    pseudo = getattr(torch.cuda, tensor)(data['pseudo'])
    kernel_size = torch.cuda.LongTensor(data['kernel_size'])
    is_open_spline = torch.cuda.ByteTensor(data['is_open_spline'])
rusty1s's avatar
rusty1s committed
53

rusty1s's avatar
rusty1s committed
54
    basis, weight_index = spline_basis(1, pseudo, kernel_size, is_open_spline)
rusty1s's avatar
rusty1s committed
55
56
    assert basis.cpu().tolist() == data['basis']
    assert weight_index.cpu().tolist() == data['weight_index']
rusty1s's avatar
rusty1s committed
57
58


rusty1s's avatar
rusty1s committed
59
60
@pytest.mark.parametrize('degree', implemented_degrees.keys())
def test_spline_basis_backward_cpu(degree):
rusty1s's avatar
rusty1s committed
61
62
63
64
65
    kernel_size = torch.LongTensor([5, 5, 5])
    is_open_spline = torch.ByteTensor([1, 0, 1])
    pseudo = torch.DoubleTensor(4, 3).uniform_(0, 1)
    pseudo = Variable(pseudo, requires_grad=True)

rusty1s's avatar
rusty1s committed
66
67
68
69
70
71
72
73
74
    op = SplineBasis(degree, kernel_size, is_open_spline)
    assert gradcheck(op, (pseudo, ), eps=1e-6, atol=1e-4) is True


@pytest.mark.skipif(not torch.cuda.is_available(), reason='no CUDA')
@pytest.mark.parametrize('degree', implemented_degrees.keys())
def test_spline_basis_backward_gpu(degree):
    kernel_size = torch.cuda.LongTensor([5, 5, 5])
    is_open_spline = torch.cuda.ByteTensor([1, 0, 1])
rusty1s's avatar
rusty1s committed
75
    pseudo = torch.cuda.DoubleTensor(4, 3).uniform_(0, 1)
rusty1s's avatar
rusty1s committed
76
77
78
    pseudo = Variable(pseudo, requires_grad=True)

    op = SplineBasis(degree, kernel_size, is_open_spline)
rusty1s's avatar
rusty1s committed
79
    assert gradcheck(op, (pseudo, ), eps=1e-6, atol=1e-4) is True