| 27 | } |
| 28 | |
| 29 | void GroupLocalImpl::exec( |
| 30 | _megdnn_tensor_in src, _megdnn_tensor_in filter, _megdnn_tensor_out dst, |
| 31 | _megdnn_workspace workspace) { |
| 32 | // Implemented by regular local |
| 33 | check_exec(src.layout, filter.layout, dst.layout, workspace.size); |
| 34 | |
| 35 | auto local_dense = static_cast<naive::LocalForwardImpl*>(m_local_opr.get()); |
| 36 | local_dense->param() = this->param(); |
| 37 | auto src_gly = src, flt_gly = filter, dst_gly = dst; |
| 38 | src_gly.layout.shape[1] /= filter.layout[0]; |
| 39 | flt_gly.layout = flt_gly.layout.remove_axis(0); |
| 40 | dst_gly.layout.shape[1] /= filter.layout[0]; |
| 41 | auto fp = local_dense->make_float_kern_param(src_gly, flt_gly, dst_gly, workspace); |
| 42 | auto kptr = local_dense->dispatch_float_noncontig_batch( |
| 43 | src_gly.layout, flt_gly.layout, dst_gly.layout); |
| 44 | auto nr_group = filter.layout.shape[0]; |
| 45 | auto flt_gstride = filter.layout.stride[0]; |
| 46 | auto data_type_size_in_bytes = src.layout.dtype.size(); |
| 47 | |
| 48 | auto kern = [fp, nr_group, kptr, flt_gstride, data_type_size_in_bytes]() { |
| 49 | auto cur_fp = fp; |
| 50 | cur_fp.src = RefPtr(); |
| 51 | cur_fp.filter = RefPtr(); |
| 52 | cur_fp.dst = RefPtr(); |
| 53 | rep(g, nr_group) { |
| 54 | auto ic = g * fp.ic; |
| 55 | auto oc = g * fp.oc; |
| 56 | cur_fp.src = fp.src; |
| 57 | cur_fp.filter = fp.filter; |
| 58 | cur_fp.dst = fp.dst; |
| 59 | cur_fp.src += ic * fp.ih * fp.iw * data_type_size_in_bytes; |
| 60 | cur_fp.filter += g * flt_gstride * data_type_size_in_bytes; |
| 61 | cur_fp.dst += oc * fp.oh * fp.ow * data_type_size_in_bytes; |
| 62 | kptr(cur_fp); |
| 63 | } |
| 64 | }; |
| 65 | static_cast<naive::HandleImpl*>(handle())->dispatch_kern(kern); |
| 66 | } |
| 67 | |
| 68 | // vim: syntax=cpp.doxygen |
nothing calls this directly
no test coverage detected