| 14 | |
| 15 | template <typename Dtype> |
| 16 | void FilterLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, |
| 17 | const vector<Blob<Dtype>*>& top) { |
| 18 | // bottom[0...k-1] are the blobs to filter |
| 19 | // bottom[last] is the "selector_blob" |
| 20 | int selector_index = bottom.size() - 1; |
| 21 | for (int i = 1; i < bottom[selector_index]->num_axes(); ++i) { |
| 22 | CHECK_EQ(bottom[selector_index]->shape(i), 1) |
| 23 | << "Selector blob dimensions must be singletons (1), except the first"; |
| 24 | } |
| 25 | for (int i = 0; i < bottom.size() - 1; ++i) { |
| 26 | CHECK_EQ(bottom[selector_index]->shape(0), bottom[i]->shape(0)) << |
| 27 | "Each bottom should have the same 0th dimension as the selector blob"; |
| 28 | } |
| 29 | |
| 30 | const Dtype* bottom_data_selector = bottom[selector_index]->cpu_data(); |
| 31 | indices_to_forward_.clear(); |
| 32 | |
| 33 | // look for non-zero elements in bottom[0]. Items of each bottom that |
| 34 | // have the same index as the items in bottom[0] with value == non-zero |
| 35 | // will be forwarded |
| 36 | for (int item_id = 0; item_id < bottom[selector_index]->shape(0); ++item_id) { |
| 37 | // we don't need an offset because item size == 1 |
| 38 | const Dtype* tmp_data_selector = bottom_data_selector + item_id; |
| 39 | if (*tmp_data_selector) { |
| 40 | indices_to_forward_.push_back(item_id); |
| 41 | } |
| 42 | } |
| 43 | // only filtered items will be forwarded |
| 44 | int new_tops_num = indices_to_forward_.size(); |
| 45 | // init |
| 46 | if (first_reshape_) { |
| 47 | new_tops_num = bottom[0]->shape(0); |
| 48 | first_reshape_ = false; |
| 49 | } |
| 50 | for (int t = 0; t < top.size(); ++t) { |
| 51 | int num_axes = bottom[t]->num_axes(); |
| 52 | vector<int> shape_top(num_axes); |
| 53 | shape_top[0] = new_tops_num; |
| 54 | for (int ts = 1; ts < num_axes; ++ts) |
| 55 | shape_top[ts] = bottom[t]->shape(ts); |
| 56 | top[t]->Reshape(shape_top); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | template <typename Dtype> |
| 61 | void FilterLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, |