| 126 | // case? |
| 127 | template <typename Dtype> |
| 128 | void PoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, |
| 129 | const vector<Blob<Dtype>*>& top) { |
| 130 | const Dtype* bottom_data = bottom[0]->cpu_data(); |
| 131 | Dtype* top_data = top[0]->mutable_cpu_data(); |
| 132 | const int top_count = top[0]->count(); |
| 133 | // We'll output the mask to top[1] if it's of size >1. |
| 134 | const bool use_top_mask = top.size() > 1; |
| 135 | int* mask = NULL; // suppress warnings about uninitalized variables |
| 136 | Dtype* top_mask = NULL; |
| 137 | // Different pooling methods. We explicitly do the switch outside the for |
| 138 | // loop to save time, although this results in more code. |
| 139 | switch (this->layer_param_.pooling_param().pool()) { |
| 140 | case PoolingParameter_PoolMethod_MAX: |
| 141 | // Initialize |
| 142 | if (use_top_mask) { |
| 143 | top_mask = top[1]->mutable_cpu_data(); |
| 144 | caffe_set(top_count, Dtype(-1), top_mask); |
| 145 | } else { |
| 146 | mask = max_idx_.mutable_cpu_data(); |
| 147 | caffe_set(top_count, -1, mask); |
| 148 | } |
| 149 | caffe_set(top_count, Dtype(-FLT_MAX), top_data); |
| 150 | // The main loop |
| 151 | for (int n = 0; n < bottom[0]->num(); ++n) { |
| 152 | for (int c = 0; c < channels_; ++c) { |
| 153 | for (int ph = 0; ph < pooled_height_; ++ph) { |
| 154 | for (int pw = 0; pw < pooled_width_; ++pw) { |
| 155 | int hstart = ph * stride_h_ - pad_h_; |
| 156 | int wstart = pw * stride_w_ - pad_w_; |
| 157 | int hend = min(hstart + kernel_h_, height_); |
| 158 | int wend = min(wstart + kernel_w_, width_); |
| 159 | hstart = max(hstart, 0); |
| 160 | wstart = max(wstart, 0); |
| 161 | const int pool_index = ph * pooled_width_ + pw; |
| 162 | for (int h = hstart; h < hend; ++h) { |
| 163 | for (int w = wstart; w < wend; ++w) { |
| 164 | const int index = h * width_ + w; |
| 165 | if (bottom_data[index] > top_data[pool_index]) { |
| 166 | top_data[pool_index] = bottom_data[index]; |
| 167 | if (use_top_mask) { |
| 168 | top_mask[pool_index] = static_cast<Dtype>(index); |
| 169 | } else { |
| 170 | mask[pool_index] = index; |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | // compute offset |
| 178 | bottom_data += bottom[0]->offset(0, 1); |
| 179 | top_data += top[0]->offset(0, 1); |
| 180 | if (use_top_mask) { |
| 181 | top_mask += top[0]->offset(0, 1); |
| 182 | } else { |
| 183 | mask += top[0]->offset(0, 1); |
| 184 | } |
| 185 | } |