78 channels_ = bottom[0]->channels();
79 height_ = bottom[0]->height();
80 width_ = bottom[0]->width();
81 top[0]->Reshape(bottom[1]->num(), channels_, pooled_height_, pooled_width_);
82 auto feat_bottom = bottom[0];
83 auto roi_bottom = bottom[1];
84 const Dtype *bottom_data = feat_bottom->cpu_data();
85 const Dtype *bottom_rois = roi_bottom->cpu_data();
87 int num_rois = roi_bottom->num();
88 int batch_size = feat_bottom->num();
89 int top_count = top[0]->count();
90 Dtype *top_data = top[0]->mutable_cpu_data();
91 memset(top_data, -1,
static_cast<size_t>(float_max_ *
sizeof(Dtype)));
92 int *argmax_data = max_idx_.mutable_cpu_data();
93 memset(argmax_data, -1, top_count *
sizeof(
int));
95 for (
int n = 0; n < num_rois; ++n) {
96 int roi_batch_ind =
static_cast<int>(bottom_rois[0]);
102 roi_start_w =
static_cast<int>(floor(bottom_rois[1] * spatial_scale_));
103 roi_start_h =
static_cast<int>(floor(bottom_rois[2] * spatial_scale_));
104 roi_end_w =
static_cast<int>(floor(bottom_rois[3] * spatial_scale_));
105 roi_end_h =
static_cast<int>(floor(bottom_rois[4] * spatial_scale_));
107 roi_start_w =
static_cast<int>(round(bottom_rois[1] * spatial_scale_));
108 roi_start_h =
static_cast<int>(round(bottom_rois[2] * spatial_scale_));
109 roi_end_w =
static_cast<int>(round(bottom_rois[3] * spatial_scale_));
110 roi_end_h =
static_cast<int>(round(bottom_rois[4] * spatial_scale_));
112 CHECK_GE(roi_batch_ind, 0);
113 CHECK_LT(roi_batch_ind, batch_size);
115 int roi_height = std::max(roi_end_h - roi_start_h + 1, 1);
116 int roi_width = std::max(roi_end_w - roi_start_w + 1, 1);
117 const Dtype bin_size_h =
118 static_cast<Dtype
>(roi_height) /
static_cast<Dtype
>(pooled_height_);
119 const Dtype bin_size_w =
120 static_cast<Dtype
>(roi_width) /
static_cast<Dtype
>(pooled_width_);
122 const Dtype *batch_data = bottom_data + bottom[0]->offset(roi_batch_ind);
124 for (
int c = 0; c < channels_; ++c) {
125 for (
int ph = 0; ph < pooled_height_; ++ph) {
126 for (
int pw = 0; pw < pooled_width_; ++pw) {
129 static_cast<int>(floor(
static_cast<Dtype
>(ph) * bin_size_h));
131 static_cast<int>(floor(
static_cast<Dtype
>(pw) * bin_size_w));
133 static_cast<int>(ceil(
static_cast<Dtype
>(ph + 1) * bin_size_h));
135 static_cast<int>(ceil(
static_cast<Dtype
>(pw + 1) * bin_size_w));
137 hstart = std::min(std::max(hstart + roi_start_h, 0), height_);
138 hend = std::min(std::max(hend + roi_start_h, 0), height_);
139 wstart = std::min(std::max(wstart + roi_start_w, 0), width_);
140 wend = std::min(std::max(wend + roi_start_w, 0), width_);
142 bool is_empty = (hend <= hstart) || (wend <= wstart);
143 const int pool_index = ph * pooled_width_ + pw;
145 top_data[pool_index] = 0;
146 argmax_data[pool_index] = -1;
149 for (
int h = hstart; h < hend; ++h) {
150 for (
int w = wstart; w < wend; ++w) {
151 const int index = h * width_ + w;
152 if (batch_data[index] > top_data[pool_index]) {
153 top_data[pool_index] = batch_data[index];
154 argmax_data[pool_index] = index;
161 batch_data += feat_bottom->offset(0, 1);
162 top_data += top[0]->offset(0, 1);
163 argmax_data += max_idx_.offset(0, 1);
166 bottom_rois += roi_bottom->offset(1);