| 109 | |
| 110 | template<typename T> |
| 111 | Array<T> convolve2_unwrap(const Array<T> &signal, const Array<T> &filter, |
| 112 | const dim4 &stride, const dim4 &padding, |
| 113 | const dim4 &dilation) { |
| 114 | dim4 sDims = signal.dims(); |
| 115 | dim4 fDims = filter.dims(); |
| 116 | |
| 117 | dim_t outputWidth = |
| 118 | 1 + (sDims[0] + 2 * padding[0] - (((fDims[0] - 1) * dilation[0]) + 1)) / |
| 119 | stride[0]; |
| 120 | dim_t outputHeight = |
| 121 | 1 + (sDims[1] + 2 * padding[1] - (((fDims[1] - 1) * dilation[1]) + 1)) / |
| 122 | stride[1]; |
| 123 | |
| 124 | const bool retCols = false; |
| 125 | Array<T> unwrapped = |
| 126 | unwrap(signal, fDims[0], fDims[1], stride[0], stride[1], padding[0], |
| 127 | padding[1], dilation[0], dilation[1], retCols); |
| 128 | |
| 129 | unwrapped = reorder(unwrapped, dim4(1, 2, 0, 3)); |
| 130 | dim4 uDims = unwrapped.dims(); |
| 131 | |
| 132 | unwrapped = |
| 133 | modDims(unwrapped, dim4(uDims[0] * uDims[1], uDims[2] * uDims[3])); |
| 134 | |
| 135 | Array<T> collapsedFilter = filter; |
| 136 | |
| 137 | collapsedFilter = flip(collapsedFilter, {1, 1, 0, 0}); |
| 138 | collapsedFilter = modDims(collapsedFilter, |
| 139 | dim4(fDims[0] * fDims[1] * fDims[2], fDims[3])); |
| 140 | |
| 141 | Array<T> res = |
| 142 | matmul(unwrapped, collapsedFilter, AF_MAT_TRANS, AF_MAT_NONE); |
| 143 | res = modDims(res, dim4(outputWidth, outputHeight, signal.dims()[3], |
| 144 | collapsedFilter.dims()[1])); |
| 145 | Array<T> out = reorder(res, dim4(0, 1, 3, 2)); |
| 146 | |
| 147 | return out; |
| 148 | } |
| 149 | |
| 150 | template<typename T> |
| 151 | Array<T> convolve2(Array<T> const &signal, Array<T> const &filter, |