| 43 | |
| 44 | template <typename Dtype> |
| 45 | void EltwiseLayer<Dtype>::Forward_cpu( |
| 46 | const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { |
| 47 | int* mask = NULL; |
| 48 | const Dtype* bottom_data_a = NULL; |
| 49 | const Dtype* bottom_data_b = NULL; |
| 50 | const int count = top[0]->count(); |
| 51 | Dtype* top_data = top[0]->mutable_cpu_data(); |
| 52 | switch (op_) { |
| 53 | case EltwiseParameter_EltwiseOp_PROD: |
| 54 | caffe_mul(count, bottom[0]->cpu_data(), bottom[1]->cpu_data(), top_data); |
| 55 | for (int i = 2; i < bottom.size(); ++i) { |
| 56 | caffe_mul(count, top_data, bottom[i]->cpu_data(), top_data); |
| 57 | } |
| 58 | break; |
| 59 | case EltwiseParameter_EltwiseOp_SUM: |
| 60 | caffe_set(count, Dtype(0), top_data); |
| 61 | // TODO(shelhamer) does BLAS optimize to sum for coeff = 1? |
| 62 | for (int i = 0; i < bottom.size(); ++i) { |
| 63 | caffe_axpy(count, coeffs_[i], bottom[i]->cpu_data(), top_data); |
| 64 | } |
| 65 | break; |
| 66 | case EltwiseParameter_EltwiseOp_MAX: |
| 67 | // Initialize |
| 68 | mask = max_idx_.mutable_cpu_data(); |
| 69 | caffe_set(count, -1, mask); |
| 70 | caffe_set(count, Dtype(-FLT_MAX), top_data); |
| 71 | // bottom 0 & 1 |
| 72 | bottom_data_a = bottom[0]->cpu_data(); |
| 73 | bottom_data_b = bottom[1]->cpu_data(); |
| 74 | for (int idx = 0; idx < count; ++idx) { |
| 75 | if (bottom_data_a[idx] > bottom_data_b[idx]) { |
| 76 | top_data[idx] = bottom_data_a[idx]; // maxval |
| 77 | mask[idx] = 0; // maxid |
| 78 | } else { |
| 79 | top_data[idx] = bottom_data_b[idx]; // maxval |
| 80 | mask[idx] = 1; // maxid |
| 81 | } |
| 82 | } |
| 83 | // bottom 2++ |
| 84 | for (int blob_idx = 2; blob_idx < bottom.size(); ++blob_idx) { |
| 85 | bottom_data_b = bottom[blob_idx]->cpu_data(); |
| 86 | for (int idx = 0; idx < count; ++idx) { |
| 87 | if (bottom_data_b[idx] > top_data[idx]) { |
| 88 | top_data[idx] = bottom_data_b[idx]; // maxval |
| 89 | mask[idx] = blob_idx; // maxid |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | break; |
| 94 | default: |
| 95 | LOG(FATAL) << "Unknown elementwise operation."; |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | template <typename Dtype> |
| 100 | void EltwiseLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, |
nothing calls this directly
no test coverage detected