| @@ -219,6 +219,7 @@ else() | |||
| include(CheckCXXCompilerFlag) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| check_cxx_compiler_flag("/arch:AVX" NCNN_COMPILER_SUPPORT_X86_AVX) | |||
| check_cxx_compiler_flag("/arch:AVX" NCNN_COMPILER_SUPPORT_X86_FMA) | |||
| check_cxx_compiler_flag("/arch:AVX" NCNN_COMPILER_SUPPORT_X86_XOP) | |||
| check_cxx_compiler_flag("/arch:AVX2" NCNN_COMPILER_SUPPORT_X86_AVX2) | |||
| check_cxx_compiler_flag("/arch:AVX2" NCNN_COMPILER_SUPPORT_X86_AVX_VNNI) | |||
| @@ -232,6 +233,7 @@ else() | |||
| endif() | |||
| else() | |||
| check_cxx_compiler_flag("-mavx" NCNN_COMPILER_SUPPORT_X86_AVX) | |||
| check_cxx_compiler_flag("-mfma" NCNN_COMPILER_SUPPORT_X86_FMA) | |||
| check_cxx_compiler_flag("-mxop" NCNN_COMPILER_SUPPORT_X86_XOP) | |||
| check_cxx_compiler_flag("-mfma -mf16c -mavx2" NCNN_COMPILER_SUPPORT_X86_AVX2) | |||
| check_cxx_compiler_flag("-mfma -mf16c -mavx512f -mavx512vl" NCNN_COMPILER_SUPPORT_X86_AVX512) | |||
| @@ -247,6 +249,13 @@ else() | |||
| if(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten" AND NCNN_COMPILER_SUPPORT_X86_AVX) | |||
| option(NCNN_AVX "optimize x86 platform with avx extension" ON) | |||
| if(NCNN_COMPILER_SUPPORT_X86_FMA) | |||
| if(NCNN_AVX) | |||
| option(NCNN_FMA "optimize x86 platform with fma extension" ON) | |||
| endif() | |||
| else() | |||
| message(WARNING "The compiler does not support fma extension. NCNN_FMA will be OFF.") | |||
| endif() | |||
| if(NCNN_COMPILER_SUPPORT_X86_XOP) | |||
| if(NCNN_AVX) | |||
| option(NCNN_XOP "optimize x86 platform with xop extension" ON) | |||
| @@ -159,82 +159,69 @@ macro(ncnn_add_layer class) | |||
| set(layer_registry "${layer_registry}#if NCNN_STRING\n{\"${class}\", 0},\n#else\n{0},\n#endif\n") | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_AVX512 AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(NCNN_RUNTIME_CPU AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| ncnn_add_arch_opt_layer(${class} avx512 "/arch:AVX512") | |||
| else() | |||
| ncnn_add_arch_opt_layer(${class} avx512 "-mfma -mf16c -mavx512f -mavx512vl") | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_AVX512VNNI AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(NCNN_COMPILER_SUPPORT_X86_AVX512_VNNI) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| ncnn_add_arch_opt_source(${class} avx512vnni "/arch:AVX512 /D__AVX512VNNI__") | |||
| else() | |||
| ncnn_add_arch_opt_source(${class} avx512vnni "-mfma -mf16c -mavx512f -mavx512vl -mavx512vnni") | |||
| if(NCNN_AVX512) | |||
| ncnn_add_arch_opt_layer(${class} avx512 "/arch:AVX512 /D__FMA__") | |||
| endif() | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_AVX2 AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| ncnn_add_arch_opt_layer(${class} avx2 "/arch:AVX2") | |||
| else() | |||
| ncnn_add_arch_opt_layer(${class} avx2 "-mfma -mf16c -mavx2") | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_AVXVNNI AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(NCNN_COMPILER_SUPPORT_X86_AVX_VNNI) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| ncnn_add_arch_opt_source(${class} avxvnni "/arch:AVX2 /D__AVXVNNI__") | |||
| else() | |||
| ncnn_add_arch_opt_source(${class} avxvnni "-mfma -mf16c -mavx2 -mavxvnni") | |||
| if(NCNN_FMA) | |||
| ncnn_add_arch_opt_layer(${class} fma "/arch:AVX /D__FMA__") | |||
| endif() | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_AVX AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| ncnn_add_arch_opt_layer(${class} avx "/arch:AVX") | |||
| else() | |||
| ncnn_add_arch_opt_layer(${class} avx "-mavx") | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_XOP AND NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(NCNN_COMPILER_SUPPORT_X86_XOP) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| if(NCNN_AVX) | |||
| ncnn_add_arch_opt_layer(${class} avx "/arch:AVX") | |||
| endif() | |||
| if(NCNN_AVX512VNNI) | |||
| ncnn_add_arch_opt_source(${class} avx512vnni "/arch:AVX512 /D__FMA__ /D__AVX512VNNI__") | |||
| endif() | |||
| if(NCNN_AVXVNNI) | |||
| ncnn_add_arch_opt_source(${class} avxvnni "/arch:AVX2 /D__FMA__ /D__AVXVNNI__") | |||
| endif() | |||
| if(NCNN_AVX2) | |||
| ncnn_add_arch_opt_source(${class} avx2 "/arch:AVX2 /D__FMA__") | |||
| endif() | |||
| if(NCNN_XOP) | |||
| ncnn_add_arch_opt_source(${class} xop "/arch:AVX /D__XOP__") | |||
| else() | |||
| endif() | |||
| else() | |||
| if(NCNN_AVX512) | |||
| ncnn_add_arch_opt_layer(${class} avx512 "-mavx512f -mavx512vl -mfma -mf16c") | |||
| endif() | |||
| if(NCNN_FMA) | |||
| ncnn_add_arch_opt_layer(${class} fma "-mavx -mfma") | |||
| endif() | |||
| if(NCNN_AVX) | |||
| ncnn_add_arch_opt_layer(${class} avx "-mavx") | |||
| endif() | |||
| if(NCNN_AVX512VNNI) | |||
| ncnn_add_arch_opt_source(${class} avx512vnni "-mavx512f -mavx512vl -mfma -mf16c -mavx512vnni") | |||
| endif() | |||
| if(NCNN_AVXVNNI) | |||
| ncnn_add_arch_opt_source(${class} avxvnni "-mavx2 -mfma -mf16c -mavxvnni") | |||
| endif() | |||
| if(NCNN_AVX2) | |||
| ncnn_add_arch_opt_source(${class} avx2 "-mavx2 -mfma -mf16c") | |||
| endif() | |||
| if(NCNN_XOP) | |||
| ncnn_add_arch_opt_source(${class} xop "-mavx -mxop") | |||
| endif() | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_ARM82 AND ((IOS AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)"))) | |||
| if(NCNN_COMPILER_SUPPORT_ARM82_FP16) | |||
| if(NCNN_RUNTIME_CPU AND ((IOS AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)"))) | |||
| if(NCNN_ARM82) | |||
| ncnn_add_arch_opt_layer(${class} arm82 "-march=armv8.2-a+fp16") | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_ARM82DOT AND ((IOS AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "arm64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)"))) | |||
| if(NCNN_COMPILER_SUPPORT_ARM82_FP16_DOTPROD) | |||
| if(NCNN_ARM82DOT) | |||
| ncnn_add_arch_opt_source(${class} arm82dot "-march=armv8.2-a+fp16+dotprod") | |||
| endif() | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_MSA AND NCNN_TARGET_ARCH STREQUAL "mips") | |||
| if(NCNN_COMPILER_SUPPORT_MIPS_MSA) | |||
| ncnn_add_arch_opt_layer(${class} msa "-mmsa") | |||
| endif() | |||
| ncnn_add_arch_opt_layer(${class} msa "-mmsa") | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_MMI AND NCNN_TARGET_ARCH STREQUAL "mips") | |||
| if(NCNN_COMPILER_SUPPORT_LOONGSON_MMI) | |||
| ncnn_add_arch_opt_layer(${class} mmi "-mmsa -mloongson-mmi") | |||
| endif() | |||
| ncnn_add_arch_opt_layer(${class} mmi "-mmsa -mloongson-mmi") | |||
| endif() | |||
| if(NCNN_RUNTIME_CPU AND NCNN_RVV AND NCNN_TARGET_ARCH STREQUAL "riscv") | |||
| @@ -7,8 +7,8 @@ file(READ ${SRC} source_data) | |||
| string(TOUPPER ${CLASS} CLASS_UPPER) | |||
| string(TOLOWER ${CLASS} CLASS_LOWER) | |||
| string(REGEX REPLACE "LAYER_${CLASS_UPPER}_X86_H" "LAYER_${CLASS_UPPER}_X86_AVX2_H" source_data "${source_data}") | |||
| string(REGEX REPLACE "${CLASS}_x86" "${CLASS}_x86_avx2" source_data "${source_data}") | |||
| string(REGEX REPLACE "#include \"${CLASS_LOWER}_x86.h\"" "#include \"${CLASS_LOWER}_x86_avx2.h\"" source_data "${source_data}") | |||
| string(REGEX REPLACE "LAYER_${CLASS_UPPER}_X86_H" "LAYER_${CLASS_UPPER}_X86_FMA_H" source_data "${source_data}") | |||
| string(REGEX REPLACE "${CLASS}_x86" "${CLASS}_x86_fma" source_data "${source_data}") | |||
| string(REGEX REPLACE "#include \"${CLASS_LOWER}_x86.h\"" "#include \"${CLASS_LOWER}_x86_fma.h\"" source_data "${source_data}") | |||
| file(WRITE ${DST} "${source_data}") | |||
| @@ -331,29 +331,37 @@ if(NCNN_TARGET_ARCH STREQUAL "x86") | |||
| if(NOT NCNN_RUNTIME_CPU AND NCNN_AVX512) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| if(NCNN_AVX512VNNI) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX512 /D__AVX512VNNI__) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX512 /D__FMA__ /D__AVX512VNNI__) | |||
| else() | |||
| target_compile_options(ncnn PRIVATE /arch:AVX512) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX512 /D__FMA__) | |||
| endif() | |||
| else() | |||
| if(NCNN_AVX512VNNI) | |||
| target_compile_options(ncnn PRIVATE -mfma -mf16c -mavx512f -mavx512vl -mavx512vnni) | |||
| target_compile_options(ncnn PRIVATE -mavx512f -mavx512vl -mfma -mf16c -mavx512vnni) | |||
| else() | |||
| target_compile_options(ncnn PRIVATE -mfma -mf16c -mavx512f -mavx512vl) | |||
| target_compile_options(ncnn PRIVATE -mavx512f -mavx512vl -mfma -mf16c) | |||
| endif() | |||
| endif() | |||
| elseif(NOT NCNN_RUNTIME_CPU AND NCNN_AVX2) | |||
| elseif(NOT NCNN_RUNTIME_CPU AND NCNN_FMA) | |||
| if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) | |||
| if(NCNN_AVXVNNI) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX2 /D__AVXVNNI__) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX2 /D__FMA__ /D__AVXVNNI__) | |||
| elseif(NCNN_AVX2) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX2 /D__FMA__) | |||
| elseif(NCNN_XOP) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX /D__FMA__ /D__XOP__) | |||
| else() | |||
| target_compile_options(ncnn PRIVATE /arch:AVX2) | |||
| target_compile_options(ncnn PRIVATE /arch:AVX /D__FMA__) | |||
| endif() | |||
| else() | |||
| if(NCNN_AVXVNNI) | |||
| target_compile_options(ncnn PRIVATE -mfma -mf16c -mavx2 -mavxvnni) | |||
| target_compile_options(ncnn PRIVATE -mavx2 -mfma -mf16c -mavxvnni) | |||
| elseif(NCNN_AVX2) | |||
| target_compile_options(ncnn PRIVATE -mavx2 -mfma -mf16c) | |||
| elseif(NCNN_XOP) | |||
| target_compile_options(ncnn PRIVATE -mavx -mfma -mxop) | |||
| else() | |||
| target_compile_options(ncnn PRIVATE -mfma -mf16c -mavx2) | |||
| target_compile_options(ncnn PRIVATE -mavx -mfma) | |||
| endif() | |||
| endif() | |||
| elseif(NOT NCNN_RUNTIME_CPU AND NCNN_AVX) | |||
| @@ -512,6 +512,30 @@ static int get_cpu_support_x86_avx() | |||
| return 1; | |||
| } | |||
| static int get_cpu_support_x86_fma() | |||
| { | |||
| #if !NCNN_FMA | |||
| return 0; | |||
| #endif | |||
| unsigned int cpu_info[4] = {0}; | |||
| x86_cpuid(0, cpu_info); | |||
| int nIds = cpu_info[0]; | |||
| if (nIds < 7) | |||
| return 0; | |||
| x86_cpuid(1, cpu_info); | |||
| // check AVX XSAVE OSXSAVE | |||
| if (!(cpu_info[2] & (1u << 28)) || !(cpu_info[2] & (1u << 26)) || !(cpu_info[2] & (1u << 27))) | |||
| return 0; | |||
| // check XSAVE enabled by kernel | |||
| if ((x86_get_xcr0() & 6) != 6) | |||
| return 0; | |||
| return cpu_info[2] & (1u << 12); | |||
| } | |||
| static int get_cpu_support_x86_xop() | |||
| { | |||
| #if !NCNN_XOP | |||
| @@ -637,6 +661,7 @@ static int get_cpu_support_x86_avx512_vnni() | |||
| } | |||
| static int g_cpu_support_x86_avx = get_cpu_support_x86_avx(); | |||
| static int g_cpu_support_x86_fma = get_cpu_support_x86_fma(); | |||
| static int g_cpu_support_x86_xop = get_cpu_support_x86_xop(); | |||
| static int g_cpu_support_x86_avx2 = get_cpu_support_x86_avx2(); | |||
| static int g_cpu_support_x86_avx_vnni = get_cpu_support_x86_avx_vnni(); | |||
| @@ -644,6 +669,7 @@ static int g_cpu_support_x86_avx512 = get_cpu_support_x86_avx512(); | |||
| static int g_cpu_support_x86_avx512_vnni = get_cpu_support_x86_avx512_vnni(); | |||
| #else // defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) | |||
| static const int g_cpu_support_x86_avx = 0; | |||
| static const int g_cpu_support_x86_fma = 0; | |||
| static const int g_cpu_support_x86_xop = 0; | |||
| static const int g_cpu_support_x86_avx2 = 0; | |||
| static const int g_cpu_support_x86_avx_vnni = 0; | |||
| @@ -656,6 +682,11 @@ int cpu_support_x86_avx() | |||
| return g_cpu_support_x86_avx; | |||
| } | |||
| int cpu_support_x86_fma() | |||
| { | |||
| return g_cpu_support_x86_fma; | |||
| } | |||
| int cpu_support_x86_xop() | |||
| { | |||
| return g_cpu_support_x86_xop; | |||
| @@ -54,17 +54,19 @@ NCNN_EXPORT int cpu_support_arm_asimdhp(); | |||
| // asimddp = aarch64 asimd dot product | |||
| NCNN_EXPORT int cpu_support_arm_asimddp(); | |||
| // avx = x86_64 avx | |||
| // avx = x86 avx | |||
| NCNN_EXPORT int cpu_support_x86_avx(); | |||
| // xop = x86_64 xop | |||
| // xop = x86 xop | |||
| NCNN_EXPORT int cpu_support_x86_xop(); | |||
| // avx2 = x86_64 avx2 + fma + f16c | |||
| // fma = x86 fma | |||
| NCNN_EXPORT int cpu_support_x86_fma(); | |||
| // avx2 = x86 avx2 + fma + f16c | |||
| NCNN_EXPORT int cpu_support_x86_avx2(); | |||
| // avx_vnni = x86_64 avx vnni | |||
| // avx_vnni = x86 avx vnni | |||
| NCNN_EXPORT int cpu_support_x86_avx_vnni(); | |||
| // avx512 = x86_64 avx512f + avx512vl | |||
| // avx512 = x86 avx512f + avx512vl | |||
| NCNN_EXPORT int cpu_support_x86_avx512(); | |||
| // avx512_vnni = x86_64 avx512 vnni | |||
| // avx512_vnni = x86 avx512 vnni | |||
| NCNN_EXPORT int cpu_support_x86_avx512_vnni(); | |||
| // msa = mips mas | |||
| @@ -239,13 +239,13 @@ Layer* create_layer(int index) | |||
| } | |||
| else | |||
| #endif// NCNN_RUNTIME_CPU && NCNN_AVX512 | |||
| #if NCNN_RUNTIME_CPU && NCNN_AVX2 | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| #if NCNN_RUNTIME_CPU && NCNN_FMA | |||
| if (ncnn::cpu_support_x86_fma()) | |||
| { | |||
| layer_creator = layer_registry_avx2[index].creator; | |||
| layer_creator = layer_registry_fma[index].creator; | |||
| } | |||
| else | |||
| #endif// NCNN_RUNTIME_CPU && NCNN_AVX2 | |||
| #endif// NCNN_RUNTIME_CPU && NCNN_FMA | |||
| #if NCNN_RUNTIME_CPU && NCNN_AVX | |||
| if (ncnn::cpu_support_x86_avx()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse(const Mat& k | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm_pack8to1, int inch, int outch, const Option& opt); | |||
| conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse_avx2(kernel, kernel_tm_pack8to1, inch, outch, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -190,6 +199,15 @@ static void conv3x3s1_winograd42_pack8to1_int8_sse(const Mat& bottom_blob, Mat& | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void conv3x3s1_winograd42_pack8to1_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| conv3x3s1_winograd42_pack8to1_int8_sse_avx2(bottom_blob, top_blob, kernel_tm, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse(const Mat& k | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm_pack8, int inch, int outch, const Option& opt); | |||
| conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse_avx2(kernel, kernel_tm_pack8, inch, outch, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -174,6 +183,15 @@ static void conv3x3s1_winograd42_pack8to4_int8_sse(const Mat& bottom_blob, Mat& | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void conv3x3s1_winograd42_pack8to4_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| conv3x3s1_winograd42_pack8to4_int8_sse_avx2(bottom_blob, top_blob, kernel_tm, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void im2col_sgemm_int8_sse(const Mat& bottom_im2col, Mat& top_blob, const | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void im2col_sgemm_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| im2col_sgemm_int8_sse_avx2(bottom_im2col, top_blob, kernel, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void im2col_sgemm_pack1to4_int8_sse(const Mat& bottom_im2col, Mat& top_bl | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void im2col_sgemm_pack1to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| im2col_sgemm_pack1to4_int8_sse_avx2(bottom_im2col, top_blob, kernel, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void im2col_sgemm_pack8to1_int8_sse(const Mat& bottom_im2col, Mat& top_bl | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void im2col_sgemm_pack8to1_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| im2col_sgemm_pack8to1_int8_sse_avx2(bottom_im2col, top_blob, kernel, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -32,6 +32,15 @@ static void im2col_sgemm_pack8to4_int8_sse(const Mat& bottom_im2col, Mat& top_bl | |||
| } | |||
| #endif | |||
| #if NCNN_AVX2 && __AVX__ && !__AVX2__ | |||
| if (ncnn::cpu_support_x86_avx2()) | |||
| { | |||
| extern void im2col_sgemm_pack8to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| im2col_sgemm_pack8to4_int8_sse_avx2(bottom_im2col, top_blob, kernel, opt); | |||
| return; | |||
| } | |||
| #endif | |||
| #if NCNN_XOP && __SSE2__ && !__XOP__ | |||
| if (ncnn::cpu_support_x86_xop()) | |||
| { | |||
| @@ -0,0 +1,74 @@ | |||
| // Tencent is pleased to support the open source community by making ncnn available. | |||
| // | |||
| // Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. | |||
| // | |||
| // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except | |||
| // in compliance with the License. You may obtain a copy of the License at | |||
| // | |||
| // https://opensource.org/licenses/BSD-3-Clause | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software distributed | |||
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |||
| // CONDITIONS OF ANY KIND, either express or implied. See the License for the | |||
| // specific language governing permissions and limitations under the License. | |||
| #include "convolution_x86_avx2.h" | |||
| #include "cpu.h" | |||
| #include "mat.h" | |||
| #include "x86_usability.h" | |||
| namespace ncnn { | |||
| #include "convolution_sgemm_int8.h" | |||
| #include "convolution_sgemm_pack1to4_int8.h" | |||
| #include "convolution_sgemm_pack8to1_int8.h" | |||
| #include "convolution_sgemm_pack8to4_int8.h" | |||
| #include "convolution_3x3_pack8to1_int8.h" | |||
| #include "convolution_3x3_pack8to4_int8.h" | |||
| // pack1 | |||
| void im2col_sgemm_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| im2col_sgemm_int8_sse(bottom_im2col, top_blob, kernel, opt); | |||
| } | |||
| // pack1to4 | |||
| void im2col_sgemm_pack1to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| im2col_sgemm_pack1to4_int8_sse(bottom_im2col, top_blob, kernel, opt); | |||
| } | |||
| // pack8to1 | |||
| void im2col_sgemm_pack8to1_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| im2col_sgemm_pack8to1_int8_sse(bottom_im2col, top_blob, kernel, opt); | |||
| } | |||
| void conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm, int inch, int outch, const Option& opt) | |||
| { | |||
| conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse(kernel, kernel_tm, inch, outch, opt); | |||
| } | |||
| void conv3x3s1_winograd42_pack8to1_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| conv3x3s1_winograd42_pack8to1_int8_sse(bottom_blob, top_blob, kernel, opt); | |||
| } | |||
| // pack8to4 | |||
| void im2col_sgemm_pack8to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| im2col_sgemm_pack8to4_int8_sse(bottom_im2col, top_blob, kernel, opt); | |||
| } | |||
| void conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm, int inch, int outch, const Option& opt) | |||
| { | |||
| conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse(kernel, kernel_tm, inch, outch, opt); | |||
| } | |||
| void conv3x3s1_winograd42_pack8to4_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt) | |||
| { | |||
| conv3x3s1_winograd42_pack8to4_int8_sse(bottom_blob, top_blob, kernel, opt); | |||
| } | |||
| } // namespace ncnn | |||
| @@ -0,0 +1,37 @@ | |||
| // Tencent is pleased to support the open source community by making ncnn available. | |||
| // | |||
| // Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. | |||
| // | |||
| // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except | |||
| // in compliance with the License. You may obtain a copy of the License at | |||
| // | |||
| // https://opensource.org/licenses/BSD-3-Clause | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software distributed | |||
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |||
| // CONDITIONS OF ANY KIND, either express or implied. See the License for the | |||
| // specific language governing permissions and limitations under the License. | |||
| #include "mat.h" | |||
| namespace ncnn { | |||
| // pack1 | |||
| void im2col_sgemm_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| // pack1to4 | |||
| void im2col_sgemm_pack1to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| // pack8to1 | |||
| void im2col_sgemm_pack8to1_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| void conv3x3s1_winograd42_transform_kernel_pack8to1_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm, int inch, int outch, const Option& opt); | |||
| void conv3x3s1_winograd42_pack8to1_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| // pack8to4 | |||
| void im2col_sgemm_pack8to4_int8_sse_avx2(const Mat& bottom_im2col, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| void conv3x3s1_winograd42_transform_kernel_pack8to4_int8_sse_avx2(const Mat& kernel, Mat& kernel_tm, int inch, int outch, const Option& opt); | |||
| void conv3x3s1_winograd42_pack8to4_int8_sse_avx2(const Mat& bottom_blob, Mat& top_blob, const Mat& kernel, const Option& opt); | |||
| } // namespace ncnn | |||
| @@ -131,7 +131,7 @@ static NCNN_FORCEINLINE __m256 tanh_avx(__m256 inputs) | |||
| { | |||
| const __m256 one = _mm256_set1_ps(1.0f); | |||
| const __m256 two = _mm256_set1_ps(2.0f); | |||
| #if __AVX2__ | |||
| #if __FMA__ | |||
| return _mm256_fmsub_ps(sigmoid_avx(_mm256_mul_ps(inputs, two)), two, one); | |||
| #else | |||
| return _mm256_sub_ps(_mm256_mul_ps(sigmoid_avx(_mm256_mul_ps(inputs, two)), two), one); | |||
| @@ -147,7 +147,7 @@ static NCNN_FORCEINLINE __m128i float2int8_sse(const __m128& _v0, const __m128& | |||
| return _v8; | |||
| } | |||
| #ifndef __AVX2__ | |||
| #ifndef __FMA__ | |||
| static NCNN_FORCEINLINE __m128 _mm_comp_fmadd_ps(__m128 _a, const __m128 _b, const __m128 _c) | |||
| { | |||
| @@ -156,7 +156,7 @@ static NCNN_FORCEINLINE __m128 _mm_comp_fmadd_ps(__m128 _a, const __m128 _b, con | |||
| #endif | |||
| #if __AVX__ | |||
| #ifndef __AVX2__ | |||
| #ifndef __FMA__ | |||
| static NCNN_FORCEINLINE __m256 _mm256_comp_fmadd_ps(__m256 _a, const __m256 _b, const __m256 _c) | |||
| { | |||
| return _mm256_add_ps(_mm256_mul_ps(_a, _b), _c); | |||
| @@ -11,11 +11,11 @@ static const layer_registry_entry layer_registry_avx512[] = { | |||
| @layer_registry_avx512@ | |||
| }; | |||
| #endif // NCNN_RUNTIME_CPU && NCNN_AVX512 | |||
| #if NCNN_RUNTIME_CPU && NCNN_AVX2 | |||
| static const layer_registry_entry layer_registry_avx2[] = { | |||
| @layer_registry_avx2@ | |||
| #if NCNN_RUNTIME_CPU && NCNN_FMA | |||
| static const layer_registry_entry layer_registry_fma[] = { | |||
| @layer_registry_fma@ | |||
| }; | |||
| #endif // NCNN_RUNTIME_CPU && NCNN_AVX2 | |||
| #endif // NCNN_RUNTIME_CPU && NCNN_FMA | |||
| #if NCNN_RUNTIME_CPU && NCNN_AVX | |||
| static const layer_registry_entry layer_registry_avx[] = { | |||
| @layer_registry_avx@ | |||
| @@ -32,6 +32,7 @@ | |||
| #cmakedefine01 NCNN_RUNTIME_CPU | |||
| #cmakedefine01 NCNN_AVX | |||
| #cmakedefine01 NCNN_XOP | |||
| #cmakedefine01 NCNN_FMA | |||
| #cmakedefine01 NCNN_AVX2 | |||
| #cmakedefine01 NCNN_AVXVNNI | |||
| #cmakedefine01 NCNN_AVX512 | |||