Loading [MathJax]/extensions/TeX/AMSsymbols.js
Open3D (C++ API)  0.14.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SparseConvTranspose.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 NORMALIZE>
44  TOut* out_features,
45  const std::vector<int>& filter_dims,
46  const TFeat* filter,
47  size_t num_out,
48  const TFeat* out_importance,
49  size_t num_inp,
50  const TFeat* inp_features,
51  const TFeat* inp_neighbors_importance_sum,
52  const int64_t* inp_neighbors_row_splits,
53  const TIndex* neighbor_index,
54  const TKernelIndex* neighbors_kernel_index,
55  const TFeat* neighbor_importance,
56  const int64_t* neighbors_row_splits) {
57  const bool NEIGHBOR_IMPORTANCE = inp_neighbors_importance_sum;
58 
59  const int in_channels = filter_dims[filter_dims.size() - 2];
60  const int out_channels = filter_dims[filter_dims.size() - 1];
61 
62  int num_kernel_elements = 1;
63  for (int i = 0; i < filter_dims.size() - 2; ++i)
64  num_kernel_elements *= filter_dims[i];
65 
66  memset(out_features, 0, sizeof(TOut) * num_out * out_channels);
67 
68  tbb::parallel_for(
69  tbb::blocked_range<size_t>(0, num_out, 32),
70  [&](const tbb::blocked_range<size_t>& r) {
71  int range_length = r.end() - r.begin();
72 
73  Eigen::Map<Eigen::Matrix<TOut, Eigen::Dynamic, Eigen::Dynamic>>
74  C(out_features + (r.begin() * out_channels),
75  out_channels, range_length);
76 
77  for (size_t out_idx = r.begin(); out_idx != r.end();
78  ++out_idx) {
79  const int out_col = out_idx - r.begin();
80  const size_t neighbor_start = neighbors_row_splits[out_idx];
81  const size_t neighbor_end =
82  neighbors_row_splits[out_idx + 1];
83 
84  for (size_t n = neighbor_start; n < neighbor_end; ++n) {
85  const size_t inp_idx = neighbor_index[n];
86  const int kernel_idx = neighbors_kernel_index[n];
87 
88  TFeat n_importance = NEIGHBOR_IMPORTANCE
89  ? neighbor_importance[n]
90  : TFeat(1);
91 
92  TFeat normalizer(1);
93  if (NORMALIZE) {
94  if (NEIGHBOR_IMPORTANCE) {
95  if (inp_neighbors_importance_sum[inp_idx] !=
96  TFeat(0))
97  normalizer /= inp_neighbors_importance_sum
98  [inp_idx];
99  } else {
100  size_t num_inp_neighbors;
101  const size_t inp_neighbor_start =
102  inp_neighbors_row_splits[inp_idx];
103  const size_t inp_neighbor_end =
104  inp_neighbors_row_splits[inp_idx + 1];
105  num_inp_neighbors =
106  inp_neighbor_end - inp_neighbor_start;
107  if (num_inp_neighbors > 0)
108  normalizer /= TFeat(num_inp_neighbors);
109  }
110  }
111 
112  Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
113  Eigen::Dynamic>>
114  A(filter + kernel_idx * out_channels *
115  in_channels,
116  out_channels, in_channels);
117 
118  Eigen::Map<const Eigen::Matrix<TFeat, Eigen::Dynamic,
119  Eigen::Dynamic>>
120  B(inp_features + inp_idx * in_channels,
121  in_channels, 1);
122  TFeat scale = normalizer * n_importance;
123  C.col(out_col) +=
124  (A * (scale * B)).template cast<TOut>();
125  }
126 
127  } // out_idx
128 
129  if (out_importance) {
130  for (int i = 0; i < range_length; ++i)
131  C.col(i) *= TOut(out_importance[r.begin() + i]);
132  }
133  });
134 }
135 
182 template <class TFeat, class TOut, class TIndex, class TKernelIndex>
184  TOut* out_features,
185  const std::vector<int>& filter_dims,
186  const TFeat* filter,
187  size_t num_out,
188  const TFeat* out_importance,
189  size_t num_inp,
190  const TFeat* inp_features,
191  const TFeat* inp_neighbors_importance_sum,
192  const int64_t* inp_neighbors_row_splits,
193  const TIndex* neighbor_index,
194  const TKernelIndex* neighbors_kernel_index,
195  const TFeat* neighbor_importance,
196  const int64_t* neighbors_row_splits,
197  bool normalize) {
198 #define FN_PARAMETERS \
199  out_features, filter_dims, filter, num_out, out_importance, num_inp, \
200  inp_features, inp_neighbors_importance_sum, \
201  inp_neighbors_row_splits, neighbor_index, neighbors_kernel_index, \
202  neighbor_importance, neighbors_row_splits
203 
204 #define CALL_TEMPLATE(NORMALIZE) \
205  if (NORMALIZE == normalize) \
206  _SparseConvTransposeComputeFeaturesCPU<TFeat, TOut, TIndex, \
207  TKernelIndex, NORMALIZE>( \
208  FN_PARAMETERS);
209 
210 #define CALL_TEMPLATE2 \
211  CALL_TEMPLATE(true) \
212  CALL_TEMPLATE(false)
213 
215 
216 #undef CALL_TEMPLATE
217 #undef CALL_TEMPLATE2
218 
219 #undef FN_PARAMETERS
220 }
221 
222 } // namespace impl
223 } // namespace ml
224 } // namespace open3d
Definition: PinholeCameraIntrinsic.cpp:35
#define CALL_TEMPLATE2
void _SparseConvTransposeComputeFeaturesCPU(TOut *out_features, const std::vector< int > &filter_dims, const TFeat *filter, size_t num_out, const TFeat *out_importance, size_t num_inp, const TFeat *inp_features, const TFeat *inp_neighbors_importance_sum, const int64_t *inp_neighbors_row_splits, const TIndex *neighbor_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbor_importance, const int64_t *neighbors_row_splits)
Definition: SparseConvTranspose.h:43
void SparseConvTransposeComputeFeaturesCPU(TOut *out_features, const std::vector< int > &filter_dims, const TFeat *filter, size_t num_out, const TFeat *out_importance, size_t num_inp, const TFeat *inp_features, const TFeat *inp_neighbors_importance_sum, const int64_t *inp_neighbors_row_splits, const TIndex *neighbor_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbor_importance, const int64_t *neighbors_row_splits, bool normalize)
Definition: SparseConvTranspose.h:183