Open3D (C++ API)  0.15.1
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
32namespace open3d {
33namespace ml {
34namespace impl {
35
38template <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
182template <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
#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
Definition: PinholeCameraIntrinsic.cpp:35