Browse Source

decouple x86 fma avx2 (#3560)

tags/20220216
nihui GitHub 4 years ago
parent
commit
4654030541
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 307 additions and 86 deletions
  1. +9
    -0
      CMakeLists.txt
  2. +44
    -57
      cmake/ncnn_add_layer.cmake
  3. +3
    -3
      cmake/ncnn_generate_fma_source.cmake
  4. +17
    -9
      src/CMakeLists.txt
  5. +31
    -0
      src/cpu.cpp
  6. +8
    -6
      src/cpu.h
  7. +4
    -4
      src/layer.cpp
  8. +18
    -0
      src/layer/x86/convolution_3x3_pack8to1_int8.h
  9. +18
    -0
      src/layer/x86/convolution_3x3_pack8to4_int8.h
  10. +9
    -0
      src/layer/x86/convolution_sgemm_int8.h
  11. +9
    -0
      src/layer/x86/convolution_sgemm_pack1to4_int8.h
  12. +9
    -0
      src/layer/x86/convolution_sgemm_pack8to1_int8.h
  13. +9
    -0
      src/layer/x86/convolution_sgemm_pack8to4_int8.h
  14. +74
    -0
      src/layer/x86/convolution_x86_avx2.cpp
  15. +37
    -0
      src/layer/x86/convolution_x86_avx2.h
  16. +1
    -1
      src/layer/x86/x86_activation.h
  17. +2
    -2
      src/layer/x86/x86_usability.h
  18. +4
    -4
      src/layer_registry.h.in
  19. +1
    -0
      src/platform.h.in

+ 9
- 0
CMakeLists.txt View File

@@ -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)


+ 44
- 57
cmake/ncnn_add_layer.cmake View File

@@ -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")


cmake/ncnn_generate_avx2_source.cmake → cmake/ncnn_generate_fma_source.cmake View File

@@ -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}")

+ 17
- 9
src/CMakeLists.txt View File

@@ -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)


+ 31
- 0
src/cpu.cpp View File

@@ -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;


+ 8
- 6
src/cpu.h View File

@@ -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


+ 4
- 4
src/layer.cpp View File

@@ -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())
{


+ 18
- 0
src/layer/x86/convolution_3x3_pack8to1_int8.h View File

@@ -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())
{


+ 18
- 0
src/layer/x86/convolution_3x3_pack8to4_int8.h View File

@@ -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())
{


+ 9
- 0
src/layer/x86/convolution_sgemm_int8.h View File

@@ -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())
{


+ 9
- 0
src/layer/x86/convolution_sgemm_pack1to4_int8.h View File

@@ -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())
{


+ 9
- 0
src/layer/x86/convolution_sgemm_pack8to1_int8.h View File

@@ -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())
{


+ 9
- 0
src/layer/x86/convolution_sgemm_pack8to4_int8.h View File

@@ -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())
{


+ 74
- 0
src/layer/x86/convolution_x86_avx2.cpp View File

@@ -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

+ 37
- 0
src/layer/x86/convolution_x86_avx2.h View File

@@ -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

+ 1
- 1
src/layer/x86/x86_activation.h View File

@@ -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);


+ 2
- 2
src/layer/x86/x86_usability.h View File

@@ -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);


+ 4
- 4
src/layer_registry.h.in View File

@@ -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@


+ 1
- 0
src/platform.h.in View File

@@ -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


Loading…
Cancel
Save