9 #include <tbb/parallel_for.h>
20 template <
class TFeat,
26 TOut* filter_backprop,
27 const std::vector<int>& filter_dims,
29 const TFeat* out_importance,
31 const TFeat* inp_features,
32 const TFeat* inp_neighbors_importance_sum,
33 const int64_t* inp_neighbors_row_splits,
34 const TIndex* neighbors_index,
35 const TKernelIndex* neighbors_kernel_index,
36 const TFeat* neighbors_importance,
37 const int64_t* neighbors_row_splits,
38 const TFeat* out_features_gradient) {
39 const bool NEIGHBOR_IMPORTANCE = neighbors_importance;
41 const int in_channels = filter_dims[filter_dims.size() - 2];
42 const int out_channels = filter_dims[filter_dims.size() - 1];
44 int num_kernel_elements = 1;
45 for (
int i = 0; i < filter_dims.size() - 2; ++i)
46 num_kernel_elements *= filter_dims[i];
48 memset(filter_backprop, 0,
49 sizeof(TOut) * num_kernel_elements * in_channels * out_channels);
50 std::mutex filter_backprop_mutex;
53 tbb::blocked_range<size_t>(0, num_out, 32),
54 [&](
const tbb::blocked_range<size_t>& r) {
55 int range_length = r.end() - r.begin();
57 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic>
B(
58 in_channels * num_kernel_elements, range_length);
60 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> C(
61 out_channels, range_length);
63 Eigen::Array<TFeat, Eigen::Dynamic, 1> infeat(in_channels, 1);
65 for (
size_t out_idx = r.begin(); out_idx != r.end();
67 const int out_col = out_idx - r.begin();
68 const size_t neighbor_start = neighbors_row_splits[out_idx];
69 const size_t neighbor_end =
70 neighbors_row_splits[out_idx + 1];
72 C.col(out_col) = Eigen::Map<
73 const Eigen::Array<TFeat, Eigen::Dynamic, 1>>(
74 out_features_gradient + out_idx * out_channels,
77 for (
size_t n = neighbor_start; n < neighbor_end; ++n) {
78 const size_t inp_idx = neighbors_index[n];
79 const int kernel_idx = neighbors_kernel_index[n];
81 TFeat n_importance = NEIGHBOR_IMPORTANCE
82 ? neighbors_importance[n]
84 for (
int ic = 0; ic < in_channels; ++ic)
86 inp_features[inp_idx * in_channels + ic] *
91 if (NEIGHBOR_IMPORTANCE) {
92 if (inp_neighbors_importance_sum[inp_idx] !=
94 normalizer /= inp_neighbors_importance_sum
97 size_t num_inp_neighbors;
98 const size_t inp_neighbor_start =
99 inp_neighbors_row_splits[inp_idx];
100 const size_t inp_neighbor_end =
101 inp_neighbors_row_splits[inp_idx + 1];
103 inp_neighbor_end - inp_neighbor_start;
104 if (num_inp_neighbors > 0)
105 normalizer /= TFeat(num_inp_neighbors);
107 for (
int ic = 0; ic < in_channels; ++ic)
108 infeat(ic) *= normalizer;
111 for (
int ic = 0; ic < in_channels; ++ic) {
112 B(kernel_idx * in_channels + ic, out_col) +=
119 if (out_importance) {
120 for (
size_t out_idx = r.begin(); out_idx != r.end();
122 const int out_col = out_idx - r.begin();
123 C.col(out_col) *= out_importance[out_idx];
127 Eigen::Matrix<TOut, Eigen::Dynamic, Eigen::Dynamic> A(
128 out_channels, num_kernel_elements * in_channels);
130 A = (C *
B.transpose()).
template cast<TOut>();
133 std::lock_guard<std::mutex> lock(filter_backprop_mutex);
135 for (
int j = 0; j < num_kernel_elements * in_channels; ++j)
136 for (
int i = 0; i < out_channels; ++i, ++linear_i) {
137 filter_backprop[linear_i] += A(i, j);
194 template <
class TFeat,
class TOut,
class TIndex,
class TKernelIndex>
196 TOut* filter_backprop,
197 const std::vector<int>& filter_dims,
199 const TFeat* out_importance,
201 const TFeat* inp_features,
202 const TFeat* inp_neighbors_importance_sum,
203 const int64_t* inp_neighbors_row_splits,
204 const TIndex* neighbors_index,
205 const TKernelIndex* neighbors_kernel_index,
206 const TFeat* neighbors_importance,
207 const int64_t* neighbors_row_splits,
208 const TFeat* out_features_gradient,
210 #define FN_PARAMETERS \
211 filter_backprop, filter_dims, num_out, out_importance, num_inp, \
212 inp_features, inp_neighbors_importance_sum, \
213 inp_neighbors_row_splits, neighbors_index, neighbors_kernel_index, \
214 neighbors_importance, neighbors_row_splits, out_features_gradient
216 #define CALL_TEMPLATE(NORMALIZE) \
217 if (NORMALIZE == normalize) \
218 _SparseConvTransposeBackpropFilterCPU<TFeat, TOut, TIndex, \
219 TKernelIndex, NORMALIZE>( \
222 #define CALL_TEMPLATE2 \
223 CALL_TEMPLATE(true) \
229 #undef CALL_TEMPLATE2
Eigen::Matrix3d B
Definition: PointCloudPlanarPatchDetection.cpp:506
void SparseConvTransposeBackpropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, 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 *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TFeat *out_features_gradient, bool normalize)
Definition: SparseConvTransposeBackpropFilter.h:195
void _SparseConvTransposeBackpropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, 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 *neighbors_index, const TKernelIndex *neighbors_kernel_index, const TFeat *neighbors_importance, const int64_t *neighbors_row_splits, const TFeat *out_features_gradient)
Definition: SparseConvTransposeBackpropFilter.h:25
Definition: PinholeCameraIntrinsic.cpp:16