34 const float *incoming_data,
const Shape &grad_shape,
float *grad_data)
39 const int batches =
MatchingDim(incoming_shape, 0, grad_shape, 0);
40 const int grad_height = grad_shape.
Dims(1);
41 const int grad_width = grad_shape.
Dims(2);
42 const int incoming_height = incoming_shape.
Dims(1);
43 const int incoming_width = incoming_shape.
Dims(2);
48 std::fill(grad_data, grad_data + grad_shape.
FlatSize(), 0.0);
53 for (
int b = 0; b < batches; ++b)
55 for (
int h = 0; h < incoming_height; ++h)
57 for (
int w = 0; w < incoming_width; ++w)
62 int h_end = std::min(h_start + params.
filter_height, grad_height);
63 h_start = h_start < 0 ? 0 : h_start;
66 int w_end = std::min(w_start + params.
filter_width, grad_width);
67 w_start = w_start < 0 ? 0 : w_start;
69 int count = (h_end - h_start) * (w_end - w_start);
71 if (h_end <= 0 || w_end <= 0 || count <= 0 || h_start >= grad_height ||
72 w_start >= grad_width)
75 int incoming_offset =
NodeOffset(b, h, w, incoming_height, incoming_width);
76 for (
int ph = h_start; ph < h_end; ++ph)
78 for (
int pw = w_start; pw < w_end; ++pw)
80 int grad_offset =
NodeOffset(b, ph, pw, grad_height, grad_width);
81 grad_mat.col(grad_offset) += incoming_mat.col(incoming_offset) / count;