Open3D (C++ API)  0.18.0
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 
14 namespace open3d {
15 namespace ml {
16 namespace impl {
17 
18 // Implementation of SparseConvBackropFilterCPU
19 template <class TFeat,
20  class TOut,
21  class TIndex,
22  class TKernelIndex,
23  bool POINT_IMPORTANCE>
24 void _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 
179 template <class TFeat, class TOut, class TIndex, class TKernelIndex>
180 void 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
Eigen::Matrix3d B
Definition: PointCloudPlanarPatchDetection.cpp:506
#define CALL_TEMPLATE2
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