whispercpp 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.document +3 -0
- data/.rdoc_options +2 -0
- data/README.md +43 -9
- data/Rakefile +18 -3
- data/ext/dependencies.rb +10 -4
- data/ext/dependencies_for_windows.rb +17 -0
- data/ext/extconf.rb +20 -8
- data/ext/options.rb +54 -14
- data/ext/options_for_windows.rb +51 -0
- data/ext/ruby_whisper.c +35 -42
- data/ext/ruby_whisper.h +141 -0
- data/ext/ruby_whisper_context.c +157 -29
- data/ext/ruby_whisper_log_queue.c +180 -0
- data/ext/ruby_whisper_log_settable.h +46 -0
- data/ext/ruby_whisper_parakeet.c +49 -0
- data/ext/ruby_whisper_parakeet_context.c +304 -0
- data/ext/ruby_whisper_parakeet_context_params.c +117 -0
- data/ext/ruby_whisper_parakeet_model.c +84 -0
- data/ext/ruby_whisper_parakeet_params.c +548 -0
- data/ext/ruby_whisper_parakeet_segment.c +157 -0
- data/ext/ruby_whisper_parakeet_token.c +188 -0
- data/ext/ruby_whisper_parakeet_transcribe.cpp +58 -0
- data/ext/ruby_whisper_params.c +265 -73
- data/ext/ruby_whisper_segment.c +6 -6
- data/ext/ruby_whisper_transcribe.cpp +23 -15
- data/ext/ruby_whisper_vad_context.c +30 -10
- data/ext/ruby_whisper_vad_context_detect.cpp +8 -9
- data/ext/ruby_whisper_vad_params.c +4 -4
- data/ext/ruby_whisper_vad_segment.c +2 -2
- data/ext/sources/CMakeLists.txt +42 -3
- data/ext/sources/CMakePresets.json +95 -0
- data/ext/sources/cmake/parakeet-config.cmake.in +30 -0
- data/ext/sources/cmake/parakeet.pc.in +10 -0
- data/ext/sources/cmake/whisper.pc.in +2 -2
- data/ext/sources/examples/CMakeLists.txt +4 -2
- data/ext/sources/examples/bench/bench.cpp +1 -1
- data/ext/sources/examples/cli/cli.cpp +52 -10
- data/ext/sources/examples/common-ggml.cpp +4 -0
- data/ext/sources/examples/common-whisper.cpp +139 -67
- data/ext/sources/examples/common-whisper.h +11 -0
- data/ext/sources/examples/ffmpeg-transcode.cpp +211 -341
- data/ext/sources/examples/parakeet-cli/CMakeLists.txt +8 -0
- data/ext/sources/examples/parakeet-cli/parakeet-cli.cpp +243 -0
- data/ext/sources/examples/parakeet-quantize/CMakeLists.txt +7 -0
- data/ext/sources/examples/parakeet-quantize/parakeet-quantize.cpp +230 -0
- data/ext/sources/examples/server/server.cpp +199 -163
- data/ext/sources/examples/vad-speech-segments/speech.cpp +3 -2
- data/ext/sources/ggml/CMakeLists.txt +21 -14
- data/ext/sources/ggml/cmake/FindNCCL.cmake +36 -0
- data/ext/sources/ggml/cmake/ggml-config.cmake.in +12 -2
- data/ext/sources/ggml/include/ggml-alloc.h +1 -0
- data/ext/sources/ggml/include/ggml-backend.h +72 -10
- data/ext/sources/ggml/include/ggml-cuda.h +2 -2
- data/ext/sources/ggml/include/ggml-rpc.h +3 -3
- data/ext/sources/ggml/include/ggml-sycl.h +8 -0
- data/ext/sources/ggml/include/ggml.h +103 -9
- data/ext/sources/ggml/include/gguf.h +10 -2
- data/ext/sources/ggml/src/CMakeLists.txt +30 -6
- data/ext/sources/ggml/src/ggml-alloc.c +5 -1
- data/ext/sources/ggml/src/ggml-backend-impl.h +22 -2
- data/ext/sources/ggml/src/ggml-backend-meta.cpp +2266 -0
- data/ext/sources/ggml/src/ggml-backend-reg.cpp +12 -0
- data/ext/sources/ggml/src/ggml-backend.cpp +110 -9
- data/ext/sources/ggml/src/ggml-blas/ggml-blas.cpp +4 -0
- data/ext/sources/ggml/src/ggml-cann/aclnn_ops.cpp +672 -257
- data/ext/sources/ggml/src/ggml-cann/aclnn_ops.h +71 -0
- data/ext/sources/ggml/src/ggml-cann/common.h +20 -10
- data/ext/sources/ggml/src/ggml-cann/ggml-cann.cpp +211 -30
- data/ext/sources/ggml/src/ggml-common.h +24 -2
- data/ext/sources/ggml/src/ggml-cpu/CMakeLists.txt +59 -30
- data/ext/sources/ggml/src/ggml-cpu/amx/amx.cpp +2 -0
- data/ext/sources/ggml/src/ggml-cpu/amx/mmq.cpp +21 -22
- data/ext/sources/ggml/src/ggml-cpu/arch/arm/quants.c +194 -11
- data/ext/sources/ggml/src/ggml-cpu/arch/arm/repack.cpp +65 -0
- data/ext/sources/ggml/src/ggml-cpu/arch/loongarch/quants.c +151 -1
- data/ext/sources/ggml/src/ggml-cpu/arch/powerpc/quants.c +0 -1
- data/ext/sources/ggml/src/ggml-cpu/arch/riscv/quants.c +4279 -1292
- data/ext/sources/ggml/src/ggml-cpu/arch/riscv/repack.cpp +5 -35
- data/ext/sources/ggml/src/ggml-cpu/arch/s390/quants.c +0 -1
- data/ext/sources/ggml/src/ggml-cpu/arch/wasm/quants.c +72 -1
- data/ext/sources/ggml/src/ggml-cpu/arch/x86/quants.c +319 -31
- data/ext/sources/ggml/src/ggml-cpu/arch/x86/repack.cpp +1 -1
- data/ext/sources/ggml/src/ggml-cpu/arch-fallback.h +12 -2
- data/ext/sources/ggml/src/ggml-cpu/cmake/FindSMTIME.cmake +32 -0
- data/ext/sources/ggml/src/ggml-cpu/ggml-cpu-impl.h +10 -0
- data/ext/sources/ggml/src/ggml-cpu/ggml-cpu.c +109 -5
- data/ext/sources/ggml/src/ggml-cpu/ggml-cpu.cpp +2 -0
- data/ext/sources/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +146 -134
- data/ext/sources/ggml/src/ggml-cpu/llamafile/sgemm.cpp +107 -82
- data/ext/sources/ggml/src/ggml-cpu/ops.cpp +501 -119
- data/ext/sources/ggml/src/ggml-cpu/ops.h +3 -0
- data/ext/sources/ggml/src/ggml-cpu/quants.c +106 -0
- data/ext/sources/ggml/src/ggml-cpu/quants.h +6 -0
- data/ext/sources/ggml/src/ggml-cpu/repack.cpp +3 -0
- data/ext/sources/ggml/src/ggml-cpu/simd-gemm.h +91 -1
- data/ext/sources/ggml/src/ggml-cpu/simd-mappings.h +14 -16
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime.cpp +1402 -687
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime.h +8 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime1_kernels.cpp +597 -2766
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime2_kernels.cpp +5768 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime_env.cpp +320 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime_env.h +55 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/ime_kernels.h +182 -19
- data/ext/sources/ggml/src/ggml-cpu/spacemit/repack.cpp +1795 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/repack.h +14 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/rvv_kernels.cpp +3178 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/rvv_kernels.h +95 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/spine_barrier.h +34 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/spine_mem_pool.cpp +760 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/spine_mem_pool.h +32 -0
- data/ext/sources/ggml/src/ggml-cpu/spacemit/spine_tcm.h +409 -0
- data/ext/sources/ggml/src/ggml-cpu/vec.cpp +39 -55
- data/ext/sources/ggml/src/ggml-cpu/vec.h +225 -240
- data/ext/sources/ggml/src/ggml-cuda/CMakeLists.txt +17 -7
- data/ext/sources/ggml/src/ggml-cuda/allreduce.cu +971 -0
- data/ext/sources/ggml/src/ggml-cuda/allreduce.cuh +29 -0
- data/ext/sources/ggml/src/ggml-cuda/argsort.cu +62 -26
- data/ext/sources/ggml/src/ggml-cuda/binbcast.cu +134 -64
- data/ext/sources/ggml/src/ggml-cuda/binbcast.cuh +1 -0
- data/ext/sources/ggml/src/ggml-cuda/col2im-1d.cu +81 -0
- data/ext/sources/ggml/src/ggml-cuda/col2im-1d.cuh +3 -0
- data/ext/sources/ggml/src/ggml-cuda/common.cuh +246 -28
- data/ext/sources/ggml/src/ggml-cuda/concat.cu +134 -116
- data/ext/sources/ggml/src/ggml-cuda/conv-transpose-1d.cu +14 -12
- data/ext/sources/ggml/src/ggml-cuda/conv2d-transpose.cu +45 -21
- data/ext/sources/ggml/src/ggml-cuda/conv2d-transpose.cuh +1 -0
- data/ext/sources/ggml/src/ggml-cuda/convert.cu +139 -34
- data/ext/sources/ggml/src/ggml-cuda/convert.cuh +10 -0
- data/ext/sources/ggml/src/ggml-cuda/cpy.cu +88 -29
- data/ext/sources/ggml/src/ggml-cuda/dequantize.cuh +22 -0
- data/ext/sources/ggml/src/ggml-cuda/fattn-common.cuh +287 -49
- data/ext/sources/ggml/src/ggml-cuda/fattn-mma-f16.cuh +335 -130
- data/ext/sources/ggml/src/ggml-cuda/fattn-tile.cu +12 -0
- data/ext/sources/ggml/src/ggml-cuda/fattn-tile.cuh +127 -24
- data/ext/sources/ggml/src/ggml-cuda/fattn-vec.cuh +40 -15
- data/ext/sources/ggml/src/ggml-cuda/fattn-wmma-f16.cu +18 -9
- data/ext/sources/ggml/src/ggml-cuda/fattn.cu +169 -60
- data/ext/sources/ggml/src/ggml-cuda/fattn.cuh +2 -0
- data/ext/sources/ggml/src/ggml-cuda/fwht.cu +101 -0
- data/ext/sources/ggml/src/ggml-cuda/fwht.cuh +4 -0
- data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cu +109 -45
- data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cuh +10 -0
- data/ext/sources/ggml/src/ggml-cuda/getrows.cu +48 -23
- data/ext/sources/ggml/src/ggml-cuda/ggml-cuda.cu +2034 -2104
- data/ext/sources/ggml/src/ggml-cuda/im2col.cu +32 -29
- data/ext/sources/ggml/src/ggml-cuda/mean.cu +4 -2
- data/ext/sources/ggml/src/ggml-cuda/mma.cuh +242 -195
- data/ext/sources/ggml/src/ggml-cuda/mmf.cuh +3 -3
- data/ext/sources/ggml/src/ggml-cuda/mmq.cu +25 -12
- data/ext/sources/ggml/src/ggml-cuda/mmq.cuh +502 -423
- data/ext/sources/ggml/src/ggml-cuda/mmvf.cu +19 -12
- data/ext/sources/ggml/src/ggml-cuda/mmvq.cu +562 -97
- data/ext/sources/ggml/src/ggml-cuda/mmvq.cuh +6 -1
- data/ext/sources/ggml/src/ggml-cuda/norm.cu +36 -10
- data/ext/sources/ggml/src/ggml-cuda/out-prod.cu +66 -7
- data/ext/sources/ggml/src/ggml-cuda/quantize.cu +133 -26
- data/ext/sources/ggml/src/ggml-cuda/quantize.cuh +1 -1
- data/ext/sources/ggml/src/ggml-cuda/reduce_rows.cuh +5 -1
- data/ext/sources/ggml/src/ggml-cuda/rope.cu +11 -4
- data/ext/sources/ggml/src/ggml-cuda/scale.cu +4 -1
- data/ext/sources/ggml/src/ggml-cuda/set-rows.cu +78 -10
- data/ext/sources/ggml/src/ggml-cuda/snake.cu +72 -0
- data/ext/sources/ggml/src/ggml-cuda/snake.cuh +8 -0
- data/ext/sources/ggml/src/ggml-cuda/softcap.cu +4 -1
- data/ext/sources/ggml/src/ggml-cuda/ssm-conv.cu +45 -13
- data/ext/sources/ggml/src/ggml-cuda/ssm-conv.cuh +1 -1
- data/ext/sources/ggml/src/ggml-cuda/ssm-scan.cu +40 -18
- data/ext/sources/ggml/src/ggml-cuda/sumrows.cu +8 -4
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_16.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_32.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_8.cu +2 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_2.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_4.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_16.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_32.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_4.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_8.cu +2 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_2.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_16.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_2.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_4.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_8.cu +2 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_2.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_4.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_8.cu +2 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq192-dv128.cu +5 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq320-dv256.cu +5 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq512-dv512.cu +5 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-f16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_0.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_1.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_0.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_1.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q8_0.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-bf16.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/mmq-instance-nvfp4.cu +5 -0
- data/ext/sources/ggml/src/ggml-cuda/template-instances/mmq-instance-q1_0.cu +5 -0
- data/ext/sources/ggml/src/ggml-cuda/top-k.cu +5 -4
- data/ext/sources/ggml/src/ggml-cuda/topk-moe.cu +33 -24
- data/ext/sources/ggml/src/ggml-cuda/unary.cu +31 -2
- data/ext/sources/ggml/src/ggml-cuda/unary.cuh +2 -0
- data/ext/sources/ggml/src/ggml-cuda/vecdotq.cuh +80 -0
- data/ext/sources/ggml/src/ggml-cuda/vendors/cuda.h +7 -2
- data/ext/sources/ggml/src/ggml-cuda/vendors/hip.h +23 -4
- data/ext/sources/ggml/src/ggml-cuda/vendors/musa.h +4 -0
- data/ext/sources/ggml/src/ggml-hexagon/CMakeLists.txt +1 -5
- data/ext/sources/ggml/src/ggml-hexagon/ggml-hexagon.cpp +2788 -1762
- data/ext/sources/ggml/src/ggml-hexagon/htp/CMakeLists.txt +13 -4
- data/ext/sources/ggml/src/ggml-hexagon/htp/act-ops.c +53 -84
- data/ext/sources/ggml/src/ggml-hexagon/htp/argsort-ops.c +25 -12
- data/ext/sources/ggml/src/ggml-hexagon/htp/binary-ops.c +165 -184
- data/ext/sources/ggml/src/ggml-hexagon/htp/cmake-toolchain.cmake +17 -19
- data/ext/sources/ggml/src/ggml-hexagon/htp/concat-ops.c +277 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/cpy-ops.c +170 -127
- data/ext/sources/ggml/src/ggml-hexagon/htp/cumsum-ops.c +270 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/diag-ops.c +216 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/fill-ops.c +123 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.c +1774 -396
- data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.h +303 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/gated-delta-net-ops.c +1148 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/get-rows-ops.c +148 -42
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-common.h +80 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-dma.c +2 -2
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-dma.h +255 -62
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-dump.h +9 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-profile.h +64 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-utils.h +25 -21
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-fa-kernels.h +555 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-mm-kernels-tiled.h +1303 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-queue.c +167 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-queue.h +157 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-utils.h +222 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ctx.h +104 -13
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ops.h +222 -57
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-vtcm.h +19 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp_iface.idl +10 -3
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-base.h +78 -26
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-copy.h +27 -10
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-div.h +63 -23
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-exp.h +48 -8
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-fa-kernels.h +232 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-flash-attn.h +47 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-log.h +65 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-mm-kernels-flat.h +1511 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-mm-kernels-tiled.h +1200 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-pow.h +42 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-repl.h +74 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-sigmoid.h +40 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-sin-cos.h +90 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-utils.h +5 -8
- data/ext/sources/ggml/src/ggml-hexagon/htp/main.c +625 -816
- data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.c +3052 -2166
- data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.h +650 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/pad-ops.c +547 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/repeat-ops.c +148 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/rope-ops.c +337 -106
- data/ext/sources/ggml/src/ggml-hexagon/htp/set-rows-ops.c +59 -37
- data/ext/sources/ggml/src/ggml-hexagon/htp/softmax-ops.c +121 -133
- data/ext/sources/ggml/src/ggml-hexagon/htp/solve-tri-ops.c +267 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/ssm-conv.c +245 -151
- data/ext/sources/ggml/src/ggml-hexagon/htp/sum-rows-ops.c +6 -6
- data/ext/sources/ggml/src/ggml-hexagon/htp/unary-ops.c +719 -45
- data/ext/sources/ggml/src/ggml-hexagon/htp/worker-pool.c +15 -3
- data/ext/sources/ggml/src/ggml-hexagon/htp/worker-pool.h +8 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp-opnode.h +390 -0
- data/ext/sources/ggml/src/ggml-hexagon/libggml-htp.inf +3 -5
- data/ext/sources/ggml/src/ggml-hip/CMakeLists.txt +27 -9
- data/ext/sources/ggml/src/ggml-impl.h +6 -1
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.cpp +207 -18
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.h +36 -2
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.m +186 -29
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-impl.h +118 -0
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.cpp +322 -21
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.h +4 -0
- data/ext/sources/ggml/src/ggml-metal/ggml-metal.cpp +39 -26
- data/ext/sources/ggml/src/ggml-metal/ggml-metal.metal +1226 -467
- data/ext/sources/ggml/src/ggml-musa/CMakeLists.txt +5 -6
- data/ext/sources/ggml/src/ggml-opencl/CMakeLists.txt +67 -5
- data/ext/sources/ggml/src/ggml-opencl/fa_tune.h +92 -0
- data/ext/sources/ggml/src/ggml-opencl/ggml-opencl.cpp +16290 -6246
- data/ext/sources/ggml/src/ggml-opencl/kernels/concat.cl +67 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/cpy.cl +59 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/cvt.cl +1997 -92
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f16.cl +81 -41
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32.cl +88 -39
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_f16.cl +1995 -96
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_q4_0.cl +1615 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_f32_q8_0.cl +1486 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/flash_attn_pre_f16.cl +156 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gated_delta_net.cl +249 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_mxfp4_f32_ns.cl +374 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_0_f32_ns.cl +324 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_1_f32_ns.cl +326 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_k_f32_ns.cl +348 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_0_f32_ns.cl +328 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_1_f32_ns.cl +330 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_k_f32_ns.cl +356 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q6_k_f32_ns.cl +335 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_iq4_nl_f32.cl +150 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q1_0_f32.cl +94 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/{mul_mat_Ab_Bi_8x4.cl → gemm_noshuffle_q4_0_f32.cl} +1 -1
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q4_k_f32.cl +172 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q5_0_f32.cl +131 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q5_1_f32.cl +134 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q5_k_f32.cl +176 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q6_k_f32.cl +140 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/{mul_mm_q8_0_f32_8x4.cl → gemm_noshuffle_q8_0_f32.cl} +1 -1
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_xmem_f16_f32_os8.cl +233 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_mxfp4_f32_ns.cl +165 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q4_0_f32_ns.cl +120 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q4_1_f32_ns.cl +123 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q4_k_f32_ns.cl +155 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q5_0_f32_ns.cl +123 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q5_1_f32_ns.cl +125 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q5_k_f32_ns.cl +160 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_moe_q6_k_f32_ns.cl +141 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_iq4_nl_f32.cl +302 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q1_0_f32.cl +121 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/{gemv_noshuffle_general.cl → gemv_noshuffle_q4_0_f32.cl} +5 -5
- data/ext/sources/ggml/src/ggml-opencl/kernels/{gemv_noshuffle.cl → gemv_noshuffle_q4_0_f32_spec.cl} +5 -5
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q4_k_f32.cl +318 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q5_0_f32.cl +291 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q5_1_f32.cl +294 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q5_k_f32.cl +326 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q6_k_f32.cl +293 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/{gemv_noshuffle_general_q8_0_f32.cl → gemv_noshuffle_q8_0_f32.cl} +1 -1
- data/ext/sources/ggml/src/ggml-opencl/kernels/get_rows.cl +15 -9
- data/ext/sources/ggml/src/ggml-opencl/kernels/moe_reorder_b.cl +30 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/moe_sort_by_expert.cl +82 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_iq4_nl_f32_l4_lm.cl +171 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q1_0_f32_l4_lm.cl +156 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q4_k_f32_l4_lm.cl +179 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q5_0_f32_l4_lm.cl +173 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q5_1_f32_l4_lm.cl +175 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mm_q5_k_f32_l4_lm.cl +192 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl +1149 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_iq4_nl_f32.cl +164 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_iq4_nl_f32_flat.cl +202 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q1_0_f32.cl +141 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q1_0_f32_flat.cl +190 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q4_k_f32_flat.cl +196 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_0_f32.cl +241 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_0_f32_flat.cl +243 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_1_f32.cl +243 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_1_f32_flat.cl +247 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_k_f32.cl +187 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q5_k_f32_flat.cl +203 -0
- data/ext/sources/ggml/src/ggml-opencl/kernels/mul_mv_q6_k_f32_flat.cl +48 -64
- data/ext/sources/ggml/src/ggml-opencl/kernels/norm.cl +5 -2
- data/ext/sources/ggml/src/ggml-opencl/kernels/set_rows.cl +500 -0
- data/ext/sources/ggml/src/ggml-opencl/libdl.h +79 -0
- data/ext/sources/ggml/src/ggml-openvino/.clang-format +0 -5
- data/ext/sources/ggml/src/ggml-openvino/CMakeLists.txt +2 -4
- data/ext/sources/ggml/src/ggml-openvino/ggml-decoder.cpp +740 -127
- data/ext/sources/ggml/src/ggml-openvino/ggml-decoder.h +76 -23
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.cpp +75 -14
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.h +29 -8
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino.cpp +339 -69
- data/ext/sources/ggml/src/ggml-openvino/ggml-quants.cpp +330 -192
- data/ext/sources/ggml/src/ggml-openvino/ggml-quants.h +10 -4
- data/ext/sources/ggml/src/ggml-openvino/openvino/decoder.h +56 -16
- data/ext/sources/ggml/src/ggml-openvino/openvino/frontend.h +1 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/input_model.h +4 -4
- data/ext/sources/ggml/src/ggml-openvino/openvino/node_context.h +94 -37
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/add_id.cpp +76 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/argsort.cpp +47 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/clamp.cpp +33 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/concat.cpp +48 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/cont.cpp +8 -16
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/cpy.cpp +14 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/div.cpp +146 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/flash_attn_ext.cpp +108 -21
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/gated_delta_net.cpp +282 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/gated_delta_net.hpp +65 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/get_rows.cpp +2 -9
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/glu_geglu.cpp +21 -7
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/glu_swiglu.cpp +41 -8
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/im2col.cpp +120 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/l2_norm.cpp +44 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/mul_mat_id.cpp +226 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/mulmat.cpp +19 -9
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/norm.cpp +58 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/pad.cpp +95 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/permute.cpp +58 -13
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/repeat.cpp +74 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/reshape.cpp +13 -6
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/rms_norm.cpp +1 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/rope.cpp +161 -39
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/set_rows.cpp +3 -3
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/softmax.cpp +126 -49
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/ssm_conv.cpp +59 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/sum_rows.cpp +27 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/transpose.cpp +32 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_silu.cpp +1 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_softplus.cpp +38 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/view.cpp +90 -25
- data/ext/sources/ggml/src/ggml-openvino/openvino/op_table.cpp +41 -22
- data/ext/sources/ggml/src/ggml-openvino/openvino/op_table.h +18 -4
- data/ext/sources/ggml/src/ggml-openvino/openvino/pass/mark_decompression_convert_constant_folding.h +1 -1
- data/ext/sources/ggml/src/ggml-openvino/openvino/rt_info/weightless_caching_attributes.hpp +41 -0
- data/ext/sources/ggml/src/ggml-openvino/openvino/translate_session.cpp +70 -43
- data/ext/sources/ggml/src/ggml-openvino/openvino/translate_session.h +5 -4
- data/ext/sources/ggml/src/ggml-openvino/openvino/utils.cpp +612 -36
- data/ext/sources/ggml/src/ggml-openvino/openvino/utils.h +29 -26
- data/ext/sources/ggml/src/ggml-openvino/utils.cpp +460 -114
- data/ext/sources/ggml/src/ggml-openvino/utils.h +32 -9
- data/ext/sources/ggml/src/ggml-opt.cpp +1 -0
- data/ext/sources/ggml/src/ggml-quants.c +365 -114
- data/ext/sources/ggml/src/ggml-quants.h +6 -0
- data/ext/sources/ggml/src/ggml-rpc/CMakeLists.txt +24 -0
- data/ext/sources/ggml/src/ggml-rpc/ggml-rpc.cpp +167 -311
- data/ext/sources/ggml/src/ggml-rpc/transport.cpp +683 -0
- data/ext/sources/ggml/src/ggml-rpc/transport.h +34 -0
- data/ext/sources/ggml/src/ggml-sycl/CMakeLists.txt +50 -4
- data/ext/sources/ggml/src/ggml-sycl/add-id.cpp +1 -1
- data/ext/sources/ggml/src/ggml-sycl/backend.hpp +5 -1
- data/ext/sources/ggml/src/ggml-sycl/binbcast.cpp +12 -0
- data/ext/sources/ggml/src/ggml-sycl/col2im-1d.cpp +102 -0
- data/ext/sources/ggml/src/ggml-sycl/col2im-1d.hpp +8 -0
- data/ext/sources/ggml/src/ggml-sycl/common.cpp +72 -2
- data/ext/sources/ggml/src/ggml-sycl/common.hpp +59 -2
- data/ext/sources/ggml/src/ggml-sycl/concat.cpp +21 -1
- data/ext/sources/ggml/src/ggml-sycl/conv2d-dw.cpp +158 -0
- data/ext/sources/ggml/src/ggml-sycl/conv2d-dw.hpp +10 -0
- data/ext/sources/ggml/src/ggml-sycl/conv2d-transpose.cpp +125 -0
- data/ext/sources/ggml/src/ggml-sycl/conv2d-transpose.hpp +10 -0
- data/ext/sources/ggml/src/ggml-sycl/conv2d.cpp +150 -0
- data/ext/sources/ggml/src/ggml-sycl/conv2d.hpp +10 -0
- data/ext/sources/ggml/src/ggml-sycl/conv3d.cpp +224 -0
- data/ext/sources/ggml/src/ggml-sycl/conv3d.hpp +8 -0
- data/ext/sources/ggml/src/ggml-sycl/convert.cpp +121 -13
- data/ext/sources/ggml/src/ggml-sycl/convert.hpp +9 -0
- data/ext/sources/ggml/src/ggml-sycl/cpy.cpp +706 -0
- data/ext/sources/ggml/src/ggml-sycl/cpy.hpp +281 -0
- data/ext/sources/ggml/src/ggml-sycl/cross_entropy_loss.cpp +255 -0
- data/ext/sources/ggml/src/ggml-sycl/cross_entropy_loss.hpp +7 -0
- data/ext/sources/ggml/src/ggml-sycl/cumsum.cpp +148 -0
- data/ext/sources/ggml/src/ggml-sycl/cumsum.hpp +5 -0
- data/ext/sources/ggml/src/ggml-sycl/dequantize.hpp +678 -0
- data/ext/sources/ggml/src/ggml-sycl/diag.cpp +67 -0
- data/ext/sources/ggml/src/ggml-sycl/diag.hpp +5 -0
- data/ext/sources/ggml/src/ggml-sycl/dmmv.cpp +997 -244
- data/ext/sources/ggml/src/ggml-sycl/dpct/helper.hpp +15 -7
- data/ext/sources/ggml/src/ggml-sycl/element_wise.cpp +215 -204
- data/ext/sources/ggml/src/ggml-sycl/element_wise.hpp +2 -2
- data/ext/sources/ggml/src/ggml-sycl/fattn-buffers.cpp +56 -0
- data/ext/sources/ggml/src/ggml-sycl/fattn-buffers.hpp +63 -0
- data/ext/sources/ggml/src/ggml-sycl/fattn-common.hpp +7 -5
- data/ext/sources/ggml/src/ggml-sycl/fattn-tile.cpp +4 -0
- data/ext/sources/ggml/src/ggml-sycl/fattn-tile.hpp +76 -168
- data/ext/sources/ggml/src/ggml-sycl/fattn-vec.hpp +7 -0
- data/ext/sources/ggml/src/ggml-sycl/fattn.cpp +3 -1
- data/ext/sources/ggml/src/ggml-sycl/fill.cpp +55 -0
- data/ext/sources/ggml/src/ggml-sycl/fill.hpp +5 -0
- data/ext/sources/ggml/src/ggml-sycl/gated_delta_net.cpp +69 -31
- data/ext/sources/ggml/src/ggml-sycl/gated_delta_net.hpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/gemm.hpp +3 -0
- data/ext/sources/ggml/src/ggml-sycl/getrows.cpp +79 -3
- data/ext/sources/ggml/src/ggml-sycl/ggml-sycl.cpp +1758 -455
- data/ext/sources/ggml/src/ggml-sycl/im2col.cpp +353 -89
- data/ext/sources/ggml/src/ggml-sycl/im2col.hpp +5 -3
- data/ext/sources/ggml/src/ggml-sycl/mmvq.cpp +1542 -39
- data/ext/sources/ggml/src/ggml-sycl/mmvq.hpp +33 -0
- data/ext/sources/ggml/src/ggml-sycl/norm.cpp +103 -49
- data/ext/sources/ggml/src/ggml-sycl/outprod.cpp +45 -9
- data/ext/sources/ggml/src/ggml-sycl/pad.cpp +27 -27
- data/ext/sources/ggml/src/ggml-sycl/pool.cpp +185 -0
- data/ext/sources/ggml/src/ggml-sycl/pool.hpp +22 -0
- data/ext/sources/ggml/src/ggml-sycl/presets.hpp +3 -1
- data/ext/sources/ggml/src/ggml-sycl/quants.hpp +71 -0
- data/ext/sources/ggml/src/ggml-sycl/set_rows.cpp +17 -3
- data/ext/sources/ggml/src/ggml-sycl/softmax.cpp +9 -10
- data/ext/sources/ggml/src/ggml-sycl/solve_tri.cpp +172 -0
- data/ext/sources/ggml/src/ggml-sycl/solve_tri.hpp +8 -0
- data/ext/sources/ggml/src/ggml-sycl/ssm_conv.cpp +6 -1
- data/ext/sources/ggml/src/ggml-sycl/ssm_scan.cpp +156 -0
- data/ext/sources/ggml/src/ggml-sycl/ssm_scan.hpp +5 -0
- data/ext/sources/ggml/src/ggml-sycl/sycl_hw.cpp +62 -10
- data/ext/sources/ggml/src/ggml-sycl/sycl_hw.hpp +18 -6
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq512-dv512.cpp +6 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-f16.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q4_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q4_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q5_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q5_1.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q8_0.cpp +1 -0
- data/ext/sources/ggml/src/ggml-sycl/type.hpp +112 -0
- data/ext/sources/ggml/src/ggml-sycl/upscale.cpp +410 -0
- data/ext/sources/ggml/src/ggml-sycl/upscale.hpp +9 -0
- data/ext/sources/ggml/src/ggml-sycl/vecdotq.hpp +242 -45
- data/ext/sources/ggml/src/ggml-virtgpu/ggml-backend-buffer.cpp +4 -0
- data/ext/sources/ggml/src/ggml-virtgpu/ggml-backend-device.cpp +2 -0
- data/ext/sources/ggml/src/ggml-virtgpu/ggml-backend.cpp +2 -0
- data/ext/sources/ggml/src/ggml-virtgpu/virtgpu-shm.cpp +1 -0
- data/ext/sources/ggml/src/ggml-virtgpu/virtgpu.cpp +1 -0
- data/ext/sources/ggml/src/ggml-virtgpu/virtgpu.h +0 -2
- data/ext/sources/ggml/src/ggml-vulkan/CMakeLists.txt +16 -0
- data/ext/sources/ggml/src/ggml-vulkan/ggml-vulkan.cpp +2843 -700
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt +4 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/col2im_1d.comp +61 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/contig_copy.comp +6 -2
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_mm.comp +146 -13
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv3d_mm.comp +431 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/copy.comp +3 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/copy_from_quant.comp +1 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/copy_to_quant.comp +25 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs.glsl +88 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs_cm2.glsl +643 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/dequant_nvfp4.comp +32 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q1_0.comp +29 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/diag.comp +3 -4
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/dot_product_funcs.glsl +27 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/coopmat2_decode_vector.comp +7 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn.comp +198 -48
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_base.glsl +60 -59
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm1.comp +116 -113
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm2.comp +122 -31
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_dequant.glsl +131 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_mmq_funcs.glsl +203 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/fwht.comp +115 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gated_delta_net.comp +125 -64
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/generic_binary_head.glsl +0 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/generic_unary_head.glsl +21 -19
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/get_rows_back.comp +25 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/glu_head.glsl +29 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/glu_main.glsl +17 -11
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp +76 -54
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/im2col_3d.comp +0 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/l2_norm.comp +4 -7
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/log.comp +0 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec.comp +122 -27
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iface.glsl +6 -6
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q2_k.comp +1 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q4_k.comp +1 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q5_k.comp +1 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq.comp +22 -24
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq_funcs.glsl +88 -55
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +42 -40
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_cm2.comp +49 -15
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_funcs.glsl +222 -171
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_funcs.glsl +8 -8
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_shmem_types.glsl +24 -9
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/multi_add.comp +0 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/norm.comp +10 -10
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/repeat_back.comp +3 -3
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/roll.comp +3 -3
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/rope_funcs.glsl +5 -2
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/rope_head.glsl +0 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/rope_params.glsl +3 -2
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/snake.comp +49 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/ssm_conv.comp +11 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/tri.comp +3 -4
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/types.glsl +79 -2
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/unary.comp +168 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +282 -211
- data/ext/sources/ggml/src/ggml-webgpu/CMakeLists.txt +5 -2
- data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu-shader-lib.hpp +2209 -283
- data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu.cpp +2618 -1416
- data/ext/sources/ggml/src/ggml-webgpu/pre_wgsl.hpp +37 -7
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/add_id.wgsl +64 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/binary.wgsl +8 -7
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/common_decls.tmpl +90 -95
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/concat.wgsl +19 -1
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/conv2d.wgsl +165 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/{cpy.tmpl.wgsl → cpy.wgsl} +25 -50
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn.wgsl +107 -184
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_quant_staging.tmpl +124 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_tile.wgsl +397 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_blk.wgsl +101 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_reduce.wgsl +84 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_split.wgsl +619 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/gated_delta_net.wgsl +149 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/get_rows.wgsl +204 -78
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/glu.wgsl +155 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/im2col.wgsl +101 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_decls.tmpl +805 -526
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id.wgsl +195 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_gather.wgsl +52 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_vec.wgsl +154 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_reg_tile.wgsl +8 -6
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_subgroup_matrix.wgsl +5 -1
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec.wgsl +90 -413
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_acc.tmpl +1553 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_q_acc.tmpl +297 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/quant_inner_loops.tmpl +21 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/quantize_q8.wgsl +178 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/rms_norm_mul.wgsl +152 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/{rope.tmpl.wgsl → rope.wgsl} +71 -142
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/row_norm.wgsl +153 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/scale.wgsl +6 -4
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/set.wgsl +109 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/set_rows.wgsl +2 -3
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/set_rows_quant.wgsl +224 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/{soft_max.tmpl.wgsl → soft_max.wgsl} +106 -206
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/solve_tri.wgsl +121 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/ssm_conv.wgsl +65 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/ssm_scan.wgsl +193 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/unary.wgsl +68 -48
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/upscale.wgsl +240 -0
- data/ext/sources/ggml/src/ggml-zdnn/ggml-zdnn.cpp +18 -14
- data/ext/sources/ggml/src/ggml-zendnn/CMakeLists.txt +1 -1
- data/ext/sources/ggml/src/ggml-zendnn/ggml-zendnn.cpp +244 -10
- data/ext/sources/ggml/src/ggml.c +146 -42
- data/ext/sources/ggml/src/gguf.cpp +173 -28
- data/ext/sources/include/parakeet.h +342 -0
- data/ext/sources/include/whisper.h +31 -0
- data/ext/sources/media/matmul.png +0 -0
- data/ext/sources/src/CMakeLists.txt +23 -0
- data/ext/sources/src/parakeet-arch.h +188 -0
- data/ext/sources/src/parakeet.cpp +3838 -0
- data/ext/sources/src/whisper.cpp +220 -26
- data/extsources.rb +26 -10
- data/lib/whisper/log_settable.rb +33 -0
- data/lib/whisper/model/uri.rb +13 -8
- data/lib/whisper/output.rb +74 -0
- data/sig/whisper.rbs +417 -62
- data/test/helper.rb +2 -0
- data/test/jfk_reader/jfk_reader.c +50 -7
- data/test/test_callback.rb +1 -0
- data/test/test_package.rb +6 -5
- data/test/test_parakeet.rb +28 -0
- data/test/test_parakeet_callback.rb +107 -0
- data/test/test_parakeet_context.rb +116 -0
- data/test/test_parakeet_context_params.rb +24 -0
- data/test/test_parakeet_model.rb +21 -0
- data/test/test_parakeet_params.rb +78 -0
- data/test/test_parakeet_segment.rb +42 -0
- data/test/test_parakeet_token.rb +73 -0
- data/test/test_params.rb +2 -0
- data/test/test_vad.rb +9 -0
- data/test/test_vad_context.rb +2 -2
- data/test/test_vad_segment.rb +1 -1
- data/test/test_whisper.rb +24 -6
- data/whispercpp.gemspec +2 -2
- metadata +263 -304
- data/ext/sources/bindings/javascript/CMakeLists.txt +0 -41
- data/ext/sources/bindings/javascript/emscripten.cpp +0 -93
- data/ext/sources/bindings/javascript/libwhisper.worker.js +0 -1
- data/ext/sources/bindings/javascript/package.json +0 -26
- data/ext/sources/bindings/javascript/whisper.js +0 -19
- data/ext/sources/examples/addon.node/CMakeLists.txt +0 -31
- data/ext/sources/examples/addon.node/__test__/whisper.spec.js +0 -133
- data/ext/sources/examples/addon.node/addon.cpp +0 -557
- data/ext/sources/examples/addon.node/index.js +0 -59
- data/ext/sources/examples/addon.node/package.json +0 -16
- data/ext/sources/examples/addon.node/vad-example.js +0 -132
- data/ext/sources/examples/bench.wasm/CMakeLists.txt +0 -49
- data/ext/sources/examples/bench.wasm/emscripten.cpp +0 -87
- data/ext/sources/examples/bench.wasm/index-tmpl.html +0 -285
- data/ext/sources/examples/coi-serviceworker.js +0 -146
- data/ext/sources/examples/command/CMakeLists.txt +0 -10
- data/ext/sources/examples/command/command.cpp +0 -802
- data/ext/sources/examples/command/commands.txt +0 -9
- data/ext/sources/examples/command.wasm/CMakeLists.txt +0 -50
- data/ext/sources/examples/command.wasm/emscripten.cpp +0 -327
- data/ext/sources/examples/command.wasm/index-tmpl.html +0 -415
- data/ext/sources/examples/generate-karaoke.sh +0 -57
- data/ext/sources/examples/helpers.js +0 -191
- data/ext/sources/examples/livestream.sh +0 -112
- data/ext/sources/examples/lsp/CMakeLists.txt +0 -10
- data/ext/sources/examples/lsp/lsp.cpp +0 -471
- data/ext/sources/examples/lsp/whisper.vim +0 -362
- data/ext/sources/examples/python/test_whisper_processor.py +0 -7
- data/ext/sources/examples/python/whisper_processor.py +0 -54
- data/ext/sources/examples/server/bench.js +0 -29
- data/ext/sources/examples/server.py +0 -120
- data/ext/sources/examples/stream/CMakeLists.txt +0 -10
- data/ext/sources/examples/stream/stream.cpp +0 -437
- data/ext/sources/examples/stream.wasm/CMakeLists.txt +0 -49
- data/ext/sources/examples/stream.wasm/emscripten.cpp +0 -216
- data/ext/sources/examples/stream.wasm/index-tmpl.html +0 -491
- data/ext/sources/examples/sycl/CMakeLists.txt +0 -9
- data/ext/sources/examples/sycl/build.sh +0 -22
- data/ext/sources/examples/sycl/ls-sycl-device.cpp +0 -11
- data/ext/sources/examples/sycl/run-whisper.sh +0 -17
- data/ext/sources/examples/talk-llama/CMakeLists.txt +0 -48
- data/ext/sources/examples/talk-llama/eleven-labs.py +0 -80
- data/ext/sources/examples/talk-llama/llama-adapter.cpp +0 -488
- data/ext/sources/examples/talk-llama/llama-adapter.h +0 -89
- data/ext/sources/examples/talk-llama/llama-arch.cpp +0 -2877
- data/ext/sources/examples/talk-llama/llama-arch.h +0 -628
- data/ext/sources/examples/talk-llama/llama-batch.cpp +0 -919
- data/ext/sources/examples/talk-llama/llama-batch.h +0 -173
- data/ext/sources/examples/talk-llama/llama-chat.cpp +0 -896
- data/ext/sources/examples/talk-llama/llama-chat.h +0 -71
- data/ext/sources/examples/talk-llama/llama-context.cpp +0 -3633
- data/ext/sources/examples/talk-llama/llama-context.h +0 -359
- data/ext/sources/examples/talk-llama/llama-cparams.cpp +0 -5
- data/ext/sources/examples/talk-llama/llama-cparams.h +0 -47
- data/ext/sources/examples/talk-llama/llama-ext.h +0 -12
- data/ext/sources/examples/talk-llama/llama-grammar.cpp +0 -1464
- data/ext/sources/examples/talk-llama/llama-grammar.h +0 -194
- data/ext/sources/examples/talk-llama/llama-graph.cpp +0 -2735
- data/ext/sources/examples/talk-llama/llama-graph.h +0 -1031
- data/ext/sources/examples/talk-llama/llama-hparams.cpp +0 -258
- data/ext/sources/examples/talk-llama/llama-hparams.h +0 -353
- data/ext/sources/examples/talk-llama/llama-impl.cpp +0 -171
- data/ext/sources/examples/talk-llama/llama-impl.h +0 -75
- data/ext/sources/examples/talk-llama/llama-io.cpp +0 -15
- data/ext/sources/examples/talk-llama/llama-io.h +0 -35
- data/ext/sources/examples/talk-llama/llama-kv-cache-iswa.cpp +0 -330
- data/ext/sources/examples/talk-llama/llama-kv-cache-iswa.h +0 -137
- data/ext/sources/examples/talk-llama/llama-kv-cache.cpp +0 -2285
- data/ext/sources/examples/talk-llama/llama-kv-cache.h +0 -389
- data/ext/sources/examples/talk-llama/llama-kv-cells.h +0 -533
- data/ext/sources/examples/talk-llama/llama-memory-hybrid-iswa.cpp +0 -275
- data/ext/sources/examples/talk-llama/llama-memory-hybrid-iswa.h +0 -140
- data/ext/sources/examples/talk-llama/llama-memory-hybrid.cpp +0 -268
- data/ext/sources/examples/talk-llama/llama-memory-hybrid.h +0 -139
- data/ext/sources/examples/talk-llama/llama-memory-recurrent.cpp +0 -1165
- data/ext/sources/examples/talk-llama/llama-memory-recurrent.h +0 -182
- data/ext/sources/examples/talk-llama/llama-memory.cpp +0 -59
- data/ext/sources/examples/talk-llama/llama-memory.h +0 -122
- data/ext/sources/examples/talk-llama/llama-mmap.cpp +0 -752
- data/ext/sources/examples/talk-llama/llama-mmap.h +0 -73
- data/ext/sources/examples/talk-llama/llama-model-loader.cpp +0 -1655
- data/ext/sources/examples/talk-llama/llama-model-loader.h +0 -206
- data/ext/sources/examples/talk-llama/llama-model-saver.cpp +0 -299
- data/ext/sources/examples/talk-llama/llama-model-saver.h +0 -40
- data/ext/sources/examples/talk-llama/llama-model.cpp +0 -9056
- data/ext/sources/examples/talk-llama/llama-model.h +0 -597
- data/ext/sources/examples/talk-llama/llama-quant.cpp +0 -1304
- data/ext/sources/examples/talk-llama/llama-quant.h +0 -1
- data/ext/sources/examples/talk-llama/llama-sampler.cpp +0 -3885
- data/ext/sources/examples/talk-llama/llama-sampler.h +0 -42
- data/ext/sources/examples/talk-llama/llama-vocab.cpp +0 -3970
- data/ext/sources/examples/talk-llama/llama-vocab.h +0 -187
- data/ext/sources/examples/talk-llama/llama.cpp +0 -1194
- data/ext/sources/examples/talk-llama/llama.h +0 -1573
- data/ext/sources/examples/talk-llama/models/afmoe.cpp +0 -190
- data/ext/sources/examples/talk-llama/models/apertus.cpp +0 -125
- data/ext/sources/examples/talk-llama/models/arcee.cpp +0 -135
- data/ext/sources/examples/talk-llama/models/arctic.cpp +0 -137
- data/ext/sources/examples/talk-llama/models/arwkv7.cpp +0 -86
- data/ext/sources/examples/talk-llama/models/baichuan.cpp +0 -123
- data/ext/sources/examples/talk-llama/models/bailingmoe.cpp +0 -143
- data/ext/sources/examples/talk-llama/models/bailingmoe2.cpp +0 -133
- data/ext/sources/examples/talk-llama/models/bert.cpp +0 -184
- data/ext/sources/examples/talk-llama/models/bitnet.cpp +0 -145
- data/ext/sources/examples/talk-llama/models/bloom.cpp +0 -101
- data/ext/sources/examples/talk-llama/models/chameleon.cpp +0 -178
- data/ext/sources/examples/talk-llama/models/chatglm.cpp +0 -132
- data/ext/sources/examples/talk-llama/models/codeshell.cpp +0 -111
- data/ext/sources/examples/talk-llama/models/cogvlm.cpp +0 -102
- data/ext/sources/examples/talk-llama/models/cohere2-iswa.cpp +0 -134
- data/ext/sources/examples/talk-llama/models/command-r.cpp +0 -122
- data/ext/sources/examples/talk-llama/models/dbrx.cpp +0 -122
- data/ext/sources/examples/talk-llama/models/deci.cpp +0 -135
- data/ext/sources/examples/talk-llama/models/deepseek.cpp +0 -142
- data/ext/sources/examples/talk-llama/models/deepseek2.cpp +0 -262
- data/ext/sources/examples/talk-llama/models/delta-net-base.cpp +0 -445
- data/ext/sources/examples/talk-llama/models/dots1.cpp +0 -132
- data/ext/sources/examples/talk-llama/models/dream.cpp +0 -105
- data/ext/sources/examples/talk-llama/models/ernie4-5-moe.cpp +0 -148
- data/ext/sources/examples/talk-llama/models/ernie4-5.cpp +0 -110
- data/ext/sources/examples/talk-llama/models/eurobert.cpp +0 -97
- data/ext/sources/examples/talk-llama/models/exaone-moe.cpp +0 -145
- data/ext/sources/examples/talk-llama/models/exaone.cpp +0 -114
- data/ext/sources/examples/talk-llama/models/exaone4.cpp +0 -123
- data/ext/sources/examples/talk-llama/models/falcon-h1.cpp +0 -111
- data/ext/sources/examples/talk-llama/models/falcon.cpp +0 -120
- data/ext/sources/examples/talk-llama/models/gemma-embedding.cpp +0 -116
- data/ext/sources/examples/talk-llama/models/gemma.cpp +0 -112
- data/ext/sources/examples/talk-llama/models/gemma2-iswa.cpp +0 -128
- data/ext/sources/examples/talk-llama/models/gemma3.cpp +0 -155
- data/ext/sources/examples/talk-llama/models/gemma3n-iswa.cpp +0 -384
- data/ext/sources/examples/talk-llama/models/glm4-moe.cpp +0 -170
- data/ext/sources/examples/talk-llama/models/glm4.cpp +0 -157
- data/ext/sources/examples/talk-llama/models/gpt2.cpp +0 -105
- data/ext/sources/examples/talk-llama/models/gptneox.cpp +0 -144
- data/ext/sources/examples/talk-llama/models/granite-hybrid.cpp +0 -195
- data/ext/sources/examples/talk-llama/models/granite.cpp +0 -210
- data/ext/sources/examples/talk-llama/models/grok.cpp +0 -159
- data/ext/sources/examples/talk-llama/models/grovemoe.cpp +0 -139
- data/ext/sources/examples/talk-llama/models/hunyuan-dense.cpp +0 -132
- data/ext/sources/examples/talk-llama/models/hunyuan-moe.cpp +0 -153
- data/ext/sources/examples/talk-llama/models/internlm2.cpp +0 -120
- data/ext/sources/examples/talk-llama/models/jais.cpp +0 -86
- data/ext/sources/examples/talk-llama/models/jais2.cpp +0 -123
- data/ext/sources/examples/talk-llama/models/jamba.cpp +0 -106
- data/ext/sources/examples/talk-llama/models/kimi-linear.cpp +0 -381
- data/ext/sources/examples/talk-llama/models/lfm2.cpp +0 -196
- data/ext/sources/examples/talk-llama/models/llada-moe.cpp +0 -122
- data/ext/sources/examples/talk-llama/models/llada.cpp +0 -99
- data/ext/sources/examples/talk-llama/models/llama-iswa.cpp +0 -178
- data/ext/sources/examples/talk-llama/models/llama.cpp +0 -175
- data/ext/sources/examples/talk-llama/models/maincoder.cpp +0 -117
- data/ext/sources/examples/talk-llama/models/mamba-base.cpp +0 -289
- data/ext/sources/examples/talk-llama/models/mamba.cpp +0 -54
- data/ext/sources/examples/talk-llama/models/mimo2-iswa.cpp +0 -129
- data/ext/sources/examples/talk-llama/models/minicpm3.cpp +0 -200
- data/ext/sources/examples/talk-llama/models/minimax-m2.cpp +0 -123
- data/ext/sources/examples/talk-llama/models/mistral3.cpp +0 -160
- data/ext/sources/examples/talk-llama/models/models.h +0 -704
- data/ext/sources/examples/talk-llama/models/modern-bert.cpp +0 -109
- data/ext/sources/examples/talk-llama/models/mpt.cpp +0 -126
- data/ext/sources/examples/talk-llama/models/nemotron-h.cpp +0 -162
- data/ext/sources/examples/talk-llama/models/nemotron.cpp +0 -122
- data/ext/sources/examples/talk-llama/models/neo-bert.cpp +0 -104
- data/ext/sources/examples/talk-llama/models/olmo.cpp +0 -121
- data/ext/sources/examples/talk-llama/models/olmo2.cpp +0 -150
- data/ext/sources/examples/talk-llama/models/olmoe.cpp +0 -124
- data/ext/sources/examples/talk-llama/models/openai-moe-iswa.cpp +0 -127
- data/ext/sources/examples/talk-llama/models/openelm.cpp +0 -124
- data/ext/sources/examples/talk-llama/models/orion.cpp +0 -123
- data/ext/sources/examples/talk-llama/models/paddleocr.cpp +0 -122
- data/ext/sources/examples/talk-llama/models/pangu-embedded.cpp +0 -121
- data/ext/sources/examples/talk-llama/models/phi2.cpp +0 -121
- data/ext/sources/examples/talk-llama/models/phi3.cpp +0 -152
- data/ext/sources/examples/talk-llama/models/plamo.cpp +0 -110
- data/ext/sources/examples/talk-llama/models/plamo2.cpp +0 -320
- data/ext/sources/examples/talk-llama/models/plamo3.cpp +0 -128
- data/ext/sources/examples/talk-llama/models/plm.cpp +0 -169
- data/ext/sources/examples/talk-llama/models/qwen.cpp +0 -108
- data/ext/sources/examples/talk-llama/models/qwen2.cpp +0 -126
- data/ext/sources/examples/talk-llama/models/qwen2moe.cpp +0 -151
- data/ext/sources/examples/talk-llama/models/qwen2vl.cpp +0 -117
- data/ext/sources/examples/talk-llama/models/qwen3.cpp +0 -120
- data/ext/sources/examples/talk-llama/models/qwen35.cpp +0 -381
- data/ext/sources/examples/talk-llama/models/qwen35moe.cpp +0 -422
- data/ext/sources/examples/talk-llama/models/qwen3moe.cpp +0 -131
- data/ext/sources/examples/talk-llama/models/qwen3next.cpp +0 -525
- data/ext/sources/examples/talk-llama/models/qwen3vl-moe.cpp +0 -140
- data/ext/sources/examples/talk-llama/models/qwen3vl.cpp +0 -132
- data/ext/sources/examples/talk-llama/models/refact.cpp +0 -94
- data/ext/sources/examples/talk-llama/models/rnd1.cpp +0 -126
- data/ext/sources/examples/talk-llama/models/rwkv6-base.cpp +0 -164
- data/ext/sources/examples/talk-llama/models/rwkv6.cpp +0 -94
- data/ext/sources/examples/talk-llama/models/rwkv6qwen2.cpp +0 -86
- data/ext/sources/examples/talk-llama/models/rwkv7-base.cpp +0 -137
- data/ext/sources/examples/talk-llama/models/rwkv7.cpp +0 -90
- data/ext/sources/examples/talk-llama/models/seed-oss.cpp +0 -124
- data/ext/sources/examples/talk-llama/models/smallthinker.cpp +0 -126
- data/ext/sources/examples/talk-llama/models/smollm3.cpp +0 -128
- data/ext/sources/examples/talk-llama/models/stablelm.cpp +0 -146
- data/ext/sources/examples/talk-llama/models/starcoder.cpp +0 -100
- data/ext/sources/examples/talk-llama/models/starcoder2.cpp +0 -121
- data/ext/sources/examples/talk-llama/models/step35-iswa.cpp +0 -165
- data/ext/sources/examples/talk-llama/models/t5-dec.cpp +0 -166
- data/ext/sources/examples/talk-llama/models/t5-enc.cpp +0 -96
- data/ext/sources/examples/talk-llama/models/wavtokenizer-dec.cpp +0 -149
- data/ext/sources/examples/talk-llama/models/xverse.cpp +0 -108
- data/ext/sources/examples/talk-llama/prompts/talk-alpaca.txt +0 -23
- data/ext/sources/examples/talk-llama/speak +0 -40
- data/ext/sources/examples/talk-llama/speak.bat +0 -1
- data/ext/sources/examples/talk-llama/speak.ps1 +0 -14
- data/ext/sources/examples/talk-llama/talk-llama.cpp +0 -813
- data/ext/sources/examples/talk-llama/unicode-data.cpp +0 -7034
- data/ext/sources/examples/talk-llama/unicode-data.h +0 -20
- data/ext/sources/examples/talk-llama/unicode.cpp +0 -1103
- data/ext/sources/examples/talk-llama/unicode.h +0 -111
- data/ext/sources/examples/wchess/CMakeLists.txt +0 -10
- data/ext/sources/examples/wchess/libwchess/CMakeLists.txt +0 -19
- data/ext/sources/examples/wchess/libwchess/Chessboard.cpp +0 -803
- data/ext/sources/examples/wchess/libwchess/Chessboard.h +0 -33
- data/ext/sources/examples/wchess/libwchess/WChess.cpp +0 -193
- data/ext/sources/examples/wchess/libwchess/WChess.h +0 -63
- data/ext/sources/examples/wchess/libwchess/test-chessboard.cpp +0 -117
- data/ext/sources/examples/wchess/wchess.cmd/CMakeLists.txt +0 -8
- data/ext/sources/examples/wchess/wchess.cmd/wchess.cmd.cpp +0 -253
- data/ext/sources/examples/whisper.wasm/CMakeLists.txt +0 -50
- data/ext/sources/examples/whisper.wasm/emscripten.cpp +0 -118
- data/ext/sources/examples/whisper.wasm/index-tmpl.html +0 -659
- data/ext/sources/ggml/src/ggml-cuda/template-instances/generate_cu_files.py +0 -99
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-msg.h +0 -155
- data/ext/sources/ggml/src/ggml-hexagon/op-desc.h +0 -153
- data/ext/sources/ggml/src/ggml-opencl/kernels/embed_kernel.py +0 -26
- data/ext/sources/ggml/src/ggml-openvino/openvino/pass/eliminate_zp.cpp +0 -123
- data/ext/sources/ggml/src/ggml-openvino/openvino/pass/eliminate_zp.h +0 -17
- data/ext/sources/ggml/src/ggml-virtgpu/regenerate_remoting.py +0 -333
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/abs.comp +0 -21
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/ceil.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/clamp.comp +0 -17
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/cos.comp +0 -17
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/elu.comp +0 -27
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/exp.comp +0 -21
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/floor.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu.comp +0 -25
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu_erf.comp +0 -39
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/gelu_quick.comp +0 -23
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/hardsigmoid.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/hardswish.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/leaky_relu.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/neg.comp +0 -20
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/relu.comp +0 -21
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/round.comp +0 -29
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/rte.glsl +0 -5
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sgn.comp +0 -21
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sigmoid.comp +0 -20
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/silu.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sin.comp +0 -17
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/softplus.comp +0 -23
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/sqrt.comp +0 -17
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/square.comp +0 -17
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/step.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/tanh.comp +0 -20
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/trunc.comp +0 -22
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/xielu.comp +0 -35
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/embed_wgsl.py +0 -182
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/glu.tmpl.wgsl +0 -323
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat.wgsl +0 -718
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/rms_norm.wgsl +0 -123
- data/ext/sources/tests/CMakeLists.txt +0 -112
- data/ext/sources/tests/earnings21/eval.mk +0 -58
- data/ext/sources/tests/earnings21/eval.py +0 -68
- data/ext/sources/tests/earnings21/normalizers/__init__.py +0 -2
- data/ext/sources/tests/earnings21/normalizers/basic.py +0 -80
- data/ext/sources/tests/earnings21/normalizers/english.json +0 -1741
- data/ext/sources/tests/earnings21/normalizers/english.py +0 -550
- data/ext/sources/tests/earnings21/requirements.txt +0 -6
- data/ext/sources/tests/en-0-ref.txt +0 -1
- data/ext/sources/tests/en-1-ref.txt +0 -1
- data/ext/sources/tests/en-2-ref.txt +0 -1
- data/ext/sources/tests/es-0-ref.txt +0 -1
- data/ext/sources/tests/librispeech/eval.mk +0 -39
- data/ext/sources/tests/librispeech/eval.py +0 -47
- data/ext/sources/tests/librispeech/normalizers/__init__.py +0 -2
- data/ext/sources/tests/librispeech/normalizers/basic.py +0 -80
- data/ext/sources/tests/librispeech/normalizers/english.json +0 -1741
- data/ext/sources/tests/librispeech/normalizers/english.py +0 -550
- data/ext/sources/tests/librispeech/requirements.txt +0 -6
- data/ext/sources/tests/run-tests.sh +0 -130
- data/ext/sources/tests/test-c.c +0 -3
- data/ext/sources/tests/test-vad-full.cpp +0 -56
- data/ext/sources/tests/test-vad.cpp +0 -83
- data/ext/sources/tests/test-whisper.js +0 -58
- data/lib/whisper/context.rb +0 -15
- data/lib/whisper/segment.rb +0 -58
|
@@ -3,217 +3,41 @@
|
|
|
3
3
|
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
|
4
4
|
|
|
5
5
|
#include <assert.h>
|
|
6
|
+
#include <HAP_compute_res.h>
|
|
6
7
|
#include <HAP_farf.h>
|
|
7
8
|
#include <HAP_perf.h>
|
|
8
9
|
#include <math.h>
|
|
10
|
+
#include <stdbool.h>
|
|
11
|
+
#include <stdatomic.h>
|
|
12
|
+
#include <stddef.h>
|
|
13
|
+
#include <stdint.h>
|
|
9
14
|
#include <string.h>
|
|
10
15
|
|
|
11
16
|
#include "hex-dma.h"
|
|
17
|
+
#include "hex-fastdiv.h"
|
|
18
|
+
#include "hex-profile.h"
|
|
19
|
+
#include "hmx-queue.h"
|
|
20
|
+
#include "hmx-utils.h"
|
|
12
21
|
#include "hvx-utils.h"
|
|
13
22
|
#include "hvx-dump.h"
|
|
23
|
+
#include "hvx-copy.h"
|
|
24
|
+
#include "hvx-reduce.h"
|
|
25
|
+
#include "hvx-flash-attn.h"
|
|
26
|
+
#include "htp-vtcm.h"
|
|
27
|
+
#include "worker-pool.h"
|
|
14
28
|
|
|
15
29
|
#define GGML_COMMON_DECL_C
|
|
16
30
|
#include "ggml-common.h"
|
|
17
31
|
#include "htp-ctx.h"
|
|
18
|
-
#include "htp-msg.h"
|
|
19
32
|
#include "htp-ops.h"
|
|
20
33
|
|
|
34
|
+
#include "flash-attn-ops.h"
|
|
35
|
+
#include "hvx-fa-kernels.h"
|
|
36
|
+
#include "hmx-fa-kernels.h"
|
|
37
|
+
|
|
21
38
|
// Must be multiple of 32
|
|
22
39
|
#define FLASH_ATTN_BLOCK_SIZE (32 * 2)
|
|
23
40
|
|
|
24
|
-
// This is a bit of a hack because the compiler is strugling to properly inline
|
|
25
|
-
// the default hvx_vec_f32_to_f16 with output into the local array.
|
|
26
|
-
static void __attribute__((noinline)) hvx_vec_f32_to_f16_a(void *ptr, HVX_Vector v0, HVX_Vector v1)
|
|
27
|
-
{
|
|
28
|
-
*(HVX_Vector *) ptr = hvx_vec_f32_to_f16(v0, v1);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Dot product of two F16 vectors, accumulating to float
|
|
32
|
-
static inline void hvx_dot_f16_f16_aa(float * restrict r, const void * restrict x, const void * restrict y, unsigned int n, float s) {
|
|
33
|
-
const HVX_Vector * restrict vx = (const HVX_Vector * restrict) x; // fp16
|
|
34
|
-
const HVX_Vector * restrict vy = (const HVX_Vector * restrict) y; // fp16
|
|
35
|
-
|
|
36
|
-
uint32_t nvec = n / VLEN_FP16; // num full fp16 hvx vectors
|
|
37
|
-
uint32_t nloe = n % VLEN_FP16; // leftover elements
|
|
38
|
-
|
|
39
|
-
HVX_VectorPair rsum_p = Q6_W_vcombine_VV(Q6_V_vsplat_R(0), Q6_V_vsplat_R(0));
|
|
40
|
-
|
|
41
|
-
uint32_t i = 0;
|
|
42
|
-
|
|
43
|
-
#pragma unroll(4)
|
|
44
|
-
for (i = 0; i < nvec; i++) {
|
|
45
|
-
rsum_p = hvx_vec_mpyacc_f32_f16(rsum_p, vx[i], vy[i]);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (nloe) {
|
|
49
|
-
HVX_VectorPred bmask = Q6_Q_vsetq_R(nloe * 2);
|
|
50
|
-
HVX_Vector y_hf = Q6_V_vand_QV(bmask, vy[i]);
|
|
51
|
-
HVX_Vector x_hf = Q6_V_vand_QV(bmask, vx[i]);
|
|
52
|
-
|
|
53
|
-
rsum_p = hvx_vec_mpyacc_f32_f16(rsum_p, x_hf, y_hf);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
HVX_Vector rsum = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(rsum_p), Q6_V_hi_W(rsum_p)));
|
|
57
|
-
rsum = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(hvx_vec_splat_f32(s), hvx_vec_reduce_sum_f32(rsum)));
|
|
58
|
-
hvx_vec_store_u(r, 4, rsum);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
static inline HVX_Vector hvx_dot_f16_f16_aa_rx4(const void * restrict y,
|
|
62
|
-
const uint8_t * restrict x,
|
|
63
|
-
const size_t stride_x,
|
|
64
|
-
const size_t nvec,
|
|
65
|
-
const size_t nloe) {
|
|
66
|
-
const HVX_Vector * restrict vx0 = (const HVX_Vector * restrict) x; // fp16
|
|
67
|
-
const HVX_Vector * restrict vx1 = (const HVX_Vector * restrict) (x + stride_x); // fp16
|
|
68
|
-
const HVX_Vector * restrict vx2 = (const HVX_Vector * restrict) (x + stride_x * 2); // fp16
|
|
69
|
-
const HVX_Vector * restrict vx3 = (const HVX_Vector * restrict) (x + stride_x * 3); // fp16
|
|
70
|
-
const HVX_Vector * restrict vy = (const HVX_Vector * restrict) y; // fp16
|
|
71
|
-
|
|
72
|
-
HVX_VectorPair rsum0_p = Q6_W_vcombine_VV(Q6_V_vsplat_R(0), Q6_V_vsplat_R(0));
|
|
73
|
-
HVX_VectorPair rsum1_p = Q6_W_vcombine_VV(Q6_V_vsplat_R(0), Q6_V_vsplat_R(0));
|
|
74
|
-
HVX_VectorPair rsum2_p = Q6_W_vcombine_VV(Q6_V_vsplat_R(0), Q6_V_vsplat_R(0));
|
|
75
|
-
HVX_VectorPair rsum3_p = Q6_W_vcombine_VV(Q6_V_vsplat_R(0), Q6_V_vsplat_R(0));
|
|
76
|
-
|
|
77
|
-
uint32_t i = 0;
|
|
78
|
-
|
|
79
|
-
for (i = 0; i < nvec; i++) {
|
|
80
|
-
HVX_Vector y_hf = vy[i];
|
|
81
|
-
HVX_Vector x0_hf = vx0[i];
|
|
82
|
-
HVX_Vector x1_hf = vx1[i];
|
|
83
|
-
HVX_Vector x2_hf = vx2[i];
|
|
84
|
-
HVX_Vector x3_hf = vx3[i];
|
|
85
|
-
|
|
86
|
-
rsum0_p = hvx_vec_mpyacc_f32_f16(rsum0_p, x0_hf, y_hf);
|
|
87
|
-
rsum1_p = hvx_vec_mpyacc_f32_f16(rsum1_p, x1_hf, y_hf);
|
|
88
|
-
rsum2_p = hvx_vec_mpyacc_f32_f16(rsum2_p, x2_hf, y_hf);
|
|
89
|
-
rsum3_p = hvx_vec_mpyacc_f32_f16(rsum3_p, x3_hf, y_hf);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (nloe) {
|
|
93
|
-
// Load x (fp16) and zero-out unused elements
|
|
94
|
-
HVX_VectorPred bmask = Q6_Q_vsetq_R(nloe * 2);
|
|
95
|
-
HVX_Vector y_hf = Q6_V_vand_QV(bmask, vy[i]);
|
|
96
|
-
HVX_Vector x0_hf = Q6_V_vand_QV(bmask, vx0[i]);
|
|
97
|
-
HVX_Vector x1_hf = Q6_V_vand_QV(bmask, vx1[i]);
|
|
98
|
-
HVX_Vector x2_hf = Q6_V_vand_QV(bmask, vx2[i]);
|
|
99
|
-
HVX_Vector x3_hf = Q6_V_vand_QV(bmask, vx3[i]);
|
|
100
|
-
|
|
101
|
-
rsum0_p = hvx_vec_mpyacc_f32_f16(rsum0_p, x0_hf, y_hf);
|
|
102
|
-
rsum1_p = hvx_vec_mpyacc_f32_f16(rsum1_p, x1_hf, y_hf);
|
|
103
|
-
rsum2_p = hvx_vec_mpyacc_f32_f16(rsum2_p, x2_hf, y_hf);
|
|
104
|
-
rsum3_p = hvx_vec_mpyacc_f32_f16(rsum3_p, x3_hf, y_hf);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
HVX_Vector rsum0 = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(rsum0_p), Q6_V_hi_W(rsum0_p)));
|
|
108
|
-
HVX_Vector rsum1 = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(rsum1_p), Q6_V_hi_W(rsum1_p)));
|
|
109
|
-
HVX_Vector rsum2 = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(rsum2_p), Q6_V_hi_W(rsum2_p)));
|
|
110
|
-
HVX_Vector rsum3 = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(rsum3_p), Q6_V_hi_W(rsum3_p)));
|
|
111
|
-
|
|
112
|
-
HVX_Vector_x4 rsum0123 = { .v = { rsum0, rsum1, rsum2, rsum3 } };
|
|
113
|
-
return hvx_vec_reduce_sum_f32x4(rsum0123);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
static inline HVX_Vector hvx_dot_f16_f16_aa_rx32(const void * restrict y,
|
|
117
|
-
const uint8_t * restrict x,
|
|
118
|
-
const size_t stride_x,
|
|
119
|
-
const size_t n,
|
|
120
|
-
float s) {
|
|
121
|
-
|
|
122
|
-
const size_t nvec = n / VLEN_FP16; // num full fp16 hvx vectors
|
|
123
|
-
const size_t nloe = n % VLEN_FP16; // leftover elements
|
|
124
|
-
|
|
125
|
-
HVX_Vector sums; // initialize at j = 0
|
|
126
|
-
const size_t stride_x_4 = stride_x * 4;
|
|
127
|
-
for (uint32_t j = 0; j < VLEN_FP32; j += 4) {
|
|
128
|
-
HVX_Vector sums_x4 = hvx_dot_f16_f16_aa_rx4(y, x, stride_x, nvec, nloe);
|
|
129
|
-
HVX_VectorPred pred = Q6_Q_vsetq_R(j * SIZEOF_FP32);
|
|
130
|
-
sums = Q6_V_vmux_QVV(pred, sums, sums_x4);
|
|
131
|
-
x += stride_x_4;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
sums = Q6_Vqf32_vmpy_VsfVsf(hvx_vec_splat_f32(s), sums);
|
|
135
|
-
return Q6_Vsf_equals_Vqf32(sums);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// MAD: y (F32) += x (F16) * s (F16)
|
|
139
|
-
static inline void hvx_mad_f32_f16_aa(float * restrict y, const void * restrict x, const __fp16 * restrict s, int n) {
|
|
140
|
-
const HVX_Vector * restrict vx0 = (const HVX_Vector *) x;
|
|
141
|
-
|
|
142
|
-
HVX_VectorPair * restrict vy_p = (HVX_VectorPair *) y;
|
|
143
|
-
HVX_Vector * restrict vy = (HVX_Vector *) y;
|
|
144
|
-
|
|
145
|
-
uint32_t nvec = n / VLEN_FP16; // num full fp16 hvx vectors
|
|
146
|
-
uint32_t nloe = n % VLEN_FP16; // leftover elements
|
|
147
|
-
|
|
148
|
-
HVX_Vector S0 = hvx_vec_splat_f16(*s);
|
|
149
|
-
|
|
150
|
-
uint32_t i = 0;
|
|
151
|
-
|
|
152
|
-
#pragma unroll(2)
|
|
153
|
-
for (i = 0; i < nvec; ++i) {
|
|
154
|
-
vy_p[i] = hvx_vec_mpyacc_f32_f16(vy_p[i], Q6_Vh_vshuff_Vh(vx0[i]), S0);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (nloe) {
|
|
158
|
-
HVX_VectorPair xy_p = vy_p[i];
|
|
159
|
-
xy_p = hvx_vec_mpyacc_f32_f16(xy_p, Q6_Vh_vshuff_Vh(vx0[i]), S0);
|
|
160
|
-
|
|
161
|
-
HVX_Vector xy = Q6_V_lo_W(xy_p);
|
|
162
|
-
i = 2 * i; // index for vy
|
|
163
|
-
|
|
164
|
-
if (nloe >= VLEN_FP32) {
|
|
165
|
-
vy[i] = xy;
|
|
166
|
-
nloe -= VLEN_FP32; ++i; xy = Q6_V_hi_W(xy_p);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (nloe) {
|
|
170
|
-
hvx_vec_store_a(&vy[i], nloe * 4, xy);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// MAD: y (F32) += x0 (F16) * s0 (F16) + x1 (F16) * s1 (F16)
|
|
176
|
-
static inline void hvx_mad_f32_f16_aa_rx2(float * restrict y, const void * restrict x0, const void * restrict x1,
|
|
177
|
-
const __fp16 * restrict s0, const __fp16 * restrict s1, int n) {
|
|
178
|
-
const HVX_Vector * restrict vx0 = (const HVX_Vector *) x0;
|
|
179
|
-
const HVX_Vector * restrict vx1 = (const HVX_Vector *) x1;
|
|
180
|
-
|
|
181
|
-
HVX_VectorPair * restrict vy_p = (HVX_VectorPair *) y;
|
|
182
|
-
HVX_Vector * restrict vy = (HVX_Vector *) y;
|
|
183
|
-
|
|
184
|
-
uint32_t nvec = n / VLEN_FP16; // num full fp16 hvx vectors
|
|
185
|
-
uint32_t nloe = n % VLEN_FP16; // leftover elements
|
|
186
|
-
|
|
187
|
-
HVX_Vector S0 = hvx_vec_splat_f16(*s0);
|
|
188
|
-
HVX_Vector S1 = hvx_vec_splat_f16(*s1);
|
|
189
|
-
|
|
190
|
-
uint32_t i = 0;
|
|
191
|
-
|
|
192
|
-
#pragma unroll(2)
|
|
193
|
-
for (i = 0; i < nvec; ++i) {
|
|
194
|
-
vy_p[i] = hvx_vec_mpyacc_f32_f16(vy_p[i], Q6_Vh_vshuff_Vh(vx0[i]), S0);
|
|
195
|
-
vy_p[i] = hvx_vec_mpyacc_f32_f16(vy_p[i], Q6_Vh_vshuff_Vh(vx1[i]), S1);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (nloe) {
|
|
199
|
-
HVX_VectorPair xy_p = vy_p[i];
|
|
200
|
-
xy_p = hvx_vec_mpyacc_f32_f16(xy_p, Q6_Vh_vshuff_Vh(vx0[i]), S0);
|
|
201
|
-
xy_p = hvx_vec_mpyacc_f32_f16(xy_p, Q6_Vh_vshuff_Vh(vx1[i]), S1);
|
|
202
|
-
|
|
203
|
-
HVX_Vector xy = Q6_V_lo_W(xy_p);
|
|
204
|
-
i = 2 * i; // index for vy
|
|
205
|
-
|
|
206
|
-
if (nloe >= VLEN_FP32) {
|
|
207
|
-
vy[i] = xy;
|
|
208
|
-
nloe -= VLEN_FP32; ++i; xy = Q6_V_hi_W(xy_p);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (nloe) {
|
|
212
|
-
hvx_vec_store_a(&vy[i], nloe * 4, xy);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
41
|
struct htp_fa_context {
|
|
218
42
|
const struct htp_ops_context * octx;
|
|
219
43
|
|
|
@@ -230,11 +54,12 @@ struct htp_fa_context {
|
|
|
230
54
|
|
|
231
55
|
float scale;
|
|
232
56
|
float max_bias;
|
|
233
|
-
|
|
57
|
+
__fp16 logit_softcap;
|
|
234
58
|
|
|
235
59
|
uint32_t n_head_log2;
|
|
236
60
|
float m0;
|
|
237
61
|
float m1;
|
|
62
|
+
__fp16 slopes[512];
|
|
238
63
|
|
|
239
64
|
uint32_t n_blocks;
|
|
240
65
|
|
|
@@ -251,39 +76,90 @@ struct htp_fa_context {
|
|
|
251
76
|
|
|
252
77
|
bool is_q_fp32;
|
|
253
78
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
static inline void hvx_scale_vec_f32_aa(uint8_t * restrict dst, const uint8_t * restrict src, const int n, HVX_Vector vs) {
|
|
258
|
-
assert((size_t) dst % 128 == 0);
|
|
259
|
-
assert((size_t) src % 128 == 0);
|
|
79
|
+
size_t size_q_block;
|
|
80
|
+
size_t size_vkq_acc;
|
|
260
81
|
|
|
261
|
-
|
|
262
|
-
|
|
82
|
+
uint8_t * spad_q;
|
|
83
|
+
uint8_t * spad_k;
|
|
84
|
+
uint8_t * spad_v;
|
|
85
|
+
uint8_t * spad_m;
|
|
86
|
+
uint8_t * spad_a;
|
|
263
87
|
|
|
264
|
-
|
|
265
|
-
|
|
88
|
+
uint64_t t_start;
|
|
89
|
+
};
|
|
266
90
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
91
|
+
struct hmx_fa_context {
|
|
92
|
+
const struct htp_ops_context * octx;
|
|
93
|
+
const struct htp_tensor * sinks; // attention sinks (src[4]), NULL if absent
|
|
94
|
+
bool pipeline; // true when n_kv_blocks >= FA_MIN_KV_BLOCKS && n_threads >= 2
|
|
95
|
+
uint32_t n_threads;
|
|
96
|
+
|
|
97
|
+
// Op parameters
|
|
98
|
+
__fp16 scale;
|
|
99
|
+
float max_bias;
|
|
100
|
+
__fp16 logit_softcap;
|
|
101
|
+
uint32_t n_head_log2;
|
|
102
|
+
float m0, m1;
|
|
103
|
+
|
|
104
|
+
// Dimensions
|
|
105
|
+
uint32_t DK, DV;
|
|
106
|
+
uint32_t n_kv; // kv_len
|
|
107
|
+
uint32_t n_kv_heads; // number of KV heads
|
|
108
|
+
uint32_t n_heads; // number of Q heads
|
|
109
|
+
uint32_t G; // GQA factor = n_heads / n_kv_heads
|
|
110
|
+
struct fastdiv_values div_G;
|
|
111
|
+
struct fastdiv_values src3_div2;
|
|
112
|
+
struct fastdiv_values src3_div3;
|
|
113
|
+
uint32_t n_kv_blocks;
|
|
114
|
+
uint32_t neq1; // Q token count
|
|
115
|
+
|
|
116
|
+
// Types
|
|
117
|
+
bool is_q_fp32;
|
|
118
|
+
bool is_dst_fp32;
|
|
119
|
+
|
|
120
|
+
// Dynamic block sizes
|
|
121
|
+
uint32_t Br; // Q tokens per block (before GQA expansion)
|
|
122
|
+
uint32_t Bc;
|
|
123
|
+
uint32_t g_br; // hex_align_up(G * Br, 32) - actual tile row dim
|
|
124
|
+
|
|
125
|
+
// VTCM buffers (allocated by vtcm_seq_alloc)
|
|
126
|
+
__fp16 * vtcm_q_tiles; // Q tile format [g_br, D]
|
|
127
|
+
__fp16 * vtcm_o_tiles[2]; // O ping-pong [g_br, D]
|
|
128
|
+
__fp16 * vtcm_k_fp16[2]; // K DMA double-buffer [Bc, D]
|
|
129
|
+
__fp16 * vtcm_v_fp16[2]; // V DMA double-buffer [Bc, D]
|
|
130
|
+
__fp16 * vtcm_k_tiles; // K tiles (transposed)
|
|
131
|
+
__fp16 * vtcm_v_tiles[2]; // V tiles (column-major, double-buffered)
|
|
132
|
+
__fp16 * vtcm_s_tiles; // S = QK^T [g_br, Bc]
|
|
133
|
+
__fp16 * vtcm_p_tiles; // P = softmax(S) [g_br, Bc]
|
|
134
|
+
__fp16 * vtcm_d_tiles; // Diagonal rescale [g_br, g_br]
|
|
135
|
+
HVX_Vector * vtcm_m_vec; // Row max [g_br]
|
|
136
|
+
HVX_Vector * vtcm_l_vec; // Row sum [g_br]
|
|
137
|
+
HVX_Vector * vtcm_s_rowmax; // Softmax intermediate [g_br]
|
|
138
|
+
HVX_Vector * vtcm_p_rowsum; // Softmax intermediate [g_br]
|
|
139
|
+
HVX_Vector * vtcm_row_bufs; // Per-thread softmax row scratch [n_threads][2][Bc/64]
|
|
140
|
+
uint8_t * vtcm_hmx_scales_id; // HMX output scales (identity)
|
|
141
|
+
uint8_t * vtcm_hmx_scales_qk; // HMX output scales (qk_scale)
|
|
142
|
+
__fp16 * vtcm_mask_buf; // VTCM mask buffer [Br * m_line], DMA'd per KV block
|
|
143
|
+
__fp16 * vtcm_slopes; // ALiBi slopes [g_br]
|
|
144
|
+
size_t row_buf_stride; // HVX vectors per row buffer (Bc/64)
|
|
145
|
+
size_t mask_buf_row_stride; // elements (__fp16) per row in mask buffer
|
|
146
|
+
size_t q_tile_bytes;
|
|
147
|
+
size_t o_tile_bytes;
|
|
148
|
+
size_t col_vec_bytes;
|
|
149
|
+
size_t d_tile_bytes;
|
|
150
|
+
bool mask_broadcast; // true when mask->ne[2] == 1 (head-independent, single 2D DMA)
|
|
151
|
+
dma_cache m_cache;
|
|
152
|
+
};
|
|
277
153
|
|
|
278
154
|
static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void * data) {
|
|
279
155
|
struct htp_fa_context * factx = (struct htp_fa_context *) data;
|
|
280
156
|
const struct htp_ops_context * octx = factx->octx;
|
|
281
|
-
const struct htp_tensor * q
|
|
282
|
-
const struct htp_tensor * k
|
|
283
|
-
const struct htp_tensor * v
|
|
284
|
-
const struct htp_tensor * mask =
|
|
285
|
-
const struct htp_tensor * sinks =
|
|
286
|
-
const struct htp_tensor * dst
|
|
157
|
+
const struct htp_tensor * q = octx->src[0];
|
|
158
|
+
const struct htp_tensor * k = octx->src[1];
|
|
159
|
+
const struct htp_tensor * v = octx->src[2];
|
|
160
|
+
const struct htp_tensor * mask = octx->src[3];
|
|
161
|
+
const struct htp_tensor * sinks = octx->src[4];
|
|
162
|
+
const struct htp_tensor * dst = octx->dst;
|
|
287
163
|
|
|
288
164
|
const uint32_t neq0 = q->ne[0];
|
|
289
165
|
const uint32_t neq1 = q->ne[1];
|
|
@@ -328,6 +204,8 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
328
204
|
|
|
329
205
|
if (ir0 >= ir1) return;
|
|
330
206
|
|
|
207
|
+
struct htp_thread_trace * tr = octx->ctx ? &octx->ctx->trace[ith] : NULL;
|
|
208
|
+
|
|
331
209
|
dma_queue * dma = octx->ctx->dma[ith];
|
|
332
210
|
|
|
333
211
|
const uint32_t DK = nek0;
|
|
@@ -338,13 +216,14 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
338
216
|
const size_t size_v_row = DV * sizeof(__fp16);
|
|
339
217
|
|
|
340
218
|
// Scratchpad buffers for Q, K, V, Mask, and VKQ32 accumulator
|
|
341
|
-
uint8_t * spad_q =
|
|
342
|
-
uint8_t * spad_k =
|
|
343
|
-
uint8_t * spad_v =
|
|
344
|
-
uint8_t * spad_m =
|
|
345
|
-
uint8_t * spad_a =
|
|
219
|
+
uint8_t * spad_q = factx->spad_q + factx->size_q_block * ith;
|
|
220
|
+
uint8_t * spad_k = factx->spad_k + factx->size_k_block * 2 * ith;
|
|
221
|
+
uint8_t * spad_v = factx->spad_v + factx->size_v_block * 2 * ith;
|
|
222
|
+
uint8_t * spad_m = factx->spad_m + (mask ? factx->size_m_block * HVX_FA_DMA_CACHE_SIZE : 0) * ith;
|
|
223
|
+
uint8_t * spad_a = factx->spad_a + factx->size_vkq_acc * ith;
|
|
346
224
|
|
|
347
|
-
|
|
225
|
+
dma_cache m_cache;
|
|
226
|
+
dma_cache_init(&m_cache, spad_m, factx->size_m_block, HVX_FA_DMA_CACHE_SIZE);
|
|
348
227
|
|
|
349
228
|
for (uint32_t ir = ir0; ir < ir1; ++ir) {
|
|
350
229
|
const uint32_t iq3 = fastdiv(ir, &factx->src0_div21);
|
|
@@ -361,9 +240,6 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
361
240
|
const uint8_t * q_row_ptr = (const uint8_t *) q->data + (iq1*nbq1 + iq2*nbq2 + iq3*nbq3);
|
|
362
241
|
dma_queue_push(dma, dma_make_ptr(spad_q, q_row_ptr), factx->size_q_row_padded, nbq1, size_q_row, 1);
|
|
363
242
|
|
|
364
|
-
// FARF(HIGH, "fa %u: prefetch Q: ir %u iq1 %u iq2 %u iq3 %u q_row_ptr %p size %u : usec %u", ith, ir, iq1, iq2, iq3, q_row_ptr, size_q_row,
|
|
365
|
-
// (unsigned)HAP_perf_qtimer_count_to_us(HAP_perf_get_qtimer_count() - factx->t_start));
|
|
366
|
-
|
|
367
243
|
const __fp16 * mp_base = NULL;
|
|
368
244
|
if (mask) {
|
|
369
245
|
const uint32_t im2 = fastmodulo(iq2, mask->ne[2], &factx->src3_div2);
|
|
@@ -389,22 +265,16 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
389
265
|
// Mask
|
|
390
266
|
if (mask) {
|
|
391
267
|
const uint8_t * m_src = (const uint8_t *) (mp_base + ic_start);
|
|
392
|
-
uint8_t * m_dst = spad_m + (ib % 2) * factx->size_m_block;
|
|
393
268
|
// Mask is 1D contiguous for this row
|
|
394
|
-
|
|
269
|
+
dma_cache_push(dma, &m_cache, m_src, current_block_size * 2, current_block_size * 2, current_block_size * 2, 1);
|
|
395
270
|
}
|
|
396
|
-
|
|
397
|
-
// FARF(HIGH, "fa %u: prefetch KVM: ir %u ib %u iq1 %u iq2 %u iq3 %u : size_k_row %u size_v_row %u bs %u: usec %u",
|
|
398
|
-
// ith, ir, ib, iq1, iq2, iq3,
|
|
399
|
-
// size_k_row, size_v_row, current_block_size,
|
|
400
|
-
// (unsigned)HAP_perf_qtimer_count_to_us(HAP_perf_get_qtimer_count() - factx->t_start));
|
|
401
271
|
}
|
|
402
272
|
|
|
403
273
|
const uint32_t h = iq2; // head index
|
|
404
|
-
const
|
|
274
|
+
const __fp16 slope = factx->slopes[h];
|
|
405
275
|
|
|
406
276
|
HVX_Vector S_vec = hvx_vec_splat_f32(0.0f);
|
|
407
|
-
HVX_Vector M_vec = hvx_vec_splat_f32(
|
|
277
|
+
HVX_Vector M_vec = hvx_vec_splat_f32(HTP_FA_M_INITIAL_VAL);
|
|
408
278
|
|
|
409
279
|
// Clear accumulator
|
|
410
280
|
hvx_splat_f32_a(spad_a, 0, DV);
|
|
@@ -416,6 +286,7 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
416
286
|
}
|
|
417
287
|
|
|
418
288
|
const HVX_Vector slope_vec = hvx_vec_splat_f16(slope);
|
|
289
|
+
const HVX_Vector v_neg_inf = Q6_Vh_vsplat_R(0xfbff);
|
|
419
290
|
for (uint32_t ib = 0; ib < factx->n_blocks; ++ib) {
|
|
420
291
|
const uint32_t ic_start = ib * FLASH_ATTN_BLOCK_SIZE;
|
|
421
292
|
const uint32_t current_block_size = MIN(FLASH_ATTN_BLOCK_SIZE, nek1 - ic_start);
|
|
@@ -425,117 +296,101 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
425
296
|
uint8_t * v_base = dma_queue_pop(dma).dst; // V
|
|
426
297
|
__fp16 * m_base = mask ? dma_queue_pop(dma).dst : NULL; // M
|
|
427
298
|
|
|
428
|
-
|
|
429
|
-
// ith, ir, ib, iq1, iq2, iq3, q_ptr_vtcm,
|
|
430
|
-
// (unsigned)HAP_perf_qtimer_count_to_us(HAP_perf_get_qtimer_count() - factx->t_start));
|
|
299
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_QK, ir);
|
|
431
300
|
|
|
432
301
|
// Inner loop processing the block from VTCM
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
HVX_Vector scores = hvx_dot_f16_f16_aa_rx32(q_ptr_vtcm, k_base + ic * factx->size_k_row_padded, factx->size_k_row_padded, DK, factx->scale);
|
|
441
|
-
|
|
442
|
-
// 2. Softcap
|
|
443
|
-
if (factx->logit_softcap != 0.0f) {
|
|
444
|
-
scores = hvx_vec_tanh_f32(scores);
|
|
445
|
-
scores = Q6_Vqf32_vmpy_VsfVsf(scores, logit_cap);
|
|
446
|
-
scores = Q6_Vsf_equals_Vqf32(scores);
|
|
447
|
-
}
|
|
302
|
+
// 1. Compute scores (64 elements FP16)
|
|
303
|
+
HVX_Vector scores_f16 = Q6_V_vzero();
|
|
304
|
+
if (current_block_size > 0) {
|
|
305
|
+
HVX_Vector scores0 = hvx_dot_f16_f16_aa_rx32(q_ptr_vtcm, k_base, factx->size_k_row_padded, DK, factx->scale);
|
|
306
|
+
HVX_Vector scores1 = (current_block_size > 32) ? hvx_dot_f16_f16_aa_rx32(q_ptr_vtcm, k_base + 32 * factx->size_k_row_padded, factx->size_k_row_padded, DK, factx->scale) : Q6_V_vzero();
|
|
307
|
+
scores_f16 = hvx_vec_f32_to_f16(scores0, scores1);
|
|
308
|
+
}
|
|
448
309
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
scores = Q6_Vqf32_vadd_Vqf32Vsf(add_val, scores);
|
|
456
|
-
scores = Q6_Vsf_equals_Vqf32(scores);
|
|
457
|
-
}
|
|
310
|
+
// 2. Softcap (in FP16)
|
|
311
|
+
if (factx->logit_softcap != 0.0f) {
|
|
312
|
+
const HVX_Vector v_cap = hvx_vec_splat_f16(factx->logit_softcap);
|
|
313
|
+
scores_f16 = hvx_vec_tanh_f16(scores_f16);
|
|
314
|
+
scores_f16 = hvx_vec_mul_f16_f16(scores_f16, v_cap);
|
|
315
|
+
}
|
|
458
316
|
|
|
459
|
-
|
|
460
|
-
|
|
317
|
+
HVX_VectorPred q_tail_keep = Q6_Q_vsetq2_R(current_block_size * sizeof(__fp16));
|
|
318
|
+
|
|
319
|
+
// 3. Mask (in FP16)
|
|
320
|
+
if (mask) {
|
|
321
|
+
HVX_Vector m_vals_f16 = *(const HVX_UVector *) m_base;
|
|
322
|
+
HVX_Vector vinf = Q6_Vh_vsplat_R(0xFC00);
|
|
323
|
+
HVX_Vector vmin = Q6_Vh_vsplat_R(0xFBFF);
|
|
324
|
+
HVX_VectorPred is_inf = Q6_Q_vcmp_eq_VhVh(m_vals_f16, vinf);
|
|
325
|
+
m_vals_f16 = Q6_V_vmux_QVV(is_inf, vmin, m_vals_f16);
|
|
326
|
+
|
|
327
|
+
HVX_Vector m_scaled = hvx_vec_mul_f16_f16(m_vals_f16, slope_vec);
|
|
328
|
+
scores_f16 = Q6_V_vmux_QVV(q_tail_keep, hvx_vec_add_f16_f16(scores_f16, m_scaled), v_neg_inf);
|
|
329
|
+
} else {
|
|
330
|
+
scores_f16 = Q6_V_vmux_QVV(q_tail_keep, scores_f16, v_neg_inf);
|
|
461
331
|
}
|
|
462
332
|
|
|
333
|
+
// Compute block max in FP16
|
|
334
|
+
HVX_Vector v_max_f16 = hvx_vec_reduce_max_f16(scores_f16);
|
|
335
|
+
HVX_Vector v_max = Q6_V_lo_W(hvx_vec_f16_to_f32(v_max_f16)); // splat block max in FP32
|
|
336
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_QK, ir);
|
|
337
|
+
|
|
338
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_SFM, ir);
|
|
463
339
|
{
|
|
340
|
+
const HVX_Vector v_log2e = hvx_vec_splat_f16(EXP_LOG2E_F);
|
|
341
|
+
|
|
464
342
|
// 4. Online Softmax Update
|
|
465
343
|
HVX_Vector M_new_vec = Q6_Vsf_vmax_VsfVsf(v_max, M_vec);
|
|
466
|
-
HVX_Vector diff_vec =
|
|
467
|
-
|
|
344
|
+
HVX_Vector diff_vec = HVX_OP_SUB_F32(M_vec, M_new_vec);
|
|
345
|
+
|
|
346
|
+
HVX_Vector diff_f16 = hvx_vec_f32_to_f16(diff_vec, diff_vec);
|
|
347
|
+
HVX_Vector diff_base2 = hvx_vec_mul_f16_f16(diff_f16, v_log2e);
|
|
348
|
+
HVX_Vector ms_f16 = hvx_vec_exp2_f16(diff_base2);
|
|
349
|
+
HVX_Vector ms_vec = Q6_V_lo_W(hvx_vec_f16_to_f32(ms_f16));
|
|
350
|
+
|
|
468
351
|
M_vec = M_new_vec;
|
|
469
352
|
|
|
470
353
|
hvx_scale_vec_f32_aa((uint8_t *) VKQ32, (const uint8_t *) VKQ32, DV, ms_vec);
|
|
471
354
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
HVX_Vector scores_shifted = Q6_Vqf32_vsub_VsfVsf(scores, M_vec);
|
|
476
|
-
HVX_Vector P = hvx_vec_exp_f32(Q6_Vsf_equals_Vqf32(scores_shifted));
|
|
355
|
+
// Compute P = exp2((S - M) * log2(e)) in FP16
|
|
356
|
+
HVX_Vector v_m_vec_f16 = hvx_vec_f32_to_f16(M_vec, M_vec);
|
|
357
|
+
HVX_Vector v_s_minus_m = Q6_Vqf16_vsub_VhfVhf(scores_f16, v_m_vec_f16);
|
|
477
358
|
|
|
478
|
-
|
|
359
|
+
HVX_Vector v_s_minus_m_base2 = hvx_vec_mul_f16_f16(Q6_Vhf_equals_Vqf16(v_s_minus_m), v_log2e);
|
|
479
360
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
hvx_vec_f32_to_f16_a(p_arr, P, hvx_vec_splat_f32(0));
|
|
361
|
+
HVX_Vector P = hvx_vec_exp2_f16(v_s_minus_m_base2);
|
|
362
|
+
P = Q6_V_vmux_QVV(q_tail_keep, P, Q6_V_vzero());
|
|
483
363
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
364
|
+
// Convert P to FP32 to update the running sum S_vec
|
|
365
|
+
HVX_VectorPair P_pair = hvx_vec_f16_to_f32(P);
|
|
366
|
+
HVX_Vector P0 = Q6_V_lo_W(P_pair);
|
|
367
|
+
HVX_Vector P1 = Q6_V_hi_W(P_pair);
|
|
368
|
+
HVX_Vector p_sum_vec = hvx_vec_reduce_sum_f32(HVX_OP_ADD_F32(P0, P1));
|
|
490
369
|
|
|
491
|
-
|
|
492
|
-
S_vec = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(S_vec, ms_vec)), p_sum_vec));
|
|
493
|
-
}
|
|
370
|
+
S_vec = HVX_OP_ADD_F32(HVX_OP_MUL_F32(S_vec, ms_vec), p_sum_vec);
|
|
494
371
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
float S = hvx_vec_get_f32(S_vec);
|
|
499
|
-
|
|
500
|
-
// Leftover
|
|
501
|
-
for (; ic < current_block_size; ++ic) {
|
|
502
|
-
float s_val;
|
|
503
|
-
const uint8_t * k_ptr = k_base + ic * factx->size_k_row_padded;
|
|
504
|
-
hvx_dot_f16_f16_aa(&s_val, q_ptr_vtcm, k_ptr, DK, factx->scale);
|
|
505
|
-
if (factx->logit_softcap != 0.0f) {
|
|
506
|
-
s_val = factx->logit_softcap * tanhf(s_val);
|
|
507
|
-
}
|
|
372
|
+
// 5. Accumulate V (F16 * F16 -> F32 accumulator)
|
|
373
|
+
__fp16 __attribute__((aligned(128))) p_arr[VLEN_FP16];
|
|
374
|
+
hvx_vec_store_a(p_arr, 128, P);
|
|
508
375
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
376
|
+
for (uint32_t j = 0; j < current_block_size; j += 2) {
|
|
377
|
+
if (j + 1 == current_block_size) {
|
|
378
|
+
if (p_arr[j] != 0.0f) {
|
|
379
|
+
const uint8_t * v_ptr = v_base + j * factx->size_v_row_padded;
|
|
380
|
+
hvx_mad_f32_f16_aa(VKQ32, v_ptr, (p_arr + j), DV);
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
512
383
|
}
|
|
513
384
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
if (s_val > M) {
|
|
518
|
-
M = s_val;
|
|
519
|
-
HVX_Vector diff_vec = hvx_vec_splat_f32(Mold - M);
|
|
520
|
-
HVX_Vector ms_vec = hvx_vec_exp_f32(diff_vec);
|
|
521
|
-
hvx_scale_vec_f32_aa((uint8_t *) VKQ32, (const uint8_t *) VKQ32, DV, ms_vec);
|
|
522
|
-
|
|
523
|
-
float ms = hvx_vec_get_f32(ms_vec);
|
|
524
|
-
S = S * ms + vs;
|
|
525
|
-
} else {
|
|
526
|
-
HVX_Vector diff_vec = hvx_vec_splat_f32(s_val - M);
|
|
527
|
-
vs = hvx_vec_get_f32(hvx_vec_exp_f32(diff_vec));
|
|
528
|
-
S += vs;
|
|
385
|
+
if (p_arr[j] == 0.0f && p_arr[j + 1] == 0.0f) {
|
|
386
|
+
continue;
|
|
529
387
|
}
|
|
530
388
|
|
|
531
|
-
const uint8_t * v_ptr = v_base +
|
|
532
|
-
|
|
533
|
-
hvx_mad_f32_f16_aa(VKQ32, v_ptr, &vs, DV);
|
|
389
|
+
const uint8_t * v_ptr = v_base + j * factx->size_v_row_padded;
|
|
390
|
+
hvx_mad_f32_f16_aa_rx2(VKQ32, v_ptr, v_ptr + factx->size_v_row_padded, (p_arr + j), (p_arr + j + 1), DV);
|
|
534
391
|
}
|
|
535
|
-
|
|
536
|
-
M_vec = hvx_vec_splat_f32(M);
|
|
537
|
-
S_vec = hvx_vec_splat_f32(S);
|
|
538
392
|
}
|
|
393
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_SFM, ir);
|
|
539
394
|
|
|
540
395
|
// Issue DMA for next+1 block (if exists)
|
|
541
396
|
if (ib + 2 < factx->n_blocks) {
|
|
@@ -554,16 +409,12 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
554
409
|
// Mask
|
|
555
410
|
if (mask) {
|
|
556
411
|
const uint8_t * m_src = (const uint8_t *) (mp_base + next_ic_start);
|
|
557
|
-
|
|
412
|
+
dma_cache_push(dma, &m_cache, m_src, next_block_size * 2, next_block_size * 2, next_block_size * 2, 1);
|
|
558
413
|
}
|
|
559
|
-
|
|
560
|
-
// FARF(HIGH, "fa %u: prefetch KVM: ir %u ib %u : iq1 %u iq2 %u iq3 %u : size_k_row %u size_v_row %u bs %u: usec %u",
|
|
561
|
-
// ith, ir, next_ib, iq1, iq2, iq3,
|
|
562
|
-
// size_k_row, size_v_row, next_block_size,
|
|
563
|
-
// (unsigned)HAP_perf_qtimer_count_to_us(HAP_perf_get_qtimer_count() - factx->t_start));
|
|
564
414
|
}
|
|
565
415
|
}
|
|
566
416
|
|
|
417
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_O_PROC, ir);
|
|
567
418
|
// sinks
|
|
568
419
|
float M = hvx_vec_get_f32(M_vec);
|
|
569
420
|
float S = hvx_vec_get_f32(S_vec);
|
|
@@ -592,119 +443,1646 @@ static void flash_attn_ext_f16_thread(unsigned int nth, unsigned int ith, void *
|
|
|
592
443
|
|
|
593
444
|
// Store result
|
|
594
445
|
// dst indices
|
|
595
|
-
const
|
|
596
|
-
const
|
|
597
|
-
const
|
|
446
|
+
const uint32_t i1 = iq1;
|
|
447
|
+
const uint32_t i2 = iq2;
|
|
448
|
+
const uint32_t i3 = iq3;
|
|
598
449
|
|
|
599
|
-
// dst is permuted
|
|
600
|
-
|
|
450
|
+
// dst is permuted: [DV, n_heads, n_tokens, n_seq]
|
|
451
|
+
// head stride is nb[1], token stride is nb[2], batch stride is nb[3]
|
|
452
|
+
uint8_t * dst_ptr = (uint8_t *) dst->data + i2 * dst->nb[1] + i1 * dst->nb[2] + i3 * dst->nb[3];
|
|
601
453
|
|
|
602
454
|
if (dst->type == HTP_TYPE_F32) {
|
|
603
455
|
hvx_copy_f32_ua(dst_ptr, (uint8_t *) VKQ32, DV);
|
|
604
456
|
} else if (dst->type == HTP_TYPE_F16) {
|
|
605
457
|
hvx_copy_f16_f32_ua(dst_ptr, (uint8_t *) VKQ32, DV);
|
|
606
458
|
}
|
|
459
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_O_PROC, ir);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ============================================================================
|
|
464
|
+
// HMX Phase args and thread logic
|
|
465
|
+
// ============================================================================
|
|
466
|
+
|
|
467
|
+
typedef struct {
|
|
468
|
+
struct hmx_fa_context * factx;
|
|
469
|
+
uint32_t kv_rows;
|
|
470
|
+
size_t src_stride;
|
|
471
|
+
void * curr_k;
|
|
472
|
+
uint32_t kv_start;
|
|
473
|
+
uint32_t rows_per_t;
|
|
474
|
+
} fa_k_int_args_t;
|
|
475
|
+
|
|
476
|
+
static void fa_k_interleave_thread(unsigned int n, unsigned int i, void * data) {
|
|
477
|
+
fa_k_int_args_t * args = (fa_k_int_args_t *) data;
|
|
478
|
+
struct hmx_fa_context * factx = args->factx;
|
|
479
|
+
|
|
480
|
+
const uint32_t total_rows = args->kv_rows;
|
|
481
|
+
const uint32_t rows_per_t = args->rows_per_t;
|
|
482
|
+
const uint32_t start = i * rows_per_t;
|
|
483
|
+
const uint32_t end = (uint32_t) hex_smin(start + rows_per_t, total_rows);
|
|
484
|
+
|
|
485
|
+
if (start >= total_rows) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
490
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_K_PREP, (uint16_t) (args->kv_start + start));
|
|
491
|
+
hmx_interleave_rows_to_tiles(factx->vtcm_k_tiles, (const __fp16 *) args->curr_k, total_rows, factx->DK,
|
|
492
|
+
args->src_stride, start, end);
|
|
493
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_K_PREP, (uint16_t) (args->kv_start + start));
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
static void fa_phase_k_interleave(struct hmx_fa_context * factx, uint32_t kv_rows, size_t src_stride, void * curr_k, uint32_t kv_start) {
|
|
497
|
+
worker_pool_context_t wp = factx->octx->ctx->worker_pool;
|
|
498
|
+
uint32_t n = 1;
|
|
499
|
+
if (factx->n_threads > 1 && kv_rows >= factx->n_threads * 2) {
|
|
500
|
+
n = factx->n_threads;
|
|
501
|
+
}
|
|
502
|
+
uint32_t rows_per_t = hex_align_up(hmx_ceil_div(kv_rows, n), 2);
|
|
503
|
+
fa_k_int_args_t args = { factx, kv_rows, src_stride, curr_k, kv_start, rows_per_t };
|
|
504
|
+
if (n > 1) {
|
|
505
|
+
worker_pool_run_func(wp, fa_k_interleave_thread, &args, n);
|
|
506
|
+
} else {
|
|
507
|
+
fa_k_interleave_thread(1, 0, &args);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
typedef struct {
|
|
512
|
+
struct hmx_fa_context * factx;
|
|
513
|
+
uint32_t kv_rows;
|
|
514
|
+
size_t src_stride;
|
|
515
|
+
void * v_src;
|
|
516
|
+
void * v_tiles_dst;
|
|
517
|
+
size_t n_col_tiles;
|
|
518
|
+
uint32_t kv_start;
|
|
519
|
+
uint32_t rows_per_t;
|
|
520
|
+
} fa_v_int_args_t;
|
|
521
|
+
|
|
522
|
+
static void fa_v_interleave_thread(unsigned int n, unsigned int i, void * data) {
|
|
523
|
+
fa_v_int_args_t * args = (fa_v_int_args_t *) data;
|
|
524
|
+
struct hmx_fa_context * factx = args->factx;
|
|
525
|
+
|
|
526
|
+
const uint32_t total_rows = args->kv_rows;
|
|
527
|
+
const uint32_t rows_per_t = args->rows_per_t;
|
|
528
|
+
const uint32_t start = i * rows_per_t;
|
|
529
|
+
const uint32_t end = (uint32_t) hex_smin(start + rows_per_t, total_rows);
|
|
530
|
+
|
|
531
|
+
if (start >= total_rows) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
__fp16 * v_tiles_dst = (__fp16 *) args->v_tiles_dst;
|
|
536
|
+
|
|
537
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
538
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_V_PREP, (uint16_t) (args->kv_start + start));
|
|
539
|
+
hmx_interleave_cols_to_tiles(v_tiles_dst, (const __fp16 *) args->v_src, total_rows, factx->DV,
|
|
540
|
+
args->src_stride, (uint32_t) args->n_col_tiles, start, end);
|
|
541
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_V_PREP, (uint16_t) (args->kv_start + start));
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
static void fa_phase_v_interleave(struct hmx_fa_context * factx,
|
|
545
|
+
uint32_t kv_rows,
|
|
546
|
+
size_t src_stride,
|
|
547
|
+
void * v_src,
|
|
548
|
+
void * v_tiles_dst,
|
|
549
|
+
size_t n_col_tiles,
|
|
550
|
+
uint32_t kv_start) {
|
|
551
|
+
worker_pool_context_t wp = factx->octx->ctx->worker_pool;
|
|
552
|
+
uint32_t n = 1;
|
|
553
|
+
if (factx->n_threads > 1 && kv_rows >= factx->n_threads * 2) {
|
|
554
|
+
n = factx->n_threads;
|
|
555
|
+
}
|
|
556
|
+
uint32_t rows_per_t = hex_align_up(hmx_ceil_div(kv_rows, n), 2);
|
|
557
|
+
fa_v_int_args_t args = { factx, kv_rows, src_stride, v_src, v_tiles_dst, n_col_tiles, kv_start, rows_per_t };
|
|
558
|
+
if (n > 1) {
|
|
559
|
+
worker_pool_run_func(wp, fa_v_interleave_thread, &args, n);
|
|
560
|
+
} else {
|
|
561
|
+
fa_v_interleave_thread(1, 0, &args);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
typedef struct {
|
|
566
|
+
struct hmx_fa_context * factx;
|
|
567
|
+
const struct htp_tensor * q;
|
|
568
|
+
uint32_t q_start;
|
|
569
|
+
uint32_t kv_head;
|
|
570
|
+
uint32_t ib3;
|
|
571
|
+
size_t n_rows_g;
|
|
572
|
+
size_t rows_per_t;
|
|
573
|
+
size_t n_rows_q;
|
|
574
|
+
bool q_transposed;
|
|
575
|
+
atomic_uint barrier;
|
|
576
|
+
} fa_q_load_args_t;
|
|
577
|
+
|
|
578
|
+
static void fa_q_load_thread(unsigned int n, unsigned int i, void * data) {
|
|
579
|
+
fa_q_load_args_t * args = (fa_q_load_args_t *) data;
|
|
580
|
+
struct hmx_fa_context * factx = args->factx;
|
|
581
|
+
|
|
582
|
+
const size_t n_rows_g = args->n_rows_g;
|
|
583
|
+
const size_t G = factx->G;
|
|
584
|
+
const size_t DK = factx->DK;
|
|
585
|
+
|
|
586
|
+
// Partition the padded Q rows (g_br) across threads.
|
|
587
|
+
// Keep start/end even so r and r+1 are always in the same thread's range.
|
|
588
|
+
const size_t rows_per_t = args->rows_per_t;
|
|
589
|
+
const size_t start = (size_t) i * rows_per_t;
|
|
590
|
+
const size_t end = hex_smin(start + rows_per_t, factx->g_br);
|
|
591
|
+
|
|
592
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
593
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_Q_PREP, (uint16_t) (args->q_start * G + start));
|
|
594
|
+
|
|
595
|
+
// Parallel initialization of per-block state
|
|
596
|
+
{
|
|
597
|
+
const uint32_t g_br = factx->g_br;
|
|
598
|
+
const uint32_t DV = factx->DV;
|
|
599
|
+
|
|
600
|
+
const size_t col_vec_bytes = factx->col_vec_bytes;
|
|
601
|
+
const size_t d_tile_bytes = factx->d_tile_bytes;
|
|
602
|
+
|
|
603
|
+
// Initialize vtcm_l_vec & vtcm_m_vec
|
|
604
|
+
const size_t l_bytes_per_t = hex_align_up(col_vec_bytes / n, 128);
|
|
605
|
+
const size_t l_start = i * l_bytes_per_t;
|
|
606
|
+
const size_t l_end = hex_smin(l_start + l_bytes_per_t, col_vec_bytes);
|
|
607
|
+
|
|
608
|
+
const size_t m_bytes_per_t = hex_align_up(col_vec_bytes / n, 128);
|
|
609
|
+
const size_t m_start = i * m_bytes_per_t;
|
|
610
|
+
const size_t m_end = hex_smin(m_start + m_bytes_per_t, col_vec_bytes);
|
|
611
|
+
|
|
612
|
+
if (factx->sinks) {
|
|
613
|
+
const float * sinks_data = (const float *) (uintptr_t) factx->sinks->data;
|
|
614
|
+
float * m_vec = (float *) factx->vtcm_m_vec;
|
|
615
|
+
const size_t r_start = l_start / sizeof(float);
|
|
616
|
+
const size_t r_end = l_end / sizeof(float);
|
|
617
|
+
const float scale_factor = EXP_LOG2E_F;
|
|
618
|
+
|
|
619
|
+
const HVX_Vector v_scale = hvx_vec_splat_f32(scale_factor);
|
|
620
|
+
|
|
621
|
+
for (size_t r = r_start; r < r_end; r += 32) {
|
|
622
|
+
HVX_VectorAlias local_m;
|
|
623
|
+
for (size_t j = 0; j < 32; ++j) {
|
|
624
|
+
size_t curr_r = r + j;
|
|
625
|
+
if (curr_r < n_rows_g) {
|
|
626
|
+
const size_t h_idx = fastmodulo(curr_r, G, &factx->div_G);
|
|
627
|
+
const size_t head = args->kv_head * G + h_idx;
|
|
628
|
+
local_m.fp32[j] = sinks_data[head];
|
|
629
|
+
} else {
|
|
630
|
+
local_m.fp32[j] = HTP_FA_M_INITIAL_VAL;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
HVX_Vector v_scaled = HVX_OP_MUL_F32(local_m.v, v_scale);
|
|
634
|
+
*(HVX_Vector *) (m_vec + r) = v_scaled;
|
|
635
|
+
}
|
|
636
|
+
if (l_start < col_vec_bytes) {
|
|
637
|
+
hvx_splat_u8_a((char *) factx->vtcm_l_vec + l_start, 0, l_end - l_start);
|
|
638
|
+
}
|
|
639
|
+
} else {
|
|
640
|
+
if (l_start < col_vec_bytes) {
|
|
641
|
+
hvx_splat_u8_a((char *) factx->vtcm_l_vec + l_start, 0, l_end - l_start);
|
|
642
|
+
}
|
|
643
|
+
if (m_start < col_vec_bytes) {
|
|
644
|
+
hvx_splat_f32_a((char *) factx->vtcm_m_vec + m_start, HTP_FA_M_INITIAL_VAL, (m_end - m_start) / sizeof(float));
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Initialize vtcm_d_tiles to 0
|
|
649
|
+
const size_t d_bytes_per_t = hex_align_up(d_tile_bytes / n, 128);
|
|
650
|
+
const size_t d_start = i * d_bytes_per_t;
|
|
651
|
+
const size_t d_end = hex_smin(d_start + d_bytes_per_t, d_tile_bytes);
|
|
652
|
+
if (d_start < d_tile_bytes) {
|
|
653
|
+
hvx_splat_u8_a((char *) factx->vtcm_d_tiles + d_start, 0, d_end - d_start);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (start < factx->g_br) {
|
|
658
|
+
const struct htp_tensor * q = args->q;
|
|
659
|
+
const uint32_t q_start = args->q_start;
|
|
660
|
+
const uint32_t kv_head = args->kv_head;
|
|
661
|
+
const uint32_t ib3 = args->ib3;
|
|
662
|
+
|
|
663
|
+
assert(factx->DK == factx->DV);
|
|
664
|
+
|
|
665
|
+
const size_t o_tile_bytes = factx->o_tile_bytes;
|
|
666
|
+
const bool use_q_dma = (2 * o_tile_bytes >= factx->g_br * DK * (factx->is_q_fp32 ? 4 : 2));
|
|
667
|
+
|
|
668
|
+
__fp16 * q_tiles = factx->vtcm_q_tiles;
|
|
669
|
+
if (use_q_dma) {
|
|
670
|
+
const size_t g_rows_end = hex_smin(end, n_rows_g);
|
|
671
|
+
const uint32_t d_limit = factx->is_q_fp32 ? DK / 32 : DK / 64;
|
|
672
|
+
|
|
673
|
+
uint8_t * q_flat = (uint8_t *) factx->vtcm_o_tiles[0];
|
|
674
|
+
if (factx->is_q_fp32) {
|
|
675
|
+
switch (d_limit) {
|
|
676
|
+
case 2: hmx_fa_q_prep_fp32_d2(q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, args->q_transposed); break;
|
|
677
|
+
case 4: hmx_fa_q_prep_fp32_d4(q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, args->q_transposed); break;
|
|
678
|
+
default: hmx_fa_q_prep_fp32( q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, d_limit, args->q_transposed); break;
|
|
679
|
+
}
|
|
680
|
+
} else {
|
|
681
|
+
switch (d_limit) {
|
|
682
|
+
case 1: hmx_fa_q_prep_fp16_d1(q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, args->q_transposed); break;
|
|
683
|
+
case 2: hmx_fa_q_prep_fp16_d2(q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, args->q_transposed); break;
|
|
684
|
+
default: hmx_fa_q_prep_fp16( q_tiles, q_flat, start, end, g_rows_end, DK, G, args->n_rows_q, &factx->div_G, d_limit, args->q_transposed); break;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
} else {
|
|
688
|
+
// Fallback: direct-from-DDR/L2 path
|
|
689
|
+
hmx_fa_q_prep_fallback(q_tiles, q->data, q->nb[1], q->nb[2], q->nb[3],
|
|
690
|
+
q_start, kv_head, ib3, start, end, n_rows_g, G, DK, factx->is_q_fp32, &factx->div_G);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Synchronize threads before zeroing out vtcm_o_tiles[0] to prevent race condition
|
|
695
|
+
if (n > 1) {
|
|
696
|
+
atomic_fetch_sub(&args->barrier, 1);
|
|
697
|
+
while (atomic_load(&args->barrier) > 0) {
|
|
698
|
+
// spin wait
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// Zero out vtcm_o_tiles[0] as it was used as temp_q_vtcm
|
|
703
|
+
{
|
|
704
|
+
const uint32_t g_br = factx->g_br;
|
|
705
|
+
const uint32_t DV = factx->DV;
|
|
706
|
+
const size_t o_tile_bytes = factx->o_tile_bytes;
|
|
707
|
+
const size_t o_bytes_per_t = hex_align_up(o_tile_bytes / n, 128);
|
|
708
|
+
const size_t o_start = i * o_bytes_per_t;
|
|
709
|
+
const size_t o_end = hex_smin(o_start + o_bytes_per_t, o_tile_bytes);
|
|
710
|
+
if (o_start < o_tile_bytes) {
|
|
711
|
+
hvx_splat_u8_a((char *) factx->vtcm_o_tiles[0] + o_start, 0, o_end - o_start);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_Q_PREP, (uint16_t) (args->q_start * G + start));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
static void fa_phase_q_load(struct hmx_fa_context * factx,
|
|
718
|
+
const struct htp_tensor * q,
|
|
719
|
+
uint32_t q_start,
|
|
720
|
+
uint32_t kv_head,
|
|
721
|
+
uint32_t ib3,
|
|
722
|
+
size_t n_rows_g) {
|
|
723
|
+
worker_pool_context_t wp = factx->octx->ctx->worker_pool;
|
|
724
|
+
uint32_t n = 1;
|
|
725
|
+
if (factx->n_threads > 1 && n_rows_g >= (size_t) (factx->n_threads * 2)) {
|
|
726
|
+
n = factx->n_threads;
|
|
727
|
+
}
|
|
728
|
+
size_t rows_per_t = hex_align_up(hmx_ceil_div(factx->g_br, n), 2);
|
|
729
|
+
const uint32_t n_rows_q = hex_smin(factx->Br, factx->neq1 - q_start);
|
|
730
|
+
fa_q_load_args_t args;
|
|
731
|
+
args.factx = factx;
|
|
732
|
+
args.q = q;
|
|
733
|
+
args.q_start = q_start;
|
|
734
|
+
args.kv_head = kv_head;
|
|
735
|
+
args.ib3 = ib3;
|
|
736
|
+
args.n_rows_g = n_rows_g;
|
|
737
|
+
args.rows_per_t = rows_per_t;
|
|
738
|
+
args.n_rows_q = n_rows_q;
|
|
739
|
+
args.q_transposed = q->nb[1] < q->nb[2];
|
|
740
|
+
atomic_init(&args.barrier, n);
|
|
741
|
+
if (n > 1) {
|
|
742
|
+
worker_pool_run_func(wp, fa_q_load_thread, &args, n);
|
|
743
|
+
} else {
|
|
744
|
+
fa_q_load_thread(1, 0, &args);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
typedef struct {
|
|
749
|
+
struct hmx_fa_context * factx;
|
|
750
|
+
const struct htp_tensor * dst;
|
|
751
|
+
const __fp16 * o_tile_src;
|
|
752
|
+
uint32_t q_start;
|
|
753
|
+
uint32_t kv_head;
|
|
754
|
+
uint32_t ib3;
|
|
755
|
+
size_t n_rows_g;
|
|
756
|
+
size_t rows_per_t;
|
|
757
|
+
} fa_o_store_args_t;
|
|
758
|
+
|
|
759
|
+
static void fa_o_store_thread_f32(unsigned int n, unsigned int i, void * data) {
|
|
760
|
+
fa_o_store_args_t * args = (fa_o_store_args_t *) data;
|
|
761
|
+
struct hmx_fa_context * factx = args->factx;
|
|
762
|
+
|
|
763
|
+
const size_t n_rows_g = args->n_rows_g;
|
|
764
|
+
const size_t G = factx->G;
|
|
765
|
+
const size_t DV = factx->DV;
|
|
766
|
+
|
|
767
|
+
const size_t rows_per_t = args->rows_per_t;
|
|
768
|
+
const size_t start = (size_t) i * rows_per_t;
|
|
769
|
+
const size_t end = hex_smin(start + rows_per_t, n_rows_g);
|
|
770
|
+
|
|
771
|
+
if (start >= n_rows_g) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
776
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) (args->q_start * G + start));
|
|
777
|
+
|
|
778
|
+
const struct htp_tensor * dst = args->dst;
|
|
779
|
+
const __fp16 * o_tile_src = args->o_tile_src;
|
|
780
|
+
const uint32_t q_start = args->q_start;
|
|
781
|
+
const uint32_t kv_head = args->kv_head;
|
|
782
|
+
const uint32_t ib3 = args->ib3;
|
|
783
|
+
|
|
784
|
+
for (size_t r = start; r < end; ++r) {
|
|
785
|
+
const size_t q_idx = fastdiv(r, &factx->div_G);
|
|
786
|
+
const size_t h_idx = fastmodulo(r, G, &factx->div_G);
|
|
787
|
+
|
|
788
|
+
float * out = (float *) ((uint8_t *) dst->data + (kv_head * G + h_idx) * dst->nb[1] +
|
|
789
|
+
(q_start + q_idx) * dst->nb[2] + ib3 * dst->nb[3]);
|
|
790
|
+
|
|
791
|
+
size_t r0 = r / HMX_FP16_TILE_N_ROWS;
|
|
792
|
+
size_t r1 = r % HMX_FP16_TILE_N_ROWS;
|
|
793
|
+
const __fp16 * tile_row_base = o_tile_src + r0 * HMX_FP16_TILE_N_ROWS * DV;
|
|
794
|
+
|
|
795
|
+
for (uint32_t d = 0; d < DV / 32; ++d) {
|
|
796
|
+
const HVX_Vector * in_tile = (const HVX_Vector *) (tile_row_base + d * HMX_FP16_TILE_N_ELMS);
|
|
797
|
+
HVX_VectorPair vp = hvx_vec_f16_to_f32_shuff(in_tile[r1 / 2]);
|
|
798
|
+
if (r1 % 2 == 0) {
|
|
799
|
+
*(HVX_UVector *) (out + d * 32) = Q6_V_lo_W(vp);
|
|
800
|
+
} else {
|
|
801
|
+
*(HVX_UVector *) (out + d * 32) = Q6_V_hi_W(vp);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) (args->q_start * G + start));
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
static void fa_o_store_thread_f16(unsigned int n, unsigned int i, void * data) {
|
|
809
|
+
fa_o_store_args_t * args = (fa_o_store_args_t *) data;
|
|
810
|
+
struct hmx_fa_context * factx = args->factx;
|
|
811
|
+
|
|
812
|
+
const size_t n_rows_g = args->n_rows_g;
|
|
813
|
+
const size_t rows_per_t = args->rows_per_t;
|
|
814
|
+
const size_t G = factx->G;
|
|
815
|
+
const size_t DV = factx->DV;
|
|
816
|
+
const size_t start = (size_t) i * rows_per_t;
|
|
817
|
+
const size_t end = hex_smin(start + rows_per_t, n_rows_g);
|
|
818
|
+
|
|
819
|
+
if (start >= n_rows_g) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
824
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) (args->q_start * G + start));
|
|
825
|
+
|
|
826
|
+
const struct htp_tensor * dst = args->dst;
|
|
827
|
+
const __fp16 * o_tile_src = args->o_tile_src;
|
|
828
|
+
const uint32_t q_start = args->q_start;
|
|
829
|
+
const uint32_t kv_head = args->kv_head;
|
|
830
|
+
const uint32_t ib3 = args->ib3;
|
|
831
|
+
|
|
832
|
+
for (size_t r = start; r < end; ++r) {
|
|
833
|
+
const size_t q_idx = fastdiv(r, &factx->div_G);
|
|
834
|
+
const size_t h_idx = fastmodulo(r, G, &factx->div_G);
|
|
835
|
+
|
|
836
|
+
__fp16 * out = (__fp16 *) ((uint8_t *) dst->data + (kv_head * G + h_idx) * dst->nb[1] +
|
|
837
|
+
(q_start + q_idx) * dst->nb[2] + ib3 * dst->nb[3]);
|
|
838
|
+
|
|
839
|
+
size_t r0 = r / HMX_FP16_TILE_N_ROWS;
|
|
840
|
+
size_t r1 = r % HMX_FP16_TILE_N_ROWS;
|
|
841
|
+
const __fp16 * tile_row_base = o_tile_src + r0 * HMX_FP16_TILE_N_ROWS * DV;
|
|
842
|
+
|
|
843
|
+
for (uint32_t d = 0; d < DV / 64; ++d) {
|
|
844
|
+
const __fp16 * in_dtile = tile_row_base + d * HMX_FP16_TILE_N_ELMS * 2;
|
|
845
|
+
const HVX_Vector * pv_in0 = ((const HVX_Vector *) in_dtile) + r1 / 2;
|
|
846
|
+
const HVX_Vector * pv_in1 = pv_in0 + 16;
|
|
847
|
+
HVX_VectorPair vp = Q6_W_vdeal_VVR(*pv_in1, *pv_in0, -2);
|
|
848
|
+
if (r1 % 2 == 0) {
|
|
849
|
+
*(HVX_UVector *) (out + d * 64) = Q6_V_lo_W(vp);
|
|
850
|
+
} else {
|
|
851
|
+
*(HVX_UVector *) (out + d * 64) = Q6_V_hi_W(vp);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) (args->q_start * G + start));
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
static void fa_phase_o_store(struct hmx_fa_context * factx,
|
|
859
|
+
const struct htp_tensor * dst,
|
|
860
|
+
const __fp16 * o_tile_src,
|
|
861
|
+
uint32_t q_start,
|
|
862
|
+
uint32_t kv_head,
|
|
863
|
+
uint32_t ib3,
|
|
864
|
+
size_t n_rows_g) {
|
|
865
|
+
worker_pool_context_t wp = factx->octx->ctx->worker_pool;
|
|
866
|
+
uint32_t n = 1;
|
|
867
|
+
if (factx->n_threads > 1 && n_rows_g >= (size_t) (factx->n_threads * 2)) {
|
|
868
|
+
n = factx->n_threads;
|
|
869
|
+
}
|
|
870
|
+
size_t rows_per_t = hmx_ceil_div(n_rows_g, n);
|
|
871
|
+
fa_o_store_args_t args = { factx, dst, o_tile_src, q_start, kv_head, ib3, n_rows_g, rows_per_t };
|
|
872
|
+
worker_callback_t store_fn = factx->is_dst_fp32 ? fa_o_store_thread_f32 : fa_o_store_thread_f16;
|
|
873
|
+
if (n > 1) {
|
|
874
|
+
worker_pool_run_func(wp, store_fn, &args, n);
|
|
875
|
+
} else {
|
|
876
|
+
store_fn(1, 0, &args);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
typedef struct {
|
|
881
|
+
struct hmx_fa_context * factx;
|
|
882
|
+
size_t kv_rows;
|
|
883
|
+
size_t n_rows_g;
|
|
884
|
+
size_t n_col_tiles;
|
|
885
|
+
size_t n_tiles_per_bc;
|
|
886
|
+
size_t n_row_tiles;
|
|
887
|
+
size_t n_row_tiles_g_br;
|
|
888
|
+
uint32_t Bc;
|
|
889
|
+
uint32_t G;
|
|
890
|
+
uint32_t kv_head;
|
|
891
|
+
uint32_t kv_start;
|
|
892
|
+
uint32_t q_start;
|
|
893
|
+
uint32_t ib3;
|
|
894
|
+
bool has_alibi; // true when max_bias != 0 (need slope * mask + add)
|
|
895
|
+
__fp16 * slopes;
|
|
896
|
+
const struct htp_tensor * mask;
|
|
897
|
+
const __fp16 * mask_vtcm; // VTCM mask buffer base (NULL = DDR fallback)
|
|
898
|
+
size_t mask_vtcm_row_stride; // elements (__fp16) per row in VTCM mask buffer
|
|
899
|
+
struct fastdiv_values thread_div;
|
|
900
|
+
} fa_softmax_args_t;
|
|
901
|
+
|
|
902
|
+
static inline void fa_softmax_impl(
|
|
903
|
+
unsigned int n, unsigned int i, void * data,
|
|
904
|
+
const bool has_mask,
|
|
905
|
+
const bool mask_broadcast,
|
|
906
|
+
const bool is_g1,
|
|
907
|
+
const bool has_alibi,
|
|
908
|
+
const bool has_softcap
|
|
909
|
+
) {
|
|
910
|
+
fa_softmax_args_t * args = (fa_softmax_args_t *) data;
|
|
911
|
+
struct hmx_fa_context * factx = args->factx;
|
|
912
|
+
|
|
913
|
+
const size_t n_rows_g = args->n_rows_g;
|
|
914
|
+
const size_t kv_rows = args->kv_rows;
|
|
915
|
+
const size_t Bc = args->Bc;
|
|
916
|
+
const size_t G = args->G;
|
|
917
|
+
const size_t n_tiles_per_bc = args->n_tiles_per_bc;
|
|
918
|
+
const size_t n_row_vec_cnt = hmx_ceil_div(n_rows_g, 64);
|
|
919
|
+
const uint32_t im3 = has_mask ? fastmodulo(args->ib3, args->mask->ne[3], &factx->src3_div3) : 0;
|
|
920
|
+
|
|
921
|
+
size_t vec_start = 0;
|
|
922
|
+
size_t vec_end = n_row_vec_cnt;
|
|
923
|
+
if (n > 1) {
|
|
924
|
+
const size_t vecs_per_t = fastdiv(n_row_vec_cnt + n - 1, &args->thread_div);
|
|
925
|
+
vec_start = i * vecs_per_t;
|
|
926
|
+
vec_end = hex_smin(vec_start + vecs_per_t, n_row_vec_cnt);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
if (vec_start >= n_row_vec_cnt) {
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
struct htp_thread_trace * tr = factx->octx->ctx ? &factx->octx->ctx->trace[i] : NULL;
|
|
934
|
+
htp_trace_event_start(tr, HTP_TRACE_EVT_HVX_FA_SFM, (uint16_t) (args->q_start * G + vec_start * 64));
|
|
935
|
+
|
|
936
|
+
// Per-thread row scratch: thread i uses bufs at offset i * 2 * stride
|
|
937
|
+
const size_t row_buf_stride = factx->row_buf_stride;
|
|
938
|
+
HVX_Vector * my_row_buf0 = factx->vtcm_row_bufs + i * 2 * row_buf_stride;
|
|
939
|
+
HVX_Vector * my_row_buf1 = my_row_buf0 + row_buf_stride;
|
|
940
|
+
|
|
941
|
+
const HVX_Vector v_neg_inf = Q6_Vh_vsplat_R(0xfbff);
|
|
942
|
+
|
|
943
|
+
for (size_t r_vec_idx = vec_start; r_vec_idx < vec_end; ++r_vec_idx) {
|
|
944
|
+
HVX_Vector rowmax_acc_v = v_neg_inf;
|
|
945
|
+
HVX_Vector rowsum_acc_v = Q6_V_vzero();
|
|
946
|
+
HVX_Vector m_prev_v0 = factx->vtcm_m_vec[r_vec_idx * 2 + 0];
|
|
947
|
+
HVX_Vector m_prev_v1 = factx->vtcm_m_vec[r_vec_idx * 2 + 1];
|
|
948
|
+
|
|
949
|
+
HVX_Vector v_slopes = Q6_V_vzero();
|
|
950
|
+
if (has_alibi) {
|
|
951
|
+
v_slopes = hvx_vmem(args->slopes + r_vec_idx * 64);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
for (uint32_t r_vec_off = 0; r_vec_off < 64; r_vec_off += 2) {
|
|
955
|
+
uint32_t r = r_vec_idx * 64 + r_vec_off;
|
|
956
|
+
if (r >= hex_align_up(n_rows_g, 2)) {
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
uint32_t r0 = r / HMX_FP16_TILE_N_ROWS;
|
|
961
|
+
uint32_t r1 = r % HMX_FP16_TILE_N_ROWS;
|
|
962
|
+
|
|
963
|
+
const __fp16 * s_ld_base = factx->vtcm_s_tiles + r0 * HMX_FP16_TILE_N_ROWS * Bc;
|
|
964
|
+
__fp16 * p_st_base = factx->vtcm_p_tiles + r0 * HMX_FP16_TILE_N_ROWS * Bc;
|
|
965
|
+
|
|
966
|
+
// Decode 2 rows from S tiles into per-thread row buffers
|
|
967
|
+
if (has_softcap) {
|
|
968
|
+
const HVX_Vector v_cap = hvx_vec_splat_f16(factx->logit_softcap);
|
|
969
|
+
for (size_t c = 0; c < kv_rows; c += 64) {
|
|
970
|
+
size_t ci = c / 64;
|
|
971
|
+
const __fp16 * in_dtile = s_ld_base + ci * HMX_FP16_TILE_N_ELMS * 2;
|
|
972
|
+
const HVX_Vector * pv_s_in0 = ((const HVX_Vector *) in_dtile) + r1 / 2;
|
|
973
|
+
const HVX_Vector * pv_s_in1 = pv_s_in0 + 16;
|
|
974
|
+
|
|
975
|
+
HVX_VectorPair vp_s_drow = Q6_W_vdeal_VVR(*pv_s_in1, *pv_s_in0, -2);
|
|
976
|
+
HVX_Vector v_s_row0 = Q6_V_lo_W(vp_s_drow);
|
|
977
|
+
HVX_Vector v_s_row1 = Q6_V_hi_W(vp_s_drow);
|
|
978
|
+
|
|
979
|
+
HVX_Vector t0 = hvx_vec_tanh_f16(v_s_row0);
|
|
980
|
+
my_row_buf0[ci] = hvx_vec_mul_f16_f16(t0, v_cap);
|
|
981
|
+
|
|
982
|
+
HVX_Vector t1 = hvx_vec_tanh_f16(v_s_row1);
|
|
983
|
+
my_row_buf1[ci] = hvx_vec_mul_f16_f16(t1, v_cap);
|
|
984
|
+
}
|
|
985
|
+
} else {
|
|
986
|
+
for (size_t c = 0; c < kv_rows; c += 64) {
|
|
987
|
+
size_t ci = c / 64;
|
|
988
|
+
const __fp16 * in_dtile = s_ld_base + ci * HMX_FP16_TILE_N_ELMS * 2;
|
|
989
|
+
const HVX_Vector * pv_s_in0 = ((const HVX_Vector *) in_dtile) + r1 / 2;
|
|
990
|
+
const HVX_Vector * pv_s_in1 = pv_s_in0 + 16;
|
|
991
|
+
|
|
992
|
+
HVX_VectorPair vp_s_drow = Q6_W_vdeal_VVR(*pv_s_in1, *pv_s_in0, -2);
|
|
993
|
+
my_row_buf0[ci] = Q6_V_lo_W(vp_s_drow);
|
|
994
|
+
my_row_buf1[ci] = Q6_V_hi_W(vp_s_drow);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// Apply mask & compute rowmax(S)
|
|
999
|
+
HVX_Vector v_slope0 = Q6_V_vzero();
|
|
1000
|
+
HVX_Vector v_slope1 = Q6_V_vzero();
|
|
1001
|
+
if (has_alibi) {
|
|
1002
|
+
v_slope0 = hvx_vec_repl_f16(Q6_V_vror_VR(v_slopes, r_vec_off * 2));
|
|
1003
|
+
v_slope1 = (r + 1 < n_rows_g) ? hvx_vec_repl_f16(Q6_V_vror_VR(v_slopes, (r_vec_off + 1) * 2)) : Q6_V_vzero();
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const HVX_Vector v_threshold = Q6_Vh_vsplat_R(0xcc00); // fp16 -16.0
|
|
1007
|
+
|
|
1008
|
+
HVX_Vector v_s_rowmax0 = v_neg_inf;
|
|
1009
|
+
HVX_Vector v_s_rowmax1 = v_neg_inf;
|
|
1010
|
+
for (size_t c = 0; c < kv_rows; c += 64) {
|
|
1011
|
+
size_t ci = c / 64;
|
|
1012
|
+
const size_t ne = hex_smin(kv_rows - c, 64);
|
|
1013
|
+
HVX_VectorPred q_tail_keep = Q6_Q_vsetq2_R(ne * sizeof(__fp16));
|
|
1014
|
+
|
|
1015
|
+
if (has_mask) {
|
|
1016
|
+
HVX_Vector v_mask0, v_mask1;
|
|
1017
|
+
|
|
1018
|
+
if (mask_broadcast) {
|
|
1019
|
+
if (is_g1) {
|
|
1020
|
+
const size_t qi0 = r + 0;
|
|
1021
|
+
v_mask0 = *(const HVX_Vector *) (args->mask_vtcm + qi0 * args->mask_vtcm_row_stride + c);
|
|
1022
|
+
v_mask1 = v_neg_inf;
|
|
1023
|
+
if (r + 1 < n_rows_g) {
|
|
1024
|
+
const size_t qi1 = r + 1;
|
|
1025
|
+
v_mask1 = *(const HVX_Vector *) (args->mask_vtcm + qi1 * args->mask_vtcm_row_stride + c);
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
const size_t qi0 = fastdiv(r + 0, &factx->div_G);
|
|
1029
|
+
v_mask0 = *(const HVX_Vector *) (args->mask_vtcm + qi0 * args->mask_vtcm_row_stride + c);
|
|
1030
|
+
v_mask1 = v_neg_inf;
|
|
1031
|
+
if (r + 1 < n_rows_g) {
|
|
1032
|
+
const size_t qi1 = fastdiv(r + 1, &factx->div_G);
|
|
1033
|
+
if (qi1 == qi0) {
|
|
1034
|
+
v_mask1 = v_mask0;
|
|
1035
|
+
} else {
|
|
1036
|
+
v_mask1 = *(const HVX_Vector *) (args->mask_vtcm + qi1 * args->mask_vtcm_row_stride + c);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
} else {
|
|
1041
|
+
// Head-dependent mask: pre-interleaved per row r.
|
|
1042
|
+
const size_t r0 = r + 0;
|
|
1043
|
+
v_mask0 = *(const HVX_Vector *) (args->mask_vtcm + r0 * args->mask_vtcm_row_stride + c);
|
|
1044
|
+
v_mask1 = v_neg_inf;
|
|
1045
|
+
if (r + 1 < n_rows_g) {
|
|
1046
|
+
const size_t r1 = r + 1;
|
|
1047
|
+
v_mask1 = *(const HVX_Vector *) (args->mask_vtcm + r1 * args->mask_vtcm_row_stride + c);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// Threshold: mask values below -16.0 are treated as -inf (causal mask).
|
|
1052
|
+
HVX_VectorPred q_keep0 = Q6_Q_and_QQ(Q6_Q_vcmp_gt_VhfVhf(v_mask0, v_threshold), q_tail_keep);
|
|
1053
|
+
HVX_VectorPred q_keep1 = Q6_Q_and_QQ(Q6_Q_vcmp_gt_VhfVhf(v_mask1, v_threshold), q_tail_keep);
|
|
1054
|
+
|
|
1055
|
+
// Scale mask values by log2(e) for base-2 calculations
|
|
1056
|
+
const HVX_Vector v_log2e = hvx_vec_splat_f16(EXP_LOG2E_F);
|
|
1057
|
+
HVX_Vector v_mask0_scaled = hvx_vec_mul_f16_f16(v_mask0, v_log2e);
|
|
1058
|
+
HVX_Vector v_mask1_scaled = hvx_vec_mul_f16_f16(v_mask1, v_log2e);
|
|
1059
|
+
|
|
1060
|
+
if (has_alibi) {
|
|
1061
|
+
HVX_Vector v_sm0 = hvx_vec_mul_f16_f16(v_mask0_scaled, v_slope0);
|
|
1062
|
+
HVX_Vector v_sm1 = hvx_vec_mul_f16_f16(v_mask1_scaled, v_slope1);
|
|
1063
|
+
my_row_buf0[ci] = Q6_V_vmux_QVV(q_keep0, hvx_vec_add_f16_f16(my_row_buf0[ci], v_sm0), v_neg_inf);
|
|
1064
|
+
my_row_buf1[ci] = Q6_V_vmux_QVV(q_keep1, hvx_vec_add_f16_f16(my_row_buf1[ci], v_sm1), v_neg_inf);
|
|
1065
|
+
} else {
|
|
1066
|
+
my_row_buf0[ci] = Q6_V_vmux_QVV(q_keep0, hvx_vec_add_f16_f16(my_row_buf0[ci], v_mask0_scaled), v_neg_inf);
|
|
1067
|
+
my_row_buf1[ci] = Q6_V_vmux_QVV(q_keep1, hvx_vec_add_f16_f16(my_row_buf1[ci], v_mask1_scaled), v_neg_inf);
|
|
1068
|
+
}
|
|
1069
|
+
} else {
|
|
1070
|
+
if (ne < 64) {
|
|
1071
|
+
my_row_buf0[ci] = Q6_V_vmux_QVV(q_tail_keep, my_row_buf0[ci], v_neg_inf);
|
|
1072
|
+
my_row_buf1[ci] = Q6_V_vmux_QVV(q_tail_keep, my_row_buf1[ci], v_neg_inf);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
v_s_rowmax0 = Q6_Vhf_vmax_VhfVhf(v_s_rowmax0, my_row_buf0[ci]);
|
|
1077
|
+
v_s_rowmax1 = Q6_Vhf_vmax_VhfVhf(v_s_rowmax1, my_row_buf1[ci]);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
v_s_rowmax0 = hvx_vec_reduce_max_f16(v_s_rowmax0);
|
|
1081
|
+
v_s_rowmax1 = hvx_vec_reduce_max_f16(v_s_rowmax1);
|
|
1082
|
+
|
|
1083
|
+
// Splat m_prev[r], m_prev[r+1] from the float per-row accumulators and convert to fp16 vectors
|
|
1084
|
+
HVX_Vector v_m_prev0, v_m_prev1;
|
|
1085
|
+
if (r_vec_off < 32) {
|
|
1086
|
+
HVX_Vector v0 = hvx_vec_repl_f32(Q6_V_vror_VR(m_prev_v0, r_vec_off * 4));
|
|
1087
|
+
v_m_prev0 = hvx_vec_f32_to_f16(v0, v0);
|
|
1088
|
+
if (r + 1 < n_rows_g) {
|
|
1089
|
+
HVX_Vector v1 = hvx_vec_repl_f32(Q6_V_vror_VR(m_prev_v0, (r_vec_off + 1) * 4));
|
|
1090
|
+
v_m_prev1 = hvx_vec_f32_to_f16(v1, v1);
|
|
1091
|
+
} else {
|
|
1092
|
+
v_m_prev1 = Q6_V_vzero();
|
|
1093
|
+
}
|
|
1094
|
+
} else {
|
|
1095
|
+
HVX_Vector v0 = hvx_vec_repl_f32(Q6_V_vror_VR(m_prev_v1, (r_vec_off - 32) * 4));
|
|
1096
|
+
v_m_prev0 = hvx_vec_f32_to_f16(v0, v0);
|
|
1097
|
+
if (r + 1 < n_rows_g) {
|
|
1098
|
+
HVX_Vector v1 = hvx_vec_repl_f32(Q6_V_vror_VR(m_prev_v1, (r_vec_off + 1 - 32) * 4));
|
|
1099
|
+
v_m_prev1 = hvx_vec_f32_to_f16(v1, v1);
|
|
1100
|
+
} else {
|
|
1101
|
+
v_m_prev1 = Q6_V_vzero();
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
HVX_Vector v_dup_m0 = Q6_Vhf_vmax_VhfVhf(v_m_prev0, v_s_rowmax0);
|
|
1106
|
+
HVX_Vector v_dup_m1 = Q6_Vhf_vmax_VhfVhf(v_m_prev1, v_s_rowmax1);
|
|
1107
|
+
|
|
1108
|
+
// Insert row r, r+1 rowmax into rowmax_acc_v
|
|
1109
|
+
{
|
|
1110
|
+
HVX_VectorPred p_start = Q6_Q_vsetq_R(r_vec_off * 2);
|
|
1111
|
+
HVX_VectorPred p_mid = Q6_Q_vsetq_R((r_vec_off + 1) * 2);
|
|
1112
|
+
HVX_VectorPred p_end = Q6_Q_vsetq2_R((r_vec_off + 2) * 2);
|
|
1113
|
+
HVX_VectorPred p_lane0 = Q6_Q_and_QQn(p_mid, p_start);
|
|
1114
|
+
HVX_VectorPred p_lane1 = Q6_Q_and_QQn(p_end, p_mid);
|
|
1115
|
+
rowmax_acc_v = Q6_V_vmux_QVV(p_lane0, v_dup_m0, rowmax_acc_v);
|
|
1116
|
+
rowmax_acc_v = Q6_V_vmux_QVV(p_lane1, v_dup_m1, rowmax_acc_v);
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// Compute P = exp(S - m_new)
|
|
1120
|
+
const HVX_Vector v_zero = Q6_V_vzero();
|
|
1121
|
+
HVX_Vector v_p_rowsum0 = v_zero;
|
|
1122
|
+
HVX_Vector v_p_rowsum1 = v_zero;
|
|
1123
|
+
|
|
1124
|
+
for (size_t c = 0; c < kv_rows; c += 64) {
|
|
1125
|
+
size_t ci = c / 64;
|
|
1126
|
+
HVX_Vector v_s_minus_m0 = Q6_Vqf16_vsub_VhfVhf(my_row_buf0[ci], v_dup_m0);
|
|
1127
|
+
HVX_Vector v_s_minus_m1 = Q6_Vqf16_vsub_VhfVhf(my_row_buf1[ci], v_dup_m1);
|
|
1128
|
+
|
|
1129
|
+
HVX_Vector v_p_row0_hf = hvx_vec_exp2_f16(Q6_Vhf_equals_Vqf16(v_s_minus_m0));
|
|
1130
|
+
HVX_Vector v_p_row1_hf = hvx_vec_exp2_f16(Q6_Vhf_equals_Vqf16(v_s_minus_m1));
|
|
1131
|
+
__fp16 * out_dtile = p_st_base + ci * HMX_FP16_TILE_N_ELMS * 2;
|
|
1132
|
+
HVX_Vector * pv_p_out0 = ((HVX_Vector *) out_dtile) + r1 / 2;
|
|
1133
|
+
HVX_Vector * pv_p_out1 = pv_p_out0 + 16;
|
|
1134
|
+
|
|
1135
|
+
HVX_VectorPair vp_p_dual = Q6_W_vshuff_VVR(v_p_row1_hf, v_p_row0_hf, -2);
|
|
1136
|
+
*pv_p_out0 = Q6_V_lo_W(vp_p_dual);
|
|
1137
|
+
*pv_p_out1 = Q6_V_hi_W(vp_p_dual);
|
|
1138
|
+
|
|
1139
|
+
HVX_VectorPair vp_p0 = hvx_vec_f16_to_f32_shuff(v_p_row0_hf);
|
|
1140
|
+
HVX_VectorPair vp_p1 = hvx_vec_f16_to_f32_shuff(v_p_row1_hf);
|
|
1141
|
+
|
|
1142
|
+
v_p_rowsum0 = Q6_Vqf32_vadd_Vqf32Vqf32(v_p_rowsum0, Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(vp_p0), Q6_V_hi_W(vp_p0)));
|
|
1143
|
+
v_p_rowsum1 = Q6_Vqf32_vadd_Vqf32Vqf32(v_p_rowsum1, Q6_Vqf32_vadd_VsfVsf(Q6_V_lo_W(vp_p1), Q6_V_hi_W(vp_p1)));
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
HVX_Vector rowsum0_sf = hvx_vec_reduce_sum_f32(Q6_Vsf_equals_Vqf32(v_p_rowsum0));
|
|
1147
|
+
HVX_Vector rowsum1_sf = hvx_vec_reduce_sum_f32(Q6_Vsf_equals_Vqf32(v_p_rowsum1));
|
|
1148
|
+
{
|
|
1149
|
+
HVX_Vector rv0_v = hvx_vec_f32_to_f16(rowsum0_sf, rowsum0_sf);
|
|
1150
|
+
HVX_Vector rv1_v = hvx_vec_f32_to_f16(rowsum1_sf, rowsum1_sf);
|
|
1151
|
+
|
|
1152
|
+
HVX_VectorPred p_start = Q6_Q_vsetq_R(r_vec_off * 2);
|
|
1153
|
+
HVX_VectorPred p_mid = Q6_Q_vsetq_R((r_vec_off + 1) * 2);
|
|
1154
|
+
HVX_VectorPred p_end = Q6_Q_vsetq2_R((r_vec_off + 2) * 2);
|
|
1155
|
+
HVX_VectorPred p_lane0 = Q6_Q_and_QQn(p_mid, p_start);
|
|
1156
|
+
HVX_VectorPred p_lane1 = Q6_Q_and_QQn(p_end, p_mid);
|
|
1157
|
+
rowsum_acc_v = Q6_V_vmux_QVV(p_lane0, rv0_v, rowsum_acc_v);
|
|
1158
|
+
rowsum_acc_v = Q6_V_vmux_QVV(p_lane1, rv1_v, rowsum_acc_v);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// Inline fa_ml_update_and_build_d for this vector (lock-free and in parallel)
|
|
1163
|
+
HVX_VectorPair rowmax_acc_pair = hvx_vec_f16_to_f32(rowmax_acc_v);
|
|
1164
|
+
HVX_Vector v_rowmax_acc_f32_0 = Q6_V_lo_W(rowmax_acc_pair);
|
|
1165
|
+
HVX_Vector v_rowmax_acc_f32_1 = Q6_V_hi_W(rowmax_acc_pair);
|
|
1166
|
+
|
|
1167
|
+
HVX_Vector v_m_curr0 = Q6_Vsf_vmax_VsfVsf(m_prev_v0, v_rowmax_acc_f32_0);
|
|
1168
|
+
HVX_Vector v_m_curr1 = Q6_Vsf_vmax_VsfVsf(m_prev_v1, v_rowmax_acc_f32_1);
|
|
1169
|
+
|
|
1170
|
+
HVX_Vector v_m_diff0 = HVX_OP_SUB_F32(m_prev_v0, v_m_curr0);
|
|
1171
|
+
HVX_Vector v_m_diff1 = HVX_OP_SUB_F32(m_prev_v1, v_m_curr1);
|
|
1172
|
+
|
|
1173
|
+
HVX_Vector v_m_diff_f16 = hvx_vec_f32_to_f16(v_m_diff0, v_m_diff1);
|
|
1174
|
+
HVX_Vector exp_m_diff_f16 = hvx_vec_exp2_f16(v_m_diff_f16);
|
|
1175
|
+
|
|
1176
|
+
HVX_VectorPair exp_m_diff_pair = hvx_vec_f16_to_f32(exp_m_diff_f16);
|
|
1177
|
+
HVX_Vector exp_m_diff0 = Q6_V_lo_W(exp_m_diff_pair);
|
|
1178
|
+
HVX_Vector exp_m_diff1 = Q6_V_hi_W(exp_m_diff_pair);
|
|
1179
|
+
|
|
1180
|
+
HVX_VectorPair rowsum_acc_pair = hvx_vec_f16_to_f32(rowsum_acc_v);
|
|
1181
|
+
HVX_Vector v_rowsum_acc_f32_0 = Q6_V_lo_W(rowsum_acc_pair);
|
|
1182
|
+
HVX_Vector v_rowsum_acc_f32_1 = Q6_V_hi_W(rowsum_acc_pair);
|
|
1183
|
+
|
|
1184
|
+
HVX_Vector v_l_curr0;
|
|
1185
|
+
HVX_Vector v_l_curr1;
|
|
1186
|
+
if (args->kv_start == 0 && factx->sinks != NULL) {
|
|
1187
|
+
// First KV block with sinks: m_prev holds the seeded sink value (not -inf),
|
|
1188
|
+
// so exp_m_diff = exp2(sink - m_curr) is the sink's contribution to the
|
|
1189
|
+
// denominator. l_prev is 0 here, so add exp_m_diff directly instead of
|
|
1190
|
+
// multiplying the (uninitialized) l_prev term.
|
|
1191
|
+
v_l_curr0 = HVX_OP_ADD_F32(exp_m_diff0, v_rowsum_acc_f32_0);
|
|
1192
|
+
v_l_curr1 = HVX_OP_ADD_F32(exp_m_diff1, v_rowsum_acc_f32_1);
|
|
1193
|
+
} else {
|
|
1194
|
+
HVX_Vector l_prev_v0 = factx->vtcm_l_vec[r_vec_idx * 2 + 0];
|
|
1195
|
+
HVX_Vector l_prev_v1 = factx->vtcm_l_vec[r_vec_idx * 2 + 1];
|
|
1196
|
+
v_l_curr0 = HVX_OP_ADD_F32(HVX_OP_MUL_F32(l_prev_v0, exp_m_diff0), v_rowsum_acc_f32_0);
|
|
1197
|
+
v_l_curr1 = HVX_OP_ADD_F32(HVX_OP_MUL_F32(l_prev_v1, exp_m_diff1), v_rowsum_acc_f32_1);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
factx->vtcm_m_vec[r_vec_idx * 2 + 0] = v_m_curr0;
|
|
1201
|
+
factx->vtcm_m_vec[r_vec_idx * 2 + 1] = v_m_curr1;
|
|
1202
|
+
factx->vtcm_l_vec[r_vec_idx * 2 + 0] = v_l_curr0;
|
|
1203
|
+
factx->vtcm_l_vec[r_vec_idx * 2 + 1] = v_l_curr1;
|
|
1204
|
+
|
|
1205
|
+
// Build diagonal tile D = diag(exp(m_diff))
|
|
1206
|
+
const HVX_Vector v_offsets = *(const HVX_Vector *) d_tile_scatter_offsets;
|
|
1207
|
+
const HVX_VectorPred q_32_mask = Q6_Q_vsetq_R(32 * sizeof(__fp16));
|
|
1208
|
+
HVX_Vector v_exp_m_diff = exp_m_diff_f16;
|
|
1209
|
+
|
|
1210
|
+
size_t t0 = r_vec_idx * 2;
|
|
1211
|
+
if (t0 < args->n_row_tiles) {
|
|
1212
|
+
const HVX_Vector v_content = v_exp_m_diff;
|
|
1213
|
+
__fp16 * out_base = factx->vtcm_d_tiles + t0 * (args->n_row_tiles_g_br + 1) * HMX_FP16_TILE_N_ELMS;
|
|
1214
|
+
Q6_vscatter_QRMVhV(q_32_mask, (size_t) out_base, HMX_FP16_TILE_SIZE - 1, v_offsets, v_content);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
size_t t1 = r_vec_idx * 2 + 1;
|
|
1218
|
+
if (t1 < args->n_row_tiles) {
|
|
1219
|
+
const HVX_Vector v_content = Q6_V_vror_VR(v_exp_m_diff, 64);
|
|
1220
|
+
__fp16 * out_base = factx->vtcm_d_tiles + t1 * (args->n_row_tiles_g_br + 1) * HMX_FP16_TILE_N_ELMS;
|
|
1221
|
+
Q6_vscatter_QRMVhV(q_32_mask, (size_t) out_base, HMX_FP16_TILE_SIZE - 1, v_offsets, v_content);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
htp_trace_event_stop(tr, HTP_TRACE_EVT_HVX_FA_SFM, (uint16_t) (args->q_start * G + vec_start * 64));
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
static void fa_softmax_thread_nomask(unsigned int n, unsigned int i, void * data) {
|
|
1228
|
+
fa_softmax_impl(n, i, data,
|
|
1229
|
+
/*has_mask=*/false,
|
|
1230
|
+
/*mask_broadcast=*/false,
|
|
1231
|
+
/*is_g1=*/false,
|
|
1232
|
+
/*has_alibi=*/false,
|
|
1233
|
+
/*has_softcap=*/false);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
static void fa_softmax_thread_mask_broadcast_g1(unsigned int n, unsigned int i, void * data) {
|
|
1237
|
+
fa_softmax_impl(n, i, data,
|
|
1238
|
+
/*has_mask=*/true,
|
|
1239
|
+
/*mask_broadcast=*/true,
|
|
1240
|
+
/*is_g1=*/true,
|
|
1241
|
+
/*has_alibi=*/false,
|
|
1242
|
+
/*has_softcap=*/false);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
static void fa_softmax_thread_mask_broadcast_gn(unsigned int n, unsigned int i, void * data) {
|
|
1246
|
+
fa_softmax_impl(n, i, data,
|
|
1247
|
+
/*has_mask=*/true,
|
|
1248
|
+
/*mask_broadcast=*/true,
|
|
1249
|
+
/*is_g1=*/false,
|
|
1250
|
+
/*has_alibi=*/false,
|
|
1251
|
+
/*has_softcap=*/false);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
static void fa_softmax_thread(unsigned int n, unsigned int i, void * data) {
|
|
1255
|
+
fa_softmax_args_t * args = (fa_softmax_args_t *) data;
|
|
1256
|
+
struct hmx_fa_context * factx = args->factx;
|
|
1257
|
+
|
|
1258
|
+
const bool has_mask = (args->mask != NULL);
|
|
1259
|
+
const bool mask_broadcast = factx->mask_broadcast;
|
|
1260
|
+
const bool is_g1 = (args->G == 1);
|
|
1261
|
+
const bool has_alibi = args->has_alibi;
|
|
1262
|
+
const bool has_softcap = (factx->logit_softcap != 0.0f);
|
|
1263
|
+
|
|
1264
|
+
fa_softmax_impl(n, i, data, has_mask, mask_broadcast, is_g1, has_alibi, has_softcap);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
static __attribute__((noinline)) void fa_build_d_diag_inv_l(struct hmx_fa_context * factx,
|
|
1268
|
+
size_t n_row_tiles,
|
|
1269
|
+
size_t n_row_tiles_g_br) {
|
|
1270
|
+
const HVX_Vector v_offsets = *(const HVX_Vector *) d_tile_scatter_offsets;
|
|
1271
|
+
const HVX_VectorPred q_32_mask = Q6_Q_vsetq_R(32 * sizeof(__fp16));
|
|
1272
|
+
const HVX_Vector one = hvx_vec_splat_f32(1.0f);
|
|
1273
|
+
|
|
1274
|
+
HVX_Vector v_content = Q6_V_vzero();
|
|
1275
|
+
for (size_t i = 0; i < n_row_tiles; ++i) {
|
|
1276
|
+
if ((i % 2) == 0) {
|
|
1277
|
+
HVX_Vector inv_lo = HVX_OP_MUL_F32(one, hvx_vec_inverse_f32(factx->vtcm_l_vec[i]));
|
|
1278
|
+
HVX_Vector inv_hi = (i + 1 < n_row_tiles) ? HVX_OP_MUL_F32(one, hvx_vec_inverse_f32(factx->vtcm_l_vec[i + 1])) : Q6_V_vzero();
|
|
1279
|
+
v_content = hvx_vec_f32_to_f16(inv_lo, inv_hi);
|
|
1280
|
+
} else {
|
|
1281
|
+
v_content = Q6_V_vror_VR(v_content, 64);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
__fp16 * out_base = factx->vtcm_d_tiles + i * (n_row_tiles_g_br + 1) * HMX_FP16_TILE_N_ELMS;
|
|
1285
|
+
Q6_vscatter_QRMVhV(q_32_mask, (size_t) out_base, HMX_FP16_TILE_SIZE - 1, v_offsets, v_content);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
static void fa_phase_softmax_and_build_d(struct hmx_fa_context * factx,
|
|
1290
|
+
fa_softmax_args_t * sargs,
|
|
1291
|
+
size_t n_row_tiles,
|
|
1292
|
+
size_t n_row_tiles_g_br) {
|
|
1293
|
+
worker_pool_context_t wp = factx->octx->ctx->worker_pool;
|
|
1294
|
+
const size_t n_row_vec_cnt = hmx_ceil_div(sargs->n_rows_g, 64);
|
|
1295
|
+
|
|
1296
|
+
worker_callback_t softmax_fn = fa_softmax_thread;
|
|
1297
|
+
if (sargs->mask == NULL && factx->logit_softcap == 0.0f && !sargs->has_alibi) {
|
|
1298
|
+
softmax_fn = fa_softmax_thread_nomask;
|
|
1299
|
+
} else if (sargs->mask != NULL && factx->mask_broadcast && factx->logit_softcap == 0.0f && !sargs->has_alibi) {
|
|
1300
|
+
if (sargs->G == 1) {
|
|
1301
|
+
softmax_fn = fa_softmax_thread_mask_broadcast_g1;
|
|
1302
|
+
} else {
|
|
1303
|
+
softmax_fn = fa_softmax_thread_mask_broadcast_gn;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if (factx->n_threads > 1 && n_row_vec_cnt >= 2) {
|
|
1308
|
+
uint32_t n_use = (uint32_t) hex_smin((size_t) factx->n_threads, n_row_vec_cnt);
|
|
1309
|
+
sargs->thread_div = init_fastdiv_values(n_use);
|
|
1310
|
+
worker_pool_run_func(wp, softmax_fn, sargs, n_use);
|
|
1311
|
+
} else {
|
|
1312
|
+
softmax_fn(1, 0, sargs);
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// ============================================================================
|
|
1317
|
+
// HMX job structs and worker functions
|
|
1318
|
+
// ============================================================================
|
|
1319
|
+
|
|
1320
|
+
typedef struct {
|
|
1321
|
+
const __fp16 * q_tiles;
|
|
1322
|
+
const __fp16 * k_tiles;
|
|
1323
|
+
__fp16 * s_tiles;
|
|
1324
|
+
size_t n_row_tiles;
|
|
1325
|
+
size_t n_col_tiles;
|
|
1326
|
+
size_t n_dot_tiles; // DK / 32
|
|
1327
|
+
size_t n_tiles_per_bc;
|
|
1328
|
+
uint8_t * hmx_scales;
|
|
1329
|
+
} hmx_fa_qk_job_t;
|
|
1330
|
+
|
|
1331
|
+
static void hmx_fa_qk_dot_worker(void * data) {
|
|
1332
|
+
hmx_fa_qk_job_t * job = (hmx_fa_qk_job_t *) data;
|
|
1333
|
+
const size_t n_row_tiles = job->n_row_tiles;
|
|
1334
|
+
const size_t n_col_tiles = job->n_col_tiles;
|
|
1335
|
+
const size_t n_dot_tiles = job->n_dot_tiles;
|
|
1336
|
+
const size_t n_tiles_per_bc = job->n_tiles_per_bc;
|
|
1337
|
+
const __fp16 * restrict q_tiles = job->q_tiles;
|
|
1338
|
+
const __fp16 * restrict k_tiles = job->k_tiles;
|
|
1339
|
+
__fp16 * restrict s_tiles = job->s_tiles;
|
|
1340
|
+
__builtin_assume(n_row_tiles > 0);
|
|
1341
|
+
__builtin_assume(n_col_tiles > 0);
|
|
1342
|
+
__builtin_assume(n_dot_tiles > 0);
|
|
1343
|
+
|
|
1344
|
+
asm volatile(HMX_SET_BIAS("%0") :: "r"((unsigned int)job->hmx_scales));
|
|
1345
|
+
const size_t dot_stride = n_dot_tiles * HMX_FP16_TILE_N_ELMS;
|
|
1346
|
+
for (size_t r = 0; r < n_row_tiles; ++r) {
|
|
1347
|
+
const __fp16 * row_tiles = q_tiles + r * dot_stride;
|
|
1348
|
+
const __fp16 * col_tiles = k_tiles;
|
|
1349
|
+
__fp16 * out_tile = s_tiles + r * n_tiles_per_bc * HMX_FP16_TILE_N_ELMS;
|
|
1350
|
+
|
|
1351
|
+
for (size_t c = 0; c < n_col_tiles; ++c) {
|
|
1352
|
+
hmx_fa_qk_dot_tile(row_tiles, col_tiles, out_tile, n_dot_tiles);
|
|
1353
|
+
col_tiles += dot_stride;
|
|
1354
|
+
out_tile += HMX_FP16_TILE_N_ELMS;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
typedef struct {
|
|
1360
|
+
__fp16 * o_curr;
|
|
1361
|
+
const __fp16 * o_prev;
|
|
1362
|
+
const __fp16 * p_tiles;
|
|
1363
|
+
const __fp16 * v_tiles;
|
|
1364
|
+
const __fp16 * d_tiles;
|
|
1365
|
+
uint8_t * hmx_scales;
|
|
1366
|
+
size_t n_row_tiles;
|
|
1367
|
+
size_t n_col_tiles;
|
|
1368
|
+
size_t n_row_tiles_g_br;
|
|
1369
|
+
size_t n_tiles_per_bc;
|
|
1370
|
+
size_t DV;
|
|
1371
|
+
} hmx_fa_o_update_job_t;
|
|
1372
|
+
|
|
1373
|
+
static void hmx_fa_o_update_worker(void * data) {
|
|
1374
|
+
hmx_fa_o_update_job_t * job = (hmx_fa_o_update_job_t *) data;
|
|
1375
|
+
const size_t n_row_tiles = job->n_row_tiles;
|
|
1376
|
+
const size_t n_col_tiles = job->n_col_tiles;
|
|
1377
|
+
const size_t n_row_tiles_g_br = job->n_row_tiles_g_br;
|
|
1378
|
+
const size_t n_tiles_per_bc = job->n_tiles_per_bc;
|
|
1379
|
+
const size_t DV_tiles = job->DV / 32;
|
|
1380
|
+
const __fp16 * restrict d_tiles = job->d_tiles;
|
|
1381
|
+
const __fp16 * restrict p_tiles = job->p_tiles;
|
|
1382
|
+
const __fp16 * restrict v_tiles = job->v_tiles;
|
|
1383
|
+
const __fp16 * restrict o_prev = job->o_prev;
|
|
1384
|
+
__fp16 * restrict o_curr = job->o_curr;
|
|
1385
|
+
__builtin_assume(n_row_tiles > 0);
|
|
1386
|
+
__builtin_assume(n_col_tiles > 0);
|
|
1387
|
+
__builtin_assume(DV_tiles > 0);
|
|
1388
|
+
|
|
1389
|
+
asm volatile(HMX_SET_BIAS("%0") :: "r"((unsigned int)job->hmx_scales));
|
|
1390
|
+
const size_t o_stride = n_row_tiles_g_br * HMX_FP16_TILE_N_ELMS;
|
|
1391
|
+
const size_t v_stride = n_tiles_per_bc * HMX_FP16_TILE_N_ELMS;
|
|
1392
|
+
for (size_t r = 0; r < n_row_tiles; ++r) {
|
|
1393
|
+
const __fp16 * d_diag = d_tiles + r * (n_row_tiles_g_br + 1) * HMX_FP16_TILE_N_ELMS;
|
|
1394
|
+
const __fp16 * p_tile_in = p_tiles + (r * n_tiles_per_bc) * HMX_FP16_TILE_N_ELMS;
|
|
1395
|
+
const __fp16 * o_rc = o_prev + r * HMX_FP16_TILE_N_ELMS;
|
|
1396
|
+
const __fp16 * v_tile_in = v_tiles;
|
|
1397
|
+
__fp16 * o_tile_out = o_curr + r * HMX_FP16_TILE_N_ELMS;
|
|
1398
|
+
|
|
1399
|
+
for (size_t c = 0; c < DV_tiles; ++c) {
|
|
1400
|
+
hmx_fa_o_update_tile(d_diag, o_rc, p_tile_in, v_tile_in, o_tile_out, n_col_tiles);
|
|
1401
|
+
o_rc += o_stride;
|
|
1402
|
+
v_tile_in += v_stride;
|
|
1403
|
+
o_tile_out += o_stride;
|
|
1404
|
+
}
|
|
607
1405
|
}
|
|
608
1406
|
}
|
|
609
1407
|
|
|
1408
|
+
typedef struct {
|
|
1409
|
+
__fp16 * o_curr; // output (row-major tile layout)
|
|
1410
|
+
const __fp16 * o_prev; // input (column-major tile layout)
|
|
1411
|
+
const __fp16 * d_tiles; // diag(1/l) tiles
|
|
1412
|
+
uint8_t * hmx_scales;
|
|
1413
|
+
size_t n_row_tiles;
|
|
1414
|
+
size_t n_row_tiles_g_br;
|
|
1415
|
+
size_t DV;
|
|
1416
|
+
} hmx_fa_o_norm_job_t;
|
|
1417
|
+
|
|
1418
|
+
static void hmx_fa_o_norm_worker(void * data) {
|
|
1419
|
+
hmx_fa_o_norm_job_t * job = (hmx_fa_o_norm_job_t *) data;
|
|
1420
|
+
const size_t n_row_tiles = job->n_row_tiles;
|
|
1421
|
+
const size_t n_row_tiles_g_br = job->n_row_tiles_g_br;
|
|
1422
|
+
const size_t DV_tiles = job->DV / 32;
|
|
1423
|
+
const __fp16 * restrict d_tiles = job->d_tiles;
|
|
1424
|
+
const __fp16 * restrict o_prev = job->o_prev;
|
|
1425
|
+
__fp16 * restrict o_curr = job->o_curr;
|
|
1426
|
+
__builtin_assume(n_row_tiles > 0);
|
|
1427
|
+
__builtin_assume(DV_tiles > 0);
|
|
1428
|
+
|
|
1429
|
+
asm volatile(HMX_SET_BIAS("%0") :: "r"((unsigned int)job->hmx_scales));
|
|
1430
|
+
const size_t o_stride = n_row_tiles_g_br * HMX_FP16_TILE_N_ELMS;
|
|
1431
|
+
for (size_t r = 0; r < n_row_tiles; ++r) {
|
|
1432
|
+
const __fp16 * d_diag = d_tiles + r * (n_row_tiles_g_br + 1) * HMX_FP16_TILE_N_ELMS;
|
|
1433
|
+
const __fp16 * o_rc = o_prev + r * HMX_FP16_TILE_N_ELMS;
|
|
1434
|
+
__fp16 * o_out = o_curr + r * DV_tiles * HMX_FP16_TILE_N_ELMS;
|
|
1435
|
+
|
|
1436
|
+
for (size_t c = 0; c < DV_tiles; ++c) {
|
|
1437
|
+
hmx_fa_o_norm_tile(d_diag, o_rc, o_out);
|
|
1438
|
+
o_rc += o_stride;
|
|
1439
|
+
o_out += HMX_FP16_TILE_N_ELMS;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
// Populate per-GQA-row ALiBi slopes for a given KV head.
|
|
1445
|
+
static __attribute__((noinline)) void fa_compute_slopes(
|
|
1446
|
+
const struct hmx_fa_context * factx,
|
|
1447
|
+
uint32_t kv_head,
|
|
1448
|
+
size_t n_rows_g) {
|
|
1449
|
+
__fp16 * slopes = factx->vtcm_slopes;
|
|
1450
|
+
if (factx->max_bias == 0.0f) {
|
|
1451
|
+
hvx_splat_f16_a(slopes, 1.0f, n_rows_g);
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
const uint32_t G = factx->G;
|
|
1456
|
+
const uint32_t n_head_log2 = factx->n_head_log2;
|
|
1457
|
+
const float m0 = factx->m0;
|
|
1458
|
+
const float m1 = factx->m1;
|
|
1459
|
+
|
|
1460
|
+
__fp16 temp_slopes[512] __attribute__((aligned(128)));
|
|
1461
|
+
if (G <= 32) {
|
|
1462
|
+
// Fast path: Compute G unique slope values in vector registers
|
|
1463
|
+
HVX_Vector v_val = hvx_alibi_slopes(kv_head, G, n_head_log2, m0, m1);
|
|
1464
|
+
|
|
1465
|
+
__fp16 temp_slopes_aligned[64] __attribute__((aligned(128)));
|
|
1466
|
+
hvx_vmem(temp_slopes_aligned) = hvx_vec_f32_to_f16(v_val, Q6_V_vzero());
|
|
1467
|
+
|
|
1468
|
+
for (uint32_t i = 0; i < G; ++i) {
|
|
1469
|
+
temp_slopes[i] = temp_slopes_aligned[i];
|
|
1470
|
+
}
|
|
1471
|
+
} else {
|
|
1472
|
+
// Fallback path: G > 32 (rare configurations)
|
|
1473
|
+
for (uint32_t i = 0; i < G; ++i) {
|
|
1474
|
+
temp_slopes[i] = (__fp16)alibi_slope(kv_head * G + i, n_head_log2, m0, m1);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
// Allocate stack buffer to avoid scalar writes to VTCM (which generates L2 misses)
|
|
1479
|
+
__fp16 local_slopes[n_rows_g] __attribute__((aligned(128)));
|
|
1480
|
+
for (size_t r = 0; r < n_rows_g; ++r) {
|
|
1481
|
+
local_slopes[r] = temp_slopes[fastmodulo(r, G, &factx->div_G)];
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
// Copy to VTCM slopes using HVX block copy (both are aligned to 128 bytes)
|
|
1485
|
+
hvx_copy_f16_aa((uint8_t *)slopes, (const uint8_t *)local_slopes, n_rows_g);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
static void fa_push_mask_dma_gqa(
|
|
1489
|
+
dma_queue * dma,
|
|
1490
|
+
const struct htp_tensor * mask,
|
|
1491
|
+
uint32_t q_start,
|
|
1492
|
+
uint32_t im3,
|
|
1493
|
+
uint32_t kv_start,
|
|
1494
|
+
uint32_t kv_head,
|
|
1495
|
+
uint32_t G,
|
|
1496
|
+
uint32_t m_line_bytes,
|
|
1497
|
+
uint32_t kv_rows,
|
|
1498
|
+
uint32_t n_rows_q,
|
|
1499
|
+
struct hmx_fa_context * factx
|
|
1500
|
+
) {
|
|
1501
|
+
for (uint32_t g = 0; g < G; ++g) {
|
|
1502
|
+
const uint32_t h_idx = kv_head * G + g;
|
|
1503
|
+
const uint32_t im2 = fastmodulo(h_idx, mask->ne[2], &factx->src3_div2);
|
|
1504
|
+
const uint8_t * ms_src = (const uint8_t *) mask->data + q_start * mask->nb[1] +
|
|
1505
|
+
im2 * mask->nb[2] + im3 * mask->nb[3] + kv_start * sizeof(__fp16);
|
|
1506
|
+
uint8_t * ms_dst = (uint8_t *) factx->vtcm_mask_buf + g * m_line_bytes;
|
|
1507
|
+
dma_queue_push(dma, dma_make_ptr(ms_dst, ms_src), G * m_line_bytes, mask->nb[1], kv_rows * sizeof(__fp16), n_rows_q);
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
static void fa_pop_mask_dma_gqa(dma_queue * dma, uint32_t G) {
|
|
1512
|
+
for (uint32_t g = 0; g < G; ++g) {
|
|
1513
|
+
dma_queue_pop(dma);
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// ============================================================================
|
|
1518
|
+
// Core HMX flash attention algorithm (GQA-merged)
|
|
1519
|
+
// ============================================================================
|
|
1520
|
+
|
|
1521
|
+
int hmx_flash_attn_ext(struct htp_ops_context * octx) {
|
|
1522
|
+
struct htp_thread_trace * tr_hvx = octx->ctx ? &octx->ctx->trace[0] : NULL;
|
|
1523
|
+
struct htp_thread_trace * tr_hmx = octx->ctx ? &octx->ctx->trace[HTP_MAX_NTHREADS] : NULL;
|
|
1524
|
+
const struct htp_tensor * q = octx->src[0];
|
|
1525
|
+
const struct htp_tensor * k = octx->src[1];
|
|
1526
|
+
const struct htp_tensor * v = octx->src[2];
|
|
1527
|
+
const struct htp_tensor * mask = (octx->src[3] && octx->src[3]->data) ? octx->src[3] : NULL;
|
|
1528
|
+
const struct htp_tensor * dst = octx->dst;
|
|
1529
|
+
|
|
1530
|
+
struct htp_context * const ctx = octx->ctx;
|
|
1531
|
+
|
|
1532
|
+
if (!ctx->hmx_enabled) {
|
|
1533
|
+
return HTP_STATUS_NO_SUPPORT;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
// Dimensions
|
|
1537
|
+
const uint32_t neq0 = q->ne[0]; // head_dim (DK)
|
|
1538
|
+
const uint32_t neq1 = q->ne[1]; // n_tokens
|
|
1539
|
+
const uint32_t neq2 = q->ne[2]; // n_heads
|
|
1540
|
+
const uint32_t neq3 = q->ne[3]; // n_seqs
|
|
1541
|
+
|
|
1542
|
+
const uint32_t nek0 = k->ne[0]; // head_dim
|
|
1543
|
+
const uint32_t nek1 = k->ne[1]; // kv_len
|
|
1544
|
+
|
|
1545
|
+
const uint32_t nev0 = v->ne[0]; // head_dim (DV)
|
|
1546
|
+
|
|
1547
|
+
const uint32_t DK = neq0;
|
|
1548
|
+
const uint32_t DV = nev0;
|
|
1549
|
+
|
|
1550
|
+
// HMX requires head_dim to be multiple of 32
|
|
1551
|
+
if (DK % 32 != 0 || DV % 32 != 0) {
|
|
1552
|
+
return HTP_STATUS_NO_SUPPORT;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
const struct htp_fa_kernel_params * kparams = (const struct htp_fa_kernel_params *) octx->kernel_params;
|
|
1556
|
+
const uint32_t n_kv_heads = k->ne[2];
|
|
1557
|
+
|
|
1558
|
+
// ======== Build context ========
|
|
1559
|
+
struct hmx_fa_context factx;
|
|
1560
|
+
memset(&factx, 0, sizeof(factx));
|
|
1561
|
+
factx.octx = octx;
|
|
1562
|
+
factx.sinks = octx->src[4]; // NULL if this op has no attention sinks
|
|
1563
|
+
factx.n_threads = kparams->n_threads;
|
|
1564
|
+
factx.DK = DK;
|
|
1565
|
+
factx.DV = DV;
|
|
1566
|
+
factx.n_kv = nek1;
|
|
1567
|
+
factx.n_kv_heads = n_kv_heads;
|
|
1568
|
+
factx.n_heads = neq2;
|
|
1569
|
+
factx.G = kparams->G;
|
|
1570
|
+
factx.div_G = kparams->u.hmx.div_G;
|
|
1571
|
+
factx.neq1 = neq1;
|
|
1572
|
+
factx.Br = kparams->Br;
|
|
1573
|
+
factx.Bc = kparams->Bc;
|
|
1574
|
+
factx.g_br = kparams->u.hmx.g_br;
|
|
1575
|
+
factx.n_kv_blocks = kparams->n_kv_blocks;
|
|
1576
|
+
factx.is_q_fp32 = (kparams->is_q_fp32 != 0);
|
|
1577
|
+
factx.is_dst_fp32 = (kparams->is_dst_fp32 != 0);
|
|
1578
|
+
factx.pipeline = (kparams->u.hmx.pipeline != 0);
|
|
1579
|
+
factx.mask_broadcast = (kparams->u.hmx.mask_broadcast != 0);
|
|
1580
|
+
if (mask) {
|
|
1581
|
+
factx.src3_div2 = kparams->src3_div2;
|
|
1582
|
+
factx.src3_div3 = kparams->src3_div3;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
if (kparams->logit_softcap == 0.0f) {
|
|
1586
|
+
factx.scale = (__fp16) (kparams->scale * EXP_LOG2E_F); // log2(e)
|
|
1587
|
+
} else {
|
|
1588
|
+
factx.scale = (__fp16) kparams->scale;
|
|
1589
|
+
}
|
|
1590
|
+
factx.max_bias = kparams->max_bias;
|
|
1591
|
+
factx.logit_softcap = (__fp16) (kparams->logit_softcap * EXP_LOG2E_F);
|
|
1592
|
+
|
|
1593
|
+
factx.n_head_log2 = kparams->n_head_log2;
|
|
1594
|
+
factx.m0 = kparams->m0;
|
|
1595
|
+
factx.m1 = kparams->m1;
|
|
1596
|
+
|
|
1597
|
+
const uint32_t Br = factx.Br;
|
|
1598
|
+
const uint32_t Bc = factx.Bc;
|
|
1599
|
+
const uint32_t g_br = factx.g_br;
|
|
1600
|
+
const bool pipeline = factx.pipeline;
|
|
1601
|
+
const uint32_t n_threads = factx.n_threads;
|
|
1602
|
+
const uint32_t G = factx.G;
|
|
1603
|
+
|
|
1604
|
+
// ======== VTCM allocation (GQA-aware) ========
|
|
1605
|
+
// K/V row sizes drive the DMA descriptors (not the VTCM layout) and are used
|
|
1606
|
+
// throughout the KV loop below.
|
|
1607
|
+
const size_t size_k_row = DK * sizeof(__fp16);
|
|
1608
|
+
const size_t size_v_row = DV * sizeof(__fp16);
|
|
1609
|
+
const size_t size_k_row_padded = hex_round_up(size_k_row, 128);
|
|
1610
|
+
const size_t size_v_row_padded = hex_round_up(size_v_row, 128);
|
|
1611
|
+
|
|
1612
|
+
// Build the VTCM layout once (shared with the host estimator) and place every
|
|
1613
|
+
// scratch buffer at its computed offset.
|
|
1614
|
+
struct hmx_fa_vtcm_layout L;
|
|
1615
|
+
hmx_fa_vtcm_layout_build(&L, G, DK, DV, Br, Bc, n_threads, pipeline);
|
|
1616
|
+
|
|
1617
|
+
if (L.total_bytes > ctx->vtcm_size) {
|
|
1618
|
+
return HTP_STATUS_VTCM_TOO_SMALL;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
uint8_t * const base = ctx->vtcm_base;
|
|
1622
|
+
|
|
1623
|
+
factx.vtcm_q_tiles = VTCM_LAYOUT_PTR(__fp16, base, L.off_q_tiles);
|
|
1624
|
+
factx.vtcm_o_tiles[0] = VTCM_LAYOUT_PTR(__fp16, base, L.off_o_tiles[0]);
|
|
1625
|
+
factx.vtcm_o_tiles[1] = VTCM_LAYOUT_PTR(__fp16, base, L.off_o_tiles[1]);
|
|
1626
|
+
factx.vtcm_k_fp16[0] = VTCM_LAYOUT_PTR(__fp16, base, L.off_k_fp16[0]);
|
|
1627
|
+
factx.vtcm_k_fp16[1] = VTCM_LAYOUT_PTR(__fp16, base, L.off_k_fp16[1]);
|
|
1628
|
+
factx.vtcm_v_fp16[0] = VTCM_LAYOUT_PTR(__fp16, base, L.off_v_fp16[0]);
|
|
1629
|
+
factx.vtcm_v_fp16[1] = VTCM_LAYOUT_PTR(__fp16, base, L.off_v_fp16[1]);
|
|
1630
|
+
factx.vtcm_k_tiles = VTCM_LAYOUT_PTR(__fp16, base, L.off_k_tiles);
|
|
1631
|
+
factx.vtcm_v_tiles[0] = VTCM_LAYOUT_PTR(__fp16, base, L.off_v_tiles[0]);
|
|
1632
|
+
factx.vtcm_v_tiles[1] = VTCM_LAYOUT_PTR_OPTIONAL(__fp16, base, L.off_v_tiles[1], pipeline);
|
|
1633
|
+
factx.vtcm_s_tiles = VTCM_LAYOUT_PTR(__fp16, base, L.off_s_tiles);
|
|
1634
|
+
factx.vtcm_p_tiles = VTCM_LAYOUT_PTR(__fp16, base, L.off_p_tiles);
|
|
1635
|
+
factx.vtcm_d_tiles = VTCM_LAYOUT_PTR(__fp16, base, L.off_d_tiles);
|
|
1636
|
+
factx.vtcm_m_vec = VTCM_LAYOUT_PTR(HVX_Vector, base, L.off_m_vec);
|
|
1637
|
+
factx.vtcm_l_vec = VTCM_LAYOUT_PTR(HVX_Vector, base, L.off_l_vec);
|
|
1638
|
+
factx.vtcm_s_rowmax = VTCM_LAYOUT_PTR(HVX_Vector, base, L.off_s_rowmax);
|
|
1639
|
+
factx.vtcm_p_rowsum = VTCM_LAYOUT_PTR(HVX_Vector, base, L.off_p_rowsum);
|
|
1640
|
+
factx.vtcm_row_bufs = VTCM_LAYOUT_PTR(HVX_Vector, base, L.off_row_bufs);
|
|
1641
|
+
factx.row_buf_stride = L.row_buf_stride;
|
|
1642
|
+
factx.vtcm_hmx_scales_id = VTCM_LAYOUT_PTR(uint8_t, base, L.off_hmx_scales_id);
|
|
1643
|
+
factx.vtcm_hmx_scales_qk = VTCM_LAYOUT_PTR(uint8_t, base, L.off_hmx_scales_qk);
|
|
1644
|
+
factx.vtcm_mask_buf = VTCM_LAYOUT_PTR(__fp16, base, L.off_mask_buf);
|
|
1645
|
+
factx.mask_buf_row_stride = L.mask_buf_row_stride;
|
|
1646
|
+
factx.q_tile_bytes = L.q_tile_bytes;
|
|
1647
|
+
factx.o_tile_bytes = L.o_tile_bytes;
|
|
1648
|
+
factx.col_vec_bytes = L.col_vec_bytes;
|
|
1649
|
+
factx.d_tile_bytes = L.d_tile_bytes;
|
|
1650
|
+
factx.vtcm_slopes = VTCM_LAYOUT_PTR(__fp16, base, L.off_slopes);
|
|
1651
|
+
|
|
1652
|
+
const size_t m_line_bytes = L.m_line_bytes; // used by the mask DMAs in the KV loop
|
|
1653
|
+
|
|
1654
|
+
dma_cache_init(&factx.m_cache, (uint8_t *) factx.vtcm_mask_buf, L.m_buf_slot_bytes, HMX_FA_DMA_CACHE_SIZE);
|
|
1655
|
+
|
|
1656
|
+
// ======== Initialize HMX output scales ========
|
|
1657
|
+
hmx_init_column_scales(factx.vtcm_hmx_scales_id, Q6_V_vsplat_R(0x3c00)); // 1.0
|
|
1658
|
+
hmx_init_column_scales(factx.vtcm_hmx_scales_qk, hvx_vec_splat_f16(factx.scale));
|
|
1659
|
+
|
|
1660
|
+
// ======== Skip compute if profiling ========
|
|
1661
|
+
if (octx->flags & HTP_OPFLAGS_SKIP_COMPUTE) {
|
|
1662
|
+
return HTP_STATUS_OK;
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// ======== DMA setup ========
|
|
1666
|
+
dma_queue * const dma = ctx->dma[0];
|
|
1667
|
+
|
|
1668
|
+
const size_t n_row_tiles_g_br = g_br / HMX_FP16_TILE_N_ROWS;
|
|
1669
|
+
const size_t n_tiles_per_bc = Bc / HMX_FP16_TILE_N_COLS;
|
|
1670
|
+
|
|
1671
|
+
const size_t qo_element_size = factx.is_q_fp32 ? sizeof(float) : sizeof(__fp16);
|
|
1672
|
+
|
|
1673
|
+
// ======== Reusable job descriptors for pipeline ========
|
|
1674
|
+
hmx_fa_qk_job_t qk_job;
|
|
1675
|
+
hmx_fa_o_update_job_t ou_job;
|
|
1676
|
+
hmx_fa_o_norm_job_t on_job;
|
|
1677
|
+
|
|
1678
|
+
// ======== Main loop ========
|
|
1679
|
+
for (uint32_t ib3 = 0; ib3 < neq3; ++ib3) {
|
|
1680
|
+
const uint32_t im3 = mask ? fastmodulo(ib3, mask->ne[3], &factx.src3_div3) : 0;
|
|
1681
|
+
for (uint32_t q_start = 0; q_start < neq1; q_start += Br) {
|
|
1682
|
+
const uint32_t n_rows_q = hex_smin(Br, neq1 - q_start);
|
|
1683
|
+
const size_t n_rows_g = n_rows_q * G;
|
|
1684
|
+
const size_t g_br_actual = hex_align_up(n_rows_g, HMX_FP16_TILE_N_ROWS);
|
|
1685
|
+
const size_t n_row_tiles = g_br_actual / HMX_FP16_TILE_N_ROWS;
|
|
1686
|
+
|
|
1687
|
+
for (uint32_t kv_head = 0; kv_head < n_kv_heads; ++kv_head) {
|
|
1688
|
+
const uint32_t ik2 = kv_head;
|
|
1689
|
+
const uint32_t ik3 = fastdiv(ib3, &kparams->broadcast_rk3);
|
|
1690
|
+
const uint32_t iv2 = kv_head;
|
|
1691
|
+
const uint32_t iv3 = fastdiv(ib3, &kparams->broadcast_rv3);
|
|
1692
|
+
|
|
1693
|
+
// 1. Push Q DMA (if Q DMA is used)
|
|
1694
|
+
const size_t o_tile_bytes = factx.o_tile_bytes;
|
|
1695
|
+
const bool use_q_dma = (2 * o_tile_bytes >= factx.g_br * factx.DK * (factx.is_q_fp32 ? 4 : 2));
|
|
1696
|
+
if (use_q_dma) {
|
|
1697
|
+
const bool q_transposed = q->nb[1] < q->nb[2];
|
|
1698
|
+
const uint8_t * q_ptr = (const uint8_t *) q->data + q_start * q->nb[1] + (kv_head * factx.G) * q->nb[2] + ib3 * q->nb[3];
|
|
1699
|
+
const size_t el_size = factx.is_q_fp32 ? sizeof(float) : sizeof(__fp16);
|
|
1700
|
+
const size_t q_row_bytes = q_transposed ? n_rows_q * factx.DK * el_size : factx.G * factx.DK * el_size;
|
|
1701
|
+
const size_t src_stride = q_transposed ? q->nb[2] : q->nb[1];
|
|
1702
|
+
const size_t n_rows = q_transposed ? factx.G : n_rows_q;
|
|
1703
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_o_tiles[0], q_ptr), q_row_bytes, hex_smax(src_stride, q_row_bytes), q_row_bytes, n_rows);
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
// 2. Prefetch first KV block
|
|
1707
|
+
if (factx.n_kv_blocks > 0) {
|
|
1708
|
+
const uint32_t kv_rows0 = hex_smin(Bc, nek1);
|
|
1709
|
+
|
|
1710
|
+
const uint8_t * k_src = (const uint8_t *) k->data + ik2 * k->nb[2] + ik3 * k->nb[3];
|
|
1711
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_k_fp16[0], k_src), size_k_row_padded, k->nb[1], size_k_row, kv_rows0);
|
|
1712
|
+
|
|
1713
|
+
const uint8_t * v_src = (const uint8_t *) v->data + iv2 * v->nb[2] + iv3 * v->nb[3];
|
|
1714
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_v_fp16[0], v_src), size_v_row_padded, v->nb[1], size_v_row, kv_rows0);
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
// 3. Pop Q DMA (blocks until Q is loaded)
|
|
1718
|
+
if (use_q_dma) {
|
|
1719
|
+
dma_queue_pop(dma);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
// ---- Load Q block & Initialize per-block state ----
|
|
1723
|
+
fa_phase_q_load(&factx, q, q_start, kv_head, ib3, n_rows_g);
|
|
1724
|
+
|
|
1725
|
+
__fp16 * o_tile_prev = factx.vtcm_o_tiles[0];
|
|
1726
|
+
__fp16 * o_tile_curr = factx.vtcm_o_tiles[1];
|
|
1727
|
+
|
|
1728
|
+
// ---- KV block loop with DMA double-buffering ----
|
|
1729
|
+
size_t buf_idx = 0;
|
|
1730
|
+
|
|
1731
|
+
htp_trace_event_start(tr_hvx, HTP_TRACE_EVT_HVX_A_PREP, (uint16_t) q_start);
|
|
1732
|
+
fa_compute_slopes(&factx, kv_head, n_rows_g);
|
|
1733
|
+
htp_trace_event_stop(tr_hvx, HTP_TRACE_EVT_HVX_A_PREP, (uint16_t) q_start);
|
|
1734
|
+
|
|
1735
|
+
const size_t k_src_stride = size_k_row_padded / sizeof(__fp16);
|
|
1736
|
+
const size_t v_src_stride = size_v_row_padded / sizeof(__fp16);
|
|
1737
|
+
|
|
1738
|
+
struct hmx_queue * hmx_q = ctx->hmx_queue;
|
|
1739
|
+
|
|
1740
|
+
if (factx.pipeline) {
|
|
1741
|
+
// Pipeline path
|
|
1742
|
+
for (uint32_t kv_blk = 0; kv_blk < factx.n_kv_blocks; ++kv_blk) {
|
|
1743
|
+
const uint32_t kv_start = kv_blk * Bc;
|
|
1744
|
+
const uint32_t kv_rows = hex_smin(Bc, nek1 - kv_start);
|
|
1745
|
+
const size_t n_col_tiles = hmx_ceil_div(kv_rows, HMX_FP16_TILE_N_COLS);
|
|
1746
|
+
|
|
1747
|
+
// Push mask DMA
|
|
1748
|
+
if (mask) {
|
|
1749
|
+
if (__builtin_expect(factx.mask_broadcast, true)) {
|
|
1750
|
+
const uint8_t * ms_src = (const uint8_t *) mask->data + q_start * mask->nb[1] + im3 * mask->nb[3] + kv_start * sizeof(__fp16);
|
|
1751
|
+
dma_cache_push(dma, &factx.m_cache, ms_src, m_line_bytes, mask->nb[1], kv_rows * sizeof(__fp16), n_rows_q);
|
|
1752
|
+
} else {
|
|
1753
|
+
fa_push_mask_dma_gqa(dma, mask, q_start, im3, kv_start, kv_head, G, m_line_bytes, kv_rows, n_rows_q, &factx);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
// Prefetch next KV block early
|
|
1758
|
+
if (kv_blk + 1 < factx.n_kv_blocks) {
|
|
1759
|
+
const uint32_t prefetch_start = (kv_blk + 1) * Bc;
|
|
1760
|
+
const uint32_t prefetch_rows = hex_smin(Bc, nek1 - prefetch_start);
|
|
1761
|
+
const size_t prefetch_buf = 1 - buf_idx;
|
|
1762
|
+
const uint8_t * k_prefetch_src = (const uint8_t *) k->data + prefetch_start * k->nb[1] + ik2 * k->nb[2] + ik3 * k->nb[3];
|
|
1763
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_k_fp16[prefetch_buf], k_prefetch_src), size_k_row_padded, k->nb[1], size_k_row, prefetch_rows);
|
|
1764
|
+
const uint8_t * v_prefetch_src = (const uint8_t *) v->data + prefetch_start * v->nb[1] + iv2 * v->nb[2] + iv3 * v->nb[3];
|
|
1765
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_v_fp16[prefetch_buf], v_prefetch_src), size_v_row_padded, v->nb[1], size_v_row, prefetch_rows);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
// ---- Phase 1: K_int ----
|
|
1769
|
+
if (kv_blk > 0) {
|
|
1770
|
+
ou_job.o_curr = o_tile_curr;
|
|
1771
|
+
ou_job.o_prev = o_tile_prev;
|
|
1772
|
+
ou_job.p_tiles = factx.vtcm_p_tiles;
|
|
1773
|
+
ou_job.v_tiles = factx.vtcm_v_tiles[1 - buf_idx];
|
|
1774
|
+
ou_job.d_tiles = factx.vtcm_d_tiles;
|
|
1775
|
+
ou_job.hmx_scales = factx.vtcm_hmx_scales_id;
|
|
1776
|
+
ou_job.n_row_tiles = n_row_tiles;
|
|
1777
|
+
ou_job.n_col_tiles = hmx_ceil_div(hex_smin(Bc, nek1 - (kv_blk - 1) * Bc), HMX_FP16_TILE_N_COLS);
|
|
1778
|
+
ou_job.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1779
|
+
ou_job.n_tiles_per_bc = n_tiles_per_bc;
|
|
1780
|
+
ou_job.DV = DV;
|
|
1781
|
+
hmx_queue_push(hmx_q, hmx_queue_make_desc(hmx_fa_o_update_worker, &ou_job));
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// Wait for current K DMA and interleave
|
|
1785
|
+
void * curr_k = dma_queue_pop(dma).dst;
|
|
1786
|
+
fa_phase_k_interleave(&factx, kv_rows, k_src_stride, curr_k, kv_start);
|
|
1787
|
+
|
|
1788
|
+
// ---- Phase 2: qk_dot ----
|
|
1789
|
+
qk_job.q_tiles = factx.vtcm_q_tiles;
|
|
1790
|
+
qk_job.k_tiles = factx.vtcm_k_tiles;
|
|
1791
|
+
qk_job.s_tiles = factx.vtcm_s_tiles;
|
|
1792
|
+
qk_job.n_row_tiles = n_row_tiles;
|
|
1793
|
+
qk_job.n_col_tiles = n_col_tiles;
|
|
1794
|
+
qk_job.n_dot_tiles = DK / 32;
|
|
1795
|
+
qk_job.n_tiles_per_bc = n_tiles_per_bc;
|
|
1796
|
+
qk_job.hmx_scales = factx.vtcm_hmx_scales_qk;
|
|
1797
|
+
hmx_queue_push(hmx_q, hmx_queue_make_desc(hmx_fa_qk_dot_worker, &qk_job));
|
|
1798
|
+
|
|
1799
|
+
// Wait for current V DMA and interleave
|
|
1800
|
+
void * curr_v = dma_queue_pop(dma).dst;
|
|
1801
|
+
fa_phase_v_interleave(&factx, kv_rows, v_src_stride, curr_v, factx.vtcm_v_tiles[buf_idx], n_tiles_per_bc, kv_start);
|
|
1802
|
+
|
|
1803
|
+
if (kv_blk > 0) {
|
|
1804
|
+
hmx_queue_pop(hmx_q);
|
|
1805
|
+
hex_swap_ptr((void **) &o_tile_curr, (void **) &o_tile_prev);
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
hmx_queue_pop(hmx_q);
|
|
1809
|
+
|
|
1810
|
+
// ---- Phase 3: softmax + build_D ----
|
|
1811
|
+
__fp16 * current_mask_vtcm = NULL;
|
|
1812
|
+
if (mask) {
|
|
1813
|
+
if (__builtin_expect(factx.mask_broadcast, true)) {
|
|
1814
|
+
current_mask_vtcm = (__fp16 *) dma_queue_pop(dma).dst;
|
|
1815
|
+
} else {
|
|
1816
|
+
fa_pop_mask_dma_gqa(dma, G);
|
|
1817
|
+
current_mask_vtcm = factx.vtcm_mask_buf;
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
fa_softmax_args_t sargs;
|
|
1822
|
+
memset(&sargs, 0, sizeof(sargs));
|
|
1823
|
+
sargs.factx = &factx;
|
|
1824
|
+
sargs.kv_rows = kv_rows;
|
|
1825
|
+
sargs.n_rows_g = n_rows_g;
|
|
1826
|
+
sargs.n_col_tiles = n_col_tiles;
|
|
1827
|
+
sargs.n_tiles_per_bc = n_tiles_per_bc;
|
|
1828
|
+
sargs.n_row_tiles = n_row_tiles;
|
|
1829
|
+
sargs.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1830
|
+
sargs.Bc = Bc;
|
|
1831
|
+
sargs.G = G;
|
|
1832
|
+
sargs.kv_head = kv_head;
|
|
1833
|
+
sargs.kv_start = kv_start;
|
|
1834
|
+
sargs.q_start = q_start;
|
|
1835
|
+
sargs.ib3 = ib3;
|
|
1836
|
+
sargs.has_alibi = (factx.max_bias != 0.0f);
|
|
1837
|
+
sargs.mask = mask;
|
|
1838
|
+
sargs.mask_vtcm = current_mask_vtcm;
|
|
1839
|
+
sargs.mask_vtcm_row_stride = factx.mask_buf_row_stride;
|
|
1840
|
+
sargs.slopes = factx.vtcm_slopes;
|
|
1841
|
+
fa_phase_softmax_and_build_d(&factx, &sargs, n_row_tiles, n_row_tiles_g_br);
|
|
1842
|
+
|
|
1843
|
+
buf_idx = 1 - buf_idx;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// Epilogue
|
|
1847
|
+
if (factx.n_kv_blocks > 0) {
|
|
1848
|
+
const uint32_t last_blk = factx.n_kv_blocks - 1;
|
|
1849
|
+
const size_t last_cols = hmx_ceil_div(hex_smin(Bc, nek1 - last_blk * Bc), HMX_FP16_TILE_N_COLS);
|
|
1850
|
+
ou_job.o_curr = o_tile_curr;
|
|
1851
|
+
ou_job.o_prev = o_tile_prev;
|
|
1852
|
+
ou_job.p_tiles = factx.vtcm_p_tiles;
|
|
1853
|
+
ou_job.v_tiles = factx.vtcm_v_tiles[1 - buf_idx];
|
|
1854
|
+
ou_job.d_tiles = factx.vtcm_d_tiles;
|
|
1855
|
+
ou_job.hmx_scales = factx.vtcm_hmx_scales_id;
|
|
1856
|
+
ou_job.n_row_tiles = n_row_tiles;
|
|
1857
|
+
ou_job.n_col_tiles = last_cols;
|
|
1858
|
+
ou_job.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1859
|
+
ou_job.n_tiles_per_bc = n_tiles_per_bc;
|
|
1860
|
+
ou_job.DV = DV;
|
|
1861
|
+
hmx_queue_push(hmx_q, hmx_queue_make_desc(hmx_fa_o_update_worker, &ou_job));
|
|
1862
|
+
hmx_queue_pop(hmx_q);
|
|
1863
|
+
|
|
1864
|
+
hex_swap_ptr((void **) &o_tile_curr, (void **) &o_tile_prev);
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
} else {
|
|
1868
|
+
// Fallback path
|
|
1869
|
+
for (uint32_t kv_blk = 0; kv_blk < factx.n_kv_blocks; ++kv_blk) {
|
|
1870
|
+
const uint32_t kv_start = kv_blk * Bc;
|
|
1871
|
+
const uint32_t kv_rows = hex_smin(Bc, nek1 - kv_start);
|
|
1872
|
+
const size_t n_col_tiles = hmx_ceil_div(kv_rows, HMX_FP16_TILE_N_COLS);
|
|
1873
|
+
|
|
1874
|
+
if (mask) {
|
|
1875
|
+
if (__builtin_expect(factx.mask_broadcast, true)) {
|
|
1876
|
+
const uint8_t * ms_src = (const uint8_t *) mask->data + q_start * mask->nb[1] + im3 * mask->nb[3] + kv_start * sizeof(__fp16);
|
|
1877
|
+
dma_cache_push(dma, &factx.m_cache, ms_src, m_line_bytes, mask->nb[1], kv_rows * sizeof(__fp16), n_rows_q);
|
|
1878
|
+
} else {
|
|
1879
|
+
fa_push_mask_dma_gqa(dma, mask, q_start, im3, kv_start, kv_head, G, m_line_bytes, kv_rows, n_rows_q, &factx);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
if (kv_blk + 1 < factx.n_kv_blocks) {
|
|
1884
|
+
const uint32_t prefetch_start = (kv_blk + 1) * Bc;
|
|
1885
|
+
const uint32_t prefetch_rows = hex_smin(Bc, nek1 - prefetch_start);
|
|
1886
|
+
const size_t prefetch_buf = 1 - buf_idx;
|
|
1887
|
+
const uint8_t * k_prefetch_src = (const uint8_t *) k->data + prefetch_start * k->nb[1] + ik2 * k->nb[2] + ik3 * k->nb[3];
|
|
1888
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_k_fp16[prefetch_buf], k_prefetch_src), size_k_row_padded, k->nb[1], size_k_row, prefetch_rows);
|
|
1889
|
+
const uint8_t * v_prefetch_src = (const uint8_t *) v->data + prefetch_start * v->nb[1] + iv2 * v->nb[2] + iv3 * v->nb[3];
|
|
1890
|
+
dma_queue_push(dma, dma_make_ptr(factx.vtcm_v_fp16[prefetch_buf], v_prefetch_src), size_v_row_padded, v->nb[1], size_v_row, prefetch_rows);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
// Wait for current K DMA and interleave
|
|
1894
|
+
void * curr_k = dma_queue_pop(dma).dst;
|
|
1895
|
+
fa_phase_k_interleave(&factx, kv_rows, k_src_stride, curr_k, kv_start);
|
|
1896
|
+
|
|
1897
|
+
{
|
|
1898
|
+
qk_job.q_tiles = factx.vtcm_q_tiles;
|
|
1899
|
+
qk_job.k_tiles = factx.vtcm_k_tiles;
|
|
1900
|
+
qk_job.s_tiles = factx.vtcm_s_tiles;
|
|
1901
|
+
qk_job.n_row_tiles = n_row_tiles;
|
|
1902
|
+
qk_job.n_col_tiles = n_col_tiles;
|
|
1903
|
+
qk_job.n_dot_tiles = (size_t) (DK / 32);
|
|
1904
|
+
qk_job.n_tiles_per_bc = n_tiles_per_bc;
|
|
1905
|
+
qk_job.hmx_scales = factx.vtcm_hmx_scales_qk;
|
|
1906
|
+
|
|
1907
|
+
hmx_queue_push(ctx->hmx_queue, hmx_queue_make_desc(hmx_fa_qk_dot_worker, &qk_job));
|
|
1908
|
+
hmx_queue_pop(ctx->hmx_queue);
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
// Wait for current V DMA and interleave
|
|
1912
|
+
void * curr_v = dma_queue_pop(dma).dst;
|
|
1913
|
+
fa_phase_v_interleave(&factx, kv_rows, v_src_stride, curr_v, factx.vtcm_v_tiles[0], n_tiles_per_bc, kv_start);
|
|
1914
|
+
|
|
1915
|
+
// ---- Phase 3: softmax + build_D ----
|
|
1916
|
+
__fp16 * current_mask_vtcm = NULL;
|
|
1917
|
+
if (mask) {
|
|
1918
|
+
if (__builtin_expect(factx.mask_broadcast, true)) {
|
|
1919
|
+
current_mask_vtcm = (__fp16 *) dma_queue_pop(dma).dst;
|
|
1920
|
+
} else {
|
|
1921
|
+
fa_pop_mask_dma_gqa(dma, G);
|
|
1922
|
+
current_mask_vtcm = factx.vtcm_mask_buf;
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
fa_softmax_args_t sargs;
|
|
1927
|
+
memset(&sargs, 0, sizeof(sargs));
|
|
1928
|
+
sargs.factx = &factx;
|
|
1929
|
+
sargs.kv_rows = kv_rows;
|
|
1930
|
+
sargs.n_rows_g = n_rows_g;
|
|
1931
|
+
sargs.n_col_tiles = n_col_tiles;
|
|
1932
|
+
sargs.n_tiles_per_bc = n_tiles_per_bc;
|
|
1933
|
+
sargs.n_row_tiles = n_row_tiles;
|
|
1934
|
+
sargs.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1935
|
+
sargs.Bc = Bc;
|
|
1936
|
+
sargs.G = G;
|
|
1937
|
+
sargs.kv_head = kv_head;
|
|
1938
|
+
sargs.kv_start = kv_start;
|
|
1939
|
+
sargs.q_start = q_start;
|
|
1940
|
+
sargs.ib3 = ib3;
|
|
1941
|
+
sargs.has_alibi = (factx.max_bias != 0.0f);
|
|
1942
|
+
sargs.mask = mask;
|
|
1943
|
+
sargs.mask_vtcm = current_mask_vtcm;
|
|
1944
|
+
sargs.mask_vtcm_row_stride = factx.mask_buf_row_stride;
|
|
1945
|
+
sargs.slopes = factx.vtcm_slopes;
|
|
1946
|
+
fa_phase_softmax_and_build_d(&factx, &sargs, n_row_tiles, n_row_tiles_g_br);
|
|
1947
|
+
|
|
1948
|
+
{
|
|
1949
|
+
ou_job.o_curr = o_tile_curr;
|
|
1950
|
+
ou_job.o_prev = o_tile_prev;
|
|
1951
|
+
ou_job.p_tiles = factx.vtcm_p_tiles;
|
|
1952
|
+
ou_job.v_tiles = factx.vtcm_v_tiles[0];
|
|
1953
|
+
ou_job.d_tiles = factx.vtcm_d_tiles;
|
|
1954
|
+
ou_job.hmx_scales = factx.vtcm_hmx_scales_id;
|
|
1955
|
+
ou_job.n_row_tiles = n_row_tiles;
|
|
1956
|
+
ou_job.n_col_tiles = n_col_tiles;
|
|
1957
|
+
ou_job.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1958
|
+
ou_job.n_tiles_per_bc = n_tiles_per_bc;
|
|
1959
|
+
ou_job.DV = DV;
|
|
1960
|
+
|
|
1961
|
+
hmx_queue_push(ctx->hmx_queue, hmx_queue_make_desc(hmx_fa_o_update_worker, &ou_job));
|
|
1962
|
+
hmx_queue_pop(ctx->hmx_queue);
|
|
1963
|
+
|
|
1964
|
+
hex_swap_ptr((void **) &o_tile_curr, (void **) &o_tile_prev);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
buf_idx = 1 - buf_idx;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// ---- Final normalization ----
|
|
1972
|
+
{
|
|
1973
|
+
htp_trace_event_start(tr_hvx, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) q_start);
|
|
1974
|
+
fa_build_d_diag_inv_l(&factx, n_row_tiles, n_row_tiles_g_br);
|
|
1975
|
+
htp_trace_event_stop(tr_hvx, HTP_TRACE_EVT_HVX_O_PROC, (uint16_t) q_start);
|
|
1976
|
+
|
|
1977
|
+
on_job.o_curr = o_tile_curr;
|
|
1978
|
+
on_job.o_prev = o_tile_prev;
|
|
1979
|
+
on_job.d_tiles = factx.vtcm_d_tiles;
|
|
1980
|
+
on_job.hmx_scales = factx.vtcm_hmx_scales_id;
|
|
1981
|
+
on_job.n_row_tiles = n_row_tiles;
|
|
1982
|
+
on_job.n_row_tiles_g_br = n_row_tiles_g_br;
|
|
1983
|
+
on_job.DV = DV;
|
|
1984
|
+
hmx_queue_push(ctx->hmx_queue, hmx_queue_make_desc(hmx_fa_o_norm_worker, &on_job));
|
|
1985
|
+
hmx_queue_pop(ctx->hmx_queue);
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// ---- Store O block ----
|
|
1989
|
+
fa_phase_o_store(&factx, dst, o_tile_curr, q_start, kv_head, ib3, n_rows_g);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
return HTP_STATUS_OK;
|
|
1995
|
+
}
|
|
1996
|
+
|
|
610
1997
|
int op_flash_attn_ext(struct htp_ops_context * octx) {
|
|
611
|
-
const struct htp_tensor * q
|
|
612
|
-
const struct htp_tensor * k
|
|
613
|
-
const struct htp_tensor * v
|
|
614
|
-
const struct htp_tensor * mask =
|
|
615
|
-
const struct htp_tensor * dst
|
|
1998
|
+
const struct htp_tensor * q = octx->src[0];
|
|
1999
|
+
const struct htp_tensor * k = octx->src[1];
|
|
2000
|
+
const struct htp_tensor * v = octx->src[2];
|
|
2001
|
+
const struct htp_tensor * mask = octx->src[3];
|
|
2002
|
+
const struct htp_tensor * dst = octx->dst;
|
|
616
2003
|
|
|
617
2004
|
// Check support
|
|
618
2005
|
if ((q->type != HTP_TYPE_F16 && q->type != HTP_TYPE_F32) || k->type != HTP_TYPE_F16 || v->type != HTP_TYPE_F16) {
|
|
619
2006
|
return HTP_STATUS_NO_SUPPORT;
|
|
620
2007
|
}
|
|
621
2008
|
|
|
2009
|
+
const struct htp_fa_kernel_params * kparams = (const struct htp_fa_kernel_params *) octx->kernel_params;
|
|
2010
|
+
|
|
2011
|
+
if (kparams->kernel_type == HTP_FA_KERNEL_UNSUPPORTED) {
|
|
2012
|
+
return HTP_STATUS_NO_SUPPORT;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
if (kparams->kernel_type == HTP_FA_KERNEL_HMX) {
|
|
2016
|
+
return hmx_flash_attn_ext(octx);
|
|
2017
|
+
}
|
|
2018
|
+
|
|
622
2019
|
struct htp_fa_context factx;
|
|
623
2020
|
factx.octx = octx;
|
|
624
2021
|
|
|
625
2022
|
factx.t_start = HAP_perf_get_qtimer_count();
|
|
626
2023
|
|
|
627
|
-
factx.src0_div21 =
|
|
628
|
-
factx.src0_div1 =
|
|
2024
|
+
factx.src0_div21 = kparams->u.hvx.src0_div21;
|
|
2025
|
+
factx.src0_div1 = kparams->u.hvx.src0_div1;
|
|
629
2026
|
|
|
630
|
-
factx.broadcast_rk2 =
|
|
631
|
-
factx.broadcast_rk3 =
|
|
632
|
-
factx.broadcast_rv2 =
|
|
633
|
-
factx.broadcast_rv3 =
|
|
2027
|
+
factx.broadcast_rk2 = kparams->broadcast_rk2;
|
|
2028
|
+
factx.broadcast_rk3 = kparams->broadcast_rk3;
|
|
2029
|
+
factx.broadcast_rv2 = kparams->broadcast_rv2;
|
|
2030
|
+
factx.broadcast_rv3 = kparams->broadcast_rv3;
|
|
634
2031
|
|
|
635
2032
|
if (mask) {
|
|
636
|
-
factx.src3_div2 =
|
|
637
|
-
factx.src3_div3 =
|
|
2033
|
+
factx.src3_div2 = kparams->src3_div2;
|
|
2034
|
+
factx.src3_div3 = kparams->src3_div3;
|
|
638
2035
|
}
|
|
639
2036
|
|
|
640
|
-
factx.is_q_fp32 = (
|
|
641
|
-
factx.size_q_row_padded =
|
|
642
|
-
factx.size_k_row_padded =
|
|
643
|
-
factx.size_v_row_padded =
|
|
2037
|
+
factx.is_q_fp32 = (kparams->is_q_fp32 != 0);
|
|
2038
|
+
factx.size_q_row_padded = kparams->u.hvx.size_q_row_padded;
|
|
2039
|
+
factx.size_k_row_padded = kparams->u.hvx.size_k_row_padded;
|
|
2040
|
+
factx.size_v_row_padded = kparams->u.hvx.size_v_row_padded;
|
|
644
2041
|
|
|
645
2042
|
size_t size_q_block = factx.size_q_row_padded * 1; // single row for now
|
|
646
2043
|
factx.size_k_block = factx.size_k_row_padded * FLASH_ATTN_BLOCK_SIZE;
|
|
647
2044
|
factx.size_v_block = factx.size_v_row_padded * FLASH_ATTN_BLOCK_SIZE;
|
|
648
2045
|
factx.size_m_block = hex_round_up(FLASH_ATTN_BLOCK_SIZE * sizeof(__fp16), 128);
|
|
649
2046
|
|
|
650
|
-
factx.n_blocks =
|
|
2047
|
+
factx.n_blocks = kparams->n_kv_blocks;
|
|
651
2048
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
2049
|
+
factx.scale = kparams->scale;
|
|
2050
|
+
factx.max_bias = kparams->max_bias;
|
|
2051
|
+
factx.logit_softcap = (__fp16) kparams->logit_softcap;
|
|
655
2052
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
2053
|
+
factx.n_head_log2 = kparams->n_head_log2;
|
|
2054
|
+
factx.m0 = kparams->m0;
|
|
2055
|
+
factx.m1 = kparams->m1;
|
|
659
2056
|
|
|
660
|
-
|
|
661
|
-
|
|
2057
|
+
const uint32_t n_head = q->ne[2];
|
|
2058
|
+
if (n_head > 512) {
|
|
2059
|
+
return HTP_STATUS_NO_SUPPORT;
|
|
2060
|
+
}
|
|
2061
|
+
for (uint32_t h = 0; h < n_head; ++h) {
|
|
2062
|
+
factx.slopes[h] = (__fp16) ((kparams->max_bias > 0.0f) ? alibi_slope(h, factx.n_head_log2, factx.m0, factx.m1) : 1.0f);
|
|
662
2063
|
}
|
|
663
|
-
|
|
664
|
-
factx.scale = scale;
|
|
665
|
-
factx.max_bias = max_bias;
|
|
666
|
-
factx.logit_softcap = logit_softcap;
|
|
667
|
-
|
|
668
|
-
uint32_t n_head = q->ne[2];
|
|
669
|
-
factx.n_head_log2 = 1u << (uint32_t) floor(log2(n_head));
|
|
670
|
-
factx.m0 = powf(2.0f, -(max_bias ) / factx.n_head_log2);
|
|
671
|
-
factx.m1 = powf(2.0f, -(max_bias / 2.0f) / factx.n_head_log2);
|
|
672
2064
|
|
|
673
2065
|
// total rows in q
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
const uint32_t neq2 = q->ne[2];
|
|
677
|
-
const uint32_t neq3 = q->ne[3];
|
|
678
|
-
|
|
679
|
-
factx.qrows = neq1*neq2*neq3;
|
|
680
|
-
factx.qrows_per_thread = (factx.qrows + octx->n_threads - 1) / octx->n_threads;
|
|
2066
|
+
factx.qrows = kparams->qrows;
|
|
2067
|
+
factx.qrows_per_thread = kparams->qrows_per_thread;
|
|
681
2068
|
|
|
682
2069
|
size_t size_vkq_acc = hex_round_up(v->ne[0] * sizeof(float), 128); // VKQ32
|
|
683
2070
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
octx->src2_spad.size_per_thread = factx.size_v_block * 2;
|
|
687
|
-
octx->src3_spad.size_per_thread = mask ? factx.size_m_block * 2 : 0;
|
|
688
|
-
octx->dst_spad.size_per_thread = size_vkq_acc;
|
|
2071
|
+
factx.size_q_block = size_q_block;
|
|
2072
|
+
factx.size_vkq_acc = size_vkq_acc;
|
|
689
2073
|
|
|
690
|
-
|
|
691
|
-
octx->src1_spad.size = octx->src1_spad.size_per_thread * octx->n_threads;
|
|
692
|
-
octx->src2_spad.size = octx->src2_spad.size_per_thread * octx->n_threads;
|
|
693
|
-
octx->src3_spad.size = octx->src3_spad.size_per_thread * octx->n_threads;
|
|
694
|
-
octx->dst_spad.size = octx->dst_spad.size_per_thread * octx->n_threads;
|
|
2074
|
+
uint8_t * vtcm_cur = octx->ctx->vtcm_base;
|
|
695
2075
|
|
|
696
|
-
|
|
2076
|
+
factx.spad_q = vtcm_seq_alloc(&vtcm_cur, size_q_block * octx->n_threads);
|
|
2077
|
+
factx.spad_k = vtcm_seq_alloc(&vtcm_cur, factx.size_k_block * 2 * octx->n_threads);
|
|
2078
|
+
factx.spad_v = vtcm_seq_alloc(&vtcm_cur, factx.size_v_block * 2 * octx->n_threads);
|
|
2079
|
+
factx.spad_m = vtcm_seq_alloc(&vtcm_cur, (mask ? factx.size_m_block * HVX_FA_DMA_CACHE_SIZE : 0) * octx->n_threads);
|
|
2080
|
+
factx.spad_a = vtcm_seq_alloc(&vtcm_cur, size_vkq_acc * octx->n_threads);
|
|
697
2081
|
|
|
698
|
-
if (octx->ctx->
|
|
2082
|
+
if ((size_t) (vtcm_cur - octx->ctx->vtcm_base) > octx->ctx->vtcm_size) {
|
|
699
2083
|
return HTP_STATUS_VTCM_TOO_SMALL;
|
|
700
2084
|
}
|
|
701
2085
|
|
|
702
|
-
octx->src0_spad.data = octx->ctx->vtcm_base;
|
|
703
|
-
octx->src1_spad.data = octx->src0_spad.data + octx->src0_spad.size;
|
|
704
|
-
octx->src2_spad.data = octx->src1_spad.data + octx->src1_spad.size;
|
|
705
|
-
octx->src3_spad.data = octx->src2_spad.data + octx->src2_spad.size;
|
|
706
|
-
octx->dst_spad.data = octx->src3_spad.data + octx->src3_spad.size;
|
|
707
|
-
|
|
708
2086
|
if (!(octx->flags & HTP_OPFLAGS_SKIP_COMPUTE)) {
|
|
709
2087
|
worker_pool_run_func(octx->ctx->worker_pool, flash_attn_ext_f16_thread, &factx, octx->n_threads);
|
|
710
2088
|
}
|