GitOrigin-RevId: 4bd109f2da
tags/v1.0.0-rc1
@@ -171,7 +171,10 @@ SmallVector<ConvBiasImpl::NCBKern> ConvBiasImpl::AlgoConv1x1::dispatch_kerns( | |||
if (pack_mode == MatrixMulImpl::AlgoBase::PackMode::DEFAULT || | |||
pack_mode == MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA) { | |||
ret_kern.push_back({kern_packA, {GROUP, oc_blocks_per_group}}); | |||
//! if enable filter preprocess kern_packA should not dispatch | |||
if (!is_enable_filter_preprocess(param)) { | |||
ret_kern.push_back({kern_packA, {GROUP, oc_blocks_per_group}}); | |||
} | |||
if (pack_mode == MatrixMulImpl::AlgoBase::PackMode::DEFAULT) { | |||
ret_kern.push_back({kern_packB, {1}}); | |||
} | |||
@@ -200,6 +203,13 @@ bool ConvBiasImpl::AlgoConv1x1::usable(const NCBKernSizeParam& param, | |||
return false; | |||
} | |||
//! only matmul's packmode is packa or default support weight preprocess | |||
if (is_enable_filter_preprocess(param) && | |||
(m_matmul_algo->packmode() == | |||
fallback::MatrixMulImpl::AlgoBase::PackMode::NO_PACK)) { | |||
return false; | |||
} | |||
if (param.src_type.enumv() != DTypeEnum::Int8 && | |||
param.src_type.enumv() != DTypeEnum::QuantizedS8 && | |||
param.src_type.enumv() != DTypeEnum::Quantized8Asymm && | |||
@@ -253,6 +263,122 @@ bool ConvBiasImpl::AlgoConv1x1::usable(const NCBKernSizeParam& param, | |||
return false; | |||
} | |||
SmallVector<TensorLayout> | |||
ConvBiasImpl::AlgoConv1x1::deduce_preprocessed_filter_layout( | |||
const NCBKernSizeParam& param) const { | |||
MIDOUT_BEGIN( | |||
megdnn_fallback_conv1x1, | |||
midout_iv( | |||
"ConvBiasImpl::AlgoConv1x1::deduce_preprocessed_filter_layout"_hash)) { | |||
fallback::MatrixMulImpl::AlgoBase::MatmulDescription matmul_desc = | |||
m_matmul_algo->matmul_description(); | |||
bool default_pack = matmul_desc.packmode == | |||
MatrixMulImpl::AlgoBase::PackMode::DEFAULT; | |||
bool only_packA = matmul_desc.packmode == | |||
MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA; | |||
//! only support default_pack and only_packa mode | |||
if (matmul_desc.packmode == | |||
MatrixMulImpl::AlgoBase::PackMode::NO_PACK) { | |||
return {}; | |||
} | |||
size_t OH = param.osz[0]; | |||
size_t OW = param.osz[1]; | |||
size_t compt_oc_block_size = get_oc_tile_size_heuristic(param); | |||
auto matmul_param = utils::get_matmul_kern_param(param, OH * OW, | |||
compt_oc_block_size); | |||
WorkspaceBundle wb(nullptr, {}); | |||
if (default_pack) { | |||
Conv1x1Kerns<MatrixMulImpl::AlgoBase::PackMode::DEFAULT> dispatcher; | |||
wb = dispatcher.get_bundle(param, matmul_param, m_matmul_algo, | |||
compt_oc_block_size); | |||
} else if (only_packA) { | |||
Conv1x1Kerns<MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA> | |||
dispatcher; | |||
wb = dispatcher.get_bundle(param, matmul_param, m_matmul_algo, | |||
compt_oc_block_size); | |||
} | |||
size_t GROUP = param.filter_meta.group; | |||
SmallVector<TensorLayout> preprocessed_layouts; | |||
preprocessed_layouts.push_back( | |||
{{GROUP, wb.get_size(0)}, dtype::Int8()}); | |||
return preprocessed_layouts; | |||
} | |||
MIDOUT_END(); | |||
return {}; | |||
} | |||
SmallVector<ConvBiasImpl::NCBKern> | |||
ConvBiasImpl::AlgoConv1x1::dispatch_preprocess_kerns( | |||
const NCBKernSizeParam& param) const { | |||
MIDOUT_BEGIN( | |||
megdnn_fallback_conv1x1, | |||
midout_iv( | |||
"ConvBiasImpl::AlgoConv1x1::dispatch_preprocess_kerns"_hash)) { | |||
SmallVector<ConvBiasImpl::NCBKern> ret_kern; | |||
size_t OH = param.osz[0]; | |||
size_t OW = param.osz[1]; | |||
size_t OC = param.filter_meta.ocpg; | |||
size_t compt_oc_block_size = get_oc_tile_size_heuristic(param); | |||
size_t GROUP = param.filter_meta.group; | |||
size_t oc_blocks_per_group = div_ceil(OC, compt_oc_block_size); | |||
auto matmul_param = utils::get_matmul_kern_param(param, OH * OW, | |||
compt_oc_block_size); | |||
WorkspaceBundle whole_bundle = {nullptr, {}}; | |||
WorkspaceBundle matmul_bundle = {nullptr, {}}; | |||
auto pack_mode = m_matmul_algo->packmode(); | |||
if (pack_mode == MatrixMulImpl::AlgoBase::PackMode::DEFAULT) { | |||
MIDOUT_BEGIN(megdnn_fallback_conv1x1, | |||
midout_iv("get_defaul_matmul_packmode_bundle"_hash)) { | |||
Conv1x1Kerns<MatrixMulImpl::AlgoBase::PackMode::DEFAULT> | |||
dispatcher; | |||
whole_bundle = dispatcher.get_bundle(param, matmul_param, | |||
m_matmul_algo, | |||
compt_oc_block_size); | |||
matmul_bundle = m_matmul_algo->get_bundle(matmul_param); | |||
} | |||
MIDOUT_END(); | |||
} else if (pack_mode == MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA) { | |||
MIDOUT_BEGIN( | |||
megdnn_fallback_conv1x1, | |||
midout_iv("get_onlypacka_matmul_packmode_bundle"_hash)) { | |||
Conv1x1Kerns<MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA> | |||
dispatcher; | |||
whole_bundle = dispatcher.get_bundle(param, matmul_param, | |||
m_matmul_algo, | |||
compt_oc_block_size); | |||
matmul_bundle = m_matmul_algo->get_bundle(matmul_param); | |||
} | |||
MIDOUT_END(); | |||
} else { | |||
//! if nopack return null so that OprWeightPreprocessProxy can run | |||
//! with nopack mode | |||
return {}; | |||
} | |||
Conv1x1StrategyBase* conv1x1_strategy = | |||
Conv1x1Factory::make_conv1x1_strategy(param, pack_mode, | |||
param.filter_meta.format); | |||
auto kern_packA = [this, whole_bundle, matmul_bundle, param, | |||
compt_oc_block_size, conv1x1_strategy]( | |||
const NCBKernParam& ncb_param, | |||
const NCBKernIndex& ncb_index) mutable { | |||
conv1x1_strategy->packA(whole_bundle, matmul_bundle, | |||
compt_oc_block_size, this->m_matmul_algo, | |||
param, ncb_param, std::move(ncb_index)); | |||
}; | |||
ret_kern.push_back({kern_packA, {GROUP, oc_blocks_per_group}}); | |||
return ret_kern; | |||
} | |||
MIDOUT_END(); | |||
return {}; | |||
} | |||
bool ConvBiasImpl::AlgoConv1x1::is_preferred( | |||
const NCBKernSizeParam& param) const { | |||
size_t OH = param.osz[0]; | |||
@@ -41,6 +41,15 @@ public: | |||
const NCBKernSizeParam& param) const override; | |||
bool is_preferred(const NCBKernSizeParam&) const override; | |||
SmallVector<TensorLayout> deduce_preprocessed_filter_layout( | |||
const NCBKernSizeParam& param) const override; | |||
size_t get_preprocess_workspace( | |||
const NCBKernSizeParam& /*param*/) const override { | |||
return 0; | |||
} | |||
SmallVector<NCBKern> dispatch_preprocess_kerns( | |||
const NCBKernSizeParam& param) const override; | |||
protected: | |||
size_t get_oc_tile_size_heuristic(const NCBKernSizeParam& param) const; | |||
@@ -35,7 +35,6 @@ public: | |||
auto matmul_bundle = matmul_algo->get_bundle(matmul_param); | |||
auto thread_bundle = utils::get_thread_bundle(param, matmul_bundle.get_size(2), | |||
oc_tile_size); | |||
//! size per thread | |||
size_t all_threads_bytes = | |||
thread_bundle.total_size_in_bytes() * param.nr_threads; | |||
@@ -44,7 +43,9 @@ public: | |||
size_t packa_bytes_per_oc_tile = matmul_bundle.get_size(0); | |||
size_t oc_tiles_per_group = div_ceil(OC, oc_tile_size); | |||
size_t all_packa_bytes = | |||
packa_bytes_per_oc_tile * oc_tiles_per_group * GROUP; | |||
is_enable_filter_preprocess(param) | |||
? 0 | |||
: packa_bytes_per_oc_tile * oc_tiles_per_group * GROUP; | |||
if (pack_mode == MatrixMulImpl::AlgoBase::PackMode::ONLY_PACKA) | |||
return WorkspaceBundle{nullptr, | |||
@@ -106,9 +106,14 @@ public: | |||
size_t numbers_offset_of_filter = | |||
oc_tile_size * IC * oc_tile_id_in_group; | |||
src_ctype* a_panel = reinterpret_cast<src_ctype*>( | |||
reinterpret_cast<int8_t*>(whole_bundle.get(0)) + | |||
bytes_offset_of_a_panel); | |||
int8_t* tmp_ptr = | |||
is_enable_filter_preprocess(param) | |||
? static_cast<int8_t*>( | |||
param.preprocessed_filter->tensors[0].raw_ptr) | |||
: static_cast<int8_t*>(whole_bundle.get(0)); | |||
src_ctype* a_panel = | |||
reinterpret_cast<src_ctype*>(tmp_ptr + bytes_offset_of_a_panel); | |||
matmul_kern_param.A_ptr = const_cast<src_ctype*>( | |||
ncb_param.filter<src_ctype>(group_id) + | |||
@@ -206,8 +211,14 @@ public: | |||
size_t bytes_offset_of_a_panel = | |||
group_id * packa_bytes_per_group + | |||
oc_tile_id_in_group * packa_bytes_per_oc_tile; | |||
int8_t* a_panel = reinterpret_cast<int8_t*>(whole_bundle.get(0)) + | |||
bytes_offset_of_a_panel; | |||
int8_t* tmp_ptr = | |||
is_enable_filter_preprocess(param) | |||
? static_cast<int8_t*>( | |||
param.preprocessed_filter->tensors[0].raw_ptr) | |||
: static_cast<int8_t*>(whole_bundle.get(0)); | |||
int8_t* a_panel = tmp_ptr + bytes_offset_of_a_panel; | |||
size_t bytes_offset_of_b_panel = | |||
batch_id * packb_bytes_per_group * GROUP + | |||
@@ -2724,7 +2724,22 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_F32) { | |||
} | |||
check_conv_bias(gemv_args, handle(), "CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_F32_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(false, false); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(args, handle(), nullptr, 0.001, \ | |||
dtype::Float32(), dtype::Float32(), \ | |||
dtype::Float32(), dtype::Float32(), name); | |||
#if MEGDNN_AARCH64 | |||
cb("CONV1x1:AARCH64_F32K8X12X1:24"); | |||
#elif MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_F32:48"); | |||
#endif | |||
#undef cb | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_MK4_PACK_F32) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = | |||
@@ -2741,7 +2756,21 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_MK4_PACK_F32) { | |||
} | |||
check_conv_bias(gemv_args, handle(), "CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_MK4_PACK_F32_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = | |||
get_nchw44_conv_bias_args({1}, 1, true, false, false); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(args, handle(), nullptr, 0.001, \ | |||
dtype::Float32(), dtype::Float32(), \ | |||
dtype::Float32(), dtype::Float32(), name); | |||
#if MEGDNN_AARCH64 | |||
cb("CONV1x1:AARCH64_F32_MK4_K8X12X1:24"); | |||
#elif MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_F32_MK4_PACK_4X12:24"); | |||
#endif | |||
#undef cb | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_MK4_NO_PACK_F32) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = | |||
@@ -2780,6 +2809,22 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_F16) { | |||
} | |||
check_conv_bias(gemv_args, handle(), "CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_F16_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(false, false); | |||
NormalRNG rng(1); | |||
#if MEGDNN_AARCH64 | |||
check_conv_bias_preprocess(args, handle(), &rng, 0.03, dtype::Float16{}, | |||
dtype::Float16{}, dtype::Float16{}, dtype::Float16{}, | |||
"CONV1x1:AARCH64_F16_K8X24X1:48"); | |||
#elif MEGDNN_ARMV7 | |||
check_conv_bias_preprocess(args, handle(), &rng, 0.03, dtype::Float16{}, | |||
dtype::Float16{}, dtype::Float16{}, dtype::Float16{}, | |||
"CONV1x1:AARCH32_F16_K4X16X1:24"); | |||
#endif | |||
} | |||
#endif | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDSYM) { | |||
@@ -2814,6 +2859,31 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDSYM) { | |||
"CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDSYM_PREPROCESS) { | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
std::vector<conv_bias::TestArg> args = | |||
get_conv_bias_1x1_args(false, false, true, true); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess( \ | |||
args, handle(), &rng, epsilon, dtype::QuantizedS8(2.5f), \ | |||
dtype::QuantizedS8(2.5f), dtype::QuantizedS32(6.25f), \ | |||
dtype::QuantizedS8(60.25f), name); | |||
#if MEGDNN_AARCH64 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH64_INT8X8X32_K8X12X4_DOTPROD:24"); | |||
#else | |||
cb("CONV1x1:AARCH64_INT8X8X32_K8X8X8:24"); | |||
cb("CONV1x1:AARCH64_INT8X8X32_K4X4X16:48"); | |||
#endif | |||
#elif MEGDNN_ARMV7 | |||
epsilon = 1; | |||
cb("CONV1x1:ARMV7_INT8X8X32_K4X8X8:48"); | |||
#endif | |||
#undef cb | |||
} | |||
#if MEGDNN_AARCH64 || MEGDNN_ARMV7 | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDASYM) { | |||
UniformIntRNG rng{-50, 50}; | |||
@@ -2849,6 +2919,32 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDASYM) { | |||
dtype::Quantized8Asymm(50.3f, (uint8_t)120), | |||
"CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUANTIZEDASYM_PREPROCESS) { | |||
UniformIntRNG rng{-50, 50}; | |||
std::vector<conv_bias::TestArg> args = | |||
get_conv_bias_1x1_args(false, false, true, true); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(args, handle(), &rng, epsilon, \ | |||
dtype::Quantized8Asymm(1.2f, (uint8_t)125), \ | |||
dtype::Quantized8Asymm(1.3f, (uint8_t)129), \ | |||
dtype::QuantizedS32(1.2 * 1.3), \ | |||
dtype::Quantized8Asymm(50.3f, (uint8_t)120), \ | |||
name); | |||
float epsilon = 0.001; | |||
#if MEGDNN_AARCH64 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH64_QUINT8_K8X8X4_DOTPROD:48"); | |||
#else | |||
cb("CONV1x1:AARCH64_QUINT8_K8X8X8:24"); | |||
#endif | |||
#elif MEGDNN_ARMV7 | |||
epsilon = 1; | |||
cb("CONV1x1:ARMV7_QUINT8_K4X8X8:48"); | |||
#endif | |||
#undef cb | |||
} | |||
#endif | |||
#if MEGDNN_AARCH64 || MEGDNN_ARMV7 | |||
@@ -2887,6 +2983,32 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUINT8x8x32) { | |||
dtype::QuantizedS32(1.2 * 1.3), {}, "CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_QUINT8x8x32_PREPROCESS) { | |||
NormalRNG rng(128.f); | |||
float epsilon = 0.001; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(true, true); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(args, handle(), &rng, epsilon, \ | |||
dtype::Quantized8Asymm(1.2f, (uint8_t)125), \ | |||
dtype::Quantized8Asymm(1.3f, (uint8_t)129), \ | |||
dtype::QuantizedS32(1.2 * 1.3), {}, name); | |||
#if MEGDNN_AARCH64 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH64_QUINT8_K8X8X4_DOTPROD:24"); | |||
#else | |||
cb("CONV1x1:AARCH64_QUINT8_K8X8X8:48"); | |||
#endif | |||
#elif MEGDNN_ARMV7 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH32_QUINT8_K4X8X4:48"); | |||
#endif | |||
cb("CONV1x1:ARMV7_QUINT8_K4X8X8:24"); | |||
#endif | |||
#undef cb | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONVBIAS_1X1_S1_INT8x8x16) { | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
@@ -2924,6 +3046,28 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONVBIAS_1X1_S1_INT8x8x16) { | |||
dtype::Int8{}, dtype::Int16{}, dtype::Int16{}, | |||
"CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONVBIAS_1X1_S1_INT8x8x16_PREPROCESS) { | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(true, true); | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, \ | |||
dtype::Int8{}, dtype::Int16{}, dtype::Int16{}, \ | |||
name); | |||
#if MEGDNN_AARCH64 | |||
cb("CONV1x1:AARCH64_INT8X8X16_K8X8X8:24"); | |||
cb("CONV1x1:AARCH64_INT8X8X16_K4X4X16:24"); | |||
cb("CONV1x1:ARM_COMMON_INT8X8X16:24");//!add nopack test | |||
#elif MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_INT8X8X16_K4X8X8:24"); | |||
cb("CONV1x1:ARMV7_INT8X8X16_K4X2X16:48"); | |||
cb("CONV1x1:ARM_COMMON_INT8X8X16:24");//!add nopack test | |||
#endif | |||
#undef cb | |||
} | |||
#endif | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32) { | |||
@@ -2959,6 +3103,32 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32) { | |||
checker_conv_bias_mul_int8x8x32(gemv_args, handle(), "CONV1x1_GEMV"); | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(true, true); | |||
#define cb(name) checker_conv_bias_int8x8x32_preprocess(args, handle(), name); | |||
#if MEGDNN_AARCH64 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH64_INT8X8X32_K8X12X4_DOTPROD:48"); | |||
#else | |||
cb("CONV1x1:AARCH64_INT8X8X32_K8X8X8:24"); | |||
cb("CONV1x1:AARCH64_INT8X8X32_K4X4X16:24"); | |||
#endif | |||
#elif MEGDNN_ARMV7 | |||
#if __ARM_FEATURE_DOTPROD | |||
cb("CONV1x1:AARCH32_INT8_K6X8X4:48"); | |||
#endif | |||
cb("CONV1x1:ARMV7_INT8X8X32_K4X8X8:24"); | |||
#endif | |||
#if MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_INT8X8X32_K4X2X16:48"); | |||
#endif | |||
#undef cb | |||
} | |||
#ifndef __ARM_FEATURE_DOTPROD | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32_MK4) { | |||
using namespace conv_bias; | |||
@@ -2988,6 +3158,36 @@ TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32_MK4) { | |||
#endif | |||
#undef cb | |||
} | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32_MK4_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = | |||
get_nchw44_conv_bias_args({1}, 1, true, true, true); | |||
#define cb(name) checker_conv_bias_int8x8x32_preprocess(args, handle(), name); | |||
#if MEGDNN_AARCH64 | |||
cb("CONV1x1:AARCH64_INT8X8X32_MK4_4X4X16:24"); | |||
#elif MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_INT8X8X32_MK4_4X2X16:24"); | |||
#endif | |||
#undef cb | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
#define cb(name) \ | |||
check_conv_bias_preprocess(get_nchw44_conv_bias_args({1}, 1, true, false, false), \ | |||
handle(), &rng, epsilon, dtype::QuantizedS8(2.5f), \ | |||
dtype::QuantizedS8(2.5f), dtype::QuantizedS32(6.25f), \ | |||
dtype::QuantizedS8(60.25f), name); | |||
#if MEGDNN_AARCH64 | |||
cb("CONV1x1:AARCH64_INT8X8X32_MK4_4X4X16:24"); | |||
#elif MEGDNN_ARMV7 | |||
cb("CONV1x1:ARMV7_INT8X8X32_MK4_4X2X16:24"); | |||
#endif | |||
#undef cb | |||
} | |||
#endif | |||
TEST_F(ARM_COMMON_MULTI_THREADS, CONV_BIAS_1X1_S1_INT8x8x32_NCHW44) { | |||
@@ -1321,6 +1321,31 @@ void checker_conv_bias(std::vector<conv_bias::TestArg> args, Handle* handle, | |||
{arg.src, arg.filter, arg.bias, {}, {}}); | |||
} | |||
} | |||
void checker_conv_bias_preprocess(std::vector<conv_bias::TestArg> args, Handle* handle, | |||
RNG* rng, float epsilon, DType type0, DType type1, | |||
DType type2, DType type3, const char* algo_name) { | |||
using namespace conv_bias; | |||
Checker<ConvBiasForward, OprWeightPreprocessProxy<ConvBiasForward>> checker( | |||
handle); | |||
checker.set_before_exec_callback( | |||
conv_bias::ConvBiasAlgoChecker<ConvBias>(algo_name)); | |||
checker.set_dtype(0, type0); | |||
checker.set_dtype(1, type1); | |||
checker.set_dtype(2, type2); | |||
checker.set_dtype(4, type3); | |||
checker.set_epsilon(epsilon); | |||
if (NULL != rng) { | |||
checker.set_rng(0, rng).set_rng(1, rng).set_rng(2, rng).set_rng(3, rng); | |||
} | |||
for (auto&& arg : args) { | |||
checker.set_param(arg.param).execs( | |||
{arg.src, arg.filter, arg.bias, {}, {}}); | |||
} | |||
} | |||
} // namespace | |||
#if MEGDNN_X86_WITH_MKL | |||
@@ -1330,14 +1355,32 @@ TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_FP32_PACKA) { | |||
check_conv_bias(args, handle(), "CONV1x1:X86_F32_MKL_PACKA:24"); | |||
} | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_FP32_PACKA_PREPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(false, false); | |||
checker_conv_bias_preprocess(args, handle(), nullptr, 0.001, | |||
dtype::Float32{}, dtype::Float32{}, | |||
dtype::Float32{}, dtype::Float32{}, | |||
"CONV1x1:X86_F32_MKL_PACKA:24"); | |||
} | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_FP32_BLAS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(false, false); | |||
check_conv_bias(args, handle(), "CONV1x1:X86_F32_BLAS:48"); | |||
} | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_FP32_BLAS_NOPACK_REPROCESS) { | |||
using namespace conv_bias; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(false, false); | |||
checker_conv_bias_preprocess(args, handle(), nullptr, 0.001, | |||
dtype::Float32{}, dtype::Float32{}, | |||
dtype::Float32{}, dtype::Float32{}, | |||
"CONV1x1:X86_F32_BLAS:24"); | |||
} | |||
#endif | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_INT8X8X) { | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_INT8X8X32) { | |||
using namespace conv_bias; | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
@@ -1374,6 +1417,38 @@ TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_INT8X8X) { | |||
dtype::Int8{}, dtype::Int16{}, dtype::Int16{}, | |||
"CONV1x1:X86_INT8X8X16_SSE"); | |||
} | |||
TEST_F(X86_MULTI_THREADS, CONV_BIAS_CONV1X1_S1_INT8X8X32_PREPROCESS) { | |||
using namespace conv_bias; | |||
UniformIntRNG rng{-50, 50}; | |||
float epsilon = 0.001; | |||
std::vector<conv_bias::TestArg> args = get_conv_bias_1x1_args(true, true); | |||
#if MEGDNN_X86_WITH_VNNI | |||
if (x86::is_supported(x86::SIMDType::VNNI)) { | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int32{}, dtype::Int32{}, | |||
"CONV1x1:X86_INT8X8X32_VNNI:24"); | |||
} | |||
#endif | |||
if (x86::is_supported(x86::SIMDType::AVX2)) { | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int32{}, dtype::Int32{}, | |||
"CONV1x1:X86_INT8X8X32_AVX2_4X16X2:24"); | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int32{}, dtype::Int32{}, | |||
"CONV1x1:X86_INT8X8X32_AVX2_2X4X16:24"); | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int16{}, dtype::Int16{}, | |||
"CONV1x1:X86_INT8X8X16_AVX2"); | |||
} | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int32{}, dtype::Int32{}, | |||
"CONV1x1:X86_INT8X8X32_SSE_4X8X2:48"); | |||
checker_conv_bias_preprocess(args, handle(), &rng, epsilon, dtype::Int8{}, | |||
dtype::Int8{}, dtype::Int16{}, dtype::Int16{}, | |||
"CONV1x1:X86_INT8X8X16_SSE"); | |||
} | |||
/************************* End Conv1x1 PackA ************************/ | |||
#endif | |||