openpoints 0.1.0__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.
- openpoints/__init__.py +3 -0
- openpoints/cpp/__init__.py +6 -0
- openpoints/cpp/chamfer_dist/__init__.py +110 -0
- openpoints/cpp/chamfer_dist/setup.py +19 -0
- openpoints/cpp/chamfer_dist/test.py +34 -0
- openpoints/cpp/emd/__init__.py +3 -0
- openpoints/cpp/emd/emd.py +88 -0
- openpoints/cpp/emd/setup.py +27 -0
- openpoints/cpp/emd/test_emd_loss.py +45 -0
- openpoints/cpp/pointnet2_batch/__init__.py +24 -0
- openpoints/cpp/pointnet2_batch/setup.py +23 -0
- openpoints/cpp/pointops/__init__.py +0 -0
- openpoints/cpp/pointops/functions/__init__.py +0 -0
- openpoints/cpp/pointops/functions/pointops.py +314 -0
- openpoints/cpp/pointops/setup.py +37 -0
- openpoints/cpp/pointops/src/__init__.py +0 -0
- openpoints/dataset/__init__.py +10 -0
- openpoints/dataset/atom3d/__init__.py +1 -0
- openpoints/dataset/atom3d/psr.py +38 -0
- openpoints/dataset/build.py +98 -0
- openpoints/dataset/data_util.py +192 -0
- openpoints/dataset/datalist.py +67 -0
- openpoints/dataset/dataset_base.py +96 -0
- openpoints/dataset/graph_dataset/__init__.py +3 -0
- openpoints/dataset/graph_dataset/graph_dataset.py +93 -0
- openpoints/dataset/graph_dataset/stack_with_pad.py +91 -0
- openpoints/dataset/graph_dataset/structural_dataset.py +73 -0
- openpoints/dataset/graph_dataset/svd_encodings_dataset.py +110 -0
- openpoints/dataset/grid_sample.py +21 -0
- openpoints/dataset/matterport3d/__init__.py +1 -0
- openpoints/dataset/matterport3d/category_mapping.tsv +1660 -0
- openpoints/dataset/matterport3d/matterport3d.py +210 -0
- openpoints/dataset/matterport3d/matterport3d_dataprocessing.py +105 -0
- openpoints/dataset/modelnet/__init__.py +3 -0
- openpoints/dataset/modelnet/modelnet40_normal_resampled_loader.py +124 -0
- openpoints/dataset/modelnet/modelnet40_ply_2048_loader.py +160 -0
- openpoints/dataset/molhiv/__init__.py +1 -0
- openpoints/dataset/molhiv/data.py +59 -0
- openpoints/dataset/molpcba/__init__.py +1 -0
- openpoints/dataset/molpcba/data.py +59 -0
- openpoints/dataset/parsers/__init__.py +1 -0
- openpoints/dataset/parsers/class_map.py +19 -0
- openpoints/dataset/parsers/constants.py +1 -0
- openpoints/dataset/parsers/parser.py +17 -0
- openpoints/dataset/parsers/parser_factory.py +29 -0
- openpoints/dataset/parsers/parser_image_folder.py +69 -0
- openpoints/dataset/parsers/parser_image_in_tar.py +222 -0
- openpoints/dataset/parsers/parser_image_tar.py +72 -0
- openpoints/dataset/parsers/parser_tfds.py +297 -0
- openpoints/dataset/pcqm4m/__init__.py +1 -0
- openpoints/dataset/pcqm4m/data.py +62 -0
- openpoints/dataset/pcqm4mv2/__init__.py +1 -0
- openpoints/dataset/pcqm4mv2/data.py +87 -0
- openpoints/dataset/s3dis/__init__.py +2 -0
- openpoints/dataset/s3dis/s3dis.py +156 -0
- openpoints/dataset/s3dis/s3dis_block.py +96 -0
- openpoints/dataset/s3dis/s3dis_sphere.py +349 -0
- openpoints/dataset/scannetv2/__init__.py +1 -0
- openpoints/dataset/scannetv2/scannet.py +176 -0
- openpoints/dataset/scanobjectnn/__init__.py +3 -0
- openpoints/dataset/scanobjectnn/scanobjectnn.py +110 -0
- openpoints/dataset/semantic_kitti/__init__.py +1 -0
- openpoints/dataset/semantic_kitti/helper_tool.py +286 -0
- openpoints/dataset/semantic_kitti/label_mapping.yaml +211 -0
- openpoints/dataset/semantic_kitti/semantickitti.py +229 -0
- openpoints/dataset/semantic_kitti/utils/meta/anno_paths.txt +272 -0
- openpoints/dataset/semantic_kitti/utils/meta/class_names.txt +13 -0
- openpoints/dataset/semantic_kitti/utils/semantic-kitti.yaml +211 -0
- openpoints/dataset/shapenet/__init__.py +1 -0
- openpoints/dataset/shapenet/shapenet55.py +76 -0
- openpoints/dataset/shapenet/shapenetpart.py +121 -0
- openpoints/dataset/shapenetpart/__init__.py +1 -0
- openpoints/dataset/shapenetpart/shapenet55.py +75 -0
- openpoints/dataset/shapenetpart/shapenetpart.py +388 -0
- openpoints/dataset/vis2d.py +17 -0
- openpoints/dataset/vis3d.py +153 -0
- openpoints/loss/__init__.py +3 -0
- openpoints/loss/build.py +281 -0
- openpoints/loss/cross_entropy.py +38 -0
- openpoints/loss/distill_loss.py +76 -0
- openpoints/models/__init__.py +10 -0
- openpoints/models/backbone/Stratified_transformer.py +558 -0
- openpoints/models/backbone/__init__.py +11 -0
- openpoints/models/backbone/baafnet.py +527 -0
- openpoints/models/backbone/ball_dgcnn.py +123 -0
- openpoints/models/backbone/curvenet.py +793 -0
- openpoints/models/backbone/debug_invvit.py +114 -0
- openpoints/models/backbone/deepgcn.py +143 -0
- openpoints/models/backbone/dgcnn.py +119 -0
- openpoints/models/backbone/graphvit3d.py +134 -0
- openpoints/models/backbone/grouppointnet.py +100 -0
- openpoints/models/backbone/pct.py +163 -0
- openpoints/models/backbone/pointmlp.py +417 -0
- openpoints/models/backbone/pointnet.py +199 -0
- openpoints/models/backbone/pointnetv2.py +511 -0
- openpoints/models/backbone/pointnext.py +663 -0
- openpoints/models/backbone/pointnextPyG.py +555 -0
- openpoints/models/backbone/pointtransformer.py +293 -0
- openpoints/models/backbone/pointvector.py +853 -0
- openpoints/models/backbone/pointvit.py +392 -0
- openpoints/models/backbone/pointvit_inv.py +942 -0
- openpoints/models/backbone/pointvit_inv_old.py +784 -0
- openpoints/models/backbone/randlenet.py +318 -0
- openpoints/models/backbone/resnet.py +342 -0
- openpoints/models/backbone/simpleview.py +153 -0
- openpoints/models/backbone/simpleview_util.py +292 -0
- openpoints/models/build.py +13 -0
- openpoints/models/classification/__init__.py +5 -0
- openpoints/models/classification/cls_base.py +136 -0
- openpoints/models/classification/point_bert.py +154 -0
- openpoints/models/layers/__init__.py +14 -0
- openpoints/models/layers/activation.py +57 -0
- openpoints/models/layers/attention.py +103 -0
- openpoints/models/layers/conv.py +167 -0
- openpoints/models/layers/drop.py +164 -0
- openpoints/models/layers/graph_conv.py +122 -0
- openpoints/models/layers/group.py +415 -0
- openpoints/models/layers/group_embed.py +286 -0
- openpoints/models/layers/helpers.py +43 -0
- openpoints/models/layers/kmeans.py +119 -0
- openpoints/models/layers/knn.py +110 -0
- openpoints/models/layers/local_aggregation.py +286 -0
- openpoints/models/layers/mlp.py +129 -0
- openpoints/models/layers/norm.py +106 -0
- openpoints/models/layers/padding.py +56 -0
- openpoints/models/layers/patch_embed.py +37 -0
- openpoints/models/layers/registry.py +168 -0
- openpoints/models/layers/subsample.py +185 -0
- openpoints/models/layers/upsampling.py +106 -0
- openpoints/models/layers/weight_init.py +89 -0
- openpoints/models/reconstruction/__init__.py +8 -0
- openpoints/models/reconstruction/base_recontruct.py +216 -0
- openpoints/models/reconstruction/maskedpoint.py +116 -0
- openpoints/models/reconstruction/maskedpointgroup.py +168 -0
- openpoints/models/reconstruction/maskedpointvit.py +253 -0
- openpoints/models/reconstruction/nodeshuffle.py +11 -0
- openpoints/models/registry.py +149 -0
- openpoints/models/segmentation/__init__.py +6 -0
- openpoints/models/segmentation/base_seg.py +278 -0
- openpoints/models/segmentation/vit_seg.py +126 -0
- openpoints/optim/__init__.py +15 -0
- openpoints/optim/adabelief.py +201 -0
- openpoints/optim/adafactor.py +167 -0
- openpoints/optim/adahessian.py +156 -0
- openpoints/optim/adamp.py +105 -0
- openpoints/optim/adamw.py +122 -0
- openpoints/optim/lamb.py +192 -0
- openpoints/optim/lars.py +135 -0
- openpoints/optim/lookahead.py +61 -0
- openpoints/optim/madgrad.py +184 -0
- openpoints/optim/nadam.py +92 -0
- openpoints/optim/nvnovograd.py +120 -0
- openpoints/optim/optim_factory.py +306 -0
- openpoints/optim/radam.py +89 -0
- openpoints/optim/rmsprop_tf.py +139 -0
- openpoints/optim/sgdp.py +70 -0
- openpoints/scheduler/__init__.py +8 -0
- openpoints/scheduler/cosine_lr.py +124 -0
- openpoints/scheduler/multistep_lr.py +65 -0
- openpoints/scheduler/plateau_lr.py +113 -0
- openpoints/scheduler/poly_lr.py +116 -0
- openpoints/scheduler/scheduler.py +110 -0
- openpoints/scheduler/scheduler_factory.py +118 -0
- openpoints/scheduler/step_lr.py +65 -0
- openpoints/scheduler/tanh_lr.py +117 -0
- openpoints/transforms/__init__.py +7 -0
- openpoints/transforms/point_transform_cpu.py +332 -0
- openpoints/transforms/point_transformer_gpu.py +764 -0
- openpoints/transforms/transforms_factory.py +60 -0
- openpoints/utils/__init__.py +8 -0
- openpoints/utils/ckpt_util.py +438 -0
- openpoints/utils/config.py +113 -0
- openpoints/utils/dist_utils.py +54 -0
- openpoints/utils/logger.py +170 -0
- openpoints/utils/metrics.py +311 -0
- openpoints/utils/random.py +16 -0
- openpoints/utils/registry.py +294 -0
- openpoints/utils/str2bool.py +11 -0
- openpoints/utils/wandb.py +88 -0
- openpoints-0.1.0.dist-info/METADATA +150 -0
- openpoints-0.1.0.dist-info/RECORD +184 -0
- openpoints-0.1.0.dist-info/WHEEL +5 -0
- openpoints-0.1.0.dist-info/licenses/LICENSE +21 -0
- openpoints-0.1.0.dist-info/top_level.txt +1 -0
openpoints/__init__.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# @Author: Thibault GROUEIX
|
|
3
|
+
# @Date: 2019-08-07 20:54:24
|
|
4
|
+
# @Last Modified by: Haozhe Xie
|
|
5
|
+
# @Last Modified time: 2019-12-18 15:06:25
|
|
6
|
+
# @Email: cshzxie@gmail.com
|
|
7
|
+
"""Chamfer distance CUDA extension loader.
|
|
8
|
+
|
|
9
|
+
The PyPI package ships Python sources and keeps compiled CUDA extensions
|
|
10
|
+
optional. Importing this module should not fail on machines where the
|
|
11
|
+
``chamfer`` extension has not been built yet; users only need the extension
|
|
12
|
+
when they instantiate/use Chamfer distance losses.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import torch
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import chamfer as _chamfer
|
|
19
|
+
except ImportError as exc:
|
|
20
|
+
_chamfer = None
|
|
21
|
+
_chamfer_import_error = exc
|
|
22
|
+
else:
|
|
23
|
+
_chamfer_import_error = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _require_chamfer():
|
|
27
|
+
if _chamfer is None:
|
|
28
|
+
raise ImportError(
|
|
29
|
+
"The `chamfer` CUDA extension is not installed. Build OpenPoints "
|
|
30
|
+
"CUDA ops from source first, e.g. `cd cpp/chamfer_dist && "
|
|
31
|
+
"python setup.py install`, or install a wheel that includes the "
|
|
32
|
+
"compiled extension."
|
|
33
|
+
) from _chamfer_import_error
|
|
34
|
+
return _chamfer
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ChamferFunction(torch.autograd.Function):
|
|
38
|
+
@staticmethod
|
|
39
|
+
def forward(ctx, xyz1, xyz2):
|
|
40
|
+
chamfer = _require_chamfer()
|
|
41
|
+
dist1, dist2, idx1, idx2 = chamfer.forward(xyz1, xyz2)
|
|
42
|
+
ctx.save_for_backward(xyz1, xyz2, idx1, idx2)
|
|
43
|
+
|
|
44
|
+
return dist1, dist2
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def backward(ctx, grad_dist1, grad_dist2):
|
|
48
|
+
chamfer = _require_chamfer()
|
|
49
|
+
xyz1, xyz2, idx1, idx2 = ctx.saved_tensors
|
|
50
|
+
grad_xyz1, grad_xyz2 = chamfer.backward(xyz1, xyz2, idx1, idx2, grad_dist1, grad_dist2)
|
|
51
|
+
return grad_xyz1, grad_xyz2
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ChamferDistanceL2(torch.nn.Module):
|
|
55
|
+
f''' Chamder Distance L2
|
|
56
|
+
'''
|
|
57
|
+
def __init__(self, ignore_zeros=False):
|
|
58
|
+
super().__init__()
|
|
59
|
+
self.ignore_zeros = ignore_zeros
|
|
60
|
+
|
|
61
|
+
def forward(self, xyz1, xyz2):
|
|
62
|
+
batch_size = xyz1.size(0)
|
|
63
|
+
if batch_size == 1 and self.ignore_zeros:
|
|
64
|
+
non_zeros1 = torch.sum(xyz1, dim=2).ne(0)
|
|
65
|
+
non_zeros2 = torch.sum(xyz2, dim=2).ne(0)
|
|
66
|
+
xyz1 = xyz1[non_zeros1].unsqueeze(dim=0)
|
|
67
|
+
xyz2 = xyz2[non_zeros2].unsqueeze(dim=0)
|
|
68
|
+
|
|
69
|
+
dist1, dist2 = ChamferFunction.apply(xyz1, xyz2)
|
|
70
|
+
return torch.mean(dist1) + torch.mean(dist2)
|
|
71
|
+
|
|
72
|
+
class ChamferDistanceL2_split(torch.nn.Module):
|
|
73
|
+
f''' Chamder Distance L2
|
|
74
|
+
'''
|
|
75
|
+
def __init__(self, ignore_zeros=False):
|
|
76
|
+
super().__init__()
|
|
77
|
+
self.ignore_zeros = ignore_zeros
|
|
78
|
+
|
|
79
|
+
def forward(self, xyz1, xyz2):
|
|
80
|
+
batch_size = xyz1.size(0)
|
|
81
|
+
if batch_size == 1 and self.ignore_zeros:
|
|
82
|
+
non_zeros1 = torch.sum(xyz1, dim=2).ne(0)
|
|
83
|
+
non_zeros2 = torch.sum(xyz2, dim=2).ne(0)
|
|
84
|
+
xyz1 = xyz1[non_zeros1].unsqueeze(dim=0)
|
|
85
|
+
xyz2 = xyz2[non_zeros2].unsqueeze(dim=0)
|
|
86
|
+
|
|
87
|
+
dist1, dist2 = ChamferFunction.apply(xyz1, xyz2)
|
|
88
|
+
return torch.mean(dist1), torch.mean(dist2)
|
|
89
|
+
|
|
90
|
+
class ChamferDistanceL1(torch.nn.Module):
|
|
91
|
+
f''' Chamder Distance L1
|
|
92
|
+
'''
|
|
93
|
+
def __init__(self, ignore_zeros=False):
|
|
94
|
+
super().__init__()
|
|
95
|
+
self.ignore_zeros = ignore_zeros
|
|
96
|
+
|
|
97
|
+
def forward(self, xyz1, xyz2):
|
|
98
|
+
batch_size = xyz1.size(0)
|
|
99
|
+
if batch_size == 1 and self.ignore_zeros:
|
|
100
|
+
non_zeros1 = torch.sum(xyz1, dim=2).ne(0)
|
|
101
|
+
non_zeros2 = torch.sum(xyz2, dim=2).ne(0)
|
|
102
|
+
xyz1 = xyz1[non_zeros1].unsqueeze(dim=0)
|
|
103
|
+
xyz2 = xyz2[non_zeros2].unsqueeze(dim=0)
|
|
104
|
+
|
|
105
|
+
dist1, dist2 = ChamferFunction.apply(xyz1, xyz2)
|
|
106
|
+
# import pdb
|
|
107
|
+
# pdb.set_trace()
|
|
108
|
+
dist1 = torch.sqrt(dist1)
|
|
109
|
+
dist2 = torch.sqrt(dist2)
|
|
110
|
+
return (torch.mean(dist1) + torch.mean(dist2))/2
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# @Author: Haozhe Xie
|
|
3
|
+
# @Date: 2019-08-07 20:54:24
|
|
4
|
+
# @Last Modified by: Haozhe Xie
|
|
5
|
+
# @Last Modified time: 2019-12-10 10:04:25
|
|
6
|
+
# @Email: cshzxie@gmail.com
|
|
7
|
+
|
|
8
|
+
from setuptools import setup
|
|
9
|
+
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
|
|
10
|
+
|
|
11
|
+
setup(name='chamfer',
|
|
12
|
+
version='2.0.0',
|
|
13
|
+
ext_modules=[
|
|
14
|
+
CUDAExtension('chamfer', [
|
|
15
|
+
'chamfer_cuda.cpp',
|
|
16
|
+
'chamfer.cu',
|
|
17
|
+
]),
|
|
18
|
+
],
|
|
19
|
+
cmdclass={'build_ext': BuildExtension})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# @Author: Haozhe Xie
|
|
3
|
+
# @Date: 2019-12-10 10:38:01
|
|
4
|
+
# @Last Modified by: Haozhe Xie
|
|
5
|
+
# @Last Modified time: 2019-12-26 14:21:36
|
|
6
|
+
# @Email: cshzxie@gmail.com
|
|
7
|
+
#
|
|
8
|
+
# Note:
|
|
9
|
+
# - Replace float -> double, kFloat -> kDouble in chamfer.cu
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import torch
|
|
14
|
+
import unittest
|
|
15
|
+
|
|
16
|
+
from torch.autograd import gradcheck
|
|
17
|
+
|
|
18
|
+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)))
|
|
19
|
+
from openpoints.cpp.chamfer_dist import ChamferFunction
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChamferDistanceTestCase(unittest.TestCase):
|
|
23
|
+
def test_chamfer_dist(self):
|
|
24
|
+
x = torch.rand(4, 64, 3).float()
|
|
25
|
+
y = torch.rand(4, 128, 3).float()
|
|
26
|
+
x.requires_grad = True
|
|
27
|
+
y.requires_grad = True
|
|
28
|
+
print(gradcheck(ChamferFunction.apply, [x.cuda(), y.cuda()]))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
x = torch.rand(32, 128, 3)
|
|
33
|
+
y = torch.rand(32, 128, 3)
|
|
34
|
+
# print()
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
import emd_cuda as _emd_cuda
|
|
5
|
+
except ImportError as exc:
|
|
6
|
+
_emd_cuda = None
|
|
7
|
+
_emd_cuda_import_error = exc
|
|
8
|
+
else:
|
|
9
|
+
_emd_cuda_import_error = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _require_emd_cuda():
|
|
13
|
+
if _emd_cuda is None:
|
|
14
|
+
raise ImportError(
|
|
15
|
+
"The `emd_cuda` extension is not installed. Build OpenPoints CUDA "
|
|
16
|
+
"ops from source first, e.g. `cd cpp/emd && python setup.py "
|
|
17
|
+
"install`, or install a wheel that includes the compiled extension."
|
|
18
|
+
) from _emd_cuda_import_error
|
|
19
|
+
return _emd_cuda
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class EarthMoverDistanceFunction(torch.autograd.Function):
|
|
23
|
+
@staticmethod
|
|
24
|
+
def forward(ctx, xyz1, xyz2):
|
|
25
|
+
emd_cuda = _require_emd_cuda()
|
|
26
|
+
xyz1 = xyz1.contiguous()
|
|
27
|
+
xyz2 = xyz2.contiguous()
|
|
28
|
+
assert xyz1.is_cuda and xyz2.is_cuda, "Only support cuda currently."
|
|
29
|
+
match = emd_cuda.approxmatch_forward(xyz1, xyz2)
|
|
30
|
+
cost = emd_cuda.matchcost_forward(xyz1, xyz2, match)
|
|
31
|
+
ctx.save_for_backward(xyz1, xyz2, match)
|
|
32
|
+
return cost
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def backward(ctx, grad_cost):
|
|
36
|
+
emd_cuda = _require_emd_cuda()
|
|
37
|
+
xyz1, xyz2, match = ctx.saved_tensors
|
|
38
|
+
grad_cost = grad_cost.contiguous()
|
|
39
|
+
grad_xyz1, grad_xyz2 = emd_cuda.matchcost_backward(grad_cost, xyz1, xyz2, match)
|
|
40
|
+
return grad_xyz1, grad_xyz2
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class earth_mover_distance(torch.nn.Module):
|
|
44
|
+
f''' emd
|
|
45
|
+
'''
|
|
46
|
+
def __init__(self):
|
|
47
|
+
super().__init__()
|
|
48
|
+
|
|
49
|
+
def forward(self, xyz1, xyz2, transpose=False):
|
|
50
|
+
"""Earth Mover Distance (Approx)
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
xyz1 (torch.Tensor): (b, n1, 3)
|
|
54
|
+
xyz2 (torch.Tensor): (b, n2, 3)
|
|
55
|
+
transpose (bool): whether to transpose inputs as it might be BCN format.
|
|
56
|
+
Extensions only support BNC format.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
cost (torch.Tensor): (b)
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
cost = EarthMoverDistanceFunction.apply(xyz1, xyz2)
|
|
64
|
+
cost = cost / xyz1.size(1)
|
|
65
|
+
|
|
66
|
+
return cost.mean()
|
|
67
|
+
# def earth_mover_distance(xyz1, xyz2, transpose=True):
|
|
68
|
+
# """Earth Mover Distance (Approx)
|
|
69
|
+
|
|
70
|
+
# Args:
|
|
71
|
+
# xyz1 (torch.Tensor): (b, 3, n1)
|
|
72
|
+
# xyz2 (torch.Tensor): (b, 3, n1)
|
|
73
|
+
# transpose (bool): whether to transpose inputs as it might be BCN format.
|
|
74
|
+
# Extensions only support BNC format.
|
|
75
|
+
|
|
76
|
+
# Returns:
|
|
77
|
+
# cost (torch.Tensor): (b)
|
|
78
|
+
|
|
79
|
+
# """
|
|
80
|
+
# if xyz1.dim() == 2:
|
|
81
|
+
# xyz1 = xyz1.unsqueeze(0)
|
|
82
|
+
# if xyz2.dim() == 2:
|
|
83
|
+
# xyz2 = xyz2.unsqueeze(0)
|
|
84
|
+
# if transpose:
|
|
85
|
+
# xyz1 = xyz1.transpose(1, 2)
|
|
86
|
+
# xyz2 = xyz2.transpose(1, 2)
|
|
87
|
+
# cost = EarthMoverDistanceFunction.apply(xyz1, xyz2)
|
|
88
|
+
# return cost
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Setup extension
|
|
2
|
+
|
|
3
|
+
Notes:
|
|
4
|
+
If extra_compile_args is provided, you need to provide different instances for different extensions.
|
|
5
|
+
Refer to https://github.com/pytorch/pytorch/issues/20169
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from setuptools import setup
|
|
10
|
+
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
setup(
|
|
14
|
+
name='emd_ext',
|
|
15
|
+
ext_modules=[
|
|
16
|
+
CUDAExtension(
|
|
17
|
+
name='emd_cuda',
|
|
18
|
+
sources=[
|
|
19
|
+
'cuda/emd.cpp',
|
|
20
|
+
'cuda/emd_kernel.cu',
|
|
21
|
+
],
|
|
22
|
+
extra_compile_args={'cxx': ['-g'], 'nvcc': ['-O2']}
|
|
23
|
+
),
|
|
24
|
+
],
|
|
25
|
+
cmdclass={
|
|
26
|
+
'build_ext': BuildExtension
|
|
27
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import numpy as np
|
|
3
|
+
import time
|
|
4
|
+
from emd import earth_mover_distance
|
|
5
|
+
|
|
6
|
+
# gt
|
|
7
|
+
p1 = torch.from_numpy(np.array([[[1.7, -0.1, 0.1], [0.1, 1.2, 0.3]]], dtype=np.float32)).cuda()
|
|
8
|
+
p1 = p1.repeat(3, 1, 1)
|
|
9
|
+
p2 = torch.from_numpy(np.array([[[0.3, 1.8, 0.2], [1.2, -0.2, 0.3]]], dtype=np.float32)).cuda()
|
|
10
|
+
p2 = p2.repeat(3, 1, 1)
|
|
11
|
+
print(p1)
|
|
12
|
+
print(p2)
|
|
13
|
+
print(p1.shape)
|
|
14
|
+
p1.requires_grad = True
|
|
15
|
+
p2.requires_grad = True
|
|
16
|
+
|
|
17
|
+
gt_dist = (((p1[0, 0] - p2[0, 1])**2).sum() + ((p1[0, 1] - p2[0, 0])**2).sum()) / 2 + \
|
|
18
|
+
(((p1[1, 0] - p2[1, 1])**2).sum() + ((p1[1, 1] - p2[1, 0])**2).sum()) * 2 + \
|
|
19
|
+
(((p1[2, 0] - p2[2, 1])**2).sum() + ((p1[2, 1] - p2[2, 0])**2).sum()) / 3
|
|
20
|
+
print('gt_dist: ', gt_dist)
|
|
21
|
+
|
|
22
|
+
gt_dist.backward()
|
|
23
|
+
print(p1.grad)
|
|
24
|
+
print(p2.grad)
|
|
25
|
+
|
|
26
|
+
# emd
|
|
27
|
+
p1 = torch.from_numpy(np.array([[[1.7, -0.1, 0.1], [0.1, 1.2, 0.3]]], dtype=np.float32)).cuda()
|
|
28
|
+
p1 = p1.repeat(3, 1, 1)
|
|
29
|
+
p2 = torch.from_numpy(np.array([[[0.3, 1.8, 0.2], [1.2, -0.2, 0.3]]], dtype=np.float32)).cuda()
|
|
30
|
+
p2 = p2.repeat(3, 1, 1)
|
|
31
|
+
print(p1)
|
|
32
|
+
print(p2)
|
|
33
|
+
p1.requires_grad = True
|
|
34
|
+
p2.requires_grad = True
|
|
35
|
+
|
|
36
|
+
d = earth_mover_distance(p1, p2, transpose=False)
|
|
37
|
+
print(d)
|
|
38
|
+
|
|
39
|
+
loss = d[0] / 2 + d[1] * 2 + d[2] / 3
|
|
40
|
+
print(loss)
|
|
41
|
+
|
|
42
|
+
loss.backward()
|
|
43
|
+
print(p1.grad)
|
|
44
|
+
print(p2.grad)
|
|
45
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""pointnet2_batch CUDA extension loader.
|
|
2
|
+
|
|
3
|
+
The PyPI wheel ships Python sources only. Build this extension from
|
|
4
|
+
``cpp/pointnet2_batch`` for full CUDA training/evaluation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class _MissingCudaExtension:
|
|
9
|
+
def __init__(self, module_name, error):
|
|
10
|
+
self.module_name = module_name
|
|
11
|
+
self.error = error
|
|
12
|
+
|
|
13
|
+
def __getattr__(self, name):
|
|
14
|
+
raise ImportError(
|
|
15
|
+
f"{self.module_name} is not installed. Build OpenPoints CUDA ops from "
|
|
16
|
+
"source first, e.g. `cd cpp/pointnet2_batch && python setup.py install`, "
|
|
17
|
+
"or install a wheel that includes the compiled CUDA extension."
|
|
18
|
+
) from self.error
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import pointnet2_batch_cuda as pointnet2_cuda
|
|
23
|
+
except ImportError as exc:
|
|
24
|
+
pointnet2_cuda = _MissingCudaExtension("pointnet2_batch_cuda", exc)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from setuptools import setup
|
|
2
|
+
from torch.utils.cpp_extension import BuildExtension, CUDAExtension
|
|
3
|
+
|
|
4
|
+
setup(
|
|
5
|
+
name='pointnet2_cuda',
|
|
6
|
+
ext_modules=[
|
|
7
|
+
CUDAExtension('pointnet2_batch_cuda', [
|
|
8
|
+
'src/pointnet2_api.cpp',
|
|
9
|
+
'src/ball_query.cpp',
|
|
10
|
+
'src/ball_query_gpu.cu',
|
|
11
|
+
'src/group_points.cpp',
|
|
12
|
+
'src/group_points_gpu.cu',
|
|
13
|
+
'src/interpolate.cpp',
|
|
14
|
+
'src/interpolate_gpu.cu',
|
|
15
|
+
'src/sampling.cpp',
|
|
16
|
+
'src/sampling_gpu.cu',
|
|
17
|
+
],
|
|
18
|
+
extra_compile_args={'cxx': ['-g'],
|
|
19
|
+
'nvcc': ['-O2']})
|
|
20
|
+
],
|
|
21
|
+
cmdclass={'build_ext': BuildExtension}
|
|
22
|
+
)
|
|
23
|
+
|
|
File without changes
|
|
File without changes
|