From 66ec3a0717e767c6773f051fcf60b876d9c253e6 Mon Sep 17 00:00:00 2001 From: Aaron Teo Date: Sun, 26 Oct 2025 13:13:54 +0800 Subject: [PATCH] ggml: initial s390 feat detection Signed-off-by: Aaron Teo --- ggml/src/CMakeLists.txt | 6 +-- ggml/src/ggml-cpu/CMakeLists.txt | 2 + ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp | 59 +++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp diff --git a/ggml/src/CMakeLists.txt b/ggml/src/CMakeLists.txt index 3356ef550d..01c6032806 100644 --- a/ggml/src/CMakeLists.txt +++ b/ggml/src/CMakeLists.txt @@ -377,9 +377,9 @@ if (GGML_CPU_ALL_VARIANTS) endif() elseif (GGML_SYSTEM_ARCH STREQUAL "s390x") if (CMAKE_SYSTEM_NAME MATCHES "Linux") - ggml_add_cpu_backend_variant(s390x_z15 Z15 VXE) - # ggml_add_cpu_backend_variant(s390x_z16 Z16 VXE) - # ggml_add_cpu_backend_variant(s390x_z17 Z17 VXE) + ggml_add_cpu_backend_variant(s390x) + ggml_add_cpu_backend_variant(z15 Z15 VXE) + ggml_add_cpu_backend_variant(z16 Z16 VXE) else() message(FATAL_ERROR "Unsupported s390x target OS: ${CMAKE_SYSTEM_NAME}") endif() diff --git a/ggml/src/ggml-cpu/CMakeLists.txt b/ggml/src/ggml-cpu/CMakeLists.txt index 34323afa07..8af62a4d1e 100644 --- a/ggml/src/ggml-cpu/CMakeLists.txt +++ b/ggml/src/ggml-cpu/CMakeLists.txt @@ -509,6 +509,8 @@ function(ggml_add_cpu_backend_variant_impl tag_name) list(APPEND ARCH_FLAGS -mvx -mzvector) list(APPEND ARCH_DEFINITIONS GGML_VXE) endif() + + ggml_add_cpu_backend_features(${GGML_CPU_NAME} arm ${ARCH_DEFINITIONS}) elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "wasm") message(STATUS "Wasm detected") list (APPEND GGML_CPU_SOURCES ggml-cpu/arch/wasm/quants.c) diff --git a/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp b/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp new file mode 100644 index 0000000000..1fd925d039 --- /dev/null +++ b/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp @@ -0,0 +1,59 @@ +#include "ggml-backend-impl.h" + +#if defined(__s390x__) +#include + +// find hwcap bits in asm/elf.h +#ifndef HWCAP_VXRS_EXT +#define HWCAP_VXRS_EXT (1 << 13) +#endif + +#ifndef HWCAP_VXRS_EXT2 +#define HWCAP_VXRS_EXT2 (1 << 15) +#endif + +#ifndef HWCAP_NNPA +#define HWCAP_NNPA (1 << 20) +#endif + +struct s390x_features { + bool has_vxe = false; + bool has_vxe2 = false; + bool has_nnpa = false; + + s390x_features() { + uint32_t hwcap = getauxval(AT_HWCAP); + uint32_t hwcap2 = getauxval(AT_HWCAP2); + + has_vxe = !!(hwcap & HWCAP_VXRS_EXT); + has_vxe2 = !!(hwcap & HWCAP_VXRS_EXT2); + has_nnpa = !!(hwcap & HWCAP_NNPA); + + GGML_LOG_INFO("s390x features detected: VXE=%d, VXE2=%d, NNPA=%d", + has_vxe, has_vxe2, has_nnpa); + } +}; + +static int ggml_backend_cpu_s390x_score() { + int score = 1; + s390x_features sf; + +#ifdef GGML_USE_VXE + if (!sf.has_vxe) { return 0; } + score += 1 << 1; +#endif +#ifdef GGML_USE_VXE2 + if (!sf.has_vxe2) { return 0; } + score += 1 << 2; +#endif +#ifdef GGML_USE_NNPA + if (!sf.has_nnpa) { return 0; } + score += 1 << 3; +#endif + + return score; +} + +GGML_BACKEND_DL_SCORE_IMPL(ggml_backend_cpu_s390x_score) + +#endif // __s390x__