Loading [MathJax]/extensions/TeX/AMSsymbols.js
Open3D (C++ API)  0.16.0
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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 
32 namespace open3d {
33 namespace ml {
34 namespace impl {
35 
38 template <class TFeat,
39  class TOut,
40  class TIndex,
41  class TKernelIndex,
42  bool POINT_IMPORTANCE>
43 void _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 
172 template <class TFeat, class TOut, class TIndex, class TKernelIndex>
173 void 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:173
Definition: PinholeCameraIntrinsic.cpp:35
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