Open3D (C++ API)  0.18.0
Loading...
Searching...
No Matches
ContinuousConvBackpropFilter.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2023 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
8#pragma once
9
10#include <tbb/parallel_for.h>
11
12#include <mutex>
13
15
16namespace open3d {
17namespace ml {
18namespace impl {
19
20// Implementation of CConvBackropFilterCPU
21template <class TFeat,
22 class TOut,
23 class TReal,
24 class TIndex,
25 InterpolationMode INTERPOLATION,
26 CoordinateMapping MAPPING,
27 bool ALIGN_CORNERS,
28 bool INDIVIDUAL_EXTENT,
29 bool ISOTROPIC_EXTENT,
30 bool POINT_IMPORTANCE>
31void _CConvBackropFilterCPU(TOut* filter_backprop,
32 const std::vector<int>& filter_dims,
33 size_t num_out,
34 const TReal* out_positions,
35 size_t num_inp,
36 const TReal* inp_positions,
37 const TFeat* inp_features,
38 const TFeat* inp_importance,
39 size_t neighbors_index_size,
40 const TIndex* neighbors_index,
41 const TFeat* neighbors_importance,
42 const int64_t* neighbors_row_splits,
43 const TReal* extents,
44 const TReal* offsets,
45 const TFeat* out_features_gradient,
46 bool normalize) {
47 const bool NEIGHBORS_IMPORTANCE = neighbors_importance;
48 const int VECSIZE = 32;
49 typedef Eigen::Array<TReal, VECSIZE, 1> Vec_t;
50 typedef InterpolationVec<TReal, VECSIZE, INTERPOLATION> InterpolationVec_t;
51 InterpolationVec_t interpolation;
52
53 const int in_channels = filter_dims[filter_dims.size() - 2];
54 const int out_channels = filter_dims[filter_dims.size() - 1];
55
56 int spatial_filter_size = 1;
57 for (int i = 0; i < 3; ++i) spatial_filter_size *= filter_dims[i];
58 const int total_filter_size =
59 spatial_filter_size * in_channels * out_channels;
60 Eigen::Array<int, 3, 1> filter_size_xyz(filter_dims[2], filter_dims[1],
61 filter_dims[0]);
62
63 memset(filter_backprop, 0, sizeof(TOut) * total_filter_size);
64 std::mutex filter_backprop_mutex;
65
66 tbb::parallel_for(
67 tbb::blocked_range<size_t>(0, num_out, 32),
68 [&](const tbb::blocked_range<size_t>& r) {
69 int range_length = r.end() - r.begin();
70
71 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> B(
72 in_channels * spatial_filter_size, range_length);
73 B.setZero();
74 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> C(
75 out_channels, range_length);
76
77 typedef Eigen::Array<TFeat, VECSIZE, Eigen::Dynamic> Matrix;
78 Matrix infeat(VECSIZE, in_channels);
79
80 Eigen::Array<TReal, 3, 1> offsets_(offsets[0], offsets[1],
81 offsets[2]);
82
83 Eigen::Array<TReal, VECSIZE, 3> inv_extents;
84 if (INDIVIDUAL_EXTENT == false) {
85 if (ISOTROPIC_EXTENT) {
86 inv_extents = 1 / extents[0];
87 } else {
88 inv_extents.col(0) = 1 / extents[0];
89 inv_extents.col(1) = 1 / extents[1];
90 inv_extents.col(2) = 1 / extents[2];
91 }
92 }
93
94 for (size_t out_idx = r.begin(); out_idx != r.end();
95 ++out_idx) {
96 const int out_col = out_idx - r.begin();
97 const size_t neighbor_start = neighbors_row_splits[out_idx];
98 const size_t neighbor_end =
99 neighbors_row_splits[out_idx + 1];
100 TOut normalizer(0);
101
102 if (INDIVIDUAL_EXTENT) {
103 if (ISOTROPIC_EXTENT) {
104 inv_extents = 1 / extents[out_idx];
105 } else {
106 inv_extents.col(0) = 1 / extents[3 * out_idx + 0];
107 inv_extents.col(1) = 1 / extents[3 * out_idx + 1];
108 inv_extents.col(2) = 1 / extents[3 * out_idx + 2];
109 }
110 }
111
112 typename InterpolationVec_t::Weight_t interp_weights;
113 typename InterpolationVec_t::Idx_t interp_indices;
114
115 int vec_valid_count = 0;
116 Vec_t x, y, z;
117
118 // set to zero to avoid problems with vectors with less than
119 // VECSIZE valid entries
120 x.setZero();
121 y.setZero();
122 z.setZero();
123 for (size_t n = neighbor_start; n < neighbor_end; ++n) {
124 const size_t inp_idx = neighbors_index[n];
125 const int i = vec_valid_count;
126 x(i) = inp_positions[inp_idx * 3 + 0] -
127 out_positions[out_idx * 3 + 0];
128 y(i) = inp_positions[inp_idx * 3 + 1] -
129 out_positions[out_idx * 3 + 1];
130 z(i) = inp_positions[inp_idx * 3 + 2] -
131 out_positions[out_idx * 3 + 2];
132
133 const TFeat n_importance =
134 (NEIGHBORS_IMPORTANCE ? neighbors_importance[n]
135 : TFeat(1));
136 normalizer += TOut(n_importance);
137
138 for (int ic = 0; ic < in_channels; ++ic)
139 infeat(i, ic) =
140 inp_features[inp_idx * in_channels + ic];
141
142 TFeat importance = TFeat(1);
143 if (POINT_IMPORTANCE)
144 importance = inp_importance[inp_idx];
145 if (NEIGHBORS_IMPORTANCE) importance *= n_importance;
146
147 if (POINT_IMPORTANCE || NEIGHBORS_IMPORTANCE) {
148 for (int ic = 0; ic < in_channels; ++ic)
149 infeat(i, ic) *= importance;
150 }
151
152 ++vec_valid_count;
153 if (vec_valid_count == VECSIZE) {
154 ComputeFilterCoordinates<ALIGN_CORNERS, MAPPING>(
155 x, y, z, filter_size_xyz, inv_extents,
156 offsets_);
157 interpolation.Interpolate(
158 interp_weights, interp_indices, x, y, z,
159 filter_size_xyz, in_channels);
160 for (int k = 0; k < VECSIZE; ++k)
161 for (int j = 0; j < InterpolationVec_t::Size();
162 ++j) {
163 for (int ic = 0; ic < in_channels; ++ic)
164 B(interp_indices(j, k) + ic, out_col) +=
165 TFeat(interp_weights(j, k)) *
166 infeat(k, ic);
167 }
168 vec_valid_count = 0;
169 }
170 }
171 if (vec_valid_count) {
172 ComputeFilterCoordinates<ALIGN_CORNERS, MAPPING>(
173 x, y, z, filter_size_xyz, inv_extents,
174 offsets_);
175 interpolation.Interpolate(interp_weights,
176 interp_indices, x, y, z,
177 filter_size_xyz, in_channels);
178 for (int k = 0; k < vec_valid_count; ++k)
179 for (int j = 0; j < InterpolationVec_t::Size();
180 ++j) {
181 for (int ic = 0; ic < in_channels; ++ic)
182 B(interp_indices(j, k) + ic, out_col) +=
183 TFeat(interp_weights(j, k)) *
184 infeat(k, ic);
185 }
186 }
187
188 C.col(out_col) = Eigen::Map<
189 const Eigen::Array<TFeat, Eigen::Dynamic, 1>>(
190 out_features_gradient + out_idx * out_channels,
191 out_channels, 1);
192
193 if (normalize && normalizer != TOut(0))
194 C.col(out_col) /= TFeat(normalizer);
195
196 } // out_idx
197
198 Eigen::Matrix<TOut, Eigen::Dynamic, Eigen::Dynamic> A(
199 out_channels, spatial_filter_size * in_channels);
200
201 A = (C * B.transpose()).template cast<TOut>();
202
203 {
204 std::lock_guard<std::mutex> lock(filter_backprop_mutex);
205 int linear_i = 0;
206 for (int j = 0; j < spatial_filter_size * in_channels; ++j)
207 for (int i = 0; i < out_channels; ++i, ++linear_i) {
208 filter_backprop[linear_i] += A(i, j);
209 }
210 }
211 });
212}
213
286template <class TFeat, class TOut, class TReal, class TIndex>
287void CConvBackpropFilterCPU(TOut* filter_backprop,
288 const std::vector<int>& filter_dims,
289 size_t num_out,
290 const TReal* out_positions,
291 size_t num_inp,
292 const TReal* inp_positions,
293 const TFeat* inp_features,
294 const TFeat* inp_importance,
295 size_t neighbors_index_size,
296 const TIndex* neighbors_index,
297 const TFeat* neighbors_importance,
298 const int64_t* neighbors_row_splits,
299 const TReal* extents,
300 const TReal* offsets,
301 const TFeat* out_features_gradient,
302 InterpolationMode interpolation,
303 CoordinateMapping coordinate_mapping,
304 bool align_corners,
305 bool individual_extent,
306 bool isotropic_extent,
307 bool normalize) {
308 bool has_importance = inp_importance;
309
310#define FN_PARAMETERS \
311 filter_backprop, filter_dims, num_out, out_positions, num_inp, \
312 inp_positions, inp_features, inp_importance, neighbors_index_size, \
313 neighbors_index, neighbors_importance, neighbors_row_splits, \
314 extents, offsets, out_features_gradient, normalize
315
316#define CALL_TEMPLATE(INTERPOLATION, MAPPING, ALIGN_CORNERS, \
317 INDIVIDUAL_EXTENT, ISOTROPIC_EXTENT, HAS_IMPORTANCE) \
318 if (INTERPOLATION == interpolation && MAPPING == coordinate_mapping && \
319 ALIGN_CORNERS == align_corners && \
320 INDIVIDUAL_EXTENT == individual_extent && \
321 ISOTROPIC_EXTENT == isotropic_extent && \
322 HAS_IMPORTANCE == has_importance) \
323 _CConvBackropFilterCPU<TFeat, TOut, TReal, TIndex, INTERPOLATION, \
324 MAPPING, ALIGN_CORNERS, INDIVIDUAL_EXTENT, \
325 ISOTROPIC_EXTENT, HAS_IMPORTANCE>( \
326 FN_PARAMETERS);
327
328#define CALL_TEMPLATE2(INTERPOLATION, MAPPING) \
329 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, true, true, true) \
330 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, true, true, false) \
331 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, true, false, true) \
332 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, true, false, false) \
333 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, false, true, true) \
334 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, false, true, false) \
335 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, false, false, true) \
336 CALL_TEMPLATE(INTERPOLATION, MAPPING, true, false, false, false) \
337 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, true, true, true) \
338 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, true, true, false) \
339 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, true, false, true) \
340 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, true, false, false) \
341 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, false, true, true) \
342 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, false, true, false) \
343 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, false, false, true) \
344 CALL_TEMPLATE(INTERPOLATION, MAPPING, false, false, false, false)
345
346#define CALL_TEMPLATE3(INTERPOLATION) \
347 CALL_TEMPLATE2(INTERPOLATION, CoordinateMapping::BALL_TO_CUBE_RADIAL) \
348 CALL_TEMPLATE2(INTERPOLATION, \
349 CoordinateMapping::BALL_TO_CUBE_VOLUME_PRESERVING) \
350 CALL_TEMPLATE2(INTERPOLATION, CoordinateMapping::IDENTITY)
351
352#define CALL_TEMPLATE4 \
353 CALL_TEMPLATE3(InterpolationMode::LINEAR) \
354 CALL_TEMPLATE3(InterpolationMode::LINEAR_BORDER) \
355 CALL_TEMPLATE3(InterpolationMode::NEAREST_NEIGHBOR)
356
358
359#undef CALL_TEMPLATE
360#undef CALL_TEMPLATE2
361#undef CALL_TEMPLATE3
362#undef CALL_TEMPLATE4
363
364#undef FN_PARAMETERS
365}
366
367} // namespace impl
368} // namespace ml
369} // namespace open3d
#define CALL_TEMPLATE4
#define VECSIZE
Eigen::Matrix3d B
Definition PointCloudPlanarPatchDetection.cpp:506
InterpolationMode
Definition ContinuousConvTypes.h:18
void _CConvBackropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, const TReal *out_positions, size_t num_inp, const TReal *inp_positions, const TFeat *inp_features, const TFeat *inp_importance, size_t neighbors_index_size, const TIndex *neighbors_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TReal *extents, const TReal *offsets, const TFeat *out_features_gradient, bool normalize)
Definition ContinuousConvBackpropFilter.h:31
void CConvBackpropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, const TReal *out_positions, size_t num_inp, const TReal *inp_positions, const TFeat *inp_features, const TFeat *inp_importance, size_t neighbors_index_size, const TIndex *neighbors_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TReal *extents, const TReal *offsets, const TFeat *out_features_gradient, InterpolationMode interpolation, CoordinateMapping coordinate_mapping, bool align_corners, bool individual_extent, bool isotropic_extent, bool normalize)
Definition ContinuousConvBackpropFilter.h:287
CoordinateMapping
Definition ContinuousConvTypes.h:26
Definition PinholeCameraIntrinsic.cpp:16
Class for computing interpolation weights.
Definition CoordinateTransformation.h:185