Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PSROIPooling layer forward CPU implementation by stealing code from its GPU implentation #10

Open
wants to merge 1 commit into
base: r-fcn
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
92 changes: 90 additions & 2 deletions src/caffe/layers/psroi_pooling_layer.cpp
Expand Up @@ -19,6 +19,84 @@ using std::floor;
using std::ceil;

namespace caffe {
template <typename Dtype>
void PSROIPoolingForward_cpu(
const int count,
const Dtype* bottom_data,
const Dtype spatial_scale,
const int channels,
const int height, const int width,
const int pooled_height, const int pooled_width,
const Dtype* bottom_rois,
const int output_dim,
const int group_size,
Dtype* top_data,
int* mapping_channel) {
const Dtype* bottom_data_bak = bottom_data;
const Dtype* bottom_rois_bak = bottom_rois;

for(int index = 0; index < count; ++index) {
bottom_data = bottom_data_bak;
bottom_rois = bottom_rois_bak;
// The output is in order (n, ctop, ph, pw)
int pw = index % pooled_width;
int ph = (index / pooled_width) % pooled_height;
int ctop = (index / pooled_width / pooled_height) % output_dim;
int n = index / pooled_width / pooled_height / output_dim;

// [start, end) interval for spatial sampling
bottom_rois += n * 5;
int roi_batch_ind = bottom_rois[0];
Dtype roi_start_w =
static_cast<Dtype>(round(bottom_rois[1])) * spatial_scale;
Dtype roi_start_h =
static_cast<Dtype>(round(bottom_rois[2])) * spatial_scale;
Dtype roi_end_w =
static_cast<Dtype>(round(bottom_rois[3]) + 1.) * spatial_scale;
Dtype roi_end_h =
static_cast<Dtype>(round(bottom_rois[4]) + 1.) * spatial_scale;

// Force too small ROIs to be 1x1
Dtype roi_width = max(roi_end_w - roi_start_w, static_cast<Dtype>(0.1f));// avoid 0
Dtype roi_height = max(roi_end_h - roi_start_h, static_cast<Dtype>(0.1f));

// Compute w and h at bottom
Dtype bin_size_h = roi_height / static_cast<Dtype>(pooled_height);
Dtype bin_size_w = roi_width / static_cast<Dtype>(pooled_width);

int hstart = floor(static_cast<Dtype>(ph) * bin_size_h
+ roi_start_h);
int wstart = floor(static_cast<Dtype>(pw)* bin_size_w
+ roi_start_w);
int hend = ceil(static_cast<Dtype>(ph + 1) * bin_size_h
+ roi_start_h);
int wend = ceil(static_cast<Dtype>(pw + 1) * bin_size_w
+ roi_start_w);
// Add roi offsets and clip to input boundaries
hstart = min(max(hstart, 0), height);
hend = min(max(hend, 0), height);
wstart = min(max(wstart, 0), width);
wend = min(max(wend, 0), width);
bool is_empty = (hend <= hstart) || (wend <= wstart);

int gw = pw;
int gh = ph;
int c = (ctop*group_size + gh)*group_size + gw;

bottom_data += (roi_batch_ind * channels + c) * height * width;
Dtype out_sum = 0;
for (int h = hstart; h < hend; ++h) {
for (int w = wstart; w < wend; ++w) {
int bottom_index = h*width + w;
out_sum += bottom_data[bottom_index];
}
}
Dtype bin_area = (hend - hstart)*(wend - wstart);
top_data[index] = is_empty? 0. : out_sum/bin_area;
mapping_channel[index] = c;
}
}

template <typename Dtype>
void PSROIPoolingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top){
Expand Down Expand Up @@ -52,7 +130,17 @@ namespace caffe {
template <typename Dtype>
void PSROIPoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top){
NOT_IMPLEMENTED;
const Dtype* bottom_data = bottom[0]->cpu_data();
const Dtype* bottom_rois = bottom[1]->cpu_data();
Dtype* top_data = top[0]->mutable_cpu_data();
int* mapping_channel_ptr = mapping_channel_.mutable_cpu_data();
int count = top[0]->count();
caffe_set(count, Dtype(0), top_data);
caffe_set(count, -1, mapping_channel_ptr);
PSROIPoolingForward_cpu(count, bottom_data, spatial_scale_,
channels_, height_, width_, pooled_height_,
pooled_width_, bottom_rois, output_dim_, group_size_,
top_data, mapping_channel_ptr);
}

template <typename Dtype>
Expand All @@ -67,4 +155,4 @@ namespace caffe {
INSTANTIATE_CLASS(PSROIPoolingLayer);
REGISTER_LAYER_CLASS(PSROIPooling);

}
}