| 203 | |
| 204 | template<typename T> |
| 205 | Array<T> conv2FilterGradient(const Array<T> &incoming_gradient, |
| 206 | const Array<T> &original_signal, |
| 207 | const Array<T> &original_filter, |
| 208 | const Array<T> & /*convolved_output*/, |
| 209 | af::dim4 stride, af::dim4 padding, |
| 210 | af::dim4 dilation) { |
| 211 | const dim4 &cDims = incoming_gradient.dims(); |
| 212 | const dim4 &fDims = original_filter.dims(); |
| 213 | |
| 214 | const bool retCols = false; |
| 215 | Array<T> unwrapped = |
| 216 | unwrap(original_signal, fDims[0], fDims[1], stride[0], stride[1], |
| 217 | padding[0], padding[1], dilation[0], dilation[1], retCols); |
| 218 | |
| 219 | unwrapped = reorder(unwrapped, dim4(1, 2, 0, 3)); |
| 220 | dim4 uDims = unwrapped.dims(); |
| 221 | unwrapped = |
| 222 | modDims(unwrapped, dim4(uDims[0] * uDims[1], uDims[2] * uDims[3])); |
| 223 | |
| 224 | Array<T> collapsed_gradient = incoming_gradient; |
| 225 | collapsed_gradient = reorder(collapsed_gradient, dim4(0, 1, 3, 2)); |
| 226 | collapsed_gradient = modDims( |
| 227 | collapsed_gradient, dim4(cDims[0] * cDims[1] * cDims[3], cDims[2])); |
| 228 | |
| 229 | Array<T> res = |
| 230 | matmul(unwrapped, collapsed_gradient, AF_MAT_NONE, AF_MAT_NONE); |
| 231 | res = modDims(res, dim4(fDims[0], fDims[1], fDims[2], fDims[3])); |
| 232 | |
| 233 | auto out = flip(res, {1, 1, 0, 0}); |
| 234 | return out; |
| 235 | } |
| 236 | |
| 237 | #define INSTANTIATE(T) \ |
| 238 | template Array<T> conv2DataGradient<T>( \ |