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