spline_conv2.py 5.7 KB
Newer Older
rusty1s's avatar
rename  
rusty1s committed
1
2
from __future__ import division

rusty1s's avatar
rusty1s committed
3
import unittest
rusty1s's avatar
rename  
rusty1s committed
4
import torch
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
5
from torch.autograd import Variable, gradcheck
rusty1s's avatar
rename  
rusty1s committed
6

rusty1s's avatar
linting  
rusty1s committed
7
8
9
from .spline_conv_gpu import (get_basis_kernel, get_basis_backward_kernel,
                              get_weighting_forward_kernel,
                              get_weighting_backward_kernel, SplineConvGPU)
rusty1s's avatar
rename  
rusty1s committed
10
11


rusty1s's avatar
rusty1s committed
12
class SplineConvTest(unittest.TestCase):
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
13
    '''
rusty1s's avatar
rusty1s committed
14
    @unittest.skipIf(not torch.cuda.is_available(), 'no GPU')
rusty1s's avatar
rename  
rusty1s committed
15
16
17
    def test_forward_gpu(self):
        edges = torch.LongTensor([[0, 0, 0, 0], [1, 2, 3, 4]])
        values = [[0.25, 0.125], [0.25, 0.375], [0.75, 0.625], [0.75, 0.875]]
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
18
        values = torch.FloatTensor(values).double()
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
19
20
21
        adj = {'indices': edges.cuda(), 'values': Variable(values.cuda()),
               'size': torch.Size([5, 5, 2])}

rusty1s's avatar
rename  
rusty1s committed
22
23
24
25

        kernel_size = torch.cuda.LongTensor([3, 4])
        is_open_spline = torch.cuda.LongTensor([1, 0])

rusty1s's avatar
linting  
rusty1s committed
26
        input = torch.DoubleTensor([[9, 10], [1, 2], [3, 4], [5, 6], [7, 8]])
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
27
        weight = torch.arange(0.5, 0.5 * 27, step=0.5).view(13, 2, 1).double()
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
28
        input, weight = input.cuda(), weight.cuda()
rusty1s's avatar
rename  
rusty1s committed
29
        input, weight = Variable(input), Variable(weight)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
30
31
        row, col = adj['indices']
        output = input[col]
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
        K = 12
        in_features = 2
        out_features = 1
        degree = 1
        dim = 2
        k_max = (degree+1)**dim
        fw_k = get_weighting_forward_kernel(in_features, out_features, k_max)
        bw_k = get_weighting_backward_kernel(in_features, out_features, k_max,
                                             K, True)

        basis_fw_k = get_basis_kernel(k_max, K, dim, degree)

        basis_bw_k = get_basis_backward_kernel(k_max, K, dim, degree)

rusty1s's avatar
rename  
rusty1s committed
46

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
        #output = spline_conv(
        #    adj, input, weight, kernel_size, is_open_spline, K, fw_k, bw_k,
        #    basis_fw_k, basis_bw_k,bp_to_adj=True)
        values = adj['values']
        output = SplineConvGPU(kernel_size, is_open_spline, K, degree,
                           basis_fw_k, basis_bw_k, fw_k, bw_k, bp_to_adj=True)\
            (output, weight, values)

        zero = output.data.new(adj['size'][1], output.size(1)).fill_(0.0)
        zero = Variable(zero) if not torch.is_tensor(output) else zero
        r = row.view(-1, 1).expand(row.size(0), output.size(1))
        output = zero.scatter_add_(0, Variable(r), output)

        # Weighten root node features by multiplying with root weight.
        output += torch.mm(input, weight[-1])

        # Normalize output by degree.
        ones = values.data.new(values.size(0)).fill_(1)
        zero = values.data.new(output.size(0)).fill_(0)
        degree = zero.scatter_add_(0, row, ones)
        degree = torch.clamp(degree, min=1)
        output = output / Variable(degree.view(-1, 1))

rusty1s's avatar
rename  
rusty1s committed
70
71
72
73
74
75
76
77
78

        expected_output = [
            [(12.5 * 9 + 13 * 10 + 266) / 4],
            [12.5 * 1 + 13 * 2],
            [12.5 * 3 + 13 * 4],
            [12.5 * 5 + 13 * 6],
            [12.5 * 7 + 13 * 8],
        ]
        assert_almost_equal(output.cpu().data.numpy(), expected_output, 1)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
79

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
80

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
81
82
83
    @unittest.skipIf(not torch.cuda.is_available(), 'no GPU')
    def test_backward(self):
        kernel_size = torch.cuda.LongTensor([3, 4])
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
84
        is_open_spline = torch.cuda.LongTensor([1, 1])
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
85
86
87

        input = torch.randn(4, 2).double().cuda()
        weight = torch.randn(12, 2, 1).double().cuda()
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
88
89
        values = torch.FloatTensor(4, 2).uniform_(0, 1).double().cuda()
        print(values)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
        input = Variable(input, requires_grad=True)
        weight = Variable(weight, requires_grad=True)
        values = Variable(values, requires_grad=True)

        K = 12
        in_features = 2
        out_features = 1
        degree = 1
        dim = 2
        k_max = (degree + 1) ** dim
        fw_k = get_weighting_forward_kernel(in_features, out_features, k_max)
        bw_k = get_weighting_backward_kernel(in_features, out_features, k_max,
                                             K, bp_to_adj=True)

        basis_fw_k = get_basis_kernel(k_max, K, dim, degree)

        basis_bw_k = get_basis_backward_kernel(k_max, K, dim, degree)

        op = SplineConvGPU(kernel_size, is_open_spline, K, degree,
                           basis_fw_k, basis_bw_k, fw_k, bw_k, bp_to_adj=True)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
110
111
112
113
114
        print(op(input, weight, values))
        #test = gradcheck(op, (input, weight, values), eps=1e-6, atol=1e-4)

        #self.assertTrue(test)
    '''
rusty1s's avatar
linting  
rusty1s committed
115

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
116
117
    @unittest.skipIf(not torch.cuda.is_available(), 'no GPU')
    def test_backward(self):
rusty1s's avatar
linting  
rusty1s committed
118

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
119
120
121
122
123
124
125
        input = torch.randn(4, 2).double().cuda()
        weight = torch.randn(9, 2, 1).double().cuda()
        values = torch.FloatTensor(4, 2).uniform_(0, 1).double().cuda()
        print(values)
        input = Variable(input, requires_grad=True)
        weight = Variable(weight, requires_grad=True)
        values = Variable(values, requires_grad=True)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
126

Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
127
128
129
130
131
        K = 9
        in_features = 2
        out_features = 1
        degree = 1
        dim = 2
rusty1s's avatar
linting  
rusty1s committed
132
        k_max = (degree + 1)**dim
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
133
134
        kernel_size = torch.cuda.LongTensor([3, 3])
        is_open_spline = torch.cuda.LongTensor([1, 0])
rusty1s's avatar
linting  
rusty1s committed
135
136
137
138
        fw_k = get_weighting_forward_kernel(
            in_features, out_features, k_max, dtype='double')
        bw_k = get_weighting_backward_kernel(
            in_features, out_features, k_max, K, True, dtype='double')
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
139
140
141

        basis_fw_k = get_basis_kernel(k_max, K, dim, degree, dtype='double')

rusty1s's avatar
linting  
rusty1s committed
142
143
144
145
146
147
148
149
150
151
152
153
154
        basis_bw_k = get_basis_backward_kernel(
            k_max, K, dim, degree, dtype='double')

        op = SplineConvGPU(
            kernel_size,
            is_open_spline,
            K,
            degree,
            basis_fw_k,
            basis_bw_k,
            fw_k,
            bw_k,
            bp_to_adj=True)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
155
        test = gradcheck(op, (input, weight, values), eps=1e-6, atol=1e-4)
Jan Eric Lenssen's avatar
Jan Eric Lenssen committed
156
157

        self.assertTrue(test)