Open3D (C++ API)  0.17.0
Loading...
Searching...
No Matches
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
13namespace open3d {
14namespace ml {
15namespace impl {
16
19template <class TFeat,
20 class TOut,
21 class TIndex,
22 class TKernelIndex,
23 bool POINT_IMPORTANCE>
24void _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
153template <class TFeat, class TOut, class TIndex, class TKernelIndex>
154void 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
#define CALL_TEMPLATE2(METRIC)
Eigen::Matrix3d B
Definition PointCloudPlanarPatchDetection.cpp:506
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