提交 f6018422 编写于 作者: M Megvii Engine Team

perf(dnn/arm_common): add nchw44 winograd f73

GitOrigin-RevId: 8ed98ab85b74fb9327c369336ea1d6f8a1884057
上级 2dc91900
......@@ -331,6 +331,51 @@ MEGDNN_WINOGRAD_ALGO_FUN_DEFINE_ALL(AlgoFP32WinogradF63_4x4_NCHW44,
megdnn_arm_common_winograd_fp32,
param::MatrixMul::Format::MK4);
/* =================== AlgoFP32WinogradF73_4x4_NCHW44 ===================== */
bool ConvBiasImpl::AlgoFP32WinogradF73_4x4_NCHW44::usable(
const NCBKernSizeParam& param,
AlgoSelectionStrategy /*algo_selection_strategy*/) const {
MIDOUT_BEGIN(megdnn_arm_common_winograd_fp32,
midout_iv("AlgoFP32WinogradF73_4x4_NCHW44"_hash)) {
if (param.filter_meta.icpg % 4 != 0 || param.filter_meta.ocpg % 4 != 0)
return false;
using Strategy = winograd::winograd_F73_mk4_f_nchw44;
Strategy strategy(param.src_type, param.filter_type, param.dst_type);
auto&& matmul_param =
megdnn::winograd::ConvBias<Strategy,
param::MatrixMul::Format::MK4>(
strategy, m_tile_size, param)
.get_matmul_kern_param(param);
return m_matmul_algo->usable(matmul_param) &&
m_matmul_algo->packmode() ==
fallback::MatrixMulImpl::AlgoBase::PackMode::NO_PACK &&
(param.filter_meta.format == param::ConvBias::Format::NCHW44 ||
(param.filter_meta.format ==
param::ConvBias::Format::NCHW44_WINOGRAD &&
param.output_block_size == 7 &&
param.winograd_matmul_format ==
param::MatrixMul::Format::MK4)) &&
!param.filter_meta.should_flip &&
(param.filter_meta.spatial[0] == param.filter_meta.spatial[1] &&
param.filter_meta.spatial[0] == 3) &&
(param.filter_meta.stride[0] == param.filter_meta.stride[1] &&
param.filter_meta.stride[0] == 1) &&
(param.filter_meta.dilation[0] ==
param.filter_meta.dilation[1] &&
param.filter_meta.dilation[0] == 1) &&
param.compute_mode == param::ConvBias::ComputeMode::DEFAULT &&
param.src_type.enumv() == DTypeEnum::Float32;
}
MIDOUT_END();
return false;
}
MEGDNN_WINOGRAD_ALGO_FUN_DEFINE_ALL(AlgoFP32WinogradF73_4x4_NCHW44,
winograd::winograd_F73_mk4_f_nchw44,
megdnn_arm_common_winograd_fp32,
param::MatrixMul::Format::MK4);
/* ===================== direct algo ===================== */
MIDOUT_DECL(megdnn_arm_common_conv_bias_f32_kimpl);
......
......@@ -124,6 +124,22 @@ public:
}
MEGDNN_WINOGRAD_ALGO_FUN_DECLARE();
};
class ConvBiasImpl::AlgoFP32WinogradF73_4x4_NCHW44 final : public AlgoBase {
public:
AlgoFP32WinogradF73_4x4_NCHW44(
fallback::MatrixMulImpl::AlgoBase* matmul_algo, uint32_t tile_size)
: m_matmul_algo{matmul_algo}, m_tile_size{tile_size} {}
const char* name() const override {
if (m_name.empty()) {
m_name = ConvBiasImpl::algo_name<ConvBias::WinogradParam>(
m_matmul_algo->name(), {4, 7, m_tile_size},
param::ConvBias::Format::NCHW44);
}
return m_name.c_str();
}
MEGDNN_WINOGRAD_ALGO_FUN_DECLARE();
};
// ================================================================= //
class ConvBiasImpl::AlgoF32Direct final : public AlgoBase {
......
......@@ -38,6 +38,9 @@ MEGDNN_REG_WINOGRAD_STRATEGY(float, float, float, float, 2, 3, 4, 4,
MEGDNN_REG_WINOGRAD_STRATEGY(float, float, float, float, 6, 3, 4, 4,
winograd_F63_mk4_f_nchw44)
MEGDNN_REG_WINOGRAD_STRATEGY(float, float, float, float, 7, 3, 4, 4,
winograd_F73_mk4_f_nchw44)
} // namespace winograd
} // namespace arm_common
} // namespace megdnn
......
/**
* \file dnn/src/arm_common/conv_bias/fp32/strategy_f
* 63_mk4_nchw44.cpp
* \file dnn/src/arm_common/conv_bias/fp32/strategy_f63_mk4_nchw44.cpp
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
*
* Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
......
......@@ -151,6 +151,13 @@ public:
static_cast<fallback::MatrixMulImpl::AlgoBase*>(algo),
tile_size));
winograd_algos.emplace_back(refhold.back().get());
//! uncomment this when low precision mode is done
#if 0
refhold.emplace_back(new AlgoFP32WinogradF73_4x4_NCHW44(
static_cast<fallback::MatrixMulImpl::AlgoBase*>(algo),
tile_size));
winograd_algos.emplace_back(refhold.back().get());
#endif
#if __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
refhold.emplace_back(new AlgoFP16WinogradF23(
static_cast<fallback::MatrixMulImpl::AlgoBase*>(algo),
......
......@@ -50,6 +50,7 @@ private:
class AlgoFP32WinogradF23_4x4_NCHW44;
class AlgoFP32WinogradF63_4x4_NCHW44;
class AlgoFP32WinogradF73_4x4_NCHW44;
class AlgoS8ChanWiseStride1NCHW44;
class AlgoS8ChanWiseStride2NCHW44;
......
......@@ -94,6 +94,10 @@ void WinogradFilterPreprocessImpl::exec(_megdnn_tensor_in src,
DISPATCH(winograd_F63_mk4_f_nchw44,
param::Winograd::Format::MK4, 0, 6);
}
} else if (m == 7) {
megdnn_assert(pack_c_size == 4, "WINOGRAD F(7,3) Only Supports NCHW44");
DISPATCH(winograd_F73_mk4_f_nchw44,
param::Winograd::Format::MK4, 0, 7);
}
} else if (FW == 4) {
if (m == 5) {
......
......@@ -122,6 +122,23 @@
cb(5, 0, ##a) cb(5, 1, ##a) cb(5, 2, ##a) cb(5, 3, ##a) \
cb(5, 4, ##a) cb(5, 5, ##a) \
#define UNROLL_RAW_7x7(cb, v0, a...) \
cb(0, 0, ##a) cb(0, 1, ##a) cb(0, 2, ##a) cb(0, 3, ##a) \
cb(0, 4, ##a) cb(0, 5, ##a) cb(0, 6, ##a) \
cb(1, 0, ##a) cb(1, 1, ##a) cb(1, 2, ##a) cb(1, 3, ##a) \
cb(1, 4, ##a) cb(1, 5, ##a) cb(1, 6, ##a) \
cb(2, 0, ##a) cb(2, 1, ##a) cb(2, 2, ##a) cb(2, 3, ##a) \
cb(2, 4, ##a) cb(2, 5, ##a) cb(2, 6, ##a) \
cb(3, 0, ##a) cb(3, 1, ##a) cb(3, 2, ##a) cb(3, 3, ##a) \
cb(3, 4, ##a) cb(3, 5, ##a) cb(3, 6, ##a) \
cb(4, 0, ##a) cb(4, 1, ##a) cb(4, 2, ##a) cb(4, 3, ##a) \
cb(4, 4, ##a) cb(4, 5, ##a) cb(4, 6, ##a) \
cb(5, 0, ##a) cb(5, 1, ##a) cb(5, 2, ##a) cb(5, 3, ##a) \
cb(5, 4, ##a) cb(5, 5, ##a) cb(5, 6, ##a) \
cb(6, 0, ##a) cb(6, 1, ##a) cb(6, 2, ##a) cb(6, 3, ##a) \
cb(6, 4, ##a) cb(6, 5, ##a) cb(6, 6, ##a) \
#define UNROLL_RAW_8x8(cb, v0, a...) \
cb(0, 0, ##a) cb(0, 1, ##a) cb(0, 2, ##a) cb(0, 3, ##a) \
cb(0, 4, ##a) cb(0, 5, ##a) cb(0, 6, ##a) cb(0, 7, ##a) \
......@@ -140,6 +157,26 @@
cb(7, 0, ##a) cb(7, 1, ##a) cb(7, 2, ##a) cb(7, 3, ##a) \
cb(7, 4, ##a) cb(7, 5, ##a) cb(7, 6, ##a) cb(7, 7, ##a)
#define UNROLL_RAW_9x9(cb, v0, a...) \
cb(0, 0, ##a) cb(0, 1, ##a) cb(0, 2, ##a) cb(0, 3, ##a) \
cb(0, 4, ##a) cb(0, 5, ##a) cb(0, 6, ##a) cb(0, 7, ##a) cb(0, 8, ##a) \
cb(1, 0, ##a) cb(1, 1, ##a) cb(1, 2, ##a) cb(1, 3, ##a) \
cb(1, 4, ##a) cb(1, 5, ##a) cb(1, 6, ##a) cb(1, 7, ##a) cb(1, 8, ##a) \
cb(2, 0, ##a) cb(2, 1, ##a) cb(2, 2, ##a) cb(2, 3, ##a) \
cb(2, 4, ##a) cb(2, 5, ##a) cb(2, 6, ##a) cb(2, 7, ##a) cb(2, 8, ##a) \
cb(3, 0, ##a) cb(3, 1, ##a) cb(3, 2, ##a) cb(3, 3, ##a) \
cb(3, 4, ##a) cb(3, 5, ##a) cb(3, 6, ##a) cb(3, 7, ##a) cb(3, 8, ##a) \
cb(4, 0, ##a) cb(4, 1, ##a) cb(4, 2, ##a) cb(4, 3, ##a) \
cb(4, 4, ##a) cb(4, 5, ##a) cb(4, 6, ##a) cb(4, 7, ##a) cb(4, 8, ##a) \
cb(5, 0, ##a) cb(5, 1, ##a) cb(5, 2, ##a) cb(5, 3, ##a) \
cb(5, 4, ##a) cb(5, 5, ##a) cb(5, 6, ##a) cb(5, 7, ##a) cb(5, 8, ##a) \
cb(6, 0, ##a) cb(6, 1, ##a) cb(6, 2, ##a) cb(6, 3, ##a) \
cb(6, 4, ##a) cb(6, 5, ##a) cb(6, 6, ##a) cb(6, 7, ##a) cb(6, 8, ##a) \
cb(7, 0, ##a) cb(7, 1, ##a) cb(7, 2, ##a) cb(7, 3, ##a) \
cb(7, 4, ##a) cb(7, 5, ##a) cb(7, 6, ##a) cb(7, 7, ##a) cb(7, 8, ##a) \
cb(8, 0, ##a) cb(8, 1, ##a) cb(8, 2, ##a) cb(8, 3, ##a) \
cb(8, 4, ##a) cb(8, 5, ##a) cb(8, 6, ##a) cb(8, 7, ##a) cb(8, 8, ##a)
#define UNROLL_CALL0_D2(step, step2, cb, v...) \
UNROLL_RAW_##step##x##step2(cb, 0, ##v)
#define UNROLL_CALL1_D2(step, step2, cb, v...) \
......
......@@ -25,7 +25,7 @@ void WinogradFilterPreprocessImpl::exec(_megdnn_tensor_in src,
_megdnn_tensor_out dst,
_megdnn_workspace workspace) {
check_exec(src.layout, dst.layout, workspace.size);
//! nchw88 group conv
size_t flt_start = 0;
size_t pack_c_size = 1;
......@@ -212,6 +212,10 @@ void WinogradFilterPreprocessImpl::exec(_megdnn_tensor_in src,
std::vector<float> interp_points = {0, 1, -1, 2,
-2, 0.5, -0.5};
DISPATCH_DTYPE(7);
} else if (m == 7) {
std::vector<float> interp_points = {0, 1, -1, 2,
-2, 0.5, -0.5, 1.5};
DISPATCH_DTYPE(8);
}
}
#undef cb
......@@ -221,6 +225,7 @@ void WinogradFilterPreprocessImpl::exec(_megdnn_tensor_in src,
#undef DISPATCH_DTYPE
}
}
megdnn_assert(execed,
"Unsupport winograd filter preprocess. m: %zu src: %s", m,
src.layout.to_string().c_str());
......
......@@ -777,7 +777,8 @@ TEST_F(ARM_COMMON, BENCHMARK_CONVBIAS_WINOGRAD_F16_F23_8x8) {
}
#endif
void benchmark_winograd_nchw_vs_nchw44(const char* algo_name, Handle* handle) {
void benchmark_winograd_nchw_vs_nchw44(const char* algo_name0,
const char* algo_name1, Handle* handle) {
using namespace conv_bias;
using NLMode = param::ConvBias::NonlineMode;
std::vector<conv_bias::TestArg> args_nchw44;
......@@ -846,9 +847,9 @@ void benchmark_winograd_nchw_vs_nchw44(const char* algo_name, Handle* handle) {
benchmark_winograd_nchw44.set_display(false);
benchmark_winograd_nchw44.set_times(RUN);
std::string winograd_nchw_algo_name = ssprintf("WINOGRAD:%s", algo_name);
std::string winograd_nchw_algo_name = ssprintf("WINOGRAD:%s", algo_name0);
std::string winograd_nchw44_algo_name =
ssprintf("WINOGRAD_NCHW44:%s", algo_name);
ssprintf("WINOGRAD_NCHW44:%s", algo_name1);
for (size_t i = 0; i < args_nchw.size(); ++i) {
auto arg_nchw = args_nchw[i];
......@@ -892,17 +893,31 @@ void benchmark_winograd_nchw_vs_nchw44(const char* algo_name, Handle* handle) {
TEST_F(ARM_COMMON, BENCHMARK_CONVBIAS_WINOGRAD_F23_MK4_NCHW_VS_NCHW44) {
#if MEGDNN_AARCH64
benchmark_winograd_nchw_vs_nchw44("AARCH64_F32_MK4_4x16:4:2", handle());
benchmark_winograd_nchw_vs_nchw44("AARCH64_F32_MK4_4x16:4:2",
"AARCH64_F32_MK4_4x16:4:2", handle());
#else
benchmark_winograd_nchw_vs_nchw44("ARMV7_F32_MK4_4x8:4:2", handle());
benchmark_winograd_nchw_vs_nchw44("ARMV7_F32_MK4_4x8:4:2",
"ARMV7_F32_MK4_4x8:4:2", handle());
#endif
}
TEST_F(ARM_COMMON, BENCHMARK_CONVBIAS_WINOGRAD_F63_MK4_NCHW_VS_NCHW44) {
#if MEGDNN_AARCH64
benchmark_winograd_nchw_vs_nchw44("AARCH64_F32_MK4_4x16:4:6", handle());
benchmark_winograd_nchw_vs_nchw44("AARCH64_F32_MK4_4x16:4:6",
"AARCH64_F32_MK4_4x16:4:6", handle());
#else
benchmark_winograd_nchw_vs_nchw44("ARMV7_F32_MK4_4x8:4:6", handle());
benchmark_winograd_nchw_vs_nchw44("ARMV7_F32_MK4_4x8:4:6",
"ARMV7_F32_MK4_4x8:4:6", handle());
#endif
}
TEST_F(ARM_COMMON, BENCHMARK_CONVBIAS_WINOGRAD_F73_MK4_NCHW_VS_NCHW44) {
#if MEGDNN_AARCH64
benchmark_winograd_nchw_vs_nchw44("AARCH64_F32_MK4_4x16:4:6",
"ARM_COMMON_F32_GEMV_MK4:4:7", handle());
#else
benchmark_winograd_nchw_vs_nchw44("ARMV7_F32_MK4_4x8:4:6",
"ARMV7_F32_MK4_4x8:4:7", handle());
#endif
}
......
......@@ -750,6 +750,26 @@ TEST_F(ARM_COMMON_MULTI_THREADS,
param::ConvBias::Format::NCHW44);
}
//! uncomment it when low precision mode is ok
#if 0
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_WINOGRAD_F73_4_NCHW44) {
using namespace conv_bias;
std::vector<TestArg> args = get_nchw44_conv_bias_args({3}, 1);
Checker<ConvBiasForward> checker(handle());
check_winograd("4:7:16", checker, args, param::MatrixMul::Format::MK4,
param::ConvBias::Format::NCHW44);
}
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_WINOGRAD_F73_4_NCHW44_WEIGHT_PREPROCESS) {
using namespace conv_bias;
std::vector<TestArg> args = get_nchw44_conv_bias_args({3}, 1);
Checker<ConvBiasForward, OprWeightPreprocessProxy<ConvBiasForward>> checker(
handle());
check_winograd("4:7:16", checker, args, param::MatrixMul::Format::MK4,
param::ConvBias::Format::NCHW44);
}
#endif
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_WINOGRAD_F54) {
using namespace conv_bias;
std::vector<TestArg> args = get_winograd_args(4);
......@@ -923,6 +943,12 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_WINOGRAD_PREPROCESS_NCHW44) {
}
}
};
//! uncomment this when low precision mode is ok
// run(handle(), nchw44_args, {2, 6, 7}, dtype::Float32(), dtype::Float32(),
// dtype::Float32(), dtype::Float32(), 1e-2f);
//! remove this when low precision mode is ok
run(handle(), nchw44_args, {2, 6}, dtype::Float32(), dtype::Float32(),
dtype::Float32(), dtype::Float32(), 1e-3f);
}
......
......@@ -399,7 +399,7 @@ TEST_F(ARM_COMMON, BENCHMARK_SGEMV_MK4) {
.set_param(param);
auto run = [&](size_t M, size_t K) {
printf("SGEMV_MK4: (%zu, %zu)\n", M, K);
printf("SGEMV_MK4: (%zu, %zu, 1)\n", M, K);
TensorShape A, B;
A = TensorShape{M / 4, K / 4, 4, 4};
B = TensorShape{K / 4, 1, 4};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册