mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-10-31 08:51:55 +00:00 
			
		
		
		
	
							
								
								
									
										260
									
								
								ggml-impl.h
									
									
									
									
									
								
							
							
						
						
									
										260
									
								
								ggml-impl.h
									
									
									
									
									
								
							| @@ -45,7 +45,7 @@ extern "C" { | ||||
| // 16-bit float | ||||
| // on Arm, we use __fp16 | ||||
| // on x86, we use uint16_t | ||||
| #if defined(__ARM_NEON) && !defined(_MSC_VER) | ||||
| #if defined(__ARM_NEON) | ||||
|  | ||||
| // if YCM cannot find <arm_neon.h>, make a symbolic link to it, for example: | ||||
| // | ||||
| @@ -53,8 +53,262 @@ extern "C" { | ||||
| // | ||||
| #include <arm_neon.h> | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
|  | ||||
| typedef uint16_t ggml_fp16_internal_t; | ||||
|  | ||||
| #define ggml_vld1q_u32(w,x,y,z) { ((w) + ((uint64_t)(x) << 32)), ((y) + ((uint64_t)(z) << 32)) } | ||||
|  | ||||
| #else | ||||
|  | ||||
| typedef __fp16 ggml_fp16_internal_t; | ||||
|  | ||||
| #define ggml_vld1q_u32(w,x,y,z) { (w), (x), (y), (z) } | ||||
|  | ||||
| #endif // _MSC_VER | ||||
|  | ||||
| #if !defined(__aarch64__) | ||||
|  | ||||
| // 32-bit ARM compatibility | ||||
|  | ||||
| // vaddvq_s16 | ||||
| // vpaddq_s16 | ||||
| // vpaddq_s32 | ||||
| // vaddvq_s32 | ||||
| // vaddvq_f32 | ||||
| // vmaxvq_f32 | ||||
| // vcvtnq_s32_f32 | ||||
| // vzip1_u8 | ||||
| // vzip2_u8 | ||||
|  | ||||
| inline static int32_t vaddvq_s16(int16x8_t v) { | ||||
|     return | ||||
|         (int32_t)vgetq_lane_s16(v, 0) + (int32_t)vgetq_lane_s16(v, 1) + | ||||
|         (int32_t)vgetq_lane_s16(v, 2) + (int32_t)vgetq_lane_s16(v, 3) + | ||||
|         (int32_t)vgetq_lane_s16(v, 4) + (int32_t)vgetq_lane_s16(v, 5) + | ||||
|         (int32_t)vgetq_lane_s16(v, 6) + (int32_t)vgetq_lane_s16(v, 7); | ||||
| } | ||||
|  | ||||
| inline static int16x8_t vpaddq_s16(int16x8_t a, int16x8_t b) { | ||||
|     int16x4_t a0 = vpadd_s16(vget_low_s16(a), vget_high_s16(a)); | ||||
|     int16x4_t b0 = vpadd_s16(vget_low_s16(b), vget_high_s16(b)); | ||||
|     return vcombine_s16(a0, b0); | ||||
| } | ||||
|  | ||||
| inline static int32x4_t vpaddq_s32(int32x4_t a, int32x4_t b) { | ||||
|     int32x2_t a0 = vpadd_s32(vget_low_s32(a), vget_high_s32(a)); | ||||
|     int32x2_t b0 = vpadd_s32(vget_low_s32(b), vget_high_s32(b)); | ||||
|     return vcombine_s32(a0, b0); | ||||
| } | ||||
|  | ||||
| inline static int32_t vaddvq_s32(int32x4_t v) { | ||||
|     return vgetq_lane_s32(v, 0) + vgetq_lane_s32(v, 1) + vgetq_lane_s32(v, 2) + vgetq_lane_s32(v, 3); | ||||
| } | ||||
|  | ||||
| inline static float vaddvq_f32(float32x4_t v) { | ||||
|     return vgetq_lane_f32(v, 0) + vgetq_lane_f32(v, 1) + vgetq_lane_f32(v, 2) + vgetq_lane_f32(v, 3); | ||||
| } | ||||
|  | ||||
| inline static float vmaxvq_f32(float32x4_t v) { | ||||
|     return | ||||
|         MAX(MAX(vgetq_lane_f32(v, 0), vgetq_lane_f32(v, 1)), | ||||
|             MAX(vgetq_lane_f32(v, 2), vgetq_lane_f32(v, 3))); | ||||
| } | ||||
|  | ||||
| inline static int32x4_t vcvtnq_s32_f32(float32x4_t v) { | ||||
|     int32x4_t res; | ||||
|  | ||||
|     res[0] = roundf(vgetq_lane_f32(v, 0)); | ||||
|     res[1] = roundf(vgetq_lane_f32(v, 1)); | ||||
|     res[2] = roundf(vgetq_lane_f32(v, 2)); | ||||
|     res[3] = roundf(vgetq_lane_f32(v, 3)); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| inline static uint8x8_t vzip1_u8(uint8x8_t a, uint8x8_t b) { | ||||
|     uint8x8_t res; | ||||
|  | ||||
|     res[0] = a[0]; res[1] = b[0]; | ||||
|     res[2] = a[1]; res[3] = b[1]; | ||||
|     res[4] = a[2]; res[5] = b[2]; | ||||
|     res[6] = a[3]; res[7] = b[3]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| inline static uint8x8_t vzip2_u8(uint8x8_t a, uint8x8_t b) { | ||||
|     uint8x8_t res; | ||||
|  | ||||
|     res[0] = a[4]; res[1] = b[4]; | ||||
|     res[2] = a[5]; res[3] = b[5]; | ||||
|     res[4] = a[6]; res[5] = b[6]; | ||||
|     res[6] = a[7]; res[7] = b[7]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // vld1q_s16_x2 | ||||
| // vld1q_u8_x2 | ||||
| // vld1q_u8_x4 | ||||
| // vld1q_s8_x2 | ||||
| // vld1q_s8_x4 | ||||
| // TODO: double-check these work correctly | ||||
|  | ||||
| typedef struct ggml_int16x8x2_t { | ||||
|     int16x8_t val[2]; | ||||
| } ggml_int16x8x2_t; | ||||
|  | ||||
| inline static ggml_int16x8x2_t ggml_vld1q_s16_x2(const int16_t * ptr) { | ||||
|     ggml_int16x8x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s16(ptr + 0); | ||||
|     res.val[1] = vld1q_s16(ptr + 8); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_uint8x16x2_t { | ||||
|     uint8x16_t val[2]; | ||||
| } ggml_uint8x16x2_t; | ||||
|  | ||||
| inline static ggml_uint8x16x2_t ggml_vld1q_u8_x2(const uint8_t * ptr) { | ||||
|     ggml_uint8x16x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_u8(ptr + 0); | ||||
|     res.val[1] = vld1q_u8(ptr + 16); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_uint8x16x4_t { | ||||
|     uint8x16_t val[4]; | ||||
| } ggml_uint8x16x4_t; | ||||
|  | ||||
| inline static ggml_uint8x16x4_t ggml_vld1q_u8_x4(const uint8_t * ptr) { | ||||
|     ggml_uint8x16x4_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_u8(ptr + 0); | ||||
|     res.val[1] = vld1q_u8(ptr + 16); | ||||
|     res.val[2] = vld1q_u8(ptr + 32); | ||||
|     res.val[3] = vld1q_u8(ptr + 48); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_int8x16x2_t { | ||||
|     int8x16_t val[2]; | ||||
| } ggml_int8x16x2_t; | ||||
|  | ||||
| inline static ggml_int8x16x2_t ggml_vld1q_s8_x2(const int8_t * ptr) { | ||||
|     ggml_int8x16x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s8(ptr + 0); | ||||
|     res.val[1] = vld1q_s8(ptr + 16); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_int8x16x4_t { | ||||
|     int8x16_t val[4]; | ||||
| } ggml_int8x16x4_t; | ||||
|  | ||||
| inline static ggml_int8x16x4_t ggml_vld1q_s8_x4(const int8_t * ptr) { | ||||
|     ggml_int8x16x4_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s8(ptr + 0); | ||||
|     res.val[1] = vld1q_s8(ptr + 16); | ||||
|     res.val[2] = vld1q_s8(ptr + 32); | ||||
|     res.val[3] = vld1q_s8(ptr + 48); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // NOTE: not tested | ||||
| inline static int8x16_t ggml_vqtbl1q_s8(int8x16_t a, uint8x16_t b) { | ||||
|     int8x16_t res; | ||||
|  | ||||
|     res[ 0] = a[b[ 0]]; | ||||
|     res[ 1] = a[b[ 1]]; | ||||
|     res[ 2] = a[b[ 2]]; | ||||
|     res[ 3] = a[b[ 3]]; | ||||
|     res[ 4] = a[b[ 4]]; | ||||
|     res[ 5] = a[b[ 5]]; | ||||
|     res[ 6] = a[b[ 6]]; | ||||
|     res[ 7] = a[b[ 7]]; | ||||
|     res[ 8] = a[b[ 8]]; | ||||
|     res[ 9] = a[b[ 9]]; | ||||
|     res[10] = a[b[10]]; | ||||
|     res[11] = a[b[11]]; | ||||
|     res[12] = a[b[12]]; | ||||
|     res[13] = a[b[13]]; | ||||
|     res[14] = a[b[14]]; | ||||
|     res[15] = a[b[15]]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // NOTE: not tested | ||||
| inline static uint8x16_t ggml_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) { | ||||
|     uint8x16_t res; | ||||
|  | ||||
|     res[ 0] = a[b[ 0]]; | ||||
|     res[ 1] = a[b[ 1]]; | ||||
|     res[ 2] = a[b[ 2]]; | ||||
|     res[ 3] = a[b[ 3]]; | ||||
|     res[ 4] = a[b[ 4]]; | ||||
|     res[ 5] = a[b[ 5]]; | ||||
|     res[ 6] = a[b[ 6]]; | ||||
|     res[ 7] = a[b[ 7]]; | ||||
|     res[ 8] = a[b[ 8]]; | ||||
|     res[ 9] = a[b[ 9]]; | ||||
|     res[10] = a[b[10]]; | ||||
|     res[11] = a[b[11]]; | ||||
|     res[12] = a[b[12]]; | ||||
|     res[13] = a[b[13]]; | ||||
|     res[14] = a[b[14]]; | ||||
|     res[15] = a[b[15]]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define ggml_int16x8x2_t  int16x8x2_t | ||||
| #define ggml_uint8x16x2_t uint8x16x2_t | ||||
| #define ggml_uint8x16x4_t uint8x16x4_t | ||||
| #define ggml_int8x16x2_t  int8x16x2_t | ||||
| #define ggml_int8x16x4_t  int8x16x4_t | ||||
|  | ||||
| #define ggml_vld1q_s16_x2 vld1q_s16_x2 | ||||
| #define ggml_vld1q_u8_x2  vld1q_u8_x2 | ||||
| #define ggml_vld1q_u8_x4  vld1q_u8_x4 | ||||
| #define ggml_vld1q_s8_x2  vld1q_s8_x2 | ||||
| #define ggml_vld1q_s8_x4  vld1q_s8_x4 | ||||
| #define ggml_vqtbl1q_s8   vqtbl1q_s8 | ||||
| #define ggml_vqtbl1q_u8   vqtbl1q_u8 | ||||
|  | ||||
| #endif // !defined(__aarch64__) | ||||
|  | ||||
| #if !defined(__ARM_FEATURE_DOTPROD) | ||||
|  | ||||
| inline static int32x4_t ggml_vdotq_s32(int32x4_t acc, int8x16_t a, int8x16_t b) { | ||||
|     const int16x8_t p0 = vmull_s8(vget_low_s8 (a), vget_low_s8 (b)); | ||||
|     const int16x8_t p1 = vmull_s8(vget_high_s8(a), vget_high_s8(b)); | ||||
|  | ||||
|     return vaddq_s32(acc, vaddq_s32(vpaddlq_s16(p0), vpaddlq_s16(p1))); | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define ggml_vdotq_s32(a, b, c) vdotq_s32(a, b, c) | ||||
|  | ||||
| #endif // !defined(__ARM_FEATURE_DOTPROD) | ||||
|  | ||||
| #endif // defined(__ARM_NEON) | ||||
|  | ||||
| #if defined(__ARM_NEON) && !defined(__MSC_VER) | ||||
|  | ||||
| #define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x) | ||||
| #define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x) | ||||
|  | ||||
| @@ -75,8 +329,6 @@ static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) { | ||||
|  | ||||
| #else | ||||
|  | ||||
| typedef uint16_t ggml_fp16_internal_t; | ||||
|  | ||||
| #ifdef __wasm_simd128__ | ||||
| #include <wasm_simd128.h> | ||||
| #else | ||||
| @@ -221,7 +473,7 @@ static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) { | ||||
|  | ||||
| #endif // __F16C__ | ||||
|  | ||||
| #endif // __ARM_NEON | ||||
| #endif // defined(__ARM_NEON) && (!defined(__MSC_VER) | ||||
|  | ||||
| // precomputed f32 table for f16 (256 KB) | ||||
| // defined in ggml.c, initialized in ggml_init() | ||||
|   | ||||
							
								
								
									
										287
									
								
								ggml-quants.c
									
									
									
									
									
								
							
							
						
						
									
										287
									
								
								ggml-quants.c
									
									
									
									
									
								
							| @@ -14,41 +14,6 @@ | ||||
| #include <stdlib.h> // for qsort | ||||
| #include <stdio.h>  // for GGML_ASSERT | ||||
|  | ||||
| #ifdef __ARM_NEON | ||||
|  | ||||
| // if YCM cannot find <arm_neon.h>, make a symbolic link to it, for example: | ||||
| // | ||||
| //   $ ln -sfn /Library/Developer/CommandLineTools/usr/lib/clang/13.1.6/include/arm_neon.h ./src/ | ||||
| // | ||||
| #include <arm_neon.h> | ||||
|  | ||||
| #else | ||||
|  | ||||
| #ifdef __wasm_simd128__ | ||||
| #include <wasm_simd128.h> | ||||
| #else | ||||
| #if defined(__POWER9_VECTOR__) || defined(__powerpc64__) | ||||
| #include <altivec.h> | ||||
| #undef bool | ||||
| #define bool _Bool | ||||
| #else | ||||
| #if defined(_MSC_VER) || defined(__MINGW32__) | ||||
| #include <intrin.h> | ||||
| #else | ||||
| #if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) || defined(__SSE3__) | ||||
| #if !defined(__riscv) | ||||
| #include <immintrin.h> | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef __riscv_v_intrinsic | ||||
| #include <riscv_vector.h> | ||||
| #endif | ||||
|  | ||||
| #undef MIN | ||||
| #undef MAX | ||||
|  | ||||
| @@ -276,258 +241,6 @@ static inline float hsum_float_4x4(const __m128 a, const __m128 b, const __m128 | ||||
| #endif // __AVX__ || __AVX2__ || __AVX512F__ | ||||
| #endif // defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) | ||||
|  | ||||
| #if defined(__ARM_NEON) | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
|  | ||||
| #define ggml_vld1q_u32(w,x,y,z) { ((w) + ((uint64_t)(x) << 32)), ((y) + ((uint64_t)(z) << 32)) } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define ggml_vld1q_u32(w,x,y,z) { (w), (x), (y), (z) } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !defined(__aarch64__) | ||||
|  | ||||
| // 64-bit compatibility | ||||
|  | ||||
| // vaddvq_s16 | ||||
| // vpaddq_s16 | ||||
| // vpaddq_s32 | ||||
| // vaddvq_s32 | ||||
| // vaddvq_f32 | ||||
| // vmaxvq_f32 | ||||
| // vcvtnq_s32_f32 | ||||
| // vzip1_u8 | ||||
| // vzip2_u8 | ||||
|  | ||||
| inline static int32_t vaddvq_s16(int16x8_t v) { | ||||
|     return | ||||
|         (int32_t)vgetq_lane_s16(v, 0) + (int32_t)vgetq_lane_s16(v, 1) + | ||||
|         (int32_t)vgetq_lane_s16(v, 2) + (int32_t)vgetq_lane_s16(v, 3) + | ||||
|         (int32_t)vgetq_lane_s16(v, 4) + (int32_t)vgetq_lane_s16(v, 5) + | ||||
|         (int32_t)vgetq_lane_s16(v, 6) + (int32_t)vgetq_lane_s16(v, 7); | ||||
| } | ||||
|  | ||||
| inline static int16x8_t vpaddq_s16(int16x8_t a, int16x8_t b) { | ||||
|     int16x4_t a0 = vpadd_s16(vget_low_s16(a), vget_high_s16(a)); | ||||
|     int16x4_t b0 = vpadd_s16(vget_low_s16(b), vget_high_s16(b)); | ||||
|     return vcombine_s16(a0, b0); | ||||
| } | ||||
|  | ||||
| inline static int32x4_t vpaddq_s32(int32x4_t a, int32x4_t b) { | ||||
|     int32x2_t a0 = vpadd_s32(vget_low_s32(a), vget_high_s32(a)); | ||||
|     int32x2_t b0 = vpadd_s32(vget_low_s32(b), vget_high_s32(b)); | ||||
|     return vcombine_s32(a0, b0); | ||||
| } | ||||
|  | ||||
| inline static int32_t vaddvq_s32(int32x4_t v) { | ||||
|     return vgetq_lane_s32(v, 0) + vgetq_lane_s32(v, 1) + vgetq_lane_s32(v, 2) + vgetq_lane_s32(v, 3); | ||||
| } | ||||
|  | ||||
| inline static float vaddvq_f32(float32x4_t v) { | ||||
|     return vgetq_lane_f32(v, 0) + vgetq_lane_f32(v, 1) + vgetq_lane_f32(v, 2) + vgetq_lane_f32(v, 3); | ||||
| } | ||||
|  | ||||
| inline static float vmaxvq_f32(float32x4_t v) { | ||||
|     return | ||||
|         MAX(MAX(vgetq_lane_f32(v, 0), vgetq_lane_f32(v, 1)), | ||||
|             MAX(vgetq_lane_f32(v, 2), vgetq_lane_f32(v, 3))); | ||||
| } | ||||
|  | ||||
| inline static int32x4_t vcvtnq_s32_f32(float32x4_t v) { | ||||
|     int32x4_t res; | ||||
|  | ||||
|     res[0] = roundf(vgetq_lane_f32(v, 0)); | ||||
|     res[1] = roundf(vgetq_lane_f32(v, 1)); | ||||
|     res[2] = roundf(vgetq_lane_f32(v, 2)); | ||||
|     res[3] = roundf(vgetq_lane_f32(v, 3)); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| inline static uint8x8_t vzip1_u8(uint8x8_t a, uint8x8_t b) { | ||||
|     uint8x8_t res; | ||||
|  | ||||
|     res[0] = a[0]; res[1] = b[0]; | ||||
|     res[2] = a[1]; res[3] = b[1]; | ||||
|     res[4] = a[2]; res[5] = b[2]; | ||||
|     res[6] = a[3]; res[7] = b[3]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| inline static uint8x8_t vzip2_u8(uint8x8_t a, uint8x8_t b) { | ||||
|     uint8x8_t res; | ||||
|  | ||||
|     res[0] = a[4]; res[1] = b[4]; | ||||
|     res[2] = a[5]; res[3] = b[5]; | ||||
|     res[4] = a[6]; res[5] = b[6]; | ||||
|     res[6] = a[7]; res[7] = b[7]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // vld1q_s16_x2 | ||||
| // vld1q_u8_x2 | ||||
| // vld1q_u8_x4 | ||||
| // vld1q_s8_x2 | ||||
| // vld1q_s8_x4 | ||||
| // TODO: double-check these work correctly | ||||
|  | ||||
| typedef struct ggml_int16x8x2_t { | ||||
|     int16x8_t val[2]; | ||||
| } ggml_int16x8x2_t; | ||||
|  | ||||
| inline static ggml_int16x8x2_t ggml_vld1q_s16_x2(const int16_t * ptr) { | ||||
|     ggml_int16x8x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s16(ptr + 0); | ||||
|     res.val[1] = vld1q_s16(ptr + 8); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_uint8x16x2_t { | ||||
|     uint8x16_t val[2]; | ||||
| } ggml_uint8x16x2_t; | ||||
|  | ||||
| inline static ggml_uint8x16x2_t ggml_vld1q_u8_x2(const uint8_t * ptr) { | ||||
|     ggml_uint8x16x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_u8(ptr + 0); | ||||
|     res.val[1] = vld1q_u8(ptr + 16); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_uint8x16x4_t { | ||||
|     uint8x16_t val[4]; | ||||
| } ggml_uint8x16x4_t; | ||||
|  | ||||
| inline static ggml_uint8x16x4_t ggml_vld1q_u8_x4(const uint8_t * ptr) { | ||||
|     ggml_uint8x16x4_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_u8(ptr + 0); | ||||
|     res.val[1] = vld1q_u8(ptr + 16); | ||||
|     res.val[2] = vld1q_u8(ptr + 32); | ||||
|     res.val[3] = vld1q_u8(ptr + 48); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_int8x16x2_t { | ||||
|     int8x16_t val[2]; | ||||
| } ggml_int8x16x2_t; | ||||
|  | ||||
| inline static ggml_int8x16x2_t ggml_vld1q_s8_x2(const int8_t * ptr) { | ||||
|     ggml_int8x16x2_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s8(ptr + 0); | ||||
|     res.val[1] = vld1q_s8(ptr + 16); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| typedef struct ggml_int8x16x4_t { | ||||
|     int8x16_t val[4]; | ||||
| } ggml_int8x16x4_t; | ||||
|  | ||||
| inline static ggml_int8x16x4_t ggml_vld1q_s8_x4(const int8_t * ptr) { | ||||
|     ggml_int8x16x4_t res; | ||||
|  | ||||
|     res.val[0] = vld1q_s8(ptr + 0); | ||||
|     res.val[1] = vld1q_s8(ptr + 16); | ||||
|     res.val[2] = vld1q_s8(ptr + 32); | ||||
|     res.val[3] = vld1q_s8(ptr + 48); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // NOTE: not tested | ||||
| inline static int8x16_t ggml_vqtbl1q_s8(int8x16_t a, uint8x16_t b) { | ||||
|     int8x16_t res; | ||||
|  | ||||
|     res[ 0] = a[b[ 0]]; | ||||
|     res[ 1] = a[b[ 1]]; | ||||
|     res[ 2] = a[b[ 2]]; | ||||
|     res[ 3] = a[b[ 3]]; | ||||
|     res[ 4] = a[b[ 4]]; | ||||
|     res[ 5] = a[b[ 5]]; | ||||
|     res[ 6] = a[b[ 6]]; | ||||
|     res[ 7] = a[b[ 7]]; | ||||
|     res[ 8] = a[b[ 8]]; | ||||
|     res[ 9] = a[b[ 9]]; | ||||
|     res[10] = a[b[10]]; | ||||
|     res[11] = a[b[11]]; | ||||
|     res[12] = a[b[12]]; | ||||
|     res[13] = a[b[13]]; | ||||
|     res[14] = a[b[14]]; | ||||
|     res[15] = a[b[15]]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| // NOTE: not tested | ||||
| inline static uint8x16_t ggml_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) { | ||||
|     uint8x16_t res; | ||||
|  | ||||
|     res[ 0] = a[b[ 0]]; | ||||
|     res[ 1] = a[b[ 1]]; | ||||
|     res[ 2] = a[b[ 2]]; | ||||
|     res[ 3] = a[b[ 3]]; | ||||
|     res[ 4] = a[b[ 4]]; | ||||
|     res[ 5] = a[b[ 5]]; | ||||
|     res[ 6] = a[b[ 6]]; | ||||
|     res[ 7] = a[b[ 7]]; | ||||
|     res[ 8] = a[b[ 8]]; | ||||
|     res[ 9] = a[b[ 9]]; | ||||
|     res[10] = a[b[10]]; | ||||
|     res[11] = a[b[11]]; | ||||
|     res[12] = a[b[12]]; | ||||
|     res[13] = a[b[13]]; | ||||
|     res[14] = a[b[14]]; | ||||
|     res[15] = a[b[15]]; | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define ggml_int16x8x2_t  int16x8x2_t | ||||
| #define ggml_uint8x16x2_t uint8x16x2_t | ||||
| #define ggml_uint8x16x4_t uint8x16x4_t | ||||
| #define ggml_int8x16x2_t  int8x16x2_t | ||||
| #define ggml_int8x16x4_t  int8x16x4_t | ||||
|  | ||||
| #define ggml_vld1q_s16_x2 vld1q_s16_x2 | ||||
| #define ggml_vld1q_u8_x2  vld1q_u8_x2 | ||||
| #define ggml_vld1q_u8_x4  vld1q_u8_x4 | ||||
| #define ggml_vld1q_s8_x2  vld1q_s8_x2 | ||||
| #define ggml_vld1q_s8_x4  vld1q_s8_x4 | ||||
| #define ggml_vqtbl1q_s8   vqtbl1q_s8 | ||||
| #define ggml_vqtbl1q_u8   vqtbl1q_u8 | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if !defined(__ARM_FEATURE_DOTPROD) | ||||
|  | ||||
| inline static int32x4_t ggml_vdotq_s32(int32x4_t acc, int8x16_t a, int8x16_t b) { | ||||
|     const int16x8_t p0 = vmull_s8(vget_low_s8 (a), vget_low_s8 (b)); | ||||
|     const int16x8_t p1 = vmull_s8(vget_high_s8(a), vget_high_s8(b)); | ||||
|  | ||||
|     return vaddq_s32(acc, vaddq_s32(vpaddlq_s16(p0), vpaddlq_s16(p1))); | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define ggml_vdotq_s32(a, b, c) vdotq_s32(a, b, c) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(__ARM_NEON) || defined(__wasm_simd128__) | ||||
| #define B1(c,s,n)  0x ## n ## c ,  0x ## n ## s | ||||
| #define B2(c,s,n) B1(c,s,n ## c), B1(c,s,n ## s) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Georgi Gerganov
					Georgi Gerganov