| 6 | namespace { |
| 7 | |
| 8 | void do_check_exec_common( |
| 9 | ConvBiasForward* opr, const TensorLayout& src, const TensorLayout& filter, |
| 10 | const TensorLayout& bias, const TensorLayout& z, const TensorLayout& dst, |
| 11 | size_t workspace_in_bytes, |
| 12 | const ConvBiasForward::PreprocessedFilter* preprocessed_filter) { |
| 13 | megdnn_assert( |
| 14 | (src.dtype.enumv() == filter.dtype.enumv()) || |
| 15 | (src.dtype.enumv() == DTypeEnum::Quantized4Asymm && |
| 16 | filter.dtype.enumv() == DTypeEnum::QuantizedS4)); |
| 17 | // check compatibility of bias's scale |
| 18 | if (src.dtype.category() == DTypeCategory::QUANTIZED) { |
| 19 | if (bias.dtype.enumv() == DTypeEnum::QuantizedS32) { |
| 20 | float scale_expected = mul_scale(src.dtype, filter.dtype); |
| 21 | float scale_bias = bias.dtype.param<dtype::QuantizedS32>().scale; |
| 22 | megdnn_assert( |
| 23 | std::abs(scale_expected - scale_bias) < 1e-6, |
| 24 | "scale_src: %f scale_filter: %f scale_bias: %f", |
| 25 | get_scale(src.dtype), get_scale(filter.dtype), scale_bias); |
| 26 | } else { |
| 27 | megdnn_assert(bias.dtype.enumv() == DTypeEnum::Float32); |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | megdnn_assert_contiguous(bias); |
| 32 | auto required_workspace_in_bytes = |
| 33 | opr->get_workspace_in_bytes(src, filter, bias, z, dst, preprocessed_filter); |
| 34 | megdnn_assert( |
| 35 | workspace_in_bytes >= required_workspace_in_bytes, |
| 36 | "worksapce have size of %zu, but need %zu", workspace_in_bytes, |
| 37 | required_workspace_in_bytes); |
| 38 | if (bias.ndim != 0) { |
| 39 | //! bias.layout == dst.layout failed, no assert information |
| 40 | auto check_eq = [](const TensorLayout& bias, const TensorLayout& dst) { |
| 41 | if (dst.dtype.category() == DTypeCategory::QUANTIZED) { |
| 42 | return bias.eq_shape(dst); |
| 43 | } else { |
| 44 | return bias.eq_layout(dst); |
| 45 | } |
| 46 | }; |
| 47 | if (check_eq(bias, dst)) { |
| 48 | return; |
| 49 | } |
| 50 | if (opr->param().format == param::ConvBias::Format::NCHW || |
| 51 | opr->param().format == param::ConvBias::Format::NCHW4_NCHW) { |
| 52 | megdnn_assert(bias.shape[0] == 1); |
| 53 | megdnn_assert( |
| 54 | bias.shape[1] == dst.shape[1], "bias:%s, dst:%s", |
| 55 | bias.to_string().c_str(), dst.to_string().c_str()); |
| 56 | megdnn_assert(bias.shape[2] == 1); |
| 57 | megdnn_assert(bias.shape[3] == 1); |
| 58 | } else if ( |
| 59 | opr->param().format == param::ConvBias::Format::NHWC || |
| 60 | opr->param().format == param::ConvBias::Format::NCHW4_NHWC) { |
| 61 | megdnn_assert(bias.shape[0] == 1); |
| 62 | megdnn_assert(bias.shape[1] == 1); |
| 63 | megdnn_assert(bias.shape[2] == 1); |
| 64 | megdnn_assert( |
| 65 | bias.shape[3] == dst.shape[3], "bias:%s, dst:%s", |