206 const size_t num_positions,
207 const T*
const positions,
208 const T voxel_size) {
209 typedef Eigen::Array<double, 3, 1> Vec3_t;
210 if (num_positions == 0) {
214 Vec3_t bb_min, bb_max;
215 bb_min << positions[0], positions[1], positions[2];
218 Vec3_t voxel_size3(voxel_size, voxel_size, voxel_size);
220 for (
size_t i = 1; i < num_positions; ++i) {
221 Vec3_t pos(positions[i * 3 + 0], positions[i * 3 + 1],
222 positions[i * 3 + 2]);
223 bb_min = bb_min.min(pos);
224 bb_max = bb_max.max(pos);
228 bb_min /= voxel_size3;
229 bb_min = bb_min.floor() * voxel_size3;
230 bb_max /= voxel_size3;
231 bb_max = bb_max.ceil() * voxel_size3;
233 if (voxel_size *
double(std::numeric_limits<int>::max()) <
235 voxel_size *
double(std::numeric_limits<int>::min()) >
237 err =
"voxel_size is too small\n";
263 const TReal*
const inp_positions,
265 const TFeat* inp_features,
267 OUTPUT_ALLOCATOR& output_allocator) {
271 output_allocator.AllocPooledPositions(&out_pos_ptr, 0);
272 output_allocator.AllocPooledFeatures(&out_feat_ptr, 0, in_channels);
276 typedef Eigen::Array<TReal, 3, 1> Vec3_t;
277 typedef Eigen::Array<TFeat, Eigen::Dynamic, 1> FeatureVec_t;
279 std::unordered_map<Eigen::Vector3i, ACCUMULATOR,
281 voxelindex_to_accpoint;
284 Eigen::Vector3i voxel_index;
285 TReal inv_voxel_size = 1 / voxel_size;
286 TReal half_voxel_size = 0.5 * voxel_size;
287 for (
size_t i = 0; i < num_inp; ++i) {
288 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
292 voxel_center << voxel_index(0) * voxel_size + half_voxel_size,
293 voxel_index(1) * voxel_size + half_voxel_size,
294 voxel_index(2) * voxel_size + half_voxel_size;
296 Eigen::Map<const FeatureVec_t> feat(inp_features + in_channels * i,
298 voxelindex_to_accpoint[voxel_index].AddPoint(
299 pos.matrix(), voxel_center.matrix(), feat);
302 const size_t num_out = voxelindex_to_accpoint.size();
306 output_allocator.AllocPooledPositions(&out_pos_ptr, num_out);
307 output_allocator.AllocPooledFeatures(&out_feat_ptr, num_out, in_channels);
310 for (
const auto point : voxelindex_to_accpoint) {
311 Vec3_t pos = point.second.Position();
312 Eigen::Map<Vec3_t> out_pos(out_pos_ptr + i * 3);
315 Eigen::Map<FeatureVec_t> out_feat(out_feat_ptr + i * in_channels,
317 out_feat = point.second.Features();
327 const TReal*
const inp_positions,
329 const TFeat*
const inp_features,
331 const TReal*
const pooled_positions,
332 const TFeat*
const pooled_features_gradient,
337 memset(features_backprop, 0,
sizeof(TFeat) * num_inp * in_channels);
339 typedef Eigen::Array<TReal, 3, 1> Vec3_t;
340 typedef Eigen::Array<TFeat, Eigen::Dynamic, 1> FeatureVec_t;
342 Vec3_t voxel_size3(voxel_size, voxel_size, voxel_size);
345 tbb::task_group task_group;
347 std::unordered_map<Eigen::Vector3i, ACCUMULATOR,
349 voxelindex_to_accpoint;
353 Eigen::Vector3i voxel_index;
354 TReal inv_voxel_size = 1 / voxel_size;
355 TReal half_voxel_size = 0.5 * voxel_size;
356 for (
size_t i = 0; i < num_inp; ++i) {
357 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
361 voxel_center << voxel_index(0) * voxel_size + half_voxel_size,
362 voxel_index(1) * voxel_size + half_voxel_size,
363 voxel_index(2) * voxel_size + half_voxel_size;
365 Eigen::Map<const FeatureVec_t> feat(inp_features + in_channels * i,
367 voxelindex_to_accpoint[voxel_index].AddPoint(
368 pos.matrix(), voxel_center.matrix(), feat, i);
372 std::unordered_map<Eigen::Vector3i, size_t,
374 voxelindex_to_gradindex;
377 Eigen::Vector3i voxel_index;
378 TReal inv_voxel_size = 1 / voxel_size;
379 for (
size_t i = 0; i < num_pooled; ++i) {
380 Eigen::Map<const Vec3_t> pos(pooled_positions + i * 3);
384 voxelindex_to_gradindex[voxel_index] = i;
391 Eigen::Vector3i voxel_index;
392 TReal inv_voxel_size = 1 / voxel_size;
393 for (
size_t i = 0; i < num_inp; ++i) {
394 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
398 Eigen::Map<FeatureVec_t> feat_bp(
399 features_backprop + in_channels * i, in_channels);
401 size_t grad_idx = voxelindex_to_gradindex[voxel_index];
402 int count = voxelindex_to_accpoint[voxel_index].Count();
403 Eigen::Map<const FeatureVec_t> grad(
404 pooled_features_gradient + in_channels * grad_idx,
406 feat_bp = grad / count;
411 for (
const auto point : voxelindex_to_accpoint) {
412 size_t idx = point.second.Index()(0);
413 Eigen::Map<FeatureVec_t> feat_bp(
414 features_backprop + in_channels * idx, in_channels);
416 size_t grad_idx = voxelindex_to_gradindex[point.first];
417 Eigen::Map<const FeatureVec_t> grad(
418 pooled_features_gradient + in_channels * grad_idx,
424 if (FEAT_FN ==
MAX) {
425 for (
const auto point : voxelindex_to_accpoint) {
426 size_t grad_idx = voxelindex_to_gradindex[point.first];
427 Eigen::Map<const FeatureVec_t> grad(
428 pooled_features_gradient + in_channels * grad_idx,
430 for (
int i = 0; i < in_channels; ++i) {
431 size_t idx = point.second.Index()(i);
432 Eigen::Map<FeatureVec_t> feat_bp(
433 features_backprop + in_channels * idx, in_channels);
434 feat_bp(i) = grad(i);
void VoxelPoolingBackprop(TFeat *features_backprop, size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *const inp_features, size_t num_pooled, const TReal *const pooled_positions, const TFeat *const pooled_features_gradient, TReal voxel_size, AccumulationFn position_fn, AccumulationFn feature_fn)
Definition VoxelPooling.h:530
void VoxelPooling(size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *inp_features, TReal voxel_size, OUTPUT_ALLOCATOR &output_allocator, AccumulationFn position_fn, AccumulationFn feature_fn)
Definition VoxelPooling.h:485
void _VoxelPoolingBackprop(TFeat *features_backprop, size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *const inp_features, size_t num_pooled, const TReal *const pooled_positions, const TFeat *const pooled_features_gradient, TReal voxel_size)
Definition VoxelPooling.h:325