| 100 | |
| 101 | template <typename Dtype> |
| 102 | void EltwiseLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, |
| 103 | const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { |
| 104 | const int* mask = NULL; |
| 105 | const int count = top[0]->count(); |
| 106 | const Dtype* top_data = top[0]->cpu_data(); |
| 107 | const Dtype* top_diff = top[0]->cpu_diff(); |
| 108 | for (int i = 0; i < bottom.size(); ++i) { |
| 109 | if (propagate_down[i]) { |
| 110 | const Dtype* bottom_data = bottom[i]->cpu_data(); |
| 111 | Dtype* bottom_diff = bottom[i]->mutable_cpu_diff(); |
| 112 | switch (op_) { |
| 113 | case EltwiseParameter_EltwiseOp_PROD: |
| 114 | if (stable_prod_grad_) { |
| 115 | bool initialized = false; |
| 116 | for (int j = 0; j < bottom.size(); ++j) { |
| 117 | if (i == j) { continue; } |
| 118 | if (!initialized) { |
| 119 | caffe_copy(count, bottom[j]->cpu_data(), bottom_diff); |
| 120 | initialized = true; |
| 121 | } else { |
| 122 | caffe_mul(count, bottom[j]->cpu_data(), bottom_diff, |
| 123 | bottom_diff); |
| 124 | } |
| 125 | } |
| 126 | } else { |
| 127 | caffe_div(count, top_data, bottom_data, bottom_diff); |
| 128 | } |
| 129 | caffe_mul(count, bottom_diff, top_diff, bottom_diff); |
| 130 | break; |
| 131 | case EltwiseParameter_EltwiseOp_SUM: |
| 132 | if (coeffs_[i] == Dtype(1)) { |
| 133 | caffe_copy(count, top_diff, bottom_diff); |
| 134 | } else { |
| 135 | caffe_cpu_scale(count, coeffs_[i], top_diff, bottom_diff); |
| 136 | } |
| 137 | break; |
| 138 | case EltwiseParameter_EltwiseOp_MAX: |
| 139 | mask = max_idx_.cpu_data(); |
| 140 | for (int index = 0; index < count; ++index) { |
| 141 | Dtype gradient = 0; |
| 142 | if (mask[index] == i) { |
| 143 | gradient += top_diff[index]; |
| 144 | } |
| 145 | bottom_diff[index] = gradient; |
| 146 | } |
| 147 | break; |
| 148 | default: |
| 149 | LOG(FATAL) << "Unknown elementwise operation."; |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | #ifdef CPU_ONLY |
| 156 | STUB_GPU(EltwiseLayer); |
nothing calls this directly
no test coverage detected