option(GGML_RV_ZICBOP "ggml: enable riscv zicbop" ON)
option(GGML_XTHEADVECTOR "ggml: enable xtheadvector" OFF)
option(GGML_VXE "ggml: enable vxe" ON)
-option(GGML_NNPA "ggml: enable nnpa" OFF) # temp disabled by default, see: https://github.com/ggml-org/llama.cpp/issues/14877
option(GGML_CPU_ALL_VARIANTS "ggml: build all variants of the CPU backend (requires GGML_BACKEND_DL)" OFF)
set(GGML_CPU_ARM_ARCH "" CACHE STRING "ggml: CPU architecture for ARM")
GGML_BACKEND_API int ggml_cpu_has_riscv_v (void);
GGML_BACKEND_API int ggml_cpu_has_vsx (void);
GGML_BACKEND_API int ggml_cpu_has_vxe (void);
- GGML_BACKEND_API int ggml_cpu_has_nnpa (void);
GGML_BACKEND_API int ggml_cpu_has_wasm_simd (void);
GGML_BACKEND_API int ggml_cpu_has_llamafile (void);
# TODO: Separation to determine activation of VX/VXE/VXE2
if (${S390X_M} MATCHES "8561|8562")
- set(GGML_NNPA OFF)
message(STATUS "z15 target")
list(APPEND ARCH_FLAGS -march=z15)
elseif (${S390X_M} MATCHES "3931")
list(APPEND ARCH_FLAGS -mvx -mzvector)
list(APPEND ARCH_DEFINITIONS GGML_VXE)
endif()
-
- if (GGML_NNPA)
- message(STATUS "NNPA enabled")
- list(APPEND ARCH_DEFINITIONS GGML_NNPA)
- endif()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "wasm")
message(STATUS "Wasm detected")
list (APPEND GGML_CPU_SOURCES ggml-cpu/arch/wasm/quants.c)
#endif // __VXE2__
#endif // __s390x__ && __VEC__
-#if defined(__s390x__) && defined(GGML_NNPA)
-#ifndef __NNPA__
-#define __NNPA__
-#endif // __NNPA__
-#endif // __s390x__ && GGML_NNPA
-
#if defined(__ARM_FEATURE_SVE)
#include <sys/prctl.h>
#endif
__m128i y_vec = _mm_cvtps_ph(x_vec, _MM_FROUND_TO_NEAREST_INT);
_mm_storel_epi64((__m128i *)(y + i), y_vec);
}
-#elif defined(__NNPA__)
- for (; i + 7 < n; i += 8) {
- float32x4_t v_xh = vec_xl(0, (const float *)(x + i + 0));
- float32x4_t v_xl = vec_xl(0, (const float *)(x + i + 4));
- uint16x8_t v_yd = vec_round_from_fp32(v_xh, v_xl, 0);
- uint16x8_t v_y = vec_convert_to_fp16(v_yd, 0);
- vec_xst(v_y, 0, (ggml_fp16_t *)(y + i));
- }
- for (; i + 3 < n; i += 4) {
- float32x4_t v_x = vec_xl(0, (const float *)(x + i));
- float32x4_t v_zero = vec_splats(0.0f);
- uint16x8_t v_yd = vec_round_from_fp32(v_x, v_zero, 0);
- uint16x8_t v_y = vec_convert_to_fp16(v_yd, 0);
- vec_xst(v_y, 0, (ggml_fp16_t *)(y + i));
- }
#elif defined(__riscv_zvfh)
for (int vl; i < n; i += vl) {
vl = __riscv_vsetvl_e32m2(n - i);
__m128 y_vec = _mm_cvtph_ps(x_vec);
_mm_storeu_ps(y + i, y_vec);
}
-#elif defined(__NNPA__)
- for (; i + 7 < n; i += 8) {
- uint16x8_t v_x = vec_xl(0, (const ggml_fp16_t *)(x + i));
- uint16x8_t v_yd = vec_convert_from_fp16(v_x, 0);
- float32x4_t v_yh = vec_extend_to_fp32_hi(v_yd, 0);
- float32x4_t v_yl = vec_extend_to_fp32_lo(v_yd, 0);
- vec_xst(v_yh, 0, (float *)(y + i + 0));
- vec_xst(v_yl, 0, (float *)(y + i + 4));
- }
- for (; i + 3 < n; i += 4) {
- uint16x8_t v_x = vec_xl(0, (const ggml_fp16_t *)(x + i));
- uint16x8_t v_yd = vec_convert_from_fp16(v_x, 0);
- float32x4_t v_yh = vec_extend_to_fp32_hi(v_yd, 0);
- vec_xst(v_yh, 0, (float *)(y + i));
- }
#endif
for (; i < n; ++i) {
#endif
}
-int ggml_cpu_has_nnpa(void) {
-#if defined(GGML_NNPA)
- return 1;
-#else
- return 0;
-#endif
-}
-
int ggml_cpu_has_neon(void) {
#if defined(__ARM_ARCH) && defined(__ARM_NEON)
return 1;
if (ggml_cpu_has_vxe()) {
features.push_back({ "VXE", "1" });
}
- if (ggml_cpu_has_nnpa()) {
- features.push_back({ "NNPA", "1" });
- }
if (ggml_cpu_has_wasm_simd()) {
features.push_back({ "WASM_SIMD", "1" });
}
#define GGML_CPU_COMPUTE_FP32_TO_FP16(x) riscv_compute_fp32_to_fp16(x)
#define GGML_CPU_FP16_TO_FP32(x) GGML_CPU_COMPUTE_FP16_TO_FP32(x)
#define GGML_CPU_FP32_TO_FP16(x) GGML_CPU_COMPUTE_FP32_TO_FP16(x)
-#elif defined(__NNPA__)
- #define GGML_CPU_COMPUTE_FP16_TO_FP32(x) nnpa_compute_fp16_to_fp32(x)
- #define GGML_CPU_COMPUTE_FP32_TO_FP16(x) nnpa_compute_fp32_to_fp16(x)
-
- #define GGML_CPU_FP16_TO_FP32(x) GGML_CPU_COMPUTE_FP16_TO_FP32(x)
- #define GGML_CPU_FP32_TO_FP16(x) GGML_CPU_COMPUTE_FP32_TO_FP16(x)
-
- static inline float nnpa_compute_fp16_to_fp32(ggml_fp16_t h) {
- uint16x8_t v_h = vec_splats(h);
- uint16x8_t v_hd = vec_convert_from_fp16(v_h, 0);
- return vec_extend_to_fp32_hi(v_hd, 0)[0];
- }
-
- static inline ggml_fp16_t nnpa_compute_fp32_to_fp16(float f) {
- float32x4_t v_f = vec_splats(f);
- float32x4_t v_zero = vec_splats(0.0f);
- uint16x8_t v_hd = vec_round_from_fp32(v_f, v_zero, 0);
- uint16x8_t v_h = vec_convert_to_fp16(v_hd, 0);
- return vec_extract(v_h, 0);
- }
#endif
// precomputed f32 table for f16 (256 KB)
#define GGML_F16_EPR GGML_F32_EPR
static inline float32x4_t __lzs_f16cx4_load(const ggml_fp16_t * x) {
-#if defined(__NNPA__)
- uint16x8_t v_x = vec_xl(0, (const ggml_fp16_t *)x);
- uint16x8_t v_xd = vec_convert_from_fp16(v_x, 0);
- return vec_extend_to_fp32_hi(v_xd, 0);
-#else
float tmp[4];
for (int i = 0; i < 4; i++) {
// note: keep type-cast here to prevent compiler bugs
// see: https://github.com/ggml-org/llama.cpp/issues/12846
return vec_xl(0, (const float *)(tmp));
-#endif
}
static inline void __lzs_f16cx4_store(ggml_fp16_t * x, float32x4_t v_y) {
-#if defined(__NNPA__)
- float32x4_t v_zero = vec_splats(0.0f);
- uint16x8_t v_xd = vec_round_from_fp32(v_y, v_zero, 0);
- uint16x8_t v_x = vec_convert_to_fp16(v_xd, 0);
-
- x[0] = vec_extract(v_x, 0);
- x[1] = vec_extract(v_x, 1);
- x[2] = vec_extract(v_x, 2);
- x[3] = vec_extract(v_x, 3);
-#else
float arr[4];
// note: keep type-cast here to prevent compiler bugs
for (int i = 0; i < 4; i++) {
x[i] = GGML_CPU_FP32_TO_FP16(arr[i]);
}
-#endif
}
#define GGML_F16_VEC GGML_F32x4