9 #include <tbb/parallel_for.h>
19 template <
class TFeat,
23 bool POINT_IMPORTANCE>
25 const std::vector<int>& filter_dims,
28 const TFeat* inp_features,
29 const TFeat* inp_importance,
30 const TIndex* neighbors_index,
31 const TKernelIndex* neighbors_kernel_index,
32 const TFeat* neighbors_importance,
33 const int64_t* neighbors_row_splits,
34 const TFeat* out_features_gradient,
36 const bool NEIGHBOR_IMPORTANCE = neighbors_importance;
38 const int in_channels = filter_dims[filter_dims.size() - 2];
39 const int out_channels = filter_dims[filter_dims.size() - 1];
41 int num_kernel_elements = 1;
42 for (std::size_t i = 0; i < filter_dims.size() - 2; ++i) {
43 num_kernel_elements *= filter_dims[i];
45 const int total_filter_size =
46 num_kernel_elements * in_channels * out_channels;
48 memset(filter_backprop, 0,
sizeof(TOut) * total_filter_size);
49 std::mutex filter_backprop_mutex;
52 tbb::blocked_range<size_t>(0, num_out, 10032),
53 [&](
const tbb::blocked_range<size_t>& r) {
54 int range_length = r.end() - r.begin();
56 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> B(
57 in_channels * num_kernel_elements, range_length);
59 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> C(
60 out_channels, range_length);
62 Eigen::Array<TFeat, Eigen::Dynamic, 1> infeat(in_channels, 1);
64 for (
size_t out_idx = r.begin(); out_idx != r.end();
66 const int out_col = out_idx - r.begin();
67 const size_t neighbor_start = neighbors_row_splits[out_idx];
68 const size_t neighbor_end =
69 neighbors_row_splits[out_idx + 1];
72 for (
size_t n = neighbor_start; n < neighbor_end; ++n) {
73 const size_t inp_idx = neighbors_index[n];
74 const int kernel_idx = neighbors_kernel_index[n];
76 const TFeat n_importance =
77 (NEIGHBOR_IMPORTANCE ? neighbors_importance[n]
79 normalizer += n_importance;
81 for (
int ic = 0; ic < in_channels; ++ic)
83 inp_features[inp_idx * in_channels + ic];
87 importance = inp_importance[inp_idx];
88 if (NEIGHBOR_IMPORTANCE) importance *= n_importance;
90 if (POINT_IMPORTANCE || NEIGHBOR_IMPORTANCE) {
91 for (
int ic = 0; ic < in_channels; ++ic)
92 infeat(ic) *= importance;
94 for (
int ic = 0; ic < in_channels; ++ic) {
95 B(kernel_idx * in_channels + ic, out_col) =
100 C.col(out_col) = Eigen::Map<
101 const Eigen::Array<TFeat, Eigen::Dynamic, 1>>(
102 out_features_gradient + out_idx * out_channels,
106 C.col(out_col) /= normalizer;
110 Eigen::Matrix<TFeat, Eigen::Dynamic, Eigen::Dynamic> A(
111 out_channels, num_kernel_elements * in_channels);
113 A = C * B.transpose();
116 std::lock_guard<std::mutex> lock(filter_backprop_mutex);
118 for (
int j = 0; j < num_kernel_elements * in_channels; ++j)
119 for (
int i = 0; i < out_channels; ++i, ++linear_i) {
120 filter_backprop[linear_i] += TOut(A(i, j));
180 template <
class TFeat,
class TOut,
class TIndex,
class TKernelIndex>
182 const std::vector<int>& filter_dims,
185 const TFeat* inp_features,
186 const TFeat* inp_importance,
187 const TIndex* neighbors_index,
188 const TKernelIndex* neighbors_kernel_index,
189 const TFeat* neighbors_importance,
190 const int64_t* neighbors_row_splits,
191 const TFeat* out_features_gradient,
193 bool has_importance = inp_importance;
195 #define FN_PARAMETERS \
196 filter_backprop, filter_dims, num_out, num_inp, inp_features, \
197 inp_importance, neighbors_index, neighbors_kernel_index, \
198 neighbors_importance, neighbors_row_splits, out_features_gradient, \
201 #define CALL_TEMPLATE(HAS_IMPORTANCE) \
202 if (HAS_IMPORTANCE == has_importance) \
203 _SparseConvBackropFilterCPU<TFeat, TOut, TIndex, TKernelIndex, \
204 HAS_IMPORTANCE>(FN_PARAMETERS);
206 #define CALL_TEMPLATE2 \
207 CALL_TEMPLATE(true) \
213 #undef CALL_TEMPLATE2
__host__ __device__ float2 normalize(float2 v)
void _SparseConvBackropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, 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)
void SparseConvBackpropFilterCPU(TOut *filter_backprop, const std::vector< int > &filter_dims, size_t num_out, size_t num_inp, const TFeat *inp_features, const TFeat *inp_importance, 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)
Generic file read and write utility for python interface.