learning3d 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- learning3d/__init__.py +0 -2
- learning3d/data_utils/dataloaders.py +11 -14
- learning3d/models/__init__.py +1 -6
- learning3d/utils/__init__.py +1 -6
- {learning3d-0.0.2.dist-info → learning3d-0.0.4.dist-info}/METADATA +1 -1
- {learning3d-0.0.2.dist-info → learning3d-0.0.4.dist-info}/RECORD +9 -44
- learning3d/examples/test_flownet.py +0 -113
- learning3d/examples/train_flownet.py +0 -259
- learning3d/models/flownet3d.py +0 -446
- learning3d/utils/lib/build/lib.linux-x86_64-3.5/pointnet2_cuda.cpython-35m-x86_64-linux-gnu.so +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/ball_query.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/ball_query_gpu.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/group_points.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/group_points_gpu.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/interpolate.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/interpolate_gpu.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/pointnet2_api.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/sampling.o +0 -0
- learning3d/utils/lib/build/temp.linux-x86_64-3.5/src/sampling_gpu.o +0 -0
- learning3d/utils/lib/dist/pointnet2-0.0.0-py3.5-linux-x86_64.egg +0 -0
- learning3d/utils/lib/pointnet2.egg-info/SOURCES.txt +0 -14
- learning3d/utils/lib/pointnet2.egg-info/dependency_links.txt +0 -1
- learning3d/utils/lib/pointnet2.egg-info/top_level.txt +0 -1
- learning3d/utils/lib/pointnet2_modules.py +0 -160
- learning3d/utils/lib/pointnet2_utils.py +0 -318
- learning3d/utils/lib/pytorch_utils.py +0 -236
- learning3d/utils/lib/setup.py +0 -23
- learning3d/utils/lib/src/ball_query.cpp +0 -25
- learning3d/utils/lib/src/ball_query_gpu.cu +0 -67
- learning3d/utils/lib/src/ball_query_gpu.h +0 -15
- learning3d/utils/lib/src/cuda_utils.h +0 -15
- learning3d/utils/lib/src/group_points.cpp +0 -36
- learning3d/utils/lib/src/group_points_gpu.cu +0 -86
- learning3d/utils/lib/src/group_points_gpu.h +0 -22
- learning3d/utils/lib/src/interpolate.cpp +0 -65
- learning3d/utils/lib/src/interpolate_gpu.cu +0 -233
- learning3d/utils/lib/src/interpolate_gpu.h +0 -36
- learning3d/utils/lib/src/pointnet2_api.cpp +0 -25
- learning3d/utils/lib/src/sampling.cpp +0 -46
- learning3d/utils/lib/src/sampling_gpu.cu +0 -253
- learning3d/utils/lib/src/sampling_gpu.h +0 -29
- {learning3d-0.0.2.dist-info → learning3d-0.0.4.dist-info}/LICENSE +0 -0
- {learning3d-0.0.2.dist-info → learning3d-0.0.4.dist-info}/WHEEL +0 -0
- {learning3d-0.0.2.dist-info → learning3d-0.0.4.dist-info}/top_level.txt +0 -0
@@ -1,318 +0,0 @@
|
|
1
|
-
import torch
|
2
|
-
from torch.autograd import Variable
|
3
|
-
from torch.autograd import Function
|
4
|
-
import torch.nn as nn
|
5
|
-
from typing import Tuple
|
6
|
-
|
7
|
-
import pointnet2_cuda as pointnet2
|
8
|
-
|
9
|
-
|
10
|
-
class FurthestPointSampling(Function):
|
11
|
-
@staticmethod
|
12
|
-
def forward(ctx, xyz: torch.Tensor, npoint: int) -> torch.Tensor:
|
13
|
-
"""
|
14
|
-
Uses iterative furthest point sampling to select a set of npoint features that have the largest
|
15
|
-
minimum distance
|
16
|
-
:param ctx:
|
17
|
-
:param xyz: (B, N, 3) where N > npoint
|
18
|
-
:param npoint: int, number of features in the sampled set
|
19
|
-
:return:
|
20
|
-
output: (B, npoint) tensor containing the set
|
21
|
-
"""
|
22
|
-
assert xyz.is_contiguous()
|
23
|
-
|
24
|
-
B, N, _ = xyz.size()
|
25
|
-
output = torch.cuda.IntTensor(B, npoint)
|
26
|
-
temp = torch.cuda.FloatTensor(B, N).fill_(1e10)
|
27
|
-
|
28
|
-
pointnet2.furthest_point_sampling_wrapper(B, N, npoint, xyz, temp, output)
|
29
|
-
return output
|
30
|
-
|
31
|
-
@staticmethod
|
32
|
-
def backward(xyz, a=None):
|
33
|
-
return None, None
|
34
|
-
|
35
|
-
|
36
|
-
furthest_point_sample = FurthestPointSampling.apply
|
37
|
-
|
38
|
-
|
39
|
-
class GatherOperation(Function):
|
40
|
-
|
41
|
-
@staticmethod
|
42
|
-
def forward(ctx, features: torch.Tensor, idx: torch.Tensor) -> torch.Tensor:
|
43
|
-
"""
|
44
|
-
:param ctx:
|
45
|
-
:param features: (B, C, N)
|
46
|
-
:param idx: (B, npoint) index tensor of the features to gather
|
47
|
-
:return:
|
48
|
-
output: (B, C, npoint)
|
49
|
-
"""
|
50
|
-
assert features.is_contiguous()
|
51
|
-
assert idx.is_contiguous()
|
52
|
-
|
53
|
-
B, npoint = idx.size()
|
54
|
-
_, C, N = features.size()
|
55
|
-
output = torch.cuda.FloatTensor(B, C, npoint)
|
56
|
-
|
57
|
-
pointnet2.gather_points_wrapper(B, C, N, npoint, features, idx, output)
|
58
|
-
|
59
|
-
ctx.for_backwards = (idx, C, N)
|
60
|
-
return output
|
61
|
-
|
62
|
-
@staticmethod
|
63
|
-
def backward(ctx, grad_out):
|
64
|
-
idx, C, N = ctx.for_backwards
|
65
|
-
B, npoint = idx.size()
|
66
|
-
|
67
|
-
grad_features = Variable(torch.cuda.FloatTensor(B, C, N).zero_())
|
68
|
-
grad_out_data = grad_out.data.contiguous()
|
69
|
-
pointnet2.gather_points_grad_wrapper(B, C, N, npoint, grad_out_data, idx, grad_features.data)
|
70
|
-
return grad_features, None
|
71
|
-
|
72
|
-
|
73
|
-
gather_operation = GatherOperation.apply
|
74
|
-
|
75
|
-
class KNN(Function):
|
76
|
-
|
77
|
-
@staticmethod
|
78
|
-
def forward(ctx, k: int, unknown: torch.Tensor, known: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
|
79
|
-
"""
|
80
|
-
Find the three nearest neighbors of unknown in known
|
81
|
-
:param ctx:
|
82
|
-
:param unknown: (B, N, 3)
|
83
|
-
:param known: (B, M, 3)
|
84
|
-
:return:
|
85
|
-
dist: (B, N, k) l2 distance to the three nearest neighbors
|
86
|
-
idx: (B, N, k) index of 3 nearest neighbors
|
87
|
-
"""
|
88
|
-
assert unknown.is_contiguous()
|
89
|
-
assert known.is_contiguous()
|
90
|
-
|
91
|
-
B, N, _ = unknown.size()
|
92
|
-
m = known.size(1)
|
93
|
-
dist2 = torch.cuda.FloatTensor(B, N, k)
|
94
|
-
idx = torch.cuda.IntTensor(B, N, k)
|
95
|
-
|
96
|
-
pointnet2.knn_wrapper(B, N, m, k, unknown, known, dist2, idx)
|
97
|
-
return torch.sqrt(dist2), idx
|
98
|
-
|
99
|
-
@staticmethod
|
100
|
-
def backward(ctx, a=None, b=None):
|
101
|
-
return None, None, None
|
102
|
-
knn = KNN.apply
|
103
|
-
|
104
|
-
class ThreeNN(Function):
|
105
|
-
|
106
|
-
@staticmethod
|
107
|
-
def forward(ctx, unknown: torch.Tensor, known: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
|
108
|
-
"""
|
109
|
-
Find the three nearest neighbors of unknown in known
|
110
|
-
:param ctx:
|
111
|
-
:param unknown: (B, N, 3)
|
112
|
-
:param known: (B, M, 3)
|
113
|
-
:return:
|
114
|
-
dist: (B, N, 3) l2 distance to the three nearest neighbors
|
115
|
-
idx: (B, N, 3) index of 3 nearest neighbors
|
116
|
-
"""
|
117
|
-
assert unknown.is_contiguous()
|
118
|
-
assert known.is_contiguous()
|
119
|
-
|
120
|
-
B, N, _ = unknown.size()
|
121
|
-
m = known.size(1)
|
122
|
-
dist2 = torch.cuda.FloatTensor(B, N, 3)
|
123
|
-
idx = torch.cuda.IntTensor(B, N, 3)
|
124
|
-
|
125
|
-
pointnet2.three_nn_wrapper(B, N, m, unknown, known, dist2, idx)
|
126
|
-
return torch.sqrt(dist2), idx
|
127
|
-
|
128
|
-
@staticmethod
|
129
|
-
def backward(ctx, a=None, b=None):
|
130
|
-
return None, None
|
131
|
-
|
132
|
-
|
133
|
-
three_nn = ThreeNN.apply
|
134
|
-
|
135
|
-
|
136
|
-
class ThreeInterpolate(Function):
|
137
|
-
|
138
|
-
@staticmethod
|
139
|
-
def forward(ctx, features: torch.Tensor, idx: torch.Tensor, weight: torch.Tensor) -> torch.Tensor:
|
140
|
-
"""
|
141
|
-
Performs weight linear interpolation on 3 features
|
142
|
-
:param ctx:
|
143
|
-
:param features: (B, C, M) Features descriptors to be interpolated from
|
144
|
-
:param idx: (B, n, 3) three nearest neighbors of the target features in features
|
145
|
-
:param weight: (B, n, 3) weights
|
146
|
-
:return:
|
147
|
-
output: (B, C, N) tensor of the interpolated features
|
148
|
-
"""
|
149
|
-
assert features.is_contiguous()
|
150
|
-
assert idx.is_contiguous()
|
151
|
-
assert weight.is_contiguous()
|
152
|
-
|
153
|
-
B, c, m = features.size()
|
154
|
-
n = idx.size(1)
|
155
|
-
ctx.three_interpolate_for_backward = (idx, weight, m)
|
156
|
-
output = torch.cuda.FloatTensor(B, c, n)
|
157
|
-
|
158
|
-
pointnet2.three_interpolate_wrapper(B, c, m, n, features, idx, weight, output)
|
159
|
-
return output
|
160
|
-
|
161
|
-
@staticmethod
|
162
|
-
def backward(ctx, grad_out: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
163
|
-
"""
|
164
|
-
:param ctx:
|
165
|
-
:param grad_out: (B, C, N) tensor with gradients of outputs
|
166
|
-
:return:
|
167
|
-
grad_features: (B, C, M) tensor with gradients of features
|
168
|
-
None:
|
169
|
-
None:
|
170
|
-
"""
|
171
|
-
idx, weight, m = ctx.three_interpolate_for_backward
|
172
|
-
B, c, n = grad_out.size()
|
173
|
-
|
174
|
-
grad_features = Variable(torch.cuda.FloatTensor(B, c, m).zero_())
|
175
|
-
grad_out_data = grad_out.data.contiguous()
|
176
|
-
|
177
|
-
pointnet2.three_interpolate_grad_wrapper(B, c, n, m, grad_out_data, idx, weight, grad_features.data)
|
178
|
-
return grad_features, None, None
|
179
|
-
|
180
|
-
|
181
|
-
three_interpolate = ThreeInterpolate.apply
|
182
|
-
|
183
|
-
|
184
|
-
class GroupingOperation(Function):
|
185
|
-
|
186
|
-
@staticmethod
|
187
|
-
def forward(ctx, features: torch.Tensor, idx: torch.Tensor) -> torch.Tensor:
|
188
|
-
"""
|
189
|
-
:param ctx:
|
190
|
-
:param features: (B, C, N) tensor of features to group
|
191
|
-
:param idx: (B, npoint, nsample) tensor containing the indicies of features to group with
|
192
|
-
:return:
|
193
|
-
output: (B, C, npoint, nsample) tensor
|
194
|
-
"""
|
195
|
-
assert features.is_contiguous()
|
196
|
-
assert idx.is_contiguous()
|
197
|
-
idx = idx.int()
|
198
|
-
B, nfeatures, nsample = idx.size()
|
199
|
-
_, C, N = features.size()
|
200
|
-
output = torch.cuda.FloatTensor(B, C, nfeatures, nsample)
|
201
|
-
|
202
|
-
pointnet2.group_points_wrapper(B, C, N, nfeatures, nsample, features, idx, output)
|
203
|
-
|
204
|
-
ctx.for_backwards = (idx, N)
|
205
|
-
return output
|
206
|
-
|
207
|
-
@staticmethod
|
208
|
-
def backward(ctx, grad_out: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
|
209
|
-
"""
|
210
|
-
:param ctx:
|
211
|
-
:param grad_out: (B, C, npoint, nsample) tensor of the gradients of the output from forward
|
212
|
-
:return:
|
213
|
-
grad_features: (B, C, N) gradient of the features
|
214
|
-
"""
|
215
|
-
idx, N = ctx.for_backwards
|
216
|
-
|
217
|
-
B, C, npoint, nsample = grad_out.size()
|
218
|
-
grad_features = Variable(torch.cuda.FloatTensor(B, C, N).zero_())
|
219
|
-
|
220
|
-
grad_out_data = grad_out.data.contiguous()
|
221
|
-
pointnet2.group_points_grad_wrapper(B, C, N, npoint, nsample, grad_out_data, idx, grad_features.data)
|
222
|
-
return grad_features, None
|
223
|
-
|
224
|
-
|
225
|
-
grouping_operation = GroupingOperation.apply
|
226
|
-
|
227
|
-
|
228
|
-
class BallQuery(Function):
|
229
|
-
|
230
|
-
@staticmethod
|
231
|
-
def forward(ctx, radius: float, nsample: int, xyz: torch.Tensor, new_xyz: torch.Tensor) -> torch.Tensor:
|
232
|
-
"""
|
233
|
-
:param ctx:
|
234
|
-
:param radius: float, radius of the balls
|
235
|
-
:param nsample: int, maximum number of features in the balls
|
236
|
-
:param xyz: (B, N, 3) xyz coordinates of the features
|
237
|
-
:param new_xyz: (B, npoint, 3) centers of the ball query
|
238
|
-
:return:
|
239
|
-
idx: (B, npoint, nsample) tensor with the indicies of the features that form the query balls
|
240
|
-
"""
|
241
|
-
assert new_xyz.is_contiguous()
|
242
|
-
assert xyz.is_contiguous()
|
243
|
-
|
244
|
-
B, N, _ = xyz.size()
|
245
|
-
npoint = new_xyz.size(1)
|
246
|
-
idx = torch.cuda.IntTensor(B, npoint, nsample).zero_()
|
247
|
-
|
248
|
-
pointnet2.ball_query_wrapper(B, N, npoint, radius, nsample, new_xyz, xyz, idx)
|
249
|
-
return idx
|
250
|
-
|
251
|
-
@staticmethod
|
252
|
-
def backward(ctx, a=None):
|
253
|
-
return None, None, None, None
|
254
|
-
|
255
|
-
|
256
|
-
ball_query = BallQuery.apply
|
257
|
-
|
258
|
-
|
259
|
-
class QueryAndGroup(nn.Module):
|
260
|
-
def __init__(self, radius: float, nsample: int, use_xyz: bool = True):
|
261
|
-
"""
|
262
|
-
:param radius: float, radius of ball
|
263
|
-
:param nsample: int, maximum number of features to gather in the ball
|
264
|
-
:param use_xyz:
|
265
|
-
"""
|
266
|
-
super().__init__()
|
267
|
-
self.radius, self.nsample, self.use_xyz = radius, nsample, use_xyz
|
268
|
-
|
269
|
-
def forward(self, xyz: torch.Tensor, new_xyz: torch.Tensor, features: torch.Tensor = None) -> Tuple[torch.Tensor]:
|
270
|
-
"""
|
271
|
-
:param xyz: (B, N, 3) xyz coordinates of the features
|
272
|
-
:param new_xyz: (B, npoint, 3) centroids
|
273
|
-
:param features: (B, C, N) descriptors of the features
|
274
|
-
:return:
|
275
|
-
new_features: (B, 3 + C, npoint, nsample)
|
276
|
-
"""
|
277
|
-
idx = ball_query(self.radius, self.nsample, xyz, new_xyz)
|
278
|
-
xyz_trans = xyz.transpose(1, 2).contiguous()
|
279
|
-
grouped_xyz = grouping_operation(xyz_trans, idx) # (B, 3, npoint, nsample)
|
280
|
-
grouped_xyz -= new_xyz.transpose(1, 2).unsqueeze(-1)
|
281
|
-
|
282
|
-
if features is not None:
|
283
|
-
grouped_features = grouping_operation(features, idx)
|
284
|
-
if self.use_xyz:
|
285
|
-
new_features = torch.cat([grouped_xyz, grouped_features], dim=1) # (B, C + 3, npoint, nsample)
|
286
|
-
else:
|
287
|
-
new_features = grouped_features
|
288
|
-
else:
|
289
|
-
assert self.use_xyz, "Cannot have not features and not use xyz as a feature!"
|
290
|
-
new_features = grouped_xyz
|
291
|
-
|
292
|
-
return new_features
|
293
|
-
|
294
|
-
|
295
|
-
class GroupAll(nn.Module):
|
296
|
-
def __init__(self, use_xyz: bool = True):
|
297
|
-
super().__init__()
|
298
|
-
self.use_xyz = use_xyz
|
299
|
-
|
300
|
-
def forward(self, xyz: torch.Tensor, new_xyz: torch.Tensor, features: torch.Tensor = None):
|
301
|
-
"""
|
302
|
-
:param xyz: (B, N, 3) xyz coordinates of the features
|
303
|
-
:param new_xyz: ignored
|
304
|
-
:param features: (B, C, N) descriptors of the features
|
305
|
-
:return:
|
306
|
-
new_features: (B, C + 3, 1, N)
|
307
|
-
"""
|
308
|
-
grouped_xyz = xyz.transpose(1, 2).unsqueeze(2)
|
309
|
-
if features is not None:
|
310
|
-
grouped_features = features.unsqueeze(2)
|
311
|
-
if self.use_xyz:
|
312
|
-
new_features = torch.cat([grouped_xyz, grouped_features], dim=1) # (B, 3 + C, 1, N)
|
313
|
-
else:
|
314
|
-
new_features = grouped_features
|
315
|
-
else:
|
316
|
-
new_features = grouped_xyz
|
317
|
-
|
318
|
-
return new_features
|
@@ -1,236 +0,0 @@
|
|
1
|
-
import torch.nn as nn
|
2
|
-
from typing import List, Tuple
|
3
|
-
|
4
|
-
|
5
|
-
class SharedMLP(nn.Sequential):
|
6
|
-
|
7
|
-
def __init__(
|
8
|
-
self,
|
9
|
-
args: List[int],
|
10
|
-
*,
|
11
|
-
bn: bool = False,
|
12
|
-
activation=nn.ReLU(inplace=True),
|
13
|
-
preact: bool = False,
|
14
|
-
first: bool = False,
|
15
|
-
name: str = "",
|
16
|
-
instance_norm: bool = False,
|
17
|
-
):
|
18
|
-
super().__init__()
|
19
|
-
|
20
|
-
for i in range(len(args) - 1):
|
21
|
-
self.add_module(
|
22
|
-
name + 'layer{}'.format(i),
|
23
|
-
Conv2d(
|
24
|
-
args[i],
|
25
|
-
args[i + 1],
|
26
|
-
bn=(not first or not preact or (i != 0)) and bn,
|
27
|
-
activation=activation
|
28
|
-
if (not first or not preact or (i != 0)) else None,
|
29
|
-
preact=preact,
|
30
|
-
instance_norm=instance_norm
|
31
|
-
)
|
32
|
-
)
|
33
|
-
|
34
|
-
|
35
|
-
class _ConvBase(nn.Sequential):
|
36
|
-
|
37
|
-
def __init__(
|
38
|
-
self,
|
39
|
-
in_size,
|
40
|
-
out_size,
|
41
|
-
kernel_size,
|
42
|
-
stride,
|
43
|
-
padding,
|
44
|
-
activation,
|
45
|
-
bn,
|
46
|
-
init,
|
47
|
-
conv=None,
|
48
|
-
batch_norm=None,
|
49
|
-
bias=True,
|
50
|
-
preact=False,
|
51
|
-
name="",
|
52
|
-
instance_norm=False,
|
53
|
-
instance_norm_func=None
|
54
|
-
):
|
55
|
-
super().__init__()
|
56
|
-
|
57
|
-
bias = bias and (not bn)
|
58
|
-
conv_unit = conv(
|
59
|
-
in_size,
|
60
|
-
out_size,
|
61
|
-
kernel_size=kernel_size,
|
62
|
-
stride=stride,
|
63
|
-
padding=padding,
|
64
|
-
bias=bias
|
65
|
-
)
|
66
|
-
init(conv_unit.weight)
|
67
|
-
if bias:
|
68
|
-
nn.init.constant_(conv_unit.bias, 0)
|
69
|
-
|
70
|
-
if bn:
|
71
|
-
if not preact:
|
72
|
-
bn_unit = batch_norm(out_size)
|
73
|
-
else:
|
74
|
-
bn_unit = batch_norm(in_size)
|
75
|
-
if instance_norm:
|
76
|
-
if not preact:
|
77
|
-
in_unit = instance_norm_func(out_size, affine=False, track_running_stats=False)
|
78
|
-
else:
|
79
|
-
in_unit = instance_norm_func(in_size, affine=False, track_running_stats=False)
|
80
|
-
|
81
|
-
if preact:
|
82
|
-
if bn:
|
83
|
-
self.add_module(name + 'bn', bn_unit)
|
84
|
-
|
85
|
-
if activation is not None:
|
86
|
-
self.add_module(name + 'activation', activation)
|
87
|
-
|
88
|
-
if not bn and instance_norm:
|
89
|
-
self.add_module(name + 'in', in_unit)
|
90
|
-
|
91
|
-
self.add_module(name + 'conv', conv_unit)
|
92
|
-
|
93
|
-
if not preact:
|
94
|
-
if bn:
|
95
|
-
self.add_module(name + 'bn', bn_unit)
|
96
|
-
|
97
|
-
if activation is not None:
|
98
|
-
self.add_module(name + 'activation', activation)
|
99
|
-
|
100
|
-
if not bn and instance_norm:
|
101
|
-
self.add_module(name + 'in', in_unit)
|
102
|
-
|
103
|
-
|
104
|
-
class _BNBase(nn.Sequential):
|
105
|
-
|
106
|
-
def __init__(self, in_size, batch_norm=None, name=""):
|
107
|
-
super().__init__()
|
108
|
-
self.add_module(name + "bn", batch_norm(in_size))
|
109
|
-
|
110
|
-
nn.init.constant_(self[0].weight, 1.0)
|
111
|
-
nn.init.constant_(self[0].bias, 0)
|
112
|
-
|
113
|
-
|
114
|
-
class BatchNorm1d(_BNBase):
|
115
|
-
|
116
|
-
def __init__(self, in_size: int, *, name: str = ""):
|
117
|
-
super().__init__(in_size, batch_norm=nn.BatchNorm1d, name=name)
|
118
|
-
|
119
|
-
|
120
|
-
class BatchNorm2d(_BNBase):
|
121
|
-
|
122
|
-
def __init__(self, in_size: int, name: str = ""):
|
123
|
-
super().__init__(in_size, batch_norm=nn.BatchNorm2d, name=name)
|
124
|
-
|
125
|
-
|
126
|
-
class Conv1d(_ConvBase):
|
127
|
-
|
128
|
-
def __init__(
|
129
|
-
self,
|
130
|
-
in_size: int,
|
131
|
-
out_size: int,
|
132
|
-
*,
|
133
|
-
kernel_size: int = 1,
|
134
|
-
stride: int = 1,
|
135
|
-
padding: int = 0,
|
136
|
-
activation=nn.ReLU(inplace=True),
|
137
|
-
bn: bool = False,
|
138
|
-
init=nn.init.kaiming_normal_,
|
139
|
-
bias: bool = True,
|
140
|
-
preact: bool = False,
|
141
|
-
name: str = "",
|
142
|
-
instance_norm=False
|
143
|
-
):
|
144
|
-
super().__init__(
|
145
|
-
in_size,
|
146
|
-
out_size,
|
147
|
-
kernel_size,
|
148
|
-
stride,
|
149
|
-
padding,
|
150
|
-
activation,
|
151
|
-
bn,
|
152
|
-
init,
|
153
|
-
conv=nn.Conv1d,
|
154
|
-
batch_norm=BatchNorm1d,
|
155
|
-
bias=bias,
|
156
|
-
preact=preact,
|
157
|
-
name=name,
|
158
|
-
instance_norm=instance_norm,
|
159
|
-
instance_norm_func=nn.InstanceNorm1d
|
160
|
-
)
|
161
|
-
|
162
|
-
|
163
|
-
class Conv2d(_ConvBase):
|
164
|
-
|
165
|
-
def __init__(
|
166
|
-
self,
|
167
|
-
in_size: int,
|
168
|
-
out_size: int,
|
169
|
-
*,
|
170
|
-
kernel_size: Tuple[int, int] = (1, 1),
|
171
|
-
stride: Tuple[int, int] = (1, 1),
|
172
|
-
padding: Tuple[int, int] = (0, 0),
|
173
|
-
activation=nn.ReLU(inplace=True),
|
174
|
-
bn: bool = False,
|
175
|
-
init=nn.init.kaiming_normal_,
|
176
|
-
bias: bool = True,
|
177
|
-
preact: bool = False,
|
178
|
-
name: str = "",
|
179
|
-
instance_norm=False
|
180
|
-
):
|
181
|
-
super().__init__(
|
182
|
-
in_size,
|
183
|
-
out_size,
|
184
|
-
kernel_size,
|
185
|
-
stride,
|
186
|
-
padding,
|
187
|
-
activation,
|
188
|
-
bn,
|
189
|
-
init,
|
190
|
-
conv=nn.Conv2d,
|
191
|
-
batch_norm=BatchNorm2d,
|
192
|
-
bias=bias,
|
193
|
-
preact=preact,
|
194
|
-
name=name,
|
195
|
-
instance_norm=instance_norm,
|
196
|
-
instance_norm_func=nn.InstanceNorm2d
|
197
|
-
)
|
198
|
-
|
199
|
-
|
200
|
-
class FC(nn.Sequential):
|
201
|
-
|
202
|
-
def __init__(
|
203
|
-
self,
|
204
|
-
in_size: int,
|
205
|
-
out_size: int,
|
206
|
-
*,
|
207
|
-
activation=nn.ReLU(inplace=True),
|
208
|
-
bn: bool = False,
|
209
|
-
init=None,
|
210
|
-
preact: bool = False,
|
211
|
-
name: str = ""
|
212
|
-
):
|
213
|
-
super().__init__()
|
214
|
-
|
215
|
-
fc = nn.Linear(in_size, out_size, bias=not bn)
|
216
|
-
if init is not None:
|
217
|
-
init(fc.weight)
|
218
|
-
if not bn:
|
219
|
-
nn.init.constant(fc.bias, 0)
|
220
|
-
|
221
|
-
if preact:
|
222
|
-
if bn:
|
223
|
-
self.add_module(name + 'bn', BatchNorm1d(in_size))
|
224
|
-
|
225
|
-
if activation is not None:
|
226
|
-
self.add_module(name + 'activation', activation)
|
227
|
-
|
228
|
-
self.add_module(name + 'fc', fc)
|
229
|
-
|
230
|
-
if not preact:
|
231
|
-
if bn:
|
232
|
-
self.add_module(name + 'bn', BatchNorm1d(out_size))
|
233
|
-
|
234
|
-
if activation is not None:
|
235
|
-
self.add_module(name + 'activation', activation)
|
236
|
-
|
learning3d/utils/lib/setup.py
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
from setuptools import setup
|
2
|
-
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
|
3
|
-
|
4
|
-
setup(
|
5
|
-
name='pointnet2',
|
6
|
-
ext_modules=[
|
7
|
-
CUDAExtension('pointnet2_cuda', [
|
8
|
-
'src/pointnet2_api.cpp',
|
9
|
-
|
10
|
-
'src/ball_query.cpp',
|
11
|
-
'src/ball_query_gpu.cu',
|
12
|
-
'src/group_points.cpp',
|
13
|
-
'src/group_points_gpu.cu',
|
14
|
-
'src/interpolate.cpp',
|
15
|
-
'src/interpolate_gpu.cu',
|
16
|
-
'src/sampling.cpp',
|
17
|
-
'src/sampling_gpu.cu',
|
18
|
-
],
|
19
|
-
extra_compile_args={'cxx': ['-g'],
|
20
|
-
'nvcc': ['-O2']})
|
21
|
-
],
|
22
|
-
cmdclass={'build_ext': BuildExtension}
|
23
|
-
)
|
@@ -1,25 +0,0 @@
|
|
1
|
-
#include <torch/serialize/tensor.h>
|
2
|
-
#include <vector>
|
3
|
-
#include <THC/THC.h>
|
4
|
-
#include <cuda.h>
|
5
|
-
#include <cuda_runtime_api.h>
|
6
|
-
#include "ball_query_gpu.h"
|
7
|
-
|
8
|
-
extern THCState *state;
|
9
|
-
|
10
|
-
#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x, " must be a CUDAtensor ")
|
11
|
-
#define CHECK_CONTIGUOUS(x) AT_CHECK(x.is_contiguous(), #x, " must be contiguous ")
|
12
|
-
#define CHECK_INPUT(x) CHECK_CUDA(x);CHECK_CONTIGUOUS(x)
|
13
|
-
|
14
|
-
int ball_query_wrapper_fast(int b, int n, int m, float radius, int nsample,
|
15
|
-
at::Tensor new_xyz_tensor, at::Tensor xyz_tensor, at::Tensor idx_tensor) {
|
16
|
-
CHECK_INPUT(new_xyz_tensor);
|
17
|
-
CHECK_INPUT(xyz_tensor);
|
18
|
-
const float *new_xyz = new_xyz_tensor.data<float>();
|
19
|
-
const float *xyz = xyz_tensor.data<float>();
|
20
|
-
int *idx = idx_tensor.data<int>();
|
21
|
-
|
22
|
-
cudaStream_t stream = THCState_getCurrentStream(state);
|
23
|
-
ball_query_kernel_launcher_fast(b, n, m, radius, nsample, new_xyz, xyz, idx, stream);
|
24
|
-
return 1;
|
25
|
-
}
|
@@ -1,67 +0,0 @@
|
|
1
|
-
#include <math.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <stdlib.h>
|
4
|
-
|
5
|
-
#include "ball_query_gpu.h"
|
6
|
-
#include "cuda_utils.h"
|
7
|
-
|
8
|
-
|
9
|
-
__global__ void ball_query_kernel_fast(int b, int n, int m, float radius, int nsample,
|
10
|
-
const float *__restrict__ new_xyz, const float *__restrict__ xyz, int *__restrict__ idx) {
|
11
|
-
// new_xyz: (B, M, 3)
|
12
|
-
// xyz: (B, N, 3)
|
13
|
-
// output:
|
14
|
-
// idx: (B, M, nsample)
|
15
|
-
int bs_idx = blockIdx.y;
|
16
|
-
int pt_idx = blockIdx.x * blockDim.x + threadIdx.x;
|
17
|
-
if (bs_idx >= b || pt_idx >= m) return;
|
18
|
-
|
19
|
-
new_xyz += bs_idx * m * 3 + pt_idx * 3;
|
20
|
-
xyz += bs_idx * n * 3;
|
21
|
-
idx += bs_idx * m * nsample + pt_idx * nsample;
|
22
|
-
|
23
|
-
float radius2 = radius * radius;
|
24
|
-
float new_x = new_xyz[0];
|
25
|
-
float new_y = new_xyz[1];
|
26
|
-
float new_z = new_xyz[2];
|
27
|
-
|
28
|
-
int cnt = 0;
|
29
|
-
for (int k = 0; k < n; ++k) {
|
30
|
-
float x = xyz[k * 3 + 0];
|
31
|
-
float y = xyz[k * 3 + 1];
|
32
|
-
float z = xyz[k * 3 + 2];
|
33
|
-
float d2 = (new_x - x) * (new_x - x) + (new_y - y) * (new_y - y) + (new_z - z) * (new_z - z);
|
34
|
-
if (d2 < radius2){
|
35
|
-
if (cnt == 0){
|
36
|
-
for (int l = 0; l < nsample; ++l) {
|
37
|
-
idx[l] = k;
|
38
|
-
}
|
39
|
-
}
|
40
|
-
idx[cnt] = k;
|
41
|
-
++cnt;
|
42
|
-
if (cnt >= nsample) break;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
|
48
|
-
void ball_query_kernel_launcher_fast(int b, int n, int m, float radius, int nsample, \
|
49
|
-
const float *new_xyz, const float *xyz, int *idx, cudaStream_t stream) {
|
50
|
-
// new_xyz: (B, M, 3)
|
51
|
-
// xyz: (B, N, 3)
|
52
|
-
// output:
|
53
|
-
// idx: (B, M, nsample)
|
54
|
-
|
55
|
-
cudaError_t err;
|
56
|
-
|
57
|
-
dim3 blocks(DIVUP(m, THREADS_PER_BLOCK), b); // blockIdx.x(col), blockIdx.y(row)
|
58
|
-
dim3 threads(THREADS_PER_BLOCK);
|
59
|
-
|
60
|
-
ball_query_kernel_fast<<<blocks, threads, 0, stream>>>(b, n, m, radius, nsample, new_xyz, xyz, idx);
|
61
|
-
// cudaDeviceSynchronize(); // for using printf in kernel function
|
62
|
-
err = cudaGetLastError();
|
63
|
-
if (cudaSuccess != err) {
|
64
|
-
fprintf(stderr, "CUDA kernel failed : %s\n", cudaGetErrorString(err));
|
65
|
-
exit(-1);
|
66
|
-
}
|
67
|
-
}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
#ifndef _BALL_QUERY_GPU_H
|
2
|
-
#define _BALL_QUERY_GPU_H
|
3
|
-
|
4
|
-
#include <torch/serialize/tensor.h>
|
5
|
-
#include <vector>
|
6
|
-
#include <cuda.h>
|
7
|
-
#include <cuda_runtime_api.h>
|
8
|
-
|
9
|
-
int ball_query_wrapper_fast(int b, int n, int m, float radius, int nsample,
|
10
|
-
at::Tensor new_xyz_tensor, at::Tensor xyz_tensor, at::Tensor idx_tensor);
|
11
|
-
|
12
|
-
void ball_query_kernel_launcher_fast(int b, int n, int m, float radius, int nsample,
|
13
|
-
const float *xyz, const float *new_xyz, int *idx, cudaStream_t stream);
|
14
|
-
|
15
|
-
#endif
|
@@ -1,15 +0,0 @@
|
|
1
|
-
#ifndef _CUDA_UTILS_H
|
2
|
-
#define _CUDA_UTILS_H
|
3
|
-
|
4
|
-
#include <cmath>
|
5
|
-
|
6
|
-
#define TOTAL_THREADS 1024
|
7
|
-
#define THREADS_PER_BLOCK 256
|
8
|
-
#define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0))
|
9
|
-
|
10
|
-
inline int opt_n_threads(int work_size) {
|
11
|
-
const int pow_2 = std::log(static_cast<double>(work_size)) / std::log(2.0);
|
12
|
-
|
13
|
-
return max(min(1 << pow_2, TOTAL_THREADS), 1);
|
14
|
-
}
|
15
|
-
#endif
|