Open3D (C++ API)  0.16.1
SparseConv.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// The MIT License (MIT)
5//
6// Copyright (c) 2018-2021 www.open3d.org
7//
8// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and associated documentation files (the "Software"), to deal
10// in the Software without restriction, including without limitation the rights
11// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12// copies of the Software, and to permit persons to whom the Software is
13// furnished to do so, subject to the following conditions:
14//
15// The above copyright notice and this permission notice shall be included in
16// all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24// IN THE SOFTWARE.
25// ----------------------------------------------------------------------------
26
27#pragma once
28#include <tbb/parallel_for.h>
29
30#include <Eigen/Core>
31
32namespace open3d {
33namespace ml {
34namespace impl {
35
38template <class TFeat,
39 class TOut,
40 class TIndex,
41 class TKernelIndex,
42 bool POINT_IMPORTANCE>
43void _SparseConvComputeFeaturesCPU(TOut* out_features,
44 const std::vector<int>& filter_dims,
45 const TFeat* filter,
46 size_t num_out,
47 size_t num_inp,
48 const TFeat* inp_features,
49 const TFeat* inp_importance,
50 size_t neighbors_index_size,
51 const TIndex* neighbors_index,
52 const TKernelIndex* neighbors_kernel_index,
53 const TFeat* neighbors_importance,
54 const int64_t* neighbors_row_splits,
55 bool normalize) {
56 const bool NEIGHBOR_IMPORTANCE = neighbors_importance != nullptr;
57
58 const int in_channels = filter_dims[filter_dims.size() - 2];
59 const int out_channels = filter_dims[filter_dims.size() - 1];
60
61 int num_kernel_elements = 1;
62 for (int i = 0; i < filter_dims.size() - 2; ++i)
63 num_kernel_elements *= filter_dims[i];
64
65 memset(out_features, 0, sizeof(TOut) * num_out * out_channels);
66
67 tbb::parallel_for(
68 tbb::blocked_range<size_t>(0, num_out, 32),
69 [&](const tbb::blocked_range<size_t>& r) {
70 int range_length = r.end() - r.begin();
71
72 Eigen::Matrix<TOut, Eigen::Dynamic, 1> normalizers(range_length,
73 1);
74 normalizers.setZero();
75
76 Eigen::Map<Eigen::Matrix<TOut, Eigen::Dynamic, Eigen::Dynamic>>
77 C(out_features + (r.begin() * out_channels),
78 out_channels, range_length);
79
80 for (size_t out_idx = r.begin(); out_idx != r.end();
81 ++out_idx) {
82 const int out_col = out_idx - r.begin();
83 const size_t neighbor_start = neighbors_row_splits[out_idx];
84 const size_t neighbor_end =
85 neighbors_row_splits[out_idx + 1];
86
87 for (size_t n = neighbor_start; n < neighbor_end; ++n) {
88 const size_t inp_idx = neighbors_index[n];
89 const int kernel_idx = neighbors_kernel_index[n];
90
91 const TFeat n_importance =
92 (NEIGHBOR_IMPORTANCE ? neighbors_importance[n]
93 : TFeat(1));
94 normalizers(out_col) += TOut(n_importance);
95
96 TFeat importance(1.0);
97 if (POINT_IMPORTANCE)
98 importance = inp_importance[inp_idx];
99 if (NEIGHBOR_IMPORTANCE) importance *= n_importance;
100
101 Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
102 Eigen::Dynamic>>
103 A(filter + kernel_idx * out_channels *
104 in_channels,
105 out_channels, in_channels);
106
107 Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
108 Eigen::Dynamic>>
109 B(inp_features + inp_idx * in_channels,
110 in_channels, 1);
111
112 C.col(out_col) +=
113 (A * (importance * B)).template cast<TOut>();
114 }
115
116 } // out_idx
117
118 if (normalize) {
119 for (int i = 0; i < range_length; ++i) {
120 if (normalizers(i) != TOut(0))
121 C.col(i) /= normalizers(i);
122 }
123 }
124 });
125}
126
172template <class TFeat, class TOut, class TIndex, class TKernelIndex>
173void SparseConvComputeFeaturesCPU(TOut* out_features,
174 const std::vector<int>& filter_dims,
175 const TFeat* filter,
176 size_t num_out,
177 size_t num_inp,
178 const TFeat* inp_features,
179 const TFeat* inp_importance,
180 size_t neighbors_index_size,
181 const TIndex* neighbors_index,
182 const TKernelIndex* neighbors_kernel_index,
183 const TFeat* neighbors_importance,
184 const int64_t* neighbors_row_splits,
185 bool normalize) {
186 // Dispatch all template parameter combinations
187 bool has_importance = inp_importance;
188
189#define FN_PARAMETERS \
190 out_features, filter_dims, filter, num_out, num_inp, inp_features, \
191 inp_importance, neighbors_index_size, neighbors_index, \
192 neighbors_kernel_index, neighbors_importance, \
193 neighbors_row_splits, normalize
194
195#define CALL_TEMPLATE(HAS_IMPORTANCE) \
196 if (HAS_IMPORTANCE == has_importance) \
197 _SparseConvComputeFeaturesCPU<TFeat, TOut, TIndex, TKernelIndex, \
198 HAS_IMPORTANCE>(FN_PARAMETERS);
199
200#define CALL_TEMPLATE2 \
201 CALL_TEMPLATE(true) \
202 CALL_TEMPLATE(false)
203
205
206#undef CALL_TEMPLATE
207#undef CALL_TEMPLATE2
208
209#undef FN_PARAMETERS
210}
211
212} // namespace impl
213} // namespace ml
214} // namespace open3d
#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:43
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:173
Definition: PinholeCameraIntrinsic.cpp:35