Skip to content

Commit

Permalink
FilterLayer cleanup and bugfix for GPU backward
Browse files Browse the repository at this point in the history
-caffe_set -> caffe_gpu_set (backward was segfaulting before)
-remove uses of 'offset' (to support >4D blobs)
-change var++ -> ++var (per Google style guide)
-cleanup comments/whitespace
  • Loading branch information
jeffdonahue committed Jun 3, 2015
1 parent 5bde20b commit 0ccf336
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
6 changes: 3 additions & 3 deletions include/caffe/common_layers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ class FilterLayer : public Layer<Dtype> {
* -# @f$ (N \times 1 \times 1 \times 1) @f$
* the selector blob
* @param top output Blob vector (length 1+)
* -# @f$ (S \times C \times H \times W) @f$ ()
* the filtered output @f$ x_1 @f$
* -# @f$ (S \times C \times H \times W) @f$ ()
* the filtered output @f$ x_1 @f$
* where S is the number of items
* that haven't been filtered
* @f$ (S \times C \times H \times W) @f$
* the filtered output @f$ x_K @f$
* the filtered output @f$ x_K @f$
* where S is the number of items
* that haven't been filtered
*/
Expand Down
25 changes: 12 additions & 13 deletions src/caffe/layers/filter_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace caffe {
template <typename Dtype>
void FilterLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
CHECK_EQ(top.size(), bottom.size()-1) <<
"Top.size() should be equal to bottom.size() - 1";
CHECK_EQ(top.size(), bottom.size() - 1);
first_reshape_ = true;
}

Expand All @@ -23,11 +22,11 @@ void FilterLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
int selector_index = bottom.size() - 1;
for (int i = 1; i < bottom[selector_index]->num_axes(); ++i) {
CHECK_EQ(bottom[selector_index]->shape(i), 1)
<< "Selector blob must have all shapes == 1 (except the first one)";
<< "Selector blob dimensions must be singletons (1), except the first";
}
for (int i = 0; i < bottom.size()-1; i++) {
for (int i = 0; i < bottom.size() - 1; ++i) {
CHECK_EQ(bottom[selector_index]->shape(0), bottom[i]->shape(0)) <<
"Each bottom should have the same dimension as the selector blob";
"Each bottom should have the same 0th dimension as the selector blob";
}

const Dtype* bottom_data_selector = bottom[selector_index]->cpu_data();
Expand All @@ -50,11 +49,11 @@ void FilterLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
new_tops_num = bottom[0]->shape(0);
first_reshape_ = false;
}
for (int t = 0; t < top.size(); t++) {
for (int t = 0; t < top.size(); ++t) {
int num_axes = bottom[t]->num_axes();
vector<int> shape_top(num_axes);
shape_top[0] = new_tops_num;
for (int ts = 1; ts < num_axes; ts++)
for (int ts = 1; ts < num_axes; ++ts)
shape_top[ts] = bottom[t]->shape(ts);
top[t]->Reshape(shape_top);
}
Expand All @@ -65,13 +64,13 @@ void FilterLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int new_tops_num = indices_to_forward_.size();
// forward all filtered items for all bottoms but the Selector (bottom[last])
for (int t = 0; t < top.size(); t++) {
for (int t = 0; t < top.size(); ++t) {
const Dtype* bottom_data = bottom[t]->cpu_data();
Dtype* top_data = top[t]->mutable_cpu_data();
int dim = bottom[t]->count() / bottom[t]->shape(0);
for (int n = 0; n < new_tops_num; n++) {
int data_offset_top = top[t]->offset(n);
int data_offset_bottom = bottom[t]->offset(indices_to_forward_[n]);
for (int n = 0; n < new_tops_num; ++n) {
int data_offset_top = n * dim;
int data_offset_bottom = indices_to_forward_[n] * bottom[t]->count(1);
caffe_copy(dim, bottom_data + data_offset_bottom,
top_data + data_offset_top);
}
Expand All @@ -95,7 +94,7 @@ void FilterLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
int data_offset_bottom = 0;
int data_offset_top = 0;
for (int n = 0; n < bottom[i]->shape(0); n++) {
data_offset_bottom = bottom[i]->offset(n);
data_offset_bottom = n * dim;
if (next_to_backward_offset >= indices_to_forward_.size()) {
// we already visited all items that were been forwarded, so
// just set to zero remaining ones
Expand All @@ -107,7 +106,7 @@ void FilterLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
caffe_set(dim, Dtype(0),
bottom[i]->mutable_cpu_diff() + data_offset_bottom);
} else { // this data was been forwarded
data_offset_top = top[i]->offset(next_to_backward_offset);
data_offset_top = next_to_backward_offset * dim;
next_to_backward_offset++; // point to next forwarded item index
caffe_copy(dim, top[i]->mutable_cpu_diff() + data_offset_top,
bottom[i]->mutable_cpu_diff() + data_offset_bottom);
Expand Down
26 changes: 13 additions & 13 deletions src/caffe/layers/filter_layer.cu
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ void FilterLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int new_tops_num = indices_to_forward_.size();
// forward all filtered items for all bottoms but the Selector (bottom[last])
for (int t = 0; t < top.size(); t++) {
for (int t = 0; t < top.size(); ++t) {
const Dtype* bottom_data = bottom[t]->gpu_data();
Dtype* top_data = top[t]->mutable_gpu_data();
int dim = bottom[t]->count() / bottom[t]->shape(0);
for (int n = 0; n < new_tops_num; n++) {
int data_offset_top = top[t]->offset(n);
int data_offset_bottom = bottom[t]->offset(indices_to_forward_[n]);
for (int n = 0; n < new_tops_num; ++n) {
int data_offset_top = n * dim;
int data_offset_bottom = indices_to_forward_[n] * dim;
caffe_copy(dim, bottom_data + data_offset_bottom,
top_data + data_offset_top);
}
Expand All @@ -29,9 +29,9 @@ void FilterLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
if (propagate_down[bottom.size() - 1]) {
LOG(FATAL) << this->type()
<< "Layer cannot backpropagate to filter index inputs";
<< "Layer cannot backpropagate to filter index inputs";
}
for (int i = 0; i < top.size(); i++) {
for (int i = 0; i < top.size(); ++i) {
// bottom[last] is the selector and never needs backpropagation
// so we can iterate over top vector because top.size() == bottom.size() -1
if (propagate_down[i]) {
Expand All @@ -40,22 +40,22 @@ void FilterLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
int batch_offset = 0;
int data_offset_bottom = 0;
int data_offset_top = 0;
for (int n = 0; n < bottom[i]->shape(0); n++) {
for (int n = 0; n < bottom[i]->shape(0); ++n) {
if (next_to_backward_offset >= indices_to_forward_.size()) {
// we already visited all items that were been forwarded, so
// just set to zero remaining ones
data_offset_bottom = top[i]->offset(n);
caffe_set(dim, Dtype(0),
data_offset_bottom = n * dim;
caffe_gpu_set(dim, Dtype(0),
bottom[i]->mutable_gpu_diff() + data_offset_bottom);
} else {
batch_offset = indices_to_forward_[next_to_backward_offset];
data_offset_bottom = top[i]->offset(n);
data_offset_bottom = n * dim;
if (n != batch_offset) { // this data was not been forwarded
caffe_set(dim, Dtype(0),
caffe_gpu_set(dim, Dtype(0),
bottom[i]->mutable_gpu_diff() + data_offset_bottom);
} else { // this data was been forwarded
data_offset_top = top[i]->offset(next_to_backward_offset);
next_to_backward_offset++; // point to next forwarded item index
data_offset_top = next_to_backward_offset * dim;
++next_to_backward_offset; // point to next forwarded item index
caffe_copy(dim, top[i]->mutable_gpu_diff() + data_offset_top,
bottom[i]->mutable_gpu_diff() + data_offset_bottom);
}
Expand Down

0 comments on commit 0ccf336

Please sign in to comment.