learning3d 0.1.0__py3-none-any.whl → 0.2.1__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.
Files changed (87) hide show
  1. {learning3d/data_utils → data_utils}/dataloaders.py +16 -14
  2. examples/test_curvenet.py +118 -0
  3. {learning3d/examples → examples}/test_dcp.py +3 -5
  4. {learning3d/examples → examples}/test_deepgmr.py +3 -5
  5. {learning3d/examples → examples}/test_masknet.py +1 -3
  6. {learning3d/examples → examples}/test_masknet2.py +1 -3
  7. {learning3d/examples → examples}/test_pcn.py +2 -4
  8. {learning3d/examples → examples}/test_pcrnet.py +1 -3
  9. {learning3d/examples → examples}/test_pnlk.py +1 -3
  10. {learning3d/examples → examples}/test_pointconv.py +1 -3
  11. {learning3d/examples → examples}/test_pointnet.py +1 -3
  12. {learning3d/examples → examples}/test_prnet.py +3 -5
  13. {learning3d/examples → examples}/test_rpmnet.py +1 -3
  14. {learning3d/examples → examples}/train_PointNetLK.py +2 -4
  15. {learning3d/examples → examples}/train_dcp.py +2 -4
  16. {learning3d/examples → examples}/train_deepgmr.py +2 -4
  17. {learning3d/examples → examples}/train_masknet.py +2 -4
  18. {learning3d/examples → examples}/train_pcn.py +2 -4
  19. {learning3d/examples → examples}/train_pcrnet.py +2 -4
  20. {learning3d/examples → examples}/train_pointconv.py +2 -4
  21. {learning3d/examples → examples}/train_pointnet.py +2 -4
  22. {learning3d/examples → examples}/train_prnet.py +2 -4
  23. {learning3d/examples → examples}/train_rpmnet.py +2 -4
  24. {learning3d-0.1.0.dist-info → learning3d-0.2.1.dist-info}/METADATA +57 -12
  25. learning3d-0.2.1.dist-info/RECORD +70 -0
  26. {learning3d-0.1.0.dist-info → learning3d-0.2.1.dist-info}/WHEEL +1 -1
  27. learning3d-0.2.1.dist-info/top_level.txt +6 -0
  28. {learning3d/models → models}/__init__.py +7 -1
  29. models/curvenet.py +130 -0
  30. {learning3d/models → models}/dgcnn.py +1 -35
  31. {learning3d/models → models}/prnet.py +5 -39
  32. utils/__init__.py +23 -0
  33. utils/curvenet_util.py +540 -0
  34. utils/model_common_utils.py +156 -0
  35. learning3d/losses/cuda/chamfer_distance/__init__.py +0 -1
  36. learning3d/losses/cuda/chamfer_distance/chamfer_distance.cpp +0 -185
  37. learning3d/losses/cuda/chamfer_distance/chamfer_distance.cu +0 -209
  38. learning3d/losses/cuda/chamfer_distance/chamfer_distance.py +0 -66
  39. learning3d/losses/cuda/emd_torch/pkg/emd_loss_layer.py +0 -41
  40. learning3d/losses/cuda/emd_torch/pkg/include/cuda/emd.cuh +0 -347
  41. learning3d/losses/cuda/emd_torch/pkg/include/cuda_helper.h +0 -18
  42. learning3d/losses/cuda/emd_torch/pkg/include/emd.h +0 -54
  43. learning3d/losses/cuda/emd_torch/pkg/layer/__init__.py +0 -1
  44. learning3d/losses/cuda/emd_torch/pkg/layer/emd_loss_layer.py +0 -40
  45. learning3d/losses/cuda/emd_torch/pkg/src/cuda/emd.cu +0 -70
  46. learning3d/losses/cuda/emd_torch/pkg/src/emd.cpp +0 -1
  47. learning3d/losses/cuda/emd_torch/setup.py +0 -29
  48. learning3d/ops/__init__.py +0 -0
  49. learning3d/utils/__init__.py +0 -4
  50. learning3d-0.1.0.dist-info/RECORD +0 -80
  51. learning3d-0.1.0.dist-info/top_level.txt +0 -1
  52. {learning3d/data_utils → data_utils}/__init__.py +0 -0
  53. {learning3d/data_utils → data_utils}/user_data.py +0 -0
  54. {learning3d-0.1.0.dist-info → learning3d-0.2.1.dist-info}/LICENSE +0 -0
  55. {learning3d/losses → losses}/__init__.py +0 -0
  56. {learning3d/losses → losses}/chamfer_distance.py +0 -0
  57. {learning3d/losses → losses}/classification.py +0 -0
  58. {learning3d/losses → losses}/correspondence_loss.py +0 -0
  59. {learning3d/losses → losses}/emd.py +0 -0
  60. {learning3d/losses → losses}/frobenius_norm.py +0 -0
  61. {learning3d/losses → losses}/rmse_features.py +0 -0
  62. {learning3d/models → models}/classifier.py +0 -0
  63. {learning3d/models → models}/dcp.py +0 -0
  64. {learning3d/models → models}/deepgmr.py +0 -0
  65. {learning3d/models → models}/masknet.py +0 -0
  66. {learning3d/models → models}/masknet2.py +0 -0
  67. {learning3d/models → models}/pcn.py +0 -0
  68. {learning3d/models → models}/pcrnet.py +0 -0
  69. {learning3d/models → models}/pointconv.py +0 -0
  70. {learning3d/models → models}/pointnet.py +0 -0
  71. {learning3d/models → models}/pointnetlk.py +0 -0
  72. {learning3d/models → models}/pooling.py +0 -0
  73. {learning3d/models → models}/ppfnet.py +0 -0
  74. {learning3d/models → models}/rpmnet.py +0 -0
  75. {learning3d/models → models}/segmentation.py +0 -0
  76. {learning3d → ops}/__init__.py +0 -0
  77. {learning3d/ops → ops}/data_utils.py +0 -0
  78. {learning3d/ops → ops}/invmat.py +0 -0
  79. {learning3d/ops → ops}/quaternion.py +0 -0
  80. {learning3d/ops → ops}/se3.py +0 -0
  81. {learning3d/ops → ops}/sinc.py +0 -0
  82. {learning3d/ops → ops}/so3.py +0 -0
  83. {learning3d/ops → ops}/transform_functions.py +0 -0
  84. {learning3d/utils → utils}/pointconv_util.py +0 -0
  85. {learning3d/utils → utils}/ppfnet_util.py +0 -0
  86. {learning3d/utils → utils}/svd.py +0 -0
  87. {learning3d/utils → utils}/transformer.py +0 -0
@@ -1,185 +0,0 @@
1
- #include <torch/torch.h>
2
-
3
- // CUDA forward declarations
4
- int ChamferDistanceKernelLauncher(
5
- const int b, const int n,
6
- const float* xyz,
7
- const int m,
8
- const float* xyz2,
9
- float* result,
10
- int* result_i,
11
- float* result2,
12
- int* result2_i);
13
-
14
- int ChamferDistanceGradKernelLauncher(
15
- const int b, const int n,
16
- const float* xyz1,
17
- const int m,
18
- const float* xyz2,
19
- const float* grad_dist1,
20
- const int* idx1,
21
- const float* grad_dist2,
22
- const int* idx2,
23
- float* grad_xyz1,
24
- float* grad_xyz2);
25
-
26
-
27
- void chamfer_distance_forward_cuda(
28
- const at::Tensor xyz1,
29
- const at::Tensor xyz2,
30
- const at::Tensor dist1,
31
- const at::Tensor dist2,
32
- const at::Tensor idx1,
33
- const at::Tensor idx2)
34
- {
35
- ChamferDistanceKernelLauncher(xyz1.size(0), xyz1.size(1), xyz1.data<float>(),
36
- xyz2.size(1), xyz2.data<float>(),
37
- dist1.data<float>(), idx1.data<int>(),
38
- dist2.data<float>(), idx2.data<int>());
39
- }
40
-
41
- void chamfer_distance_backward_cuda(
42
- const at::Tensor xyz1,
43
- const at::Tensor xyz2,
44
- at::Tensor gradxyz1,
45
- at::Tensor gradxyz2,
46
- at::Tensor graddist1,
47
- at::Tensor graddist2,
48
- at::Tensor idx1,
49
- at::Tensor idx2)
50
- {
51
- ChamferDistanceGradKernelLauncher(xyz1.size(0), xyz1.size(1), xyz1.data<float>(),
52
- xyz2.size(1), xyz2.data<float>(),
53
- graddist1.data<float>(), idx1.data<int>(),
54
- graddist2.data<float>(), idx2.data<int>(),
55
- gradxyz1.data<float>(), gradxyz2.data<float>());
56
- }
57
-
58
-
59
- void nnsearch(
60
- const int b, const int n, const int m,
61
- const float* xyz1,
62
- const float* xyz2,
63
- float* dist,
64
- int* idx)
65
- {
66
- for (int i = 0; i < b; i++) {
67
- for (int j = 0; j < n; j++) {
68
- const float x1 = xyz1[(i*n+j)*3+0];
69
- const float y1 = xyz1[(i*n+j)*3+1];
70
- const float z1 = xyz1[(i*n+j)*3+2];
71
- double best = 0;
72
- int besti = 0;
73
- for (int k = 0; k < m; k++) {
74
- const float x2 = xyz2[(i*m+k)*3+0] - x1;
75
- const float y2 = xyz2[(i*m+k)*3+1] - y1;
76
- const float z2 = xyz2[(i*m+k)*3+2] - z1;
77
- const double d=x2*x2+y2*y2+z2*z2;
78
- if (k==0 || d < best){
79
- best = d;
80
- besti = k;
81
- }
82
- }
83
- dist[i*n+j] = best;
84
- idx[i*n+j] = besti;
85
- }
86
- }
87
- }
88
-
89
-
90
- void chamfer_distance_forward(
91
- const at::Tensor xyz1,
92
- const at::Tensor xyz2,
93
- const at::Tensor dist1,
94
- const at::Tensor dist2,
95
- const at::Tensor idx1,
96
- const at::Tensor idx2)
97
- {
98
- const int batchsize = xyz1.size(0);
99
- const int n = xyz1.size(1);
100
- const int m = xyz2.size(1);
101
-
102
- const float* xyz1_data = xyz1.data<float>();
103
- const float* xyz2_data = xyz2.data<float>();
104
- float* dist1_data = dist1.data<float>();
105
- float* dist2_data = dist2.data<float>();
106
- int* idx1_data = idx1.data<int>();
107
- int* idx2_data = idx2.data<int>();
108
-
109
- nnsearch(batchsize, n, m, xyz1_data, xyz2_data, dist1_data, idx1_data);
110
- nnsearch(batchsize, m, n, xyz2_data, xyz1_data, dist2_data, idx2_data);
111
- }
112
-
113
-
114
- void chamfer_distance_backward(
115
- const at::Tensor xyz1,
116
- const at::Tensor xyz2,
117
- at::Tensor gradxyz1,
118
- at::Tensor gradxyz2,
119
- at::Tensor graddist1,
120
- at::Tensor graddist2,
121
- at::Tensor idx1,
122
- at::Tensor idx2)
123
- {
124
- const int b = xyz1.size(0);
125
- const int n = xyz1.size(1);
126
- const int m = xyz2.size(1);
127
-
128
- const float* xyz1_data = xyz1.data<float>();
129
- const float* xyz2_data = xyz2.data<float>();
130
- float* gradxyz1_data = gradxyz1.data<float>();
131
- float* gradxyz2_data = gradxyz2.data<float>();
132
- float* graddist1_data = graddist1.data<float>();
133
- float* graddist2_data = graddist2.data<float>();
134
- const int* idx1_data = idx1.data<int>();
135
- const int* idx2_data = idx2.data<int>();
136
-
137
- for (int i = 0; i < b*n*3; i++)
138
- gradxyz1_data[i] = 0;
139
- for (int i = 0; i < b*m*3; i++)
140
- gradxyz2_data[i] = 0;
141
- for (int i = 0;i < b; i++) {
142
- for (int j = 0; j < n; j++) {
143
- const float x1 = xyz1_data[(i*n+j)*3+0];
144
- const float y1 = xyz1_data[(i*n+j)*3+1];
145
- const float z1 = xyz1_data[(i*n+j)*3+2];
146
- const int j2 = idx1_data[i*n+j];
147
-
148
- const float x2 = xyz2_data[(i*m+j2)*3+0];
149
- const float y2 = xyz2_data[(i*m+j2)*3+1];
150
- const float z2 = xyz2_data[(i*m+j2)*3+2];
151
- const float g = graddist1_data[i*n+j]*2;
152
-
153
- gradxyz1_data[(i*n+j)*3+0] += g*(x1-x2);
154
- gradxyz1_data[(i*n+j)*3+1] += g*(y1-y2);
155
- gradxyz1_data[(i*n+j)*3+2] += g*(z1-z2);
156
- gradxyz2_data[(i*m+j2)*3+0] -= (g*(x1-x2));
157
- gradxyz2_data[(i*m+j2)*3+1] -= (g*(y1-y2));
158
- gradxyz2_data[(i*m+j2)*3+2] -= (g*(z1-z2));
159
- }
160
- for (int j = 0; j < m; j++) {
161
- const float x1 = xyz2_data[(i*m+j)*3+0];
162
- const float y1 = xyz2_data[(i*m+j)*3+1];
163
- const float z1 = xyz2_data[(i*m+j)*3+2];
164
- const int j2 = idx2_data[i*m+j];
165
- const float x2 = xyz1_data[(i*n+j2)*3+0];
166
- const float y2 = xyz1_data[(i*n+j2)*3+1];
167
- const float z2 = xyz1_data[(i*n+j2)*3+2];
168
- const float g = graddist2_data[i*m+j]*2;
169
- gradxyz2_data[(i*m+j)*3+0] += g*(x1-x2);
170
- gradxyz2_data[(i*m+j)*3+1] += g*(y1-y2);
171
- gradxyz2_data[(i*m+j)*3+2] += g*(z1-z2);
172
- gradxyz1_data[(i*n+j2)*3+0] -= (g*(x1-x2));
173
- gradxyz1_data[(i*n+j2)*3+1] -= (g*(y1-y2));
174
- gradxyz1_data[(i*n+j2)*3+2] -= (g*(z1-z2));
175
- }
176
- }
177
- }
178
-
179
-
180
- PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
181
- m.def("forward", &chamfer_distance_forward, "ChamferDistance forward");
182
- m.def("forward_cuda", &chamfer_distance_forward_cuda, "ChamferDistance forward (CUDA)");
183
- m.def("backward", &chamfer_distance_backward, "ChamferDistance backward");
184
- m.def("backward_cuda", &chamfer_distance_backward_cuda, "ChamferDistance backward (CUDA)");
185
- }
@@ -1,209 +0,0 @@
1
- #include <ATen/ATen.h>
2
-
3
- #include <cuda.h>
4
- #include <cuda_runtime.h>
5
-
6
- __global__
7
- void ChamferDistanceKernel(
8
- int b,
9
- int n,
10
- const float* xyz,
11
- int m,
12
- const float* xyz2,
13
- float* result,
14
- int* result_i)
15
- {
16
- const int batch=512;
17
- __shared__ float buf[batch*3];
18
- for (int i=blockIdx.x;i<b;i+=gridDim.x){
19
- for (int k2=0;k2<m;k2+=batch){
20
- int end_k=min(m,k2+batch)-k2;
21
- for (int j=threadIdx.x;j<end_k*3;j+=blockDim.x){
22
- buf[j]=xyz2[(i*m+k2)*3+j];
23
- }
24
- __syncthreads();
25
- for (int j=threadIdx.x+blockIdx.y*blockDim.x;j<n;j+=blockDim.x*gridDim.y){
26
- float x1=xyz[(i*n+j)*3+0];
27
- float y1=xyz[(i*n+j)*3+1];
28
- float z1=xyz[(i*n+j)*3+2];
29
- int best_i=0;
30
- float best=0;
31
- int end_ka=end_k-(end_k&3);
32
- if (end_ka==batch){
33
- for (int k=0;k<batch;k+=4){
34
- {
35
- float x2=buf[k*3+0]-x1;
36
- float y2=buf[k*3+1]-y1;
37
- float z2=buf[k*3+2]-z1;
38
- float d=x2*x2+y2*y2+z2*z2;
39
- if (k==0 || d<best){
40
- best=d;
41
- best_i=k+k2;
42
- }
43
- }
44
- {
45
- float x2=buf[k*3+3]-x1;
46
- float y2=buf[k*3+4]-y1;
47
- float z2=buf[k*3+5]-z1;
48
- float d=x2*x2+y2*y2+z2*z2;
49
- if (d<best){
50
- best=d;
51
- best_i=k+k2+1;
52
- }
53
- }
54
- {
55
- float x2=buf[k*3+6]-x1;
56
- float y2=buf[k*3+7]-y1;
57
- float z2=buf[k*3+8]-z1;
58
- float d=x2*x2+y2*y2+z2*z2;
59
- if (d<best){
60
- best=d;
61
- best_i=k+k2+2;
62
- }
63
- }
64
- {
65
- float x2=buf[k*3+9]-x1;
66
- float y2=buf[k*3+10]-y1;
67
- float z2=buf[k*3+11]-z1;
68
- float d=x2*x2+y2*y2+z2*z2;
69
- if (d<best){
70
- best=d;
71
- best_i=k+k2+3;
72
- }
73
- }
74
- }
75
- }else{
76
- for (int k=0;k<end_ka;k+=4){
77
- {
78
- float x2=buf[k*3+0]-x1;
79
- float y2=buf[k*3+1]-y1;
80
- float z2=buf[k*3+2]-z1;
81
- float d=x2*x2+y2*y2+z2*z2;
82
- if (k==0 || d<best){
83
- best=d;
84
- best_i=k+k2;
85
- }
86
- }
87
- {
88
- float x2=buf[k*3+3]-x1;
89
- float y2=buf[k*3+4]-y1;
90
- float z2=buf[k*3+5]-z1;
91
- float d=x2*x2+y2*y2+z2*z2;
92
- if (d<best){
93
- best=d;
94
- best_i=k+k2+1;
95
- }
96
- }
97
- {
98
- float x2=buf[k*3+6]-x1;
99
- float y2=buf[k*3+7]-y1;
100
- float z2=buf[k*3+8]-z1;
101
- float d=x2*x2+y2*y2+z2*z2;
102
- if (d<best){
103
- best=d;
104
- best_i=k+k2+2;
105
- }
106
- }
107
- {
108
- float x2=buf[k*3+9]-x1;
109
- float y2=buf[k*3+10]-y1;
110
- float z2=buf[k*3+11]-z1;
111
- float d=x2*x2+y2*y2+z2*z2;
112
- if (d<best){
113
- best=d;
114
- best_i=k+k2+3;
115
- }
116
- }
117
- }
118
- }
119
- for (int k=end_ka;k<end_k;k++){
120
- float x2=buf[k*3+0]-x1;
121
- float y2=buf[k*3+1]-y1;
122
- float z2=buf[k*3+2]-z1;
123
- float d=x2*x2+y2*y2+z2*z2;
124
- if (k==0 || d<best){
125
- best=d;
126
- best_i=k+k2;
127
- }
128
- }
129
- if (k2==0 || result[(i*n+j)]>best){
130
- result[(i*n+j)]=best;
131
- result_i[(i*n+j)]=best_i;
132
- }
133
- }
134
- __syncthreads();
135
- }
136
- }
137
- }
138
-
139
- void ChamferDistanceKernelLauncher(
140
- const int b, const int n,
141
- const float* xyz,
142
- const int m,
143
- const float* xyz2,
144
- float* result,
145
- int* result_i,
146
- float* result2,
147
- int* result2_i)
148
- {
149
- ChamferDistanceKernel<<<dim3(32,16,1),512>>>(b, n, xyz, m, xyz2, result, result_i);
150
- ChamferDistanceKernel<<<dim3(32,16,1),512>>>(b, m, xyz2, n, xyz, result2, result2_i);
151
-
152
- cudaError_t err = cudaGetLastError();
153
- if (err != cudaSuccess)
154
- printf("error in chamfer distance updateOutput: %s\n", cudaGetErrorString(err));
155
- }
156
-
157
-
158
- __global__
159
- void ChamferDistanceGradKernel(
160
- int b, int n,
161
- const float* xyz1,
162
- int m,
163
- const float* xyz2,
164
- const float* grad_dist1,
165
- const int* idx1,
166
- float* grad_xyz1,
167
- float* grad_xyz2)
168
- {
169
- for (int i = blockIdx.x; i<b; i += gridDim.x) {
170
- for (int j = threadIdx.x + blockIdx.y * blockDim.x; j < n; j += blockDim.x*gridDim.y) {
171
- float x1=xyz1[(i*n+j)*3+0];
172
- float y1=xyz1[(i*n+j)*3+1];
173
- float z1=xyz1[(i*n+j)*3+2];
174
- int j2=idx1[i*n+j];
175
- float x2=xyz2[(i*m+j2)*3+0];
176
- float y2=xyz2[(i*m+j2)*3+1];
177
- float z2=xyz2[(i*m+j2)*3+2];
178
- float g=grad_dist1[i*n+j]*2;
179
- atomicAdd(&(grad_xyz1[(i*n+j)*3+0]),g*(x1-x2));
180
- atomicAdd(&(grad_xyz1[(i*n+j)*3+1]),g*(y1-y2));
181
- atomicAdd(&(grad_xyz1[(i*n+j)*3+2]),g*(z1-z2));
182
- atomicAdd(&(grad_xyz2[(i*m+j2)*3+0]),-(g*(x1-x2)));
183
- atomicAdd(&(grad_xyz2[(i*m+j2)*3+1]),-(g*(y1-y2)));
184
- atomicAdd(&(grad_xyz2[(i*m+j2)*3+2]),-(g*(z1-z2)));
185
- }
186
- }
187
- }
188
-
189
- void ChamferDistanceGradKernelLauncher(
190
- const int b, const int n,
191
- const float* xyz1,
192
- const int m,
193
- const float* xyz2,
194
- const float* grad_dist1,
195
- const int* idx1,
196
- const float* grad_dist2,
197
- const int* idx2,
198
- float* grad_xyz1,
199
- float* grad_xyz2)
200
- {
201
- cudaMemset(grad_xyz1, 0, b*n*3*4);
202
- cudaMemset(grad_xyz2, 0, b*m*3*4);
203
- ChamferDistanceGradKernel<<<dim3(1,16,1), 256>>>(b, n, xyz1, m, xyz2, grad_dist1, idx1, grad_xyz1, grad_xyz2);
204
- ChamferDistanceGradKernel<<<dim3(1,16,1), 256>>>(b, m, xyz2, n, xyz1, grad_dist2, idx2, grad_xyz2, grad_xyz1);
205
-
206
- cudaError_t err = cudaGetLastError();
207
- if (err != cudaSuccess)
208
- printf("error in chamfer distance get grad: %s\n", cudaGetErrorString(err));
209
- }
@@ -1,66 +0,0 @@
1
- import torch
2
- from torch.utils.cpp_extension import load
3
- import os
4
-
5
- script_dir = os.path.dirname(__file__)
6
- sources = [
7
- os.path.join(script_dir, "chamfer_distance.cpp"),
8
- os.path.join(script_dir, "chamfer_distance.cu"),
9
- ]
10
-
11
- cd = load(name="cd", sources=sources)
12
-
13
-
14
- class ChamferDistanceFunction(torch.autograd.Function):
15
- @staticmethod
16
- def forward(ctx, xyz1, xyz2):
17
- batchsize, n, _ = xyz1.size()
18
- _, m, _ = xyz2.size()
19
- xyz1 = xyz1.contiguous()
20
- xyz2 = xyz2.contiguous()
21
- dist1 = torch.zeros(batchsize, n)
22
- dist2 = torch.zeros(batchsize, m)
23
-
24
- idx1 = torch.zeros(batchsize, n, dtype=torch.int)
25
- idx2 = torch.zeros(batchsize, m, dtype=torch.int)
26
-
27
- if not xyz1.is_cuda:
28
- cd.forward(xyz1, xyz2, dist1, dist2, idx1, idx2)
29
- else:
30
- dist1 = dist1.cuda()
31
- dist2 = dist2.cuda()
32
- idx1 = idx1.cuda()
33
- idx2 = idx2.cuda()
34
- cd.forward_cuda(xyz1, xyz2, dist1, dist2, idx1, idx2)
35
-
36
- ctx.save_for_backward(xyz1, xyz2, idx1, idx2)
37
-
38
- return dist1, dist2
39
-
40
- @staticmethod
41
- def backward(ctx, graddist1, graddist2):
42
- xyz1, xyz2, idx1, idx2 = ctx.saved_tensors
43
-
44
- graddist1 = graddist1.contiguous()
45
- graddist2 = graddist2.contiguous()
46
-
47
- gradxyz1 = torch.zeros(xyz1.size())
48
- gradxyz2 = torch.zeros(xyz2.size())
49
-
50
- if not graddist1.is_cuda:
51
- cd.backward(
52
- xyz1, xyz2, gradxyz1, gradxyz2, graddist1, graddist2, idx1, idx2
53
- )
54
- else:
55
- gradxyz1 = gradxyz1.cuda()
56
- gradxyz2 = gradxyz2.cuda()
57
- cd.backward_cuda(
58
- xyz1, xyz2, gradxyz1, gradxyz2, graddist1, graddist2, idx1, idx2
59
- )
60
-
61
- return gradxyz1, gradxyz2
62
-
63
-
64
- class ChamferDistance(torch.nn.Module):
65
- def forward(self, xyz1, xyz2):
66
- return ChamferDistanceFunction.apply(xyz1, xyz2)
@@ -1,41 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
-
4
- import _emd_ext._emd as emd
5
-
6
-
7
- class EMDFunction(torch.autograd.Function):
8
- @staticmethod
9
- def forward(self, xyz1, xyz2):
10
- cost, match = emd.emd_forward(xyz1, xyz2)
11
- self.save_for_backward(xyz1, xyz2, match)
12
- return cost
13
-
14
-
15
- @staticmethod
16
- def backward(self, grad_output):
17
- xyz1, xyz2, match = self.saved_tensors
18
- grad_xyz1, grad_xyz2 = emd.emd_backward(xyz1, xyz2, match)
19
- return grad_xyz1, grad_xyz2
20
-
21
-
22
-
23
-
24
- class EMDLoss(nn.Module):
25
- '''
26
- Computes the (approximate) Earth Mover's Distance between two point sets.
27
-
28
- IMPLEMENTATION LIMITATIONS:
29
- - Double tensors must have <=11 dimensions
30
- - Float tensors must have <=23 dimensions
31
- This is due to the use of CUDA shared memory in the computation. This shared memory is limited by the hardware to 48kB.
32
- '''
33
-
34
- def __init__(self):
35
- super(EMDLoss, self).__init__()
36
-
37
- def forward(self, xyz1, xyz2):
38
-
39
- assert xyz1.shape[-1] == xyz2.shape[-1], 'Both point sets must have the same dimensions!'
40
- assert xyz1.shape[1] == xyz2.shape[1], 'Both Point Clouds must have same number of points in it.'
41
- return EMDFunction.apply(xyz1, xyz2)