Open3D (C++ API)  0.17.0
SparseConv.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 
13 namespace open3d {
14 namespace ml {
15 namespace impl {
16 
19 template <class TFeat,
20  class TOut,
21  class TIndex,
22  class TKernelIndex,
23  bool POINT_IMPORTANCE>
24 void _SparseConvComputeFeaturesCPU(TOut* out_features,
25  const std::vector<int>& filter_dims,
26  const TFeat* filter,
27  size_t num_out,
28  size_t num_inp,
29  const TFeat* inp_features,
30  const TFeat* inp_importance,
31  size_t neighbors_index_size,
32  const TIndex* neighbors_index,
33  const TKernelIndex* neighbors_kernel_index,
34  const TFeat* neighbors_importance,
35  const int64_t* neighbors_row_splits,
36  bool normalize) {
37  const bool NEIGHBOR_IMPORTANCE = neighbors_importance != nullptr;
38 
39  const int in_channels = filter_dims[filter_dims.size() - 2];
40  const int out_channels = filter_dims[filter_dims.size() - 1];
41 
42  int num_kernel_elements = 1;
43  for (int i = 0; i < filter_dims.size() - 2; ++i)
44  num_kernel_elements *= filter_dims[i];
45 
46  memset(out_features, 0, sizeof(TOut) * num_out * out_channels);
47 
48  tbb::parallel_for(
49  tbb::blocked_range<size_t>(0, num_out, 32),
50  [&](const tbb::blocked_range<size_t>& r) {
51  int range_length = r.end() - r.begin();
52 
53  Eigen::Matrix<TOut, Eigen::Dynamic, 1> normalizers(range_length,
54  1);
55  normalizers.setZero();
56 
57  Eigen::Map<Eigen::Matrix<TOut, Eigen::Dynamic, Eigen::Dynamic>>
58  C(out_features + (r.begin() * out_channels),
59  out_channels, range_length);
60 
61  for (size_t out_idx = r.begin(); out_idx != r.end();
62  ++out_idx) {
63  const int out_col = out_idx - r.begin();
64  const size_t neighbor_start = neighbors_row_splits[out_idx];
65  const size_t neighbor_end =
66  neighbors_row_splits[out_idx + 1];
67 
68  for (size_t n = neighbor_start; n < neighbor_end; ++n) {
69  const size_t inp_idx = neighbors_index[n];
70  const int kernel_idx = neighbors_kernel_index[n];
71 
72  const TFeat n_importance =
73  (NEIGHBOR_IMPORTANCE ? neighbors_importance[n]
74  : TFeat(1));
75  normalizers(out_col) += TOut(n_importance);
76 
77  TFeat importance(1.0);
78  if (POINT_IMPORTANCE)
79  importance = inp_importance[inp_idx];
80  if (NEIGHBOR_IMPORTANCE) importance *= n_importance;
81 
82  Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
83  Eigen::Dynamic>>
84  A(filter + kernel_idx * out_channels *
85  in_channels,
86  out_channels, in_channels);
87 
88  Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
89  Eigen::Dynamic>>
90  B(inp_features + inp_idx * in_channels,
91  in_channels, 1);
92 
93  C.col(out_col) +=
94  (A * (importance * B)).template cast<TOut>();
95  }
96 
97  } // out_idx
98 
99  if (normalize) {
100  for (int i = 0; i < range_length; ++i) {
101  if (normalizers(i) != TOut(0))
102  C.col(i) /= normalizers(i);
103  }
104  }
105  });
106 }
107 
153 template <class TFeat, class TOut, class TIndex, class TKernelIndex>
154 void SparseConvComputeFeaturesCPU(TOut* out_features,
155  const std::vector<int>& filter_dims,
156  const TFeat* filter,
157  size_t num_out,
158  size_t num_inp,
159  const TFeat* inp_features,
160  const TFeat* inp_importance,
161  size_t neighbors_index_size,
162  const TIndex* neighbors_index,
163  const TKernelIndex* neighbors_kernel_index,
164  const TFeat* neighbors_importance,
165  const int64_t* neighbors_row_splits,
166  bool normalize) {
167  // Dispatch all template parameter combinations
168  bool has_importance = inp_importance;
169 
170 #define FN_PARAMETERS \
171  out_features, filter_dims, filter, num_out, num_inp, inp_features, \
172  inp_importance, neighbors_index_size, neighbors_index, \
173  neighbors_kernel_index, neighbors_importance, \
174  neighbors_row_splits, normalize
175 
176 #define CALL_TEMPLATE(HAS_IMPORTANCE) \
177  if (HAS_IMPORTANCE == has_importance) \
178  _SparseConvComputeFeaturesCPU<TFeat, TOut, TIndex, TKernelIndex, \
179  HAS_IMPORTANCE>(FN_PARAMETERS);
180 
181 #define CALL_TEMPLATE2 \
182  CALL_TEMPLATE(true) \
183  CALL_TEMPLATE(false)
184 
186 
187 #undef CALL_TEMPLATE
188 #undef CALL_TEMPLATE2
189 
190 #undef FN_PARAMETERS
191 }
192 
193 } // namespace impl
194 } // namespace ml
195 } // namespace open3d
Eigen::Matrix3d B
Definition: PointCloudPlanarPatchDetection.cpp:506
#define CALL_TEMPLATE2
void _SparseConvComputeFeaturesCPU(TOut *out_features, const std::vector< int > &filter_dims, const TFeat *filter, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, size_t neighbors_index_size, const TIndex *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, bool normalize)
Definition: SparseConv.h:24
void SparseConvComputeFeaturesCPU(TOut *out_features, const std::vector< int > &filter_dims, const TFeat *filter, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, size_t neighbors_index_size, const TIndex *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, bool normalize)
Definition: SparseConv.h:154
Definition: PinholeCameraIntrinsic.cpp:16