Open3D (C++ API)  0.18.0
Loading...
Searching...
No Matches
SparseConvBackpropFilter.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#include <tbb/parallel_for.h>
10
11#include <Eigen/Core>
12#include <mutex>
13
14namespace open3d {
15namespace ml {
16namespace impl {
17
18// Implementation of SparseConvBackropFilterCPU
19template <class TFeat,
20 class TOut,
21 class TIndex,
22 class TKernelIndex,
23 bool POINT_IMPORTANCE>
24void _SparseConvBackropFilterCPU(TOut* filter_backprop,
25 const std::vector<int>& filter_dims,
26 size_t num_out,
27 size_t num_inp,
28 const TFeat* inp_features,
29 const TFeat* inp_importance,
30 const TIndex* neighbors_index,
31 const TKernelIndex* neighbors_kernel_index,
32 const TFeat* neighbors_importance,
33 const int64_t* neighbors_row_splits,
34 const TFeat* out_features_gradient,
35 bool normalize) {
36 const bool NEIGHBOR_IMPORTANCE = neighbors_importance;
37
38 const int in_channels = filter_dims[filter_dims.size() - 2];
39 const int out_channels = filter_dims[filter_dims.size() - 1];
40
41 int num_kernel_elements = 1;
42 for (int i = 0; i < filter_dims.size() - 2; ++i)
43 num_kernel_elements *= filter_dims[i];
44 const int total_filter_size =
45 num_kernel_elements * in_channels * out_channels;
46
47 memset(filter_backprop, 0, sizeof(TOut) * total_filter_size);
48 std::mutex filter_backprop_mutex;
49
50 tbb::parallel_for(
51 tbb::blocked_range<size_t>(0, num_out, 10032),
52 [&](const tbb::blocked_range<size_t>& r) {
53 int range_length = r.end() - r.begin();
54
55 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> B(
56 in_channels * num_kernel_elements, range_length);
57 B.setZero();
58 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> C(
59 out_channels, range_length);
60
61 Eigen::Array<TFeat, Eigen::Dynamic, 1> infeat(in_channels, 1);
62
63 for (size_t out_idx = r.begin(); out_idx != r.end();
64 ++out_idx) {
65 const int out_col = out_idx - r.begin();
66 const size_t neighbor_start = neighbors_row_splits[out_idx];
67 const size_t neighbor_end =
68 neighbors_row_splits[out_idx + 1];
69 TFeat normalizer(0);
70
71 for (size_t n = neighbor_start; n < neighbor_end; ++n) {
72 const size_t inp_idx = neighbors_index[n];
73 const int kernel_idx = neighbors_kernel_index[n];
74
75 const TFeat n_importance =
76 (NEIGHBOR_IMPORTANCE ? neighbors_importance[n]
77 : TFeat(1));
78 normalizer += n_importance;
79
80 for (int ic = 0; ic < in_channels; ++ic)
81 infeat(ic) =
82 inp_features[inp_idx * in_channels + ic];
83
84 TFeat importance(1);
85 if (POINT_IMPORTANCE)
86 importance = inp_importance[inp_idx];
87 if (NEIGHBOR_IMPORTANCE) importance *= n_importance;
88
89 if (POINT_IMPORTANCE || NEIGHBOR_IMPORTANCE) {
90 for (int ic = 0; ic < in_channels; ++ic)
91 infeat(ic) *= importance;
92 }
93 for (int ic = 0; ic < in_channels; ++ic) {
94 B(kernel_idx * in_channels + ic, out_col) =
95 infeat(ic);
96 }
97 }
98
99 C.col(out_col) = Eigen::Map<
100 const Eigen::Array<TFeat, Eigen::Dynamic, 1>>(
101 out_features_gradient + out_idx * out_channels,
102 out_channels, 1);
103
104 if (normalize && normalizer != TFeat(0))
105 C.col(out_col) /= normalizer;
106
107 } // out_idx
108
109 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> A(
110 out_channels, num_kernel_elements * in_channels);
111
112 A = C * B.transpose();
113
114 {
115 std::lock_guard<std::mutex> lock(filter_backprop_mutex);
116 int linear_i = 0;
117 for (int j = 0; j < num_kernel_elements * in_channels; ++j)
118 for (int i = 0; i < out_channels; ++i, ++linear_i) {
119 filter_backprop[linear_i] += TOut(A(i, j));
120 }
121 }
122 });
123}
124
179template <class TFeat, class TOut, class TIndex, class TKernelIndex>
180void SparseConvBackpropFilterCPU(TOut* filter_backprop,
181 const std::vector<int>& filter_dims,
182 size_t num_out,
183 size_t num_inp,
184 const TFeat* inp_features,
185 const TFeat* inp_importance,
186 const TIndex* neighbors_index,
187 const TKernelIndex* neighbors_kernel_index,
188 const TFeat* neighbors_importance,
189 const int64_t* neighbors_row_splits,
190 const TFeat* out_features_gradient,
191 bool normalize) {
192 bool has_importance = inp_importance;
193
194#define FN_PARAMETERS \
195 filter_backprop, filter_dims, num_out, num_inp, inp_features, \
196 inp_importance, neighbors_index, neighbors_kernel_index, \
197 neighbors_importance, neighbors_row_splits, out_features_gradient, \
198 normalize
199
200#define CALL_TEMPLATE(HAS_IMPORTANCE) \
201 if (HAS_IMPORTANCE == has_importance) \
202 _SparseConvBackropFilterCPU<TFeat, TOut, TIndex, TKernelIndex, \
203 HAS_IMPORTANCE>(FN_PARAMETERS);
204
205#define CALL_TEMPLATE2 \
206 CALL_TEMPLATE(true) \
207 CALL_TEMPLATE(false)
208
210
211#undef CALL_TEMPLATE
212#undef CALL_TEMPLATE2
213
214#undef FN_PARAMETERS
215}
216
217} // namespace impl
218} // namespace ml
219} // namespace open3d
#define CALL_TEMPLATE2(METRIC)
Eigen::Matrix3d B
Definition PointCloudPlanarPatchDetection.cpp:506
void _SparseConvBackropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, const TIndex *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TFeat *out_features_gradient, bool normalize)
Definition SparseConvBackpropFilter.h:24
void SparseConvBackpropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, const TIndex *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TFeat *out_features_gradient, bool normalize)
Definition SparseConvBackpropFilter.h:180
Definition PinholeCameraIntrinsic.cpp:16