From 7ecc18ec7a5cc7871846f4a8132adb3d95f6de74 Mon Sep 17 00:00:00 2001 From: inspiremenow Date: Tue, 8 Oct 2024 01:39:09 +0800 Subject: [PATCH] feat: add environment detection tests - Added environment detection tests to CMake configuration, setting ISA env flags based on the system architecture for Linux, Windows, Darwin, and Android. Signed-off-by: Kaiyao Duan --- tests/CMakeLists.txt | 52 ++++++++++++++++++++++ tests/test_env_detect.cpp | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 tests/test_env_detect.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d30229b870c4..d0d2a66899a6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -61,6 +61,58 @@ endif() ncnn_add_test(c_api) ncnn_add_test(cpu) +set(ENABLE_ENV_DETECT_TEST ON CACHE BOOL "Enable the environment detection test") +if(ENABLE_ENV_DETECT_TEST) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(DEFINED CMAKE_SYSTEM_PROCESSOR) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(ENV{NCNN_ISA} "-avx,-fma") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + set(ENV{NCNN_ISA} "-neon") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") + set(ENV{NCNN_ISA} "-neon") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "loongarch64") + set(ENV{NCNN_ISA} "-lsx,-lasx") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "mips") + set(ENV{NCNN_ISA} "-msa") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv") + set(ENV{NCNN_ISA} "-rvv") + endif() + endif() + + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + if(DEFINED CMAKE_SYSTEM_PROCESSOR) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(ENV{NCNN_ISA} "-avx,-fma") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64") + set(ENV{NCNN_ISA} "-neon") + endif() + endif() + + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + if(DEFINED CMAKE_SYSTEM_PROCESSOR) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(ENV{NCNN_ISA} "-avx,-fma") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + set(ENV{NCNN_ISA} "-neon") + endif() + endif() + + elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") + if(DEFINED CMAKE_SYSTEM_PROCESSOR) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64-v8a") + set(ENV{NCNN_ISA} "-neon") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "armeabi-v7a") + set(ENV{NCNN_ISA} "-neon") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(ENV{NCNN_ISA} "-avx,-fma") + endif() + endif() + endif() + + ncnn_add_test(env_detect) +endif() + if(NCNN_VULKAN) ncnn_add_test(command) endif() diff --git a/tests/test_env_detect.cpp b/tests/test_env_detect.cpp new file mode 100644 index 000000000000..dae1ccc918e7 --- /dev/null +++ b/tests/test_env_detect.cpp @@ -0,0 +1,92 @@ +#include "cpu.h" +#include +#include +#include + +// Improved version of is_option_disabled function that doesn't modify the original string +bool is_option_disabled(const char* options, const char* option) +{ + char* options_copy = strdup(options); + char* token = strtok(options_copy, ","); + bool disabled = false; + + while (token) + { + if (strcmp(token, option) == 0) + { + disabled = true; + break; + } + token = strtok(nullptr, ","); + } + + free(options_copy); + return disabled; +} + +// Helper function to check and report instruction set support +bool check_instruction_disabled(const char* options, const char* option, bool cpu_support, const char* instruction_name) +{ + if (is_option_disabled(options, option) && cpu_support) + { + fprintf(stderr, "Error: %s should be disabled but it is enabled!\n", instruction_name); + return true; + } + return false; +} + +int main() +{ + const char* ncnn_isa = std::getenv("NCNN_ISA"); + + // Check if NCNN_ISA is set to disable certain options + if (ncnn_isa) + { +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) + if (check_instruction_disabled(ncnn_isa, "-avx", ncnn::cpu_support_x86_avx(), "avx")) return 1; + if (check_instruction_disabled(ncnn_isa, "-xop", ncnn::cpu_support_x86_xop(), "xop")) return 1; + if (check_instruction_disabled(ncnn_isa, "-fma", ncnn::cpu_support_x86_fma(), "fma")) return 1; + if (check_instruction_disabled(ncnn_isa, "-f16c", ncnn::cpu_support_x86_f16c(), "f16c")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx2", ncnn::cpu_support_x86_avx2(), "avx2")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx512", ncnn::cpu_support_x86_avx512(), "avx512")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx_vnni", ncnn::cpu_support_x86_avx_vnni(), "avx_vnni")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx512_vnni", ncnn::cpu_support_x86_avx512_vnni(), "avx512_vnni")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx512_bf16", ncnn::cpu_support_x86_avx512_bf16(), "avx512_bf16")) return 1; + if (check_instruction_disabled(ncnn_isa, "-avx512_fp16", ncnn::cpu_support_x86_avx512_fp16(), "avx512_fp16")) return 1; +#endif + +#if defined(__aarch64__) || defined(__arm__) + if (check_instruction_disabled(ncnn_isa, "-cpuid", ncnn::cpu_support_arm_cpuid(), "cpuid")) return 1; + if (check_instruction_disabled(ncnn_isa, "-asimdhp", ncnn::cpu_support_arm_asimdhp(), "asimdhp")) return 1; + if (check_instruction_disabled(ncnn_isa, "-asimddp", ncnn::cpu_support_arm_asimddp(), "asimddp")) return 1; + if (check_instruction_disabled(ncnn_isa, "-asimdfhm", ncnn::cpu_support_arm_asimdfhm(), "asimdfhm")) return 1; + if (check_instruction_disabled(ncnn_isa, "-bf16", ncnn::cpu_support_arm_bf16(), "bf16")) return 1; + if (check_instruction_disabled(ncnn_isa, "-i8mm", ncnn::cpu_support_arm_i8mm(), "i8mm")) return 1; + if (check_instruction_disabled(ncnn_isa, "-sve", ncnn::cpu_support_arm_sve(), "sve")) return 1; + if (check_instruction_disabled(ncnn_isa, "-sve2", ncnn::cpu_support_arm_sve2(), "sve2")) return 1; + if (check_instruction_disabled(ncnn_isa, "-svebf16", ncnn::cpu_support_arm_svebf16(), "svebf16")) return 1; + if (check_instruction_disabled(ncnn_isa, "-svei8mm", ncnn::cpu_support_arm_svei8mm(), "svei8mm")) return 1; + if (check_instruction_disabled(ncnn_isa, "-svef32mm", ncnn::cpu_support_arm_svef32mm(), "svef32mm")) return 1; + if (check_instruction_disabled(ncnn_isa, "-edsp", ncnn::cpu_support_arm_edsp(), "edsp")) return 1; + if (check_instruction_disabled(ncnn_isa, "-vfpv4", ncnn::cpu_support_arm_vfpv4(), "vfpv4")) return 1; + if (check_instruction_disabled(ncnn_isa, "-neon", ncnn::cpu_support_arm_neon(), "neon")) return 1; +#endif + +#if defined(__loongarch64) + if (check_instruction_disabled(ncnn_isa, "-lsx", ncnn::cpu_support_loongarch_lsx(), "lsx")) return 1; + if (check_instruction_disabled(ncnn_isa, "-lasx", ncnn::cpu_support_loongarch_lasx(), "lasx")) return 1; +#endif + +#if defined(__mips__) + if (check_instruction_disabled(ncnn_isa, "-msa", ncnn::cpu_support_mips_msa(), "msa")) return 1; + if (check_instruction_disabled(ncnn_isa, "-mmi", ncnn::cpu_support_loongson_mmi(), "mmi")) return 1; +#endif + +#if defined(__riscv) + if (check_instruction_disabled(ncnn_isa, "-rvv", ncnn::cpu_support_riscv_v(), "rvv")) return 1; + if (check_instruction_disabled(ncnn_isa, "-zfh", ncnn::cpu_support_riscv_zfh(), "zfh")) return 1; +#endif + } + + return 0; +}