| 24 | } |
| 25 | |
| 26 | BatchConvBiasForward::CanonizedFilterMeta BatchConvBiasForward::check_exec( |
| 27 | const TensorLayout& src, const TensorLayout& filter, const TensorLayout& bias, |
| 28 | const TensorLayout& z, const TensorLayout& dst, size_t workspace_in_bytes) { |
| 29 | megdnn_assert( |
| 30 | src.dtype.enumv() == filter.dtype.enumv() && |
| 31 | src.dtype.enumv() == DTypeEnum::QuantizedS8, |
| 32 | "batch conv only support qint8"); |
| 33 | float scale_src = src.dtype.param<dtype::QuantizedS8>().scale; |
| 34 | float scale_filter = filter.dtype.param<dtype::QuantizedS8>().scale; |
| 35 | float scale_bias = bias.dtype.param<dtype::QuantizedS32>().scale; |
| 36 | megdnn_assert( |
| 37 | std::abs(scale_src * scale_filter - scale_bias) < 1e-6, |
| 38 | "scale_bias is not equal to the product of scale_src and " |
| 39 | "scale_filter (scale_src: %f scale_filter: %f scale_bias: %f).", |
| 40 | scale_src, scale_filter, scale_bias); |
| 41 | TensorLayout non_batch_filter; |
| 42 | non_batch_filter.ndim = filter.ndim - 1; |
| 43 | non_batch_filter.dtype = filter.dtype; |
| 44 | for (size_t i = 0; i < non_batch_filter.ndim; i++) { |
| 45 | non_batch_filter[i] = filter[i + 1]; |
| 46 | non_batch_filter.stride[i] = filter.stride[i + 1]; |
| 47 | } |
| 48 | non_batch_filter.format = filter.format; |
| 49 | auto ret = check_layout_fwd(src, non_batch_filter, dst); |
| 50 | megdnn_assert_contiguous(bias); |
| 51 | auto required_workspace_in_bytes = |
| 52 | get_workspace_in_bytes(src, filter, bias, z, dst); |
| 53 | megdnn_assert(workspace_in_bytes >= required_workspace_in_bytes); |
| 54 | if (bias.ndim != 0) { |
| 55 | //! bias.layout == dst.layout failed, no assert information |
| 56 | auto check_eq = [](const TensorLayout& bias, const TensorLayout& dst) { |
| 57 | if (dst.dtype.category() == DTypeCategory::QUANTIZED) { |
| 58 | return bias.eq_shape(dst); |
| 59 | } else { |
| 60 | return bias.eq_layout(dst); |
| 61 | } |
| 62 | }; |
| 63 | if (check_eq(bias, dst)) |
| 64 | return ret; |
| 65 | if (param().format == param::BatchConvBias::Format::NCHW4) { |
| 66 | megdnn_assert(bias.shape[0] == 1); |
| 67 | megdnn_assert( |
| 68 | bias.shape[1] == dst.shape[1], "bias:%s, dst:%s", |
| 69 | bias.to_string().c_str(), dst.to_string().c_str()); |
| 70 | megdnn_assert(bias.shape[2] == 1); |
| 71 | megdnn_assert(bias.shape[3] == 1); |
| 72 | megdnn_assert(bias.shape[4] == 4); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | if (z.ndim != 0) { |
| 77 | megdnn_assert(z.dtype.enumv() == dst.dtype.enumv()); |
| 78 | megdnn_assert(z.eq_shape(dst)); |
| 79 | } |
| 80 | return ret; |
| 81 | } |
| 82 | } // namespace megdnn |
| 83 | |