| 41 | |
| 42 | template <typename io_ctype, typename compute_ctype> |
| 43 | WorkspaceBundle MultithreadDirectConvCommon<io_ctype, compute_ctype>::get_bundle( |
| 44 | const ConvBiasImpl::NCBKernSizeParam& param, bool m_large_group) { |
| 45 | auto&& fm = param.filter_meta; |
| 46 | size_t nr_threads = param.nr_threads; |
| 47 | size_t group = fm.group, batch = param.n; |
| 48 | size_t IH2 = param.isz[0] + 2 * fm.padding[0]; |
| 49 | size_t IW2 = param.isz[1] + 2 * fm.padding[1]; |
| 50 | // part0: copied src |
| 51 | // part1: copied filter |
| 52 | size_t part0, part1; |
| 53 | if (fm.padding[0] == 0 && fm.padding[1] == 0) { |
| 54 | //! only the last plane need to be copied, add 16 Byte extra space in |
| 55 | //! case of invalid read and write |
| 56 | part0 = (param.isz[0] * param.isz[1]) * sizeof(io_ctype) + 16; |
| 57 | } else if (m_large_group) { |
| 58 | //! Serial in group, each thread process one group, parallel by group |
| 59 | part0 = (IH2 * IW2 * fm.icpg * nr_threads) * sizeof(io_ctype) + 16; |
| 60 | } else { |
| 61 | //! Parallel in group, Then should copy every inputs to workspace |
| 62 | part0 = (IH2 * IW2 * fm.icpg * group * batch) * sizeof(io_ctype) + 16; |
| 63 | } |
| 64 | if (param.filter_meta.should_flip) { |
| 65 | if (m_large_group) { |
| 66 | //! Serial in group, each thread has own workspace and then reuse |
| 67 | part1 = fm.spatial[0] * fm.spatial[1] * fm.ocpg * fm.icpg * nr_threads * |
| 68 | sizeof(io_ctype); |
| 69 | } else { |
| 70 | part1 = fm.spatial[0] * fm.spatial[1] * fm.ocpg * fm.icpg * group * |
| 71 | sizeof(io_ctype); |
| 72 | } |
| 73 | } else { |
| 74 | part1 = 0; |
| 75 | } |
| 76 | return {nullptr, {part0, part1}}; |
| 77 | } |
| 78 | template <typename io_ctype, typename compute_ctype> |
| 79 | WorkspaceBundle MultithreadDirectConvCommon<io_ctype, compute_ctype>::get_bundle_stride( |
| 80 | const ConvBiasImpl::NCBKernSizeParam& param, bool m_large_group) { |
no outgoing calls
no test coverage detected