Skip to content

Commit a6f995e

Browse files
authored
Merge pull request #11 from seventual/development
modify reduce_sum and reduce_max, remove the recursive functions (Author: Lucia)
2 parents b755679 + 8efc8ae commit a6f995e

File tree

4 files changed

+108
-126
lines changed

4 files changed

+108
-126
lines changed

include/caffe/layers/reduce_max_layer.hpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,7 @@ namespace caffe {
2323
virtual inline int ExactNumBottomBlobs() const { return 1; }
2424
virtual inline int ExactNumTopBlobs() const { return 1; }
2525

26-
inline int count_shape(vector<int>shape, int start) const {
27-
CHECK_GE(start, 0);
28-
CHECK_LE(start, shape.size());
29-
int count = 1;
30-
for (int i = start; i < shape.size(); ++i) {
31-
count *= shape[i];
32-
}
33-
return count;
34-
}
35-
3626
protected:
37-
virtual void OutReduceMax(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
38-
int lv_out, int b_idx, int lv_in, int t_idx);
39-
virtual void InReduceMax(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
40-
int b_idx, int lv_in, int t_idx);
4127

4228
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
4329
const vector<Blob<Dtype>*>& top);
@@ -47,6 +33,9 @@ namespace caffe {
4733
NOT_IMPLEMENTED;
4834
}
4935

36+
inline vector<int> indices(int offset, const vector<int> &shape) const;
37+
inline int offset(const vector<Blob<Dtype>*> &bottom, const vector<int> &shape, const vector<int> &axis_ind, const vector<int> &indices) const;
38+
5039
vector<int> reduce_max_axis_;
5140
bool reduce_max_keepdims_;
5241
int axis_dim_;

include/caffe/layers/reduce_sum_layer.hpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,8 @@ class ReduceSumLayer : public Layer<Dtype> {
2323
virtual inline int ExactNumBottomBlobs() const { return 1; }
2424
virtual inline int ExactNumTopBlobs() const { return 1; }
2525

26-
inline int count_shape(vector<int>shape, int start) const {
27-
CHECK_GE(start, 0);
28-
CHECK_LE(start, shape.size());
29-
int count = 1;
30-
for (int i = start; i < shape.size(); ++i) {
31-
count *= shape[i];
32-
}
33-
return count;
34-
}
3526

3627
protected:
37-
virtual void OutReduceSum(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
38-
int lv_out, int b_idx, int lv_in, int t_idx);
39-
virtual void InReduceSum(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
40-
int b_idx, int lv_in, int t_idx);
4128

4229
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
4330
const vector<Blob<Dtype>*>& top);
@@ -46,7 +33,10 @@ class ReduceSumLayer : public Layer<Dtype> {
4633
const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
4734
NOT_IMPLEMENTED;
4835
}
49-
36+
37+
inline vector<int> indices(int offset, const vector<int> &shape) const;
38+
inline int offset(const vector<Blob<Dtype>*> &bottom, const vector<int> &shape, const vector<int> &axis_ind, const vector<int> &indices) const;
39+
5040
vector<int> reduce_sum_axis_;
5141
bool reduce_sum_keepdims_;
5242
int axis_dim_;

src/caffe/layers/reduce_max_layer.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -58,55 +58,30 @@ namespace caffe {
5858
top[0]->Reshape(top_shape);
5959
}
6060

61-
template <typename Dtype>
62-
void ReduceMaxLayer<Dtype>::InReduceMax(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
63-
int b_idx, int lv_in, int t_idx) {
64-
const Dtype* bottom_data = bottom[0]->cpu_data();
65-
Dtype* top_data = top[0]->mutable_cpu_data();
66-
vector<int> shape_in(reduce_max_axis_.size(), 0);
67-
for (int i = 0; i < reduce_max_axis_.size(); ++i) {
68-
shape_in[i] = bottom[0]->shape()[reduce_max_axis_[i]];
69-
}
70-
for (int i = 0; i < shape_in[lv_in]; ++i) {
71-
int b_idx_add = i * bottom[0]->count(reduce_max_axis_[lv_in] + 1);
72-
if (lv_in == shape_in.size() - 1) {
73-
if (top_data[t_idx] < bottom_data[b_idx + b_idx_add]) {
74-
top_data[t_idx] = bottom_data[b_idx + b_idx_add];
75-
}
76-
}
77-
if (lv_in < shape_in.size() - 1) {
78-
InReduceMax(bottom, top, b_idx + b_idx_add, lv_in + 1, t_idx);
79-
}
80-
}
81-
};
82-
8361

8462
template <typename Dtype>
85-
void ReduceMaxLayer<Dtype>::OutReduceMax(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
86-
int lv_out, int b_idx, int lv_in, int t_idx) {
87-
// parameters: axis_dim_, shape_out, idx_out
88-
vector<int> shape_out = bottom[0]->shape();
89-
vector<int> idx_out(bottom[0]->num_axes(), 0);
90-
for (int i = 0; i < idx_out.size(); ++i) {
91-
idx_out[i] = i;
92-
}
93-
for (int i = axis_dim_ - 1; i > -1; --i) {
94-
shape_out.erase(shape_out.begin() + reduce_max_axis_[i]);
95-
idx_out.erase(idx_out.begin() + reduce_max_axis_[i]);
96-
}
63+
inline vector<int>
64+
ReduceMaxLayer<Dtype>::indices(int offset, const vector<int> &shape) const {
65+
vector<int> indices(shape.size());
66+
int r = offset;
67+
for (int i = shape.size() - 1; i >= 0; i--) {
68+
indices[i] = r % shape[i];
69+
r /= shape[i];
70+
}
71+
return indices;
72+
}
9773

98-
// main part
99-
for (int i = 0; i < shape_out[lv_out]; ++i) {
100-
int b_idx_add = i * bottom[0]->count(idx_out[lv_out] + 1);
101-
int t_idx_add = i * count_shape(shape_out, lv_out + 1);
102-
if (lv_out == shape_out.size() - 1) {
103-
InReduceMax(bottom, top, b_idx + b_idx_add, lv_in, t_idx + t_idx_add);
104-
}
105-
if (lv_out < shape_out.size() - 1) {
106-
OutReduceMax(bottom, top, lv_out + 1, b_idx + b_idx_add, lv_in, t_idx + t_idx_add);
107-
}
74+
template <typename Dtype>
75+
inline int
76+
ReduceMaxLayer<Dtype>::offset(const vector<Blob<Dtype>*>& bottom, const vector<int> &shape,
77+
const vector<int> &axis_ind, const vector<int> &indices) const {
78+
int offset = 0;
79+
for (int i = 0; i < axis_ind.size(); ++i) {
80+
offset += indices[i] * bottom[0]->count(axis_ind[i] + 1);
10881
}
109-
};
82+
return offset;
83+
}
84+
11085

11186
template <typename Dtype>
11287
void ReduceMaxLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
@@ -116,6 +91,7 @@ namespace caffe {
11691
Dtype* top_data = top[0]->mutable_cpu_data();
11792
const int bottom_count = bottom[0]->count();
11893
const int top_count = top[0]->count();
94+
const vector<int> bottom_shape = bottom[0]->shape();
11995
// initialize the top_data
12096
std::vector<Dtype> bottom_sort(bottom_count, 0);
12197
for (int i = 0; i < bottom_count; ++i) {
@@ -135,11 +111,35 @@ namespace caffe {
135111
}
136112
else {
137113
// has axis, compare all elements in dim:reduce_max_axis_
138-
int lv_out = 0;
139-
int lv_in = 0;
140-
int b_idx = 0;
141-
int t_idx = 0;
142-
OutReduceMax(bottom, top, lv_out, b_idx, lv_in, t_idx);
114+
vector<int> shape_out = bottom[0]->shape();
115+
vector<int> axis_out(bottom[0]->num_axes(), 0);
116+
for (int i = 0; i < axis_out.size(); ++i) {
117+
axis_out[i] = i;
118+
}
119+
for (int i = axis_dim_ - 1; i > -1; --i) {
120+
shape_out.erase(shape_out.begin() + reduce_max_axis_[i]);
121+
axis_out.erase(axis_out.begin() + reduce_max_axis_[i]);
122+
}
123+
124+
vector<int> shape_in(reduce_max_axis_.size(), 0);
125+
for (int i = 0; i < reduce_max_axis_.size(); ++i) {
126+
shape_in[i] = bottom[0]->shape()[reduce_max_axis_[i]];
127+
}
128+
129+
130+
for (int i = 0; i < top_count; ++i){
131+
vector<int> ind_out = indices(i, shape_out);
132+
int offset_out = offset(bottom, bottom_shape, axis_out, ind_out);
133+
for (int j = 0; j < bottom_count/top_count; ++j) {
134+
vector<int> ind_in = indices(j, shape_in);
135+
int offset_in = offset(bottom, bottom_shape, reduce_max_axis_, ind_in);
136+
int b_idx = offset_out + offset_in;
137+
if (top_data[i] < bottom_data[b_idx]) {
138+
top_data[i] = bottom_data[b_idx];
139+
}
140+
141+
}
142+
}
143143
}
144144
}
145145

src/caffe/layers/reduce_sum_layer.cpp

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "caffe/util/math_functions.hpp"
66

77
namespace caffe {
8-
98
template <typename Dtype>
109
void ReduceSumLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
1110
const vector<Blob<Dtype>*>& top) {
@@ -58,71 +57,75 @@ namespace caffe {
5857
top[0]->Reshape(top_shape);
5958
}
6059

60+
6161
template <typename Dtype>
62-
void ReduceSumLayer<Dtype>::InReduceSum(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
63-
int b_idx, int lv_in, int t_idx) {
64-
const Dtype* bottom_data = bottom[0]->cpu_data();
65-
Dtype* top_data = top[0]->mutable_cpu_data();
66-
vector<int> shape_in(reduce_sum_axis_.size(), 0);
67-
for (int i = 0; i < reduce_sum_axis_.size(); ++i) {
68-
shape_in[i] = bottom[0]->shape()[reduce_sum_axis_[i]];
69-
}
70-
for (int i = 0; i < shape_in[lv_in]; ++i) {
71-
int b_idx_add = i * bottom[0]->count(reduce_sum_axis_[lv_in] + 1);
72-
if (lv_in == shape_in.size() - 1) {
73-
top_data[t_idx] += bottom_data[b_idx + b_idx_add];
74-
}
75-
if (lv_in < shape_in.size() - 1) {
76-
InReduceSum(bottom, top, b_idx + b_idx_add, lv_in + 1, t_idx);
77-
}
78-
}
79-
};
62+
inline vector<int>
63+
ReduceSumLayer<Dtype>::indices(int offset, const vector<int> &shape) const {
64+
vector<int> indices(shape.size());
65+
int r = offset;
66+
for (int i = shape.size() - 1; i >= 0; i--) {
67+
indices[i] = r % shape[i];
68+
r /= shape[i];
69+
}
70+
return indices;
71+
}
8072

8173
template <typename Dtype>
82-
void ReduceSumLayer<Dtype>::OutReduceSum(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top,
83-
int lv_out, int b_idx, int lv_in, int t_idx) {
84-
// parameters: shape_out, idx_out
85-
vector<int> shape_out = bottom[0]->shape();
86-
vector<int> idx_out(bottom[0]->num_axes(), 0);
87-
for (int i = 0; i < idx_out.size(); ++i) {
88-
idx_out[i] = i;
89-
}
90-
for (int i = axis_dim_ - 1; i > -1; --i) {
91-
shape_out.erase(shape_out.begin() + reduce_sum_axis_[i]);
92-
idx_out.erase(idx_out.begin() + reduce_sum_axis_[i]);
93-
}
94-
// main part
95-
for (int i = 0; i < shape_out[lv_out]; ++i) {
96-
int b_idx_add = i * bottom[0]->count(idx_out[lv_out] + 1);
97-
int t_idx_add = i * count_shape(shape_out, lv_out + 1);
98-
if (lv_out == shape_out.size() - 1) {
99-
InReduceSum(bottom, top, b_idx + b_idx_add, lv_in, t_idx + t_idx_add);
100-
}
101-
if (lv_out < shape_out.size() - 1) {
102-
OutReduceSum(bottom, top, lv_out + 1, b_idx + b_idx_add, lv_in, t_idx + t_idx_add);
103-
}
74+
inline int
75+
ReduceSumLayer<Dtype>::offset(const vector<Blob<Dtype>*>& bottom, const vector<int> &shape,
76+
const vector<int> &axis_ind, const vector<int> &indices) const {
77+
int offset = 0;
78+
for (int i = 0; i < axis_ind.size(); ++i) {
79+
offset += indices[i] * bottom[0]->count(axis_ind[i] + 1);
10480
}
105-
};
81+
return offset;
82+
}
83+
10684

10785
template <typename Dtype>
10886
void ReduceSumLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
10987
const vector<Blob<Dtype>*>& top) {
11088
const Dtype* bottom_data = bottom[0]->cpu_data();
11189
Dtype* top_data = top[0]->mutable_cpu_data();
90+
const vector<int> bottom_shape = bottom[0]->shape();
11291
const int bottom_count = bottom[0]->count();
92+
const int top_count = top[0]->count();
93+
caffe_set(top_count, Dtype(0), top_data);
11394
if (axis_dim_ == 0 || axis_dim_ == bottom[0]->num_axes()) {
11495
// no axis, add all elements
11596
for (int i = 0; i < bottom_count; ++i) {
11697
top_data[0] += bottom_data[i];
117-
}
98+
}
11899
}
119100
else {
120101
// has axis, add all elements in dim:reduce_sum_axis_
121-
int lv_out = 0;
122-
int lv_in = 0;
123-
int b_idx = 0;
124-
int t_idx = 0;
125-
OutReduceSum(bottom, top, lv_out, b_idx, lv_in, t_idx);
102+
vector<int> shape_out = bottom[0]->shape();
103+
vector<int> axis_out(bottom[0]->num_axes(), 0);
104+
for (int i = 0; i < axis_out.size(); ++i) {
105+
axis_out[i] = i;
106+
}
107+
for (int i = axis_dim_ - 1; i > -1; --i) {
108+
shape_out.erase(shape_out.begin() + reduce_sum_axis_[i]);
109+
axis_out.erase(axis_out.begin() + reduce_sum_axis_[i]);
110+
}
111+
112+
vector<int> shape_in(reduce_sum_axis_.size(), 0);
113+
for (int i = 0; i < reduce_sum_axis_.size(); ++i) {
114+
shape_in[i] = bottom[0]->shape()[reduce_sum_axis_[i]];
115+
}
116+
117+
118+
for (int i = 0; i < top_count; ++i){
119+
vector<int> ind_out = indices(i, shape_out);
120+
int offset_out = offset(bottom, bottom_shape, axis_out, ind_out);
121+
for (int j = 0; j < bottom_count/top_count; ++j) {
122+
vector<int> ind_in = indices(j, shape_in);
123+
int offset_in = offset(bottom, bottom_shape, reduce_sum_axis_, ind_in);
124+
int b_idx = offset_out + offset_in;
125+
top_data[i] += bottom_data[b_idx];
126+
127+
}
128+
}
126129
}
127130
}
128131

0 commit comments

Comments
 (0)