| 136 | |
| 137 | template <typename T> |
| 138 | void ConvBiasForwardImpl::AlgoMatmul::exec_internal( |
| 139 | const ExecArgs& args, const WorkspaceBundle& bundle) { |
| 140 | auto&& fm = args.filter_meta; |
| 141 | size_t N = args.src_layout->shape[0], IC = fm.icpg, IH = args.src_layout->shape[2], |
| 142 | IW = args.src_layout->shape[3], OC = fm.ocpg, |
| 143 | OH = args.dst_tensor->layout.shape[2], OW = args.dst_tensor->layout.shape[3], |
| 144 | FH = fm.spatial[0], FW = fm.spatial[1], PH = fm.padding[0], |
| 145 | PW = fm.padding[1], SH = fm.stride[0], SW = fm.stride[1], |
| 146 | DH = fm.dilation[0], DW = fm.dilation[1]; |
| 147 | auto stream = cuda_stream(args.handle); |
| 148 | T* dst_t = static_cast<T*>(bundle.get(0)); |
| 149 | T* col = static_cast<T*>(bundle.get(1)); |
| 150 | conv_bias::im2col<T>( |
| 151 | args.src_tensor->ptr<T>(), col, N, args.src_layout->stride[0], IC, IH, IW, |
| 152 | FH, FW, OH, OW, PH, PW, SH, SW, DH, DW, stream); |
| 153 | |
| 154 | auto config = prepare_sub_opr(args); |
| 155 | |
| 156 | TensorND A(args.filter_tensor->ptr<T>(), config.first[0]), B(col, config.first[1]), |
| 157 | C(dst_t, config.first[2]); |
| 158 | size_t matmul_ws_idx = 2; |
| 159 | if (fm.should_flip) { |
| 160 | conv_bias::flip_filter(args, bundle.get_workspace(2), A.get_ref_ptr()); |
| 161 | matmul_ws_idx = 3; |
| 162 | } |
| 163 | |
| 164 | config.second->exec(A, B, C, bundle.get_workspace(matmul_ws_idx)); |
| 165 | |
| 166 | TensorLayout C2l({OC * OH * OW, N}, typename DTypeTrait<T>::dtype()), C3l = C2l; |
| 167 | C3l.stride[0] = 1; |
| 168 | C3l.stride[1] = args.dst_tensor->layout.stride[0]; |
| 169 | TensorND C2(dst_t, C2l); |
| 170 | TensorND C3(args.dst_tensor->ptr<T>(), C3l); |
| 171 | args.handle->relayout_opr()->exec(C2, C3); |
| 172 | } |
| 173 | |
| 174 | // vim: syntax=cpp.doxygen |
nothing calls this directly
no test coverage detected