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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#ifndef GGML_WEBGPU_SHADER_LIB_HPP
|
|
2
2
|
#define GGML_WEBGPU_SHADER_LIB_HPP
|
|
3
3
|
|
|
4
|
+
#include "ggml-impl.h"
|
|
4
5
|
#include "ggml-wgsl-shaders.hpp"
|
|
5
6
|
#include "ggml.h"
|
|
6
7
|
#include "pre_wgsl.hpp"
|
|
@@ -17,6 +18,9 @@
|
|
|
17
18
|
#define GGML_WEBGPU_F32_SIZE_BYTES 4
|
|
18
19
|
#define GGML_WEBGPU_I32_SIZE_BYTES 4
|
|
19
20
|
#define GGML_WEBGPU_FLASH_ATTN_PREFERRED_KV_SG_TILES 8u
|
|
21
|
+
#define GGML_WEBGPU_FLASH_ATTN_VEC_MAX_SEQ_LEN 20u
|
|
22
|
+
#define GGML_WEBGPU_FLASH_ATTN_VEC_MAX_KV_TILE 32u
|
|
23
|
+
#define GGML_WEBGPU_FLASH_ATTN_TILE_MAX_KV_TILE 64u
|
|
20
24
|
#define GGML_WEBGPU_FLASH_ATTN_PREFERRED_WG_SIZE 128u
|
|
21
25
|
// Matches GGML_PAD(..., 256) in src/llama-context.cpp for KV cache sizing.
|
|
22
26
|
#define GGML_WEBGPU_KV_SEQ_PAD 256u
|
|
@@ -26,38 +30,32 @@
|
|
|
26
30
|
// Matrix multiplication parameters
|
|
27
31
|
|
|
28
32
|
// Register tiling parameters
|
|
29
|
-
#define WEBGPU_MUL_MAT_TILE_M
|
|
30
|
-
#define WEBGPU_MUL_MAT_TILE_N
|
|
31
|
-
#define WEBGPU_MUL_MAT_WG_SIZE_M
|
|
32
|
-
#define WEBGPU_MUL_MAT_WG_SIZE_N
|
|
33
|
-
#define
|
|
33
|
+
#define WEBGPU_MUL_MAT_TILE_M 4
|
|
34
|
+
#define WEBGPU_MUL_MAT_TILE_N 4
|
|
35
|
+
#define WEBGPU_MUL_MAT_WG_SIZE_M 8
|
|
36
|
+
#define WEBGPU_MUL_MAT_WG_SIZE_N 8
|
|
37
|
+
#define WEBGPU_MUL_MAT_REG_TILE_K_FLOAT 8
|
|
38
|
+
#define WEBGPU_MUL_MAT_REG_TILE_K_QUANT 32
|
|
34
39
|
|
|
35
40
|
// Subgroup matrix parameters
|
|
36
41
|
// The number of subgroups in the M dimension
|
|
37
|
-
#define WEBGPU_MUL_MAT_SUBGROUP_M
|
|
42
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_M 2
|
|
38
43
|
// The number of subgroups in the N dimension
|
|
39
|
-
#define WEBGPU_MUL_MAT_SUBGROUP_N
|
|
44
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_N 4
|
|
40
45
|
// The number of subgroup matrices each subgroup accumulates over
|
|
41
|
-
#define WEBGPU_MUL_MAT_SUBGROUP_MATRIX_M
|
|
42
|
-
#define WEBGPU_MUL_MAT_SUBGROUP_MATRIX_N
|
|
46
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_MATRIX_M 4
|
|
47
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_MATRIX_N 2
|
|
48
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_TILE_K_FLOAT 32
|
|
49
|
+
#define WEBGPU_MUL_MAT_SUBGROUP_TILE_K_QUANT 32
|
|
43
50
|
|
|
44
51
|
// Matrix-vector multiplication parameters
|
|
45
52
|
#define WEBGPU_MUL_MAT_VEC_WG_SIZE 256
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#define
|
|
50
|
-
#define WEBGPU_MUL_MAT_VEC_FLOAT_TILE_K 256
|
|
54
|
+
#define WEBGPU_MUL_MAT_VEC_FLOAT_OUTPUTS_PER_WG 4
|
|
55
|
+
#define WEBGPU_MUL_MAT_VEC_LEGACY_Q_OUTPUTS_PER_WG 4
|
|
56
|
+
#define WEBGPU_MUL_MAT_VEC_K_Q_OUTPUTS_PER_WG 4
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
#define WEBGPU_MUL_MAT_VEC_LEGACY_Q_TILE_K 256
|
|
54
|
-
|
|
55
|
-
// Requires 32 threads per output (wg_size/outputs_per_wg == 32)
|
|
56
|
-
#define WEBGPU_MUL_MAT_VEC_K_Q_OUTPUTS_PER_WG 8
|
|
57
|
-
// Requires at least two (and multiple of 2) k-quant blocks per tile
|
|
58
|
-
#define WEBGPU_MUL_MAT_VEC_K_Q_TILE_K 512
|
|
59
|
-
|
|
60
|
-
// default size for legacy matrix multiplication
|
|
58
|
+
// default size for reg-tile matrix multiplication
|
|
61
59
|
#define WEBGPU_MUL_MAT_WG_SIZE 256
|
|
62
60
|
|
|
63
61
|
// Same hash combine function as in boost
|
|
@@ -65,24 +63,41 @@ template <typename T> inline void ggml_webgpu_hash_combine(size_t & seed, const
|
|
|
65
63
|
seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
66
64
|
}
|
|
67
65
|
|
|
66
|
+
// Calculates base address of a tensor ignoring the fake base pointer
|
|
67
|
+
inline uintptr_t ggml_webgpu_tensor_addr(const ggml_tensor * tensor) {
|
|
68
|
+
const ggml_tensor * base_tensor = tensor->view_src ? tensor->view_src : tensor;
|
|
69
|
+
return (uintptr_t) base_tensor->data + tensor->view_offs;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
inline bool ggml_webgpu_tensor_equal(const ggml_tensor * a, const ggml_tensor * b) {
|
|
73
|
+
return a->buffer == b->buffer && ggml_webgpu_tensor_addr(a) == ggml_webgpu_tensor_addr(b);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
inline bool ggml_webgpu_tensor_overlap(const ggml_tensor * a, const ggml_tensor * b) {
|
|
77
|
+
return a->buffer == b->buffer && ggml_webgpu_tensor_addr(a) < ggml_webgpu_tensor_addr(b) + ggml_nbytes(b) &&
|
|
78
|
+
ggml_webgpu_tensor_addr(b) < ggml_webgpu_tensor_addr(a) + ggml_nbytes(a);
|
|
79
|
+
}
|
|
80
|
+
|
|
68
81
|
struct ggml_webgpu_shader_lib_context {
|
|
69
82
|
ggml_tensor * src0;
|
|
70
83
|
ggml_tensor * src1;
|
|
71
84
|
ggml_tensor * src2;
|
|
72
85
|
ggml_tensor * src3;
|
|
73
86
|
ggml_tensor * src4;
|
|
87
|
+
ggml_tensor * src5;
|
|
74
88
|
ggml_tensor * dst;
|
|
75
89
|
|
|
76
|
-
uint32_t
|
|
77
|
-
size_t
|
|
78
|
-
bool
|
|
79
|
-
bool
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
uint32_t
|
|
83
|
-
uint32_t
|
|
84
|
-
uint32_t
|
|
85
|
-
|
|
90
|
+
uint32_t max_wg_size;
|
|
91
|
+
size_t wg_mem_limit_bytes = 0;
|
|
92
|
+
bool supports_subgroups = false;
|
|
93
|
+
bool supports_subgroup_matrix = false;
|
|
94
|
+
uint32_t sg_mat_m = 0;
|
|
95
|
+
uint32_t sg_mat_n = 0;
|
|
96
|
+
uint32_t sg_mat_k = 0;
|
|
97
|
+
uint32_t min_subgroup_size = 0;
|
|
98
|
+
uint32_t max_subgroup_size = 0;
|
|
99
|
+
bool supports_dot_product = false;
|
|
100
|
+
std::string vendor;
|
|
86
101
|
};
|
|
87
102
|
|
|
88
103
|
struct webgpu_pipeline {
|
|
@@ -93,6 +108,51 @@ struct webgpu_pipeline {
|
|
|
93
108
|
|
|
94
109
|
struct ggml_webgpu_generic_shader_decisions {
|
|
95
110
|
uint32_t wg_size = 0;
|
|
111
|
+
bool inplace = false;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
struct ggml_webgpu_binary_shader_decisions {
|
|
115
|
+
uint32_t wg_size = 0;
|
|
116
|
+
bool inplace = false;
|
|
117
|
+
bool overlap = false;
|
|
118
|
+
bool src_overlap = false;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
struct ggml_webgpu_processed_shader {
|
|
122
|
+
std::string wgsl;
|
|
123
|
+
std::string variant;
|
|
124
|
+
std::shared_ptr<void> decisions;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
struct ggml_webgpu_ssm_conv_shader_decisions {
|
|
128
|
+
uint32_t block_size;
|
|
129
|
+
uint32_t tokens_per_wg;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
struct ggml_webgpu_ssm_scan_pipeline_key {
|
|
133
|
+
int type;
|
|
134
|
+
int d_state;
|
|
135
|
+
bool xbc_overlap;
|
|
136
|
+
|
|
137
|
+
bool operator==(const ggml_webgpu_ssm_scan_pipeline_key & other) const {
|
|
138
|
+
return type == other.type && d_state == other.d_state && xbc_overlap == other.xbc_overlap;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
struct ggml_webgpu_ssm_scan_pipeline_key_hash {
|
|
143
|
+
size_t operator()(const ggml_webgpu_ssm_scan_pipeline_key & key) const {
|
|
144
|
+
size_t seed = 0;
|
|
145
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
146
|
+
ggml_webgpu_hash_combine(seed, key.d_state);
|
|
147
|
+
ggml_webgpu_hash_combine(seed, key.xbc_overlap);
|
|
148
|
+
return seed;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
struct ggml_webgpu_ssm_scan_shader_decisions {
|
|
153
|
+
uint32_t wg_size;
|
|
154
|
+
uint32_t tokens_per_tile;
|
|
155
|
+
bool xbc_overlap = false;
|
|
96
156
|
};
|
|
97
157
|
|
|
98
158
|
/** Argsort **/
|
|
@@ -109,9 +169,11 @@ struct ggml_webgpu_set_rows_pipeline_key {
|
|
|
109
169
|
int dst_type;
|
|
110
170
|
int vec4;
|
|
111
171
|
int i64_idx;
|
|
172
|
+
int pair_blocks;
|
|
112
173
|
|
|
113
174
|
bool operator==(const ggml_webgpu_set_rows_pipeline_key & other) const {
|
|
114
|
-
return dst_type == other.dst_type && vec4 == other.vec4 && i64_idx == other.i64_idx
|
|
175
|
+
return dst_type == other.dst_type && vec4 == other.vec4 && i64_idx == other.i64_idx &&
|
|
176
|
+
pair_blocks == other.pair_blocks;
|
|
115
177
|
}
|
|
116
178
|
};
|
|
117
179
|
|
|
@@ -121,6 +183,7 @@ struct ggml_webgpu_set_rows_pipeline_key_hash {
|
|
|
121
183
|
ggml_webgpu_hash_combine(seed, key.dst_type);
|
|
122
184
|
ggml_webgpu_hash_combine(seed, key.vec4);
|
|
123
185
|
ggml_webgpu_hash_combine(seed, key.i64_idx);
|
|
186
|
+
ggml_webgpu_hash_combine(seed, key.pair_blocks);
|
|
124
187
|
return seed;
|
|
125
188
|
}
|
|
126
189
|
};
|
|
@@ -128,9 +191,30 @@ struct ggml_webgpu_set_rows_pipeline_key_hash {
|
|
|
128
191
|
struct ggml_webgpu_set_rows_shader_decisions {
|
|
129
192
|
bool vec4;
|
|
130
193
|
bool i64_idx;
|
|
194
|
+
bool pair_blocks;
|
|
131
195
|
uint32_t wg_size;
|
|
132
196
|
};
|
|
133
197
|
|
|
198
|
+
/** Set **/
|
|
199
|
+
|
|
200
|
+
struct ggml_webgpu_set_pipeline_key {
|
|
201
|
+
ggml_type type;
|
|
202
|
+
bool inplace;
|
|
203
|
+
|
|
204
|
+
bool operator==(const ggml_webgpu_set_pipeline_key & other) const {
|
|
205
|
+
return type == other.type && inplace == other.inplace;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
struct ggml_webgpu_set_pipeline_key_hash {
|
|
210
|
+
size_t operator()(const ggml_webgpu_set_pipeline_key & key) const {
|
|
211
|
+
size_t seed = 0;
|
|
212
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
213
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
214
|
+
return seed;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
134
218
|
/** Get Rows **/
|
|
135
219
|
|
|
136
220
|
struct ggml_webgpu_get_rows_pipeline_key {
|
|
@@ -151,6 +235,59 @@ struct ggml_webgpu_get_rows_pipeline_key_hash {
|
|
|
151
235
|
}
|
|
152
236
|
};
|
|
153
237
|
|
|
238
|
+
/** Row Norm **/
|
|
239
|
+
|
|
240
|
+
struct ggml_webgpu_row_norm_pipeline_key {
|
|
241
|
+
ggml_op op;
|
|
242
|
+
ggml_type src_type;
|
|
243
|
+
ggml_type dst_type;
|
|
244
|
+
bool inplace;
|
|
245
|
+
|
|
246
|
+
bool operator==(const ggml_webgpu_row_norm_pipeline_key & other) const {
|
|
247
|
+
return op == other.op && src_type == other.src_type && dst_type == other.dst_type && inplace == other.inplace;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
struct ggml_webgpu_row_norm_pipeline_key_hash {
|
|
252
|
+
size_t operator()(const ggml_webgpu_row_norm_pipeline_key & key) const {
|
|
253
|
+
size_t seed = 0;
|
|
254
|
+
ggml_webgpu_hash_combine(seed, key.op);
|
|
255
|
+
ggml_webgpu_hash_combine(seed, key.src_type);
|
|
256
|
+
ggml_webgpu_hash_combine(seed, key.dst_type);
|
|
257
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
258
|
+
return seed;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
/** RMS_NORM + MUL **/
|
|
263
|
+
|
|
264
|
+
struct ggml_webgpu_rms_norm_mul_pipeline_key {
|
|
265
|
+
bool inplace; // rn_src == dst
|
|
266
|
+
bool overlap; // mul_src == dst
|
|
267
|
+
bool src_overlap; // rn_src == mul_src
|
|
268
|
+
|
|
269
|
+
bool operator==(const ggml_webgpu_rms_norm_mul_pipeline_key & other) const {
|
|
270
|
+
return inplace == other.inplace && overlap == other.overlap && src_overlap == other.src_overlap;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
struct ggml_webgpu_rms_norm_mul_pipeline_key_hash {
|
|
275
|
+
size_t operator()(const ggml_webgpu_rms_norm_mul_pipeline_key & key) const {
|
|
276
|
+
size_t seed = 0;
|
|
277
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
278
|
+
ggml_webgpu_hash_combine(seed, key.overlap);
|
|
279
|
+
ggml_webgpu_hash_combine(seed, key.src_overlap);
|
|
280
|
+
return seed;
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
struct ggml_webgpu_rms_norm_mul_shader_decisions {
|
|
285
|
+
uint32_t wg_size = 0;
|
|
286
|
+
bool inplace = false;
|
|
287
|
+
bool overlap = false;
|
|
288
|
+
bool src_overlap = false;
|
|
289
|
+
};
|
|
290
|
+
|
|
154
291
|
/** Pad **/
|
|
155
292
|
struct ggml_webgpu_pad_pipeline_key {
|
|
156
293
|
bool circular;
|
|
@@ -166,6 +303,107 @@ struct ggml_webgpu_pad_pipeline_key_hash {
|
|
|
166
303
|
}
|
|
167
304
|
};
|
|
168
305
|
|
|
306
|
+
/** Solve Tri **/
|
|
307
|
+
struct ggml_webgpu_solve_tri_pipeline_key {
|
|
308
|
+
int type;
|
|
309
|
+
int n;
|
|
310
|
+
int k;
|
|
311
|
+
|
|
312
|
+
bool operator==(const ggml_webgpu_solve_tri_pipeline_key & other) const {
|
|
313
|
+
return type == other.type && n == other.n && k == other.k;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
struct ggml_webgpu_solve_tri_pipeline_key_hash {
|
|
318
|
+
size_t operator()(const ggml_webgpu_solve_tri_pipeline_key & key) const {
|
|
319
|
+
size_t seed = 0;
|
|
320
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
321
|
+
ggml_webgpu_hash_combine(seed, key.n);
|
|
322
|
+
ggml_webgpu_hash_combine(seed, key.k);
|
|
323
|
+
return seed;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
/** SSM Conv **/
|
|
328
|
+
struct ggml_webgpu_ssm_conv_pipeline_key {
|
|
329
|
+
int type;
|
|
330
|
+
int vectorized;
|
|
331
|
+
|
|
332
|
+
bool operator==(const ggml_webgpu_ssm_conv_pipeline_key & other) const {
|
|
333
|
+
return type == other.type && vectorized == other.vectorized;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
/** CONV 2D */
|
|
338
|
+
struct ggml_webgpu_conv2d_pipeline_key {
|
|
339
|
+
ggml_type weight_type;
|
|
340
|
+
ggml_type input_type;
|
|
341
|
+
ggml_type output_type;
|
|
342
|
+
|
|
343
|
+
bool operator==(const ggml_webgpu_conv2d_pipeline_key & other) const {
|
|
344
|
+
return weight_type == other.weight_type && input_type == other.input_type && output_type == other.output_type;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
struct ggml_webgpu_conv2d_pipeline_key_hash {
|
|
349
|
+
size_t operator()(const ggml_webgpu_conv2d_pipeline_key & key) const {
|
|
350
|
+
size_t seed = 0;
|
|
351
|
+
ggml_webgpu_hash_combine(seed, key.weight_type);
|
|
352
|
+
ggml_webgpu_hash_combine(seed, key.input_type);
|
|
353
|
+
ggml_webgpu_hash_combine(seed, key.output_type);
|
|
354
|
+
return seed;
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
/** Im2Col **/
|
|
359
|
+
struct ggml_webgpu_im2col_pipeline_key {
|
|
360
|
+
ggml_type input_type;
|
|
361
|
+
ggml_type output_type;
|
|
362
|
+
|
|
363
|
+
bool operator==(const ggml_webgpu_im2col_pipeline_key & other) const {
|
|
364
|
+
return input_type == other.input_type && output_type == other.output_type;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
struct ggml_webgpu_im2col_pipeline_key_hash {
|
|
369
|
+
size_t operator()(const ggml_webgpu_im2col_pipeline_key & key) const {
|
|
370
|
+
size_t seed = 0;
|
|
371
|
+
ggml_webgpu_hash_combine(seed, key.input_type);
|
|
372
|
+
ggml_webgpu_hash_combine(seed, key.output_type);
|
|
373
|
+
return seed;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
/** Gated Delta Net **/
|
|
378
|
+
struct ggml_webgpu_gated_delta_net_pipeline_key {
|
|
379
|
+
int type;
|
|
380
|
+
int s_v;
|
|
381
|
+
int kda;
|
|
382
|
+
|
|
383
|
+
bool operator==(const ggml_webgpu_gated_delta_net_pipeline_key & other) const {
|
|
384
|
+
return type == other.type && s_v == other.s_v && kda == other.kda;
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
struct ggml_webgpu_gated_delta_net_pipeline_key_hash {
|
|
389
|
+
size_t operator()(const ggml_webgpu_gated_delta_net_pipeline_key & key) const {
|
|
390
|
+
size_t seed = 0;
|
|
391
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
392
|
+
ggml_webgpu_hash_combine(seed, key.s_v);
|
|
393
|
+
ggml_webgpu_hash_combine(seed, key.kda);
|
|
394
|
+
return seed;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
struct ggml_webgpu_ssm_conv_pipeline_key_hash {
|
|
399
|
+
size_t operator()(const ggml_webgpu_ssm_conv_pipeline_key & key) const {
|
|
400
|
+
size_t seed = 0;
|
|
401
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
402
|
+
ggml_webgpu_hash_combine(seed, key.vectorized);
|
|
403
|
+
return seed;
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
169
407
|
/** Scale **/
|
|
170
408
|
|
|
171
409
|
struct ggml_webgpu_scale_pipeline_key {
|
|
@@ -182,18 +420,47 @@ struct ggml_webgpu_scale_pipeline_key_hash {
|
|
|
182
420
|
}
|
|
183
421
|
};
|
|
184
422
|
|
|
423
|
+
/** Upscale **/
|
|
424
|
+
|
|
425
|
+
struct ggml_webgpu_upscale_pipeline_key {
|
|
426
|
+
ggml_type input_type;
|
|
427
|
+
ggml_type output_type;
|
|
428
|
+
uint32_t base_mode;
|
|
429
|
+
bool antialias;
|
|
430
|
+
|
|
431
|
+
bool operator==(const ggml_webgpu_upscale_pipeline_key & other) const {
|
|
432
|
+
return input_type == other.input_type && output_type == other.output_type && base_mode == other.base_mode &&
|
|
433
|
+
antialias == other.antialias;
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
struct ggml_webgpu_upscale_pipeline_key_hash {
|
|
438
|
+
size_t operator()(const ggml_webgpu_upscale_pipeline_key & key) const {
|
|
439
|
+
size_t seed = 0;
|
|
440
|
+
ggml_webgpu_hash_combine(seed, key.input_type);
|
|
441
|
+
ggml_webgpu_hash_combine(seed, key.output_type);
|
|
442
|
+
ggml_webgpu_hash_combine(seed, key.base_mode);
|
|
443
|
+
ggml_webgpu_hash_combine(seed, key.antialias);
|
|
444
|
+
return seed;
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
185
448
|
/** Concat **/
|
|
186
449
|
|
|
187
450
|
struct ggml_webgpu_concat_pipeline_key {
|
|
188
|
-
int
|
|
451
|
+
int type;
|
|
452
|
+
bool src_overlap;
|
|
189
453
|
|
|
190
|
-
bool operator==(const ggml_webgpu_concat_pipeline_key & other) const {
|
|
454
|
+
bool operator==(const ggml_webgpu_concat_pipeline_key & other) const {
|
|
455
|
+
return type == other.type && src_overlap == other.src_overlap;
|
|
456
|
+
}
|
|
191
457
|
};
|
|
192
458
|
|
|
193
459
|
struct ggml_webgpu_concat_pipeline_key_hash {
|
|
194
460
|
size_t operator()(const ggml_webgpu_concat_pipeline_key & key) const {
|
|
195
461
|
size_t seed = 0;
|
|
196
462
|
ggml_webgpu_hash_combine(seed, key.type);
|
|
463
|
+
ggml_webgpu_hash_combine(seed, key.src_overlap);
|
|
197
464
|
return seed;
|
|
198
465
|
}
|
|
199
466
|
};
|
|
@@ -241,16 +508,34 @@ struct ggml_webgpu_binary_pipeline_key_hash {
|
|
|
241
508
|
}
|
|
242
509
|
};
|
|
243
510
|
|
|
511
|
+
/* Add_Id */
|
|
512
|
+
|
|
513
|
+
struct ggml_webgpu_add_id_pipeline_key {
|
|
514
|
+
bool inplace;
|
|
515
|
+
|
|
516
|
+
bool operator==(const ggml_webgpu_add_id_pipeline_key & other) const { return inplace == other.inplace; }
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
struct ggml_webgpu_add_id_pipeline_key_hash {
|
|
520
|
+
size_t operator()(const ggml_webgpu_add_id_pipeline_key & key) const {
|
|
521
|
+
size_t seed = 0;
|
|
522
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
523
|
+
return seed;
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
244
527
|
/** Unary **/
|
|
245
528
|
|
|
246
529
|
struct ggml_webgpu_unary_pipeline_key {
|
|
247
|
-
int
|
|
248
|
-
int
|
|
249
|
-
bool
|
|
250
|
-
bool
|
|
530
|
+
int type;
|
|
531
|
+
int op;
|
|
532
|
+
bool is_unary; // many unary operators fall under the GGML_OP_UNARY umbrella
|
|
533
|
+
bool inplace;
|
|
534
|
+
ggml_tri_type ttype; // only used for GGML_OP_TRI
|
|
251
535
|
|
|
252
536
|
bool operator==(const ggml_webgpu_unary_pipeline_key & other) const {
|
|
253
|
-
return type == other.type && op == other.op && is_unary == other.is_unary && inplace == other.inplace
|
|
537
|
+
return type == other.type && op == other.op && is_unary == other.is_unary && inplace == other.inplace &&
|
|
538
|
+
ttype == other.ttype;
|
|
254
539
|
}
|
|
255
540
|
};
|
|
256
541
|
|
|
@@ -261,58 +546,285 @@ struct ggml_webgpu_unary_pipeline_key_hash {
|
|
|
261
546
|
ggml_webgpu_hash_combine(seed, key.op);
|
|
262
547
|
ggml_webgpu_hash_combine(seed, key.is_unary);
|
|
263
548
|
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
549
|
+
ggml_webgpu_hash_combine(seed, key.ttype);
|
|
264
550
|
return seed;
|
|
265
551
|
}
|
|
266
552
|
};
|
|
267
553
|
|
|
268
554
|
/** FlashAttention */
|
|
269
555
|
|
|
270
|
-
struct
|
|
271
|
-
ggml_type
|
|
556
|
+
struct ggml_webgpu_flash_attn_common_pipeline_key {
|
|
557
|
+
ggml_type q_type;
|
|
558
|
+
ggml_type k_type;
|
|
559
|
+
ggml_type v_type;
|
|
560
|
+
ggml_type dst_type;
|
|
272
561
|
uint32_t head_dim_qk;
|
|
273
562
|
uint32_t head_dim_v;
|
|
274
563
|
bool kv_direct;
|
|
564
|
+
bool kv_overlap;
|
|
275
565
|
bool has_mask;
|
|
276
566
|
bool has_sinks;
|
|
277
567
|
bool uses_logit_softcap;
|
|
278
568
|
|
|
569
|
+
bool operator==(const ggml_webgpu_flash_attn_common_pipeline_key & other) const {
|
|
570
|
+
return q_type == other.q_type && k_type == other.k_type && v_type == other.v_type &&
|
|
571
|
+
dst_type == other.dst_type && head_dim_qk == other.head_dim_qk && head_dim_v == other.head_dim_v &&
|
|
572
|
+
kv_direct == other.kv_direct && kv_overlap == other.kv_overlap && has_mask == other.has_mask &&
|
|
573
|
+
has_sinks == other.has_sinks && uses_logit_softcap == other.uses_logit_softcap;
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
inline void ggml_webgpu_flash_attn_hash_common_pipeline_key(size_t & seed,
|
|
578
|
+
const ggml_webgpu_flash_attn_common_pipeline_key & key) {
|
|
579
|
+
ggml_webgpu_hash_combine(seed, key.q_type);
|
|
580
|
+
ggml_webgpu_hash_combine(seed, key.k_type);
|
|
581
|
+
ggml_webgpu_hash_combine(seed, key.v_type);
|
|
582
|
+
ggml_webgpu_hash_combine(seed, key.dst_type);
|
|
583
|
+
ggml_webgpu_hash_combine(seed, key.head_dim_qk);
|
|
584
|
+
ggml_webgpu_hash_combine(seed, key.head_dim_v);
|
|
585
|
+
ggml_webgpu_hash_combine(seed, key.kv_direct);
|
|
586
|
+
ggml_webgpu_hash_combine(seed, key.kv_overlap);
|
|
587
|
+
ggml_webgpu_hash_combine(seed, key.has_mask);
|
|
588
|
+
ggml_webgpu_hash_combine(seed, key.has_sinks);
|
|
589
|
+
ggml_webgpu_hash_combine(seed, key.uses_logit_softcap);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
struct ggml_webgpu_flash_attn_vec_pipeline_key {
|
|
593
|
+
ggml_webgpu_flash_attn_common_pipeline_key common;
|
|
594
|
+
|
|
595
|
+
bool operator==(const ggml_webgpu_flash_attn_vec_pipeline_key & other) const { return common == other.common; }
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
struct ggml_webgpu_flash_attn_vec_pipeline_key_hash {
|
|
599
|
+
size_t operator()(const ggml_webgpu_flash_attn_vec_pipeline_key & key) const {
|
|
600
|
+
size_t seed = 0;
|
|
601
|
+
ggml_webgpu_flash_attn_hash_common_pipeline_key(seed, key.common);
|
|
602
|
+
return seed;
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
struct ggml_webgpu_flash_attn_pipeline_key {
|
|
607
|
+
ggml_webgpu_flash_attn_common_pipeline_key common;
|
|
608
|
+
bool use_sg_matrix;
|
|
609
|
+
|
|
279
610
|
bool operator==(const ggml_webgpu_flash_attn_pipeline_key & other) const {
|
|
280
|
-
return
|
|
281
|
-
kv_direct == other.kv_direct && has_mask == other.has_mask && has_sinks == other.has_sinks &&
|
|
282
|
-
uses_logit_softcap == other.uses_logit_softcap;
|
|
611
|
+
return common == other.common && use_sg_matrix == other.use_sg_matrix;
|
|
283
612
|
}
|
|
284
613
|
};
|
|
285
614
|
|
|
286
615
|
struct ggml_webgpu_flash_attn_pipeline_key_hash {
|
|
287
616
|
size_t operator()(const ggml_webgpu_flash_attn_pipeline_key & key) const {
|
|
288
617
|
size_t seed = 0;
|
|
289
|
-
|
|
290
|
-
ggml_webgpu_hash_combine(seed, key.
|
|
618
|
+
ggml_webgpu_flash_attn_hash_common_pipeline_key(seed, key.common);
|
|
619
|
+
ggml_webgpu_hash_combine(seed, key.use_sg_matrix);
|
|
620
|
+
return seed;
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
struct ggml_webgpu_flash_attn_vec_decisions {
|
|
625
|
+
uint32_t kv_tile = 0;
|
|
626
|
+
uint32_t wg_size = 0;
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
struct ggml_webgpu_flash_attn_decisions {
|
|
630
|
+
bool use_sg_matrix = false;
|
|
631
|
+
uint32_t q_tile = 0;
|
|
632
|
+
uint32_t kv_tile = 0;
|
|
633
|
+
uint32_t wg_size = 0;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
inline constexpr uint32_t GGML_WEBGPU_FLASH_ATTN_TILE_KV_VEC_WIDTH = 4u;
|
|
637
|
+
inline constexpr uint32_t GGML_WEBGPU_FLASH_ATTN_TILE_Q_TILE = 4u;
|
|
638
|
+
|
|
639
|
+
inline size_t ggml_webgpu_flash_attn_tensor_offset(const ggml_tensor * tensor) {
|
|
640
|
+
constexpr uintptr_t ptr_base_addr = 0x1000u;
|
|
641
|
+
const ggml_tensor * base = tensor->view_src != nullptr ? tensor->view_src : tensor;
|
|
642
|
+
return reinterpret_cast<uintptr_t>(base->data) - ptr_base_addr + tensor->view_offs;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
inline bool ggml_webgpu_flash_attn_float_vec4_aligned(const ggml_tensor * K, size_t storage_offset_alignment) {
|
|
646
|
+
const uint32_t offset_elems =
|
|
647
|
+
(uint32_t) ((ggml_webgpu_flash_attn_tensor_offset(K) & (storage_offset_alignment - 1)) /
|
|
648
|
+
ggml_type_size(K->type));
|
|
649
|
+
return offset_elems % GGML_WEBGPU_FLASH_ATTN_TILE_KV_VEC_WIDTH == 0u;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
inline bool ggml_webgpu_flash_attn_float_vec4_aligned(const ggml_tensor * K,
|
|
653
|
+
const ggml_tensor * V,
|
|
654
|
+
size_t storage_offset_alignment) {
|
|
655
|
+
return ggml_webgpu_flash_attn_float_vec4_aligned(K, storage_offset_alignment) &&
|
|
656
|
+
ggml_webgpu_flash_attn_float_vec4_aligned(V, storage_offset_alignment);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
inline bool ggml_webgpu_flash_attn_kv_direct(const ggml_tensor * Q,
|
|
660
|
+
const ggml_tensor * K,
|
|
661
|
+
const ggml_tensor * V,
|
|
662
|
+
uint32_t kv_direct_align) {
|
|
663
|
+
return K->type == GGML_TYPE_F16 && V->type == GGML_TYPE_F16 && (Q->ne[0] % kv_direct_align == 0) &&
|
|
664
|
+
(K->ne[1] % GGML_WEBGPU_KV_SEQ_PAD == 0);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
inline ggml_webgpu_flash_attn_common_pipeline_key ggml_webgpu_flash_attn_make_common_pipeline_key(
|
|
668
|
+
const ggml_webgpu_shader_lib_context & context,
|
|
669
|
+
uint32_t kv_direct_align) {
|
|
670
|
+
ggml_webgpu_flash_attn_common_pipeline_key key = {};
|
|
671
|
+
key.q_type = context.src0->type;
|
|
672
|
+
key.k_type = context.src1->type;
|
|
673
|
+
key.v_type = context.src2->type;
|
|
674
|
+
key.dst_type = context.dst->type;
|
|
675
|
+
key.head_dim_qk = (uint32_t) context.src0->ne[0];
|
|
676
|
+
key.head_dim_v = (uint32_t) context.src2->ne[0];
|
|
677
|
+
key.kv_direct = ggml_webgpu_flash_attn_kv_direct(context.src0, context.src1, context.src2, kv_direct_align);
|
|
678
|
+
key.kv_overlap = ggml_webgpu_tensor_overlap(context.src1, context.src2);
|
|
679
|
+
key.has_mask = context.src3 != nullptr;
|
|
680
|
+
key.has_sinks = context.src4 != nullptr;
|
|
681
|
+
key.uses_logit_softcap = ggml_get_op_params_f32(context.dst, 2) != 0.0f;
|
|
682
|
+
return key;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
inline std::vector<std::string> ggml_webgpu_flash_attn_common_defines(
|
|
686
|
+
const ggml_webgpu_flash_attn_common_pipeline_key & key,
|
|
687
|
+
std::string & variant,
|
|
688
|
+
uint32_t q_tile,
|
|
689
|
+
uint32_t kv_tile,
|
|
690
|
+
uint32_t wg_size) {
|
|
691
|
+
std::vector<std::string> defines;
|
|
692
|
+
|
|
693
|
+
switch (key.k_type) {
|
|
694
|
+
case GGML_TYPE_F32:
|
|
695
|
+
defines.push_back("K_F32");
|
|
696
|
+
break;
|
|
697
|
+
case GGML_TYPE_F16:
|
|
698
|
+
defines.push_back("K_F16");
|
|
699
|
+
break;
|
|
700
|
+
case GGML_TYPE_Q4_0:
|
|
701
|
+
defines.push_back("K_Q4_0");
|
|
702
|
+
break;
|
|
703
|
+
case GGML_TYPE_Q8_0:
|
|
704
|
+
defines.push_back("K_Q8_0");
|
|
705
|
+
break;
|
|
706
|
+
default:
|
|
707
|
+
GGML_ABORT("Unsupported K type for flash attention shader");
|
|
708
|
+
}
|
|
709
|
+
variant += std::string("_k") + ggml_type_name(key.k_type);
|
|
710
|
+
|
|
711
|
+
switch (key.v_type) {
|
|
712
|
+
case GGML_TYPE_F32:
|
|
713
|
+
defines.push_back("V_F32");
|
|
714
|
+
break;
|
|
715
|
+
case GGML_TYPE_F16:
|
|
716
|
+
defines.push_back("V_F16");
|
|
717
|
+
break;
|
|
718
|
+
case GGML_TYPE_Q4_0:
|
|
719
|
+
defines.push_back("V_Q4_0");
|
|
720
|
+
break;
|
|
721
|
+
case GGML_TYPE_Q8_0:
|
|
722
|
+
defines.push_back("V_Q8_0");
|
|
723
|
+
break;
|
|
724
|
+
default:
|
|
725
|
+
GGML_ABORT("Unsupported V type for flash attention shader");
|
|
726
|
+
}
|
|
727
|
+
variant += std::string("_v") + ggml_type_name(key.v_type);
|
|
728
|
+
|
|
729
|
+
switch (key.q_type) {
|
|
730
|
+
case GGML_TYPE_F32:
|
|
731
|
+
defines.push_back("Q_F32");
|
|
732
|
+
break;
|
|
733
|
+
case GGML_TYPE_F16:
|
|
734
|
+
defines.push_back("Q_F16");
|
|
735
|
+
break;
|
|
736
|
+
default:
|
|
737
|
+
GGML_ABORT("Unsupported Q type for flash attention shader");
|
|
738
|
+
}
|
|
739
|
+
variant += std::string("_q") + ggml_type_name(key.q_type);
|
|
740
|
+
|
|
741
|
+
switch (key.dst_type) {
|
|
742
|
+
case GGML_TYPE_F32:
|
|
743
|
+
defines.push_back("DST_F32");
|
|
744
|
+
break;
|
|
745
|
+
case GGML_TYPE_F16:
|
|
746
|
+
defines.push_back("DST_F16");
|
|
747
|
+
break;
|
|
748
|
+
default:
|
|
749
|
+
GGML_ABORT("Unsupported dst type for flash attention shader");
|
|
750
|
+
}
|
|
751
|
+
variant += std::string("_dst") + ggml_type_name(key.dst_type);
|
|
752
|
+
|
|
753
|
+
if (key.has_mask) {
|
|
754
|
+
defines.push_back("MASK");
|
|
755
|
+
variant += "_mask";
|
|
756
|
+
}
|
|
757
|
+
if (key.has_sinks) {
|
|
758
|
+
defines.push_back("SINKS");
|
|
759
|
+
variant += "_sinks";
|
|
760
|
+
}
|
|
761
|
+
if (key.uses_logit_softcap) {
|
|
762
|
+
defines.push_back("LOGIT_SOFTCAP");
|
|
763
|
+
variant += "_lgsc";
|
|
764
|
+
}
|
|
765
|
+
if (key.kv_direct) {
|
|
766
|
+
defines.push_back("KV_DIRECT");
|
|
767
|
+
variant += "_kvdirect";
|
|
768
|
+
}
|
|
769
|
+
if (key.kv_overlap) {
|
|
770
|
+
defines.push_back("KV_OVERLAP");
|
|
771
|
+
variant += "_kv_overlap";
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
defines.push_back(std::string("HEAD_DIM_QK=") + std::to_string(key.head_dim_qk));
|
|
775
|
+
variant += std::string("_hsqk") + std::to_string(key.head_dim_qk);
|
|
776
|
+
|
|
777
|
+
defines.push_back(std::string("HEAD_DIM_V=") + std::to_string(key.head_dim_v));
|
|
778
|
+
variant += std::string("_hsv") + std::to_string(key.head_dim_v);
|
|
779
|
+
|
|
780
|
+
defines.push_back(std::string("Q_TILE=") + std::to_string(q_tile));
|
|
781
|
+
defines.push_back(std::string("KV_TILE=") + std::to_string(kv_tile));
|
|
782
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
783
|
+
|
|
784
|
+
if (ggml_is_quantized(key.k_type) || ggml_is_quantized(key.v_type)) {
|
|
785
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return defines;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
struct ggml_webgpu_flash_attn_vec_reduce_pipeline_key {
|
|
792
|
+
uint32_t head_dim_v;
|
|
793
|
+
uint32_t wg_size;
|
|
794
|
+
ggml_type dst_type;
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
struct ggml_webgpu_flash_attn_vec_reduce_pipeline_key_hash {
|
|
798
|
+
size_t operator()(const ggml_webgpu_flash_attn_vec_reduce_pipeline_key & key) const {
|
|
799
|
+
size_t seed = 0;
|
|
291
800
|
ggml_webgpu_hash_combine(seed, key.head_dim_v);
|
|
292
|
-
ggml_webgpu_hash_combine(seed, key.
|
|
293
|
-
ggml_webgpu_hash_combine(seed, key.
|
|
294
|
-
ggml_webgpu_hash_combine(seed, key.has_sinks);
|
|
295
|
-
ggml_webgpu_hash_combine(seed, key.uses_logit_softcap);
|
|
801
|
+
ggml_webgpu_hash_combine(seed, key.wg_size);
|
|
802
|
+
ggml_webgpu_hash_combine(seed, key.dst_type);
|
|
296
803
|
return seed;
|
|
297
804
|
}
|
|
298
805
|
};
|
|
299
806
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
uint32_t
|
|
807
|
+
inline bool operator==(const ggml_webgpu_flash_attn_vec_reduce_pipeline_key & lhs,
|
|
808
|
+
const ggml_webgpu_flash_attn_vec_reduce_pipeline_key & rhs) {
|
|
809
|
+
return lhs.head_dim_v == rhs.head_dim_v && lhs.wg_size == rhs.wg_size && lhs.dst_type == rhs.dst_type;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
struct ggml_webgpu_flash_attn_blk_pipeline_key {
|
|
813
|
+
uint32_t kv_tile;
|
|
814
|
+
|
|
815
|
+
bool operator==(const ggml_webgpu_flash_attn_blk_pipeline_key & other) const { return kv_tile == other.kv_tile; }
|
|
307
816
|
};
|
|
308
817
|
|
|
309
|
-
struct
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
818
|
+
struct ggml_webgpu_flash_attn_blk_pipeline_key_hash {
|
|
819
|
+
size_t operator()(const ggml_webgpu_flash_attn_blk_pipeline_key & key) const {
|
|
820
|
+
size_t seed = 0;
|
|
821
|
+
ggml_webgpu_hash_combine(seed, key.kv_tile);
|
|
822
|
+
return seed;
|
|
823
|
+
}
|
|
313
824
|
};
|
|
314
825
|
|
|
315
|
-
//
|
|
826
|
+
// Note: this will slightly overestimate memory usage for vec path
|
|
827
|
+
// since row_max and exp_sum shmem are not needed.
|
|
316
828
|
inline size_t ggml_webgpu_flash_attn_wg_mem_bytes(uint32_t q_tile,
|
|
317
829
|
uint32_t kv_tile,
|
|
318
830
|
uint32_t head_dim_qk,
|
|
@@ -322,47 +834,83 @@ inline size_t ggml_webgpu_flash_attn_wg_mem_bytes(uint32_t q_tile,
|
|
|
322
834
|
const uint32_t max_head_dim = std::max(head_dim_qk, head_dim_v);
|
|
323
835
|
size_t f16_elems = 0;
|
|
324
836
|
size_t f32_elems = 0;
|
|
325
|
-
|
|
837
|
+
|
|
838
|
+
f32_elems += q_tile * head_dim_qk; // q_shmem
|
|
326
839
|
if (!kv_direct) {
|
|
327
|
-
|
|
840
|
+
f32_elems += kv_tile * max_head_dim; // kv_shmem
|
|
328
841
|
}
|
|
329
|
-
|
|
842
|
+
f32_elems += q_tile * head_dim_v; // o_shmem
|
|
330
843
|
if (has_mask) {
|
|
331
|
-
|
|
844
|
+
f32_elems += q_tile * kv_tile; // mask_shmem
|
|
332
845
|
}
|
|
333
|
-
|
|
846
|
+
f32_elems += q_tile * kv_tile; // inter_shmem
|
|
334
847
|
f32_elems += q_tile; // row_max_shmem
|
|
335
848
|
f32_elems += q_tile; // exp_sum_shmem
|
|
336
849
|
return f16_elems * GGML_WEBGPU_F16_SIZE_BYTES + f32_elems * GGML_WEBGPU_F32_SIZE_BYTES;
|
|
337
850
|
}
|
|
338
851
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
852
|
+
inline uint32_t ggml_webgpu_flash_attn_max_kv_tile(size_t limit_bytes,
|
|
853
|
+
uint32_t q_tile,
|
|
854
|
+
uint32_t kv_granularity,
|
|
855
|
+
uint32_t head_dim_qk,
|
|
856
|
+
uint32_t head_dim_v,
|
|
857
|
+
bool has_mask,
|
|
858
|
+
bool kv_direct) {
|
|
859
|
+
const size_t base_q_bytes =
|
|
860
|
+
ggml_webgpu_flash_attn_wg_mem_bytes(q_tile, 0, head_dim_qk, head_dim_v, has_mask, kv_direct);
|
|
861
|
+
if (limit_bytes <= base_q_bytes) {
|
|
862
|
+
return 0;
|
|
347
863
|
}
|
|
348
|
-
|
|
864
|
+
const size_t one_kv_bytes =
|
|
865
|
+
ggml_webgpu_flash_attn_wg_mem_bytes(q_tile, 1, head_dim_qk, head_dim_v, has_mask, kv_direct);
|
|
866
|
+
const size_t bytes_per_kv = one_kv_bytes - base_q_bytes;
|
|
867
|
+
if (bytes_per_kv == 0) {
|
|
868
|
+
return 0;
|
|
869
|
+
}
|
|
870
|
+
const size_t max_kv_tile = (limit_bytes - base_q_bytes) / bytes_per_kv;
|
|
871
|
+
return (uint32_t) ((max_kv_tile / kv_granularity) * kv_granularity);
|
|
872
|
+
}
|
|
349
873
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
874
|
+
inline uint32_t ggml_webgpu_flash_attn_get_vec_kv_tile(size_t wg_mem_limit_bytes,
|
|
875
|
+
uint32_t head_dim_qk,
|
|
876
|
+
uint32_t head_dim_v,
|
|
877
|
+
bool has_mask,
|
|
878
|
+
bool kv_direct) {
|
|
879
|
+
const uint32_t max_kv_tile =
|
|
880
|
+
ggml_webgpu_flash_attn_max_kv_tile(wg_mem_limit_bytes, 1u, 1u, head_dim_qk, head_dim_v, has_mask, kv_direct);
|
|
881
|
+
GGML_ASSERT(max_kv_tile > 0);
|
|
882
|
+
|
|
883
|
+
uint32_t kv_tile = std::min(GGML_WEBGPU_FLASH_ATTN_VEC_MAX_KV_TILE, max_kv_tile);
|
|
884
|
+
if (kv_direct) {
|
|
885
|
+
kv_tile = std::min(kv_tile, GGML_WEBGPU_KV_SEQ_PAD);
|
|
886
|
+
while (GGML_WEBGPU_KV_SEQ_PAD % kv_tile != 0) {
|
|
887
|
+
kv_tile -= 1u;
|
|
888
|
+
}
|
|
356
889
|
}
|
|
357
|
-
|
|
890
|
+
|
|
891
|
+
return kv_tile;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
inline bool ggml_webgpu_flash_attn_can_use_subgroup_matrix_path(bool supports_subgroup_matrix,
|
|
895
|
+
uint32_t sg_mat_k,
|
|
896
|
+
uint32_t sg_mat_n,
|
|
897
|
+
const ggml_tensor * Q,
|
|
898
|
+
const ggml_tensor * V) {
|
|
899
|
+
return supports_subgroup_matrix && Q->ne[0] % sg_mat_k == 0 && V->ne[0] % sg_mat_n == 0;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/** Matrix Multiplication **/
|
|
358
903
|
|
|
359
904
|
struct ggml_webgpu_mul_mat_vec_pipeline_key {
|
|
360
905
|
ggml_type src0_type;
|
|
361
906
|
ggml_type src1_type;
|
|
362
907
|
int vectorized;
|
|
908
|
+
uint32_t num_cols;
|
|
909
|
+
bool use_mmvq;
|
|
363
910
|
|
|
364
911
|
bool operator==(const ggml_webgpu_mul_mat_vec_pipeline_key & other) const {
|
|
365
|
-
return src0_type == other.src0_type && src1_type == other.src1_type && vectorized == other.vectorized
|
|
912
|
+
return src0_type == other.src0_type && src1_type == other.src1_type && vectorized == other.vectorized &&
|
|
913
|
+
num_cols == other.num_cols && use_mmvq == other.use_mmvq;
|
|
366
914
|
}
|
|
367
915
|
};
|
|
368
916
|
|
|
@@ -372,17 +920,32 @@ struct ggml_webgpu_mul_mat_vec_pipeline_key_hash {
|
|
|
372
920
|
ggml_webgpu_hash_combine(seed, key.src0_type);
|
|
373
921
|
ggml_webgpu_hash_combine(seed, key.src1_type);
|
|
374
922
|
ggml_webgpu_hash_combine(seed, key.vectorized);
|
|
923
|
+
ggml_webgpu_hash_combine(seed, key.num_cols);
|
|
924
|
+
ggml_webgpu_hash_combine(seed, key.use_mmvq);
|
|
375
925
|
return seed;
|
|
376
926
|
}
|
|
377
927
|
};
|
|
378
928
|
|
|
379
929
|
struct ggml_webgpu_mul_mat_vec_shader_decisions {
|
|
380
930
|
uint32_t wg_size;
|
|
381
|
-
uint32_t tile_k;
|
|
382
931
|
uint32_t outputs_per_wg;
|
|
383
932
|
uint32_t vec_size;
|
|
384
933
|
};
|
|
385
934
|
|
|
935
|
+
struct ggml_webgpu_quantize_q8_pipeline_key {
|
|
936
|
+
ggml_type src0_type;
|
|
937
|
+
|
|
938
|
+
bool operator==(const ggml_webgpu_quantize_q8_pipeline_key & other) const { return src0_type == other.src0_type; }
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
struct ggml_webgpu_quantize_q8_pipeline_key_hash {
|
|
942
|
+
size_t operator()(const ggml_webgpu_quantize_q8_pipeline_key & key) const {
|
|
943
|
+
size_t seed = 0;
|
|
944
|
+
ggml_webgpu_hash_combine(seed, key.src0_type);
|
|
945
|
+
return seed;
|
|
946
|
+
}
|
|
947
|
+
};
|
|
948
|
+
|
|
386
949
|
struct ggml_webgpu_mul_mat_pipeline_key {
|
|
387
950
|
ggml_type src0_type;
|
|
388
951
|
ggml_type src1_type;
|
|
@@ -426,8 +989,154 @@ struct ggml_webgpu_mul_mat_shader_decisions {
|
|
|
426
989
|
uint32_t mul_mat_wg_size;
|
|
427
990
|
};
|
|
428
991
|
|
|
429
|
-
|
|
430
|
-
|
|
992
|
+
/** MUL_MAT_ID **/
|
|
993
|
+
|
|
994
|
+
struct ggml_webgpu_mul_mat_id_pipeline_key {
|
|
995
|
+
ggml_type src0_type;
|
|
996
|
+
ggml_type src1_type;
|
|
997
|
+
uint32_t n_experts;
|
|
998
|
+
uint32_t num_cols;
|
|
999
|
+
int vectorized;
|
|
1000
|
+
|
|
1001
|
+
bool operator==(const ggml_webgpu_mul_mat_id_pipeline_key & other) const {
|
|
1002
|
+
return src0_type == other.src0_type && src1_type == other.src1_type && n_experts == other.n_experts &&
|
|
1003
|
+
num_cols == other.num_cols && vectorized == other.vectorized;
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
struct ggml_webgpu_mul_mat_id_pipeline_key_hash {
|
|
1008
|
+
size_t operator()(const ggml_webgpu_mul_mat_id_pipeline_key & key) const {
|
|
1009
|
+
size_t seed = 0;
|
|
1010
|
+
ggml_webgpu_hash_combine(seed, key.src0_type);
|
|
1011
|
+
ggml_webgpu_hash_combine(seed, key.src1_type);
|
|
1012
|
+
ggml_webgpu_hash_combine(seed, key.n_experts);
|
|
1013
|
+
ggml_webgpu_hash_combine(seed, key.num_cols);
|
|
1014
|
+
ggml_webgpu_hash_combine(seed, key.vectorized);
|
|
1015
|
+
return seed;
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
/** Cpy **/
|
|
1020
|
+
|
|
1021
|
+
struct ggml_webgpu_cpy_pipeline_key {
|
|
1022
|
+
ggml_type src_type;
|
|
1023
|
+
ggml_type dst_type;
|
|
1024
|
+
|
|
1025
|
+
bool operator==(const ggml_webgpu_cpy_pipeline_key & other) const {
|
|
1026
|
+
return src_type == other.src_type && dst_type == other.dst_type;
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
struct ggml_webgpu_cpy_pipeline_key_hash {
|
|
1031
|
+
size_t operator()(const ggml_webgpu_cpy_pipeline_key & key) const {
|
|
1032
|
+
size_t seed = 0;
|
|
1033
|
+
ggml_webgpu_hash_combine(seed, key.src_type);
|
|
1034
|
+
ggml_webgpu_hash_combine(seed, key.dst_type);
|
|
1035
|
+
return seed;
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
/** Glu **/
|
|
1040
|
+
|
|
1041
|
+
struct ggml_webgpu_glu_pipeline_key {
|
|
1042
|
+
ggml_glu_op glu_op;
|
|
1043
|
+
ggml_type type;
|
|
1044
|
+
bool split;
|
|
1045
|
+
|
|
1046
|
+
bool operator==(const ggml_webgpu_glu_pipeline_key & other) const {
|
|
1047
|
+
return glu_op == other.glu_op && type == other.type && split == other.split;
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
struct ggml_webgpu_glu_pipeline_key_hash {
|
|
1052
|
+
size_t operator()(const ggml_webgpu_glu_pipeline_key & key) const {
|
|
1053
|
+
size_t seed = 0;
|
|
1054
|
+
ggml_webgpu_hash_combine(seed, key.glu_op);
|
|
1055
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
1056
|
+
ggml_webgpu_hash_combine(seed, key.split);
|
|
1057
|
+
return seed;
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
/** Rope **/
|
|
1062
|
+
|
|
1063
|
+
struct ggml_webgpu_rope_pipeline_key {
|
|
1064
|
+
ggml_type type;
|
|
1065
|
+
bool inplace;
|
|
1066
|
+
bool has_ff;
|
|
1067
|
+
|
|
1068
|
+
bool operator==(const ggml_webgpu_rope_pipeline_key & other) const {
|
|
1069
|
+
return type == other.type && inplace == other.inplace && has_ff == other.has_ff;
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
struct ggml_webgpu_rope_pipeline_key_hash {
|
|
1074
|
+
size_t operator()(const ggml_webgpu_rope_pipeline_key & key) const {
|
|
1075
|
+
size_t seed = 0;
|
|
1076
|
+
ggml_webgpu_hash_combine(seed, key.type);
|
|
1077
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
1078
|
+
ggml_webgpu_hash_combine(seed, key.has_ff);
|
|
1079
|
+
return seed;
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
/** SoftMax **/
|
|
1084
|
+
|
|
1085
|
+
struct ggml_webgpu_soft_max_pipeline_key {
|
|
1086
|
+
ggml_type mask_type;
|
|
1087
|
+
bool has_mask;
|
|
1088
|
+
bool has_sink;
|
|
1089
|
+
bool inplace;
|
|
1090
|
+
|
|
1091
|
+
bool operator==(const ggml_webgpu_soft_max_pipeline_key & other) const {
|
|
1092
|
+
return mask_type == other.mask_type && has_mask == other.has_mask && has_sink == other.has_sink &&
|
|
1093
|
+
inplace == other.inplace;
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
struct ggml_webgpu_soft_max_pipeline_key_hash {
|
|
1098
|
+
size_t operator()(const ggml_webgpu_soft_max_pipeline_key & key) const {
|
|
1099
|
+
size_t seed = 0;
|
|
1100
|
+
ggml_webgpu_hash_combine(seed, key.mask_type);
|
|
1101
|
+
ggml_webgpu_hash_combine(seed, key.has_mask);
|
|
1102
|
+
ggml_webgpu_hash_combine(seed, key.has_sink);
|
|
1103
|
+
ggml_webgpu_hash_combine(seed, key.inplace);
|
|
1104
|
+
return seed;
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
/** MMVQ **/
|
|
1109
|
+
|
|
1110
|
+
inline bool ggml_webgpu_can_use_mmvq(const ggml_tensor * src0,
|
|
1111
|
+
const ggml_tensor * src1,
|
|
1112
|
+
bool supports_dot_product,
|
|
1113
|
+
const std::string & vendor) {
|
|
1114
|
+
if (src1->ne[1] <= 4) {
|
|
1115
|
+
bool supports_dp4a = vendor == "amd" || vendor == "intel" || vendor == "nvidia";
|
|
1116
|
+
if (supports_dp4a && supports_dot_product) {
|
|
1117
|
+
switch (src1->type) {
|
|
1118
|
+
case GGML_TYPE_F32:
|
|
1119
|
+
switch (src0->type) {
|
|
1120
|
+
case GGML_TYPE_Q4_0:
|
|
1121
|
+
case GGML_TYPE_Q4_1:
|
|
1122
|
+
case GGML_TYPE_Q8_0:
|
|
1123
|
+
case GGML_TYPE_Q2_K:
|
|
1124
|
+
case GGML_TYPE_Q4_K:
|
|
1125
|
+
return src0->ne[0] % 4 == 0;
|
|
1126
|
+
default:
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
break;
|
|
1130
|
+
default:
|
|
1131
|
+
break;
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
class ggml_webgpu_shader_lib {
|
|
1139
|
+
wgpu::Device device;
|
|
431
1140
|
pre_wgsl::Preprocessor preprocessor;
|
|
432
1141
|
|
|
433
1142
|
std::unordered_map<int, webgpu_pipeline> sum_rows_pipelines; // key is fixed, no variants yet
|
|
@@ -435,33 +1144,81 @@ class ggml_webgpu_shader_lib {
|
|
|
435
1144
|
std::unordered_map<int, webgpu_pipeline> argsort_pipelines; // key is order
|
|
436
1145
|
std::unordered_map<int, webgpu_pipeline> argsort_merge_pipelines; // key is order
|
|
437
1146
|
std::unordered_map<int, webgpu_pipeline> cumsum_pipelines; // key is fixed, no variants yet
|
|
1147
|
+
std::unordered_map<ggml_webgpu_row_norm_pipeline_key, webgpu_pipeline, ggml_webgpu_row_norm_pipeline_key_hash>
|
|
1148
|
+
row_norm_pipelines; // op/inplace
|
|
1149
|
+
|
|
438
1150
|
std::unordered_map<ggml_webgpu_get_rows_pipeline_key, webgpu_pipeline, ggml_webgpu_get_rows_pipeline_key_hash>
|
|
439
|
-
get_rows_pipelines;
|
|
1151
|
+
get_rows_pipelines; // src_type, vectorized
|
|
440
1152
|
std::unordered_map<ggml_webgpu_unary_pipeline_key, webgpu_pipeline, ggml_webgpu_unary_pipeline_key_hash>
|
|
441
|
-
unary_pipelines;
|
|
1153
|
+
unary_pipelines; // type/op/inplace
|
|
442
1154
|
std::unordered_map<ggml_webgpu_scale_pipeline_key, webgpu_pipeline, ggml_webgpu_scale_pipeline_key_hash>
|
|
443
|
-
scale_pipelines;
|
|
1155
|
+
scale_pipelines; // inplace
|
|
1156
|
+
std::unordered_map<ggml_webgpu_solve_tri_pipeline_key, webgpu_pipeline, ggml_webgpu_solve_tri_pipeline_key_hash>
|
|
1157
|
+
solve_tri_pipelines; // type
|
|
1158
|
+
std::unordered_map<ggml_webgpu_ssm_conv_pipeline_key, webgpu_pipeline, ggml_webgpu_ssm_conv_pipeline_key_hash>
|
|
1159
|
+
ssm_conv_pipelines; // type/vectorized
|
|
1160
|
+
std::unordered_map<ggml_webgpu_ssm_scan_pipeline_key, webgpu_pipeline, ggml_webgpu_ssm_scan_pipeline_key_hash>
|
|
1161
|
+
ssm_scan_pipelines; // type/d_state
|
|
1162
|
+
std::unordered_map<ggml_webgpu_gated_delta_net_pipeline_key,
|
|
1163
|
+
webgpu_pipeline,
|
|
1164
|
+
ggml_webgpu_gated_delta_net_pipeline_key_hash>
|
|
1165
|
+
gated_delta_net_pipelines; // type/S_v/kda
|
|
444
1166
|
std::unordered_map<ggml_webgpu_pad_pipeline_key, webgpu_pipeline, ggml_webgpu_pad_pipeline_key_hash>
|
|
445
|
-
pad_pipelines;
|
|
1167
|
+
pad_pipelines; // circular/non-circular
|
|
446
1168
|
std::unordered_map<ggml_webgpu_binary_pipeline_key, webgpu_pipeline, ggml_webgpu_binary_pipeline_key_hash>
|
|
447
|
-
binary_pipelines;
|
|
1169
|
+
binary_pipelines; // type/op/inplace/overlap/src_overlap
|
|
1170
|
+
std::unordered_map<ggml_webgpu_add_id_pipeline_key, webgpu_pipeline, ggml_webgpu_add_id_pipeline_key_hash>
|
|
1171
|
+
add_id_pipelines; // inplace
|
|
448
1172
|
std::unordered_map<ggml_webgpu_concat_pipeline_key, webgpu_pipeline, ggml_webgpu_concat_pipeline_key_hash>
|
|
449
|
-
concat_pipelines;
|
|
1173
|
+
concat_pipelines; // type
|
|
450
1174
|
std::unordered_map<ggml_webgpu_repeat_pipeline_key, webgpu_pipeline, ggml_webgpu_repeat_pipeline_key_hash>
|
|
451
|
-
repeat_pipelines;
|
|
1175
|
+
repeat_pipelines; // type
|
|
1176
|
+
std::unordered_map<ggml_webgpu_flash_attn_vec_pipeline_key,
|
|
1177
|
+
webgpu_pipeline,
|
|
1178
|
+
ggml_webgpu_flash_attn_vec_pipeline_key_hash>
|
|
1179
|
+
flash_attn_vec_pipelines;
|
|
452
1180
|
std::unordered_map<ggml_webgpu_flash_attn_pipeline_key, webgpu_pipeline, ggml_webgpu_flash_attn_pipeline_key_hash>
|
|
453
1181
|
flash_attn_pipelines;
|
|
454
|
-
std::unordered_map<
|
|
1182
|
+
std::unordered_map<ggml_webgpu_flash_attn_vec_reduce_pipeline_key,
|
|
455
1183
|
webgpu_pipeline,
|
|
456
|
-
|
|
457
|
-
|
|
1184
|
+
ggml_webgpu_flash_attn_vec_reduce_pipeline_key_hash>
|
|
1185
|
+
flash_attn_vec_reduce_pipelines;
|
|
1186
|
+
std::unordered_map<ggml_webgpu_flash_attn_blk_pipeline_key,
|
|
1187
|
+
webgpu_pipeline,
|
|
1188
|
+
ggml_webgpu_flash_attn_blk_pipeline_key_hash>
|
|
1189
|
+
flash_attn_blk_pipelines;
|
|
458
1190
|
std::unordered_map<ggml_webgpu_mul_mat_vec_pipeline_key, webgpu_pipeline, ggml_webgpu_mul_mat_vec_pipeline_key_hash>
|
|
459
|
-
mul_mat_vec_pipelines;
|
|
1191
|
+
mul_mat_vec_pipelines; // fast mat-vec (n==1)
|
|
460
1192
|
std::unordered_map<ggml_webgpu_mul_mat_pipeline_key, webgpu_pipeline, ggml_webgpu_mul_mat_pipeline_key_hash>
|
|
461
|
-
mul_mat_fast_pipelines;
|
|
1193
|
+
mul_mat_fast_pipelines; // fast mat-mat (reg-tile or subgroup)
|
|
1194
|
+
std::unordered_map<ggml_webgpu_quantize_q8_pipeline_key, webgpu_pipeline, ggml_webgpu_quantize_q8_pipeline_key_hash>
|
|
1195
|
+
quantize_q8_pipelines;
|
|
1196
|
+
std::unordered_map<int, webgpu_pipeline> mul_mat_id_gather_pipelines; // key is fixed
|
|
1197
|
+
std::unordered_map<ggml_webgpu_mul_mat_id_pipeline_key, webgpu_pipeline, ggml_webgpu_mul_mat_id_pipeline_key_hash>
|
|
1198
|
+
mul_mat_id_pipelines; // src0_type/src1_type
|
|
1199
|
+
std::unordered_map<ggml_webgpu_mul_mat_id_pipeline_key, webgpu_pipeline, ggml_webgpu_mul_mat_id_pipeline_key_hash>
|
|
1200
|
+
mul_mat_id_vec_pipelines; // src0_type/src1_type
|
|
462
1201
|
|
|
463
1202
|
std::unordered_map<ggml_webgpu_set_rows_pipeline_key, webgpu_pipeline, ggml_webgpu_set_rows_pipeline_key_hash>
|
|
464
1203
|
set_rows_pipelines;
|
|
1204
|
+
std::unordered_map<ggml_webgpu_set_pipeline_key, webgpu_pipeline, ggml_webgpu_set_pipeline_key_hash> set_pipelines;
|
|
1205
|
+
std::unordered_map<ggml_webgpu_cpy_pipeline_key, webgpu_pipeline, ggml_webgpu_cpy_pipeline_key_hash> cpy_pipelines;
|
|
1206
|
+
std::unordered_map<ggml_webgpu_glu_pipeline_key, webgpu_pipeline, ggml_webgpu_glu_pipeline_key_hash> glu_pipelines;
|
|
1207
|
+
std::unordered_map<ggml_webgpu_rope_pipeline_key, webgpu_pipeline, ggml_webgpu_rope_pipeline_key_hash>
|
|
1208
|
+
rope_pipelines;
|
|
1209
|
+
std::unordered_map<ggml_webgpu_soft_max_pipeline_key, webgpu_pipeline, ggml_webgpu_soft_max_pipeline_key_hash>
|
|
1210
|
+
soft_max_pipelines;
|
|
1211
|
+
std::unordered_map<ggml_webgpu_conv2d_pipeline_key, webgpu_pipeline, ggml_webgpu_conv2d_pipeline_key_hash>
|
|
1212
|
+
conv2d_pipelines;
|
|
1213
|
+
std::unordered_map<ggml_webgpu_im2col_pipeline_key, webgpu_pipeline, ggml_webgpu_im2col_pipeline_key_hash>
|
|
1214
|
+
im2col_pipelines;
|
|
1215
|
+
|
|
1216
|
+
std::unordered_map<ggml_webgpu_rms_norm_mul_pipeline_key,
|
|
1217
|
+
webgpu_pipeline,
|
|
1218
|
+
ggml_webgpu_rms_norm_mul_pipeline_key_hash>
|
|
1219
|
+
rms_norm_mul_pipelines;
|
|
1220
|
+
std::unordered_map<ggml_webgpu_upscale_pipeline_key, webgpu_pipeline, ggml_webgpu_upscale_pipeline_key_hash>
|
|
1221
|
+
upscale_pipelines;
|
|
465
1222
|
|
|
466
1223
|
public:
|
|
467
1224
|
ggml_webgpu_shader_lib(wgpu::Device device) { this->device = device; }
|
|
@@ -479,6 +1236,70 @@ class ggml_webgpu_shader_lib {
|
|
|
479
1236
|
return sum_rows_pipelines[1];
|
|
480
1237
|
}
|
|
481
1238
|
|
|
1239
|
+
webgpu_pipeline get_row_norm_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1240
|
+
ggml_webgpu_row_norm_pipeline_key key = {};
|
|
1241
|
+
key.op = context.dst->op;
|
|
1242
|
+
key.src_type = context.src0->type;
|
|
1243
|
+
key.dst_type = context.dst->type;
|
|
1244
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
1245
|
+
|
|
1246
|
+
auto it = row_norm_pipelines.find(key);
|
|
1247
|
+
if (it != row_norm_pipelines.end()) {
|
|
1248
|
+
return it->second;
|
|
1249
|
+
}
|
|
1250
|
+
std::vector<std::string> defines;
|
|
1251
|
+
std::string variant;
|
|
1252
|
+
|
|
1253
|
+
switch (key.op) {
|
|
1254
|
+
case GGML_OP_RMS_NORM:
|
|
1255
|
+
defines.push_back("RMS_NORM");
|
|
1256
|
+
variant = "rms_norm";
|
|
1257
|
+
break;
|
|
1258
|
+
case GGML_OP_NORM:
|
|
1259
|
+
defines.push_back("NORM");
|
|
1260
|
+
variant = "norm";
|
|
1261
|
+
break;
|
|
1262
|
+
case GGML_OP_L2_NORM:
|
|
1263
|
+
defines.push_back("L2_NORM");
|
|
1264
|
+
variant = "l2_norm";
|
|
1265
|
+
break;
|
|
1266
|
+
default:
|
|
1267
|
+
GGML_ABORT("Unsupported op for row_norm shader");
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
if (key.inplace) {
|
|
1271
|
+
defines.push_back("INPLACE");
|
|
1272
|
+
variant += "_inplace";
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
if (key.src_type == GGML_TYPE_F32) {
|
|
1276
|
+
defines.push_back("SRC_F32");
|
|
1277
|
+
variant += "_src_f32";
|
|
1278
|
+
} else if (key.src_type == GGML_TYPE_F16) {
|
|
1279
|
+
defines.push_back("SRC_F16");
|
|
1280
|
+
variant += "_src_f16";
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
if (key.dst_type == GGML_TYPE_F32) {
|
|
1284
|
+
defines.push_back("DST_F32");
|
|
1285
|
+
variant += "_dst_f32";
|
|
1286
|
+
} else if (key.dst_type == GGML_TYPE_F16) {
|
|
1287
|
+
defines.push_back("DST_F16");
|
|
1288
|
+
variant += "_dst_f16";
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
const uint32_t row_norm_wg_size = 128u;
|
|
1292
|
+
uint32_t wg_size = std::min(context.max_wg_size, row_norm_wg_size);
|
|
1293
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
1294
|
+
auto processed = preprocessor.preprocess(wgsl_row_norm, defines);
|
|
1295
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
1296
|
+
decisions->wg_size = wg_size;
|
|
1297
|
+
decisions->inplace = key.inplace;
|
|
1298
|
+
row_norm_pipelines[key] = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1299
|
+
row_norm_pipelines[key].context = decisions;
|
|
1300
|
+
return row_norm_pipelines[key];
|
|
1301
|
+
}
|
|
1302
|
+
|
|
482
1303
|
webgpu_pipeline get_argmax_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
483
1304
|
bool vec4 = context.src0->ne[0] % 4 == 0;
|
|
484
1305
|
|
|
@@ -500,9 +1321,13 @@ class ggml_webgpu_shader_lib {
|
|
|
500
1321
|
}
|
|
501
1322
|
|
|
502
1323
|
webgpu_pipeline get_set_rows_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
1324
|
+
const bool quantized = ggml_is_quantized(context.dst->type);
|
|
1325
|
+
ggml_webgpu_set_rows_pipeline_key key = {};
|
|
1326
|
+
key.dst_type = context.dst->type;
|
|
1327
|
+
key.vec4 =
|
|
1328
|
+
(context.dst->type == GGML_TYPE_F32 || context.dst->type == GGML_TYPE_F16) && context.src0->ne[0] % 4 == 0;
|
|
1329
|
+
key.i64_idx = context.src1->type == GGML_TYPE_I64;
|
|
1330
|
+
key.pair_blocks = quantized && ((context.src0->ne[0] / ggml_blck_size(context.dst->type)) % 2 == 0);
|
|
506
1331
|
|
|
507
1332
|
auto it = set_rows_pipelines.find(key);
|
|
508
1333
|
if (it != set_rows_pipelines.end()) {
|
|
@@ -521,6 +1346,14 @@ class ggml_webgpu_shader_lib {
|
|
|
521
1346
|
defines.push_back("DST_F16");
|
|
522
1347
|
variant += "_dstf16";
|
|
523
1348
|
break;
|
|
1349
|
+
case GGML_TYPE_Q8_0:
|
|
1350
|
+
defines.push_back("DST_Q8_0");
|
|
1351
|
+
variant += "_dstq8_0";
|
|
1352
|
+
break;
|
|
1353
|
+
case GGML_TYPE_Q4_0:
|
|
1354
|
+
defines.push_back("DST_Q4_0");
|
|
1355
|
+
variant += "_dstq4_0";
|
|
1356
|
+
break;
|
|
524
1357
|
default:
|
|
525
1358
|
GGML_ABORT("Unsupported dst type for set_rows shader");
|
|
526
1359
|
}
|
|
@@ -533,19 +1366,68 @@ class ggml_webgpu_shader_lib {
|
|
|
533
1366
|
defines.push_back("I64_IDX");
|
|
534
1367
|
variant += "_i64idx";
|
|
535
1368
|
}
|
|
1369
|
+
if (key.pair_blocks) {
|
|
1370
|
+
defines.push_back("PAIR_BLOCKS");
|
|
1371
|
+
variant += "_pair_blocks";
|
|
1372
|
+
}
|
|
536
1373
|
|
|
537
1374
|
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
538
1375
|
|
|
539
|
-
auto
|
|
540
|
-
auto
|
|
1376
|
+
const auto & shader_source = quantized ? wgsl_set_rows_quant : wgsl_set_rows;
|
|
1377
|
+
auto processed = preprocessor.preprocess(shader_source, defines);
|
|
1378
|
+
auto decisions = std::make_shared<ggml_webgpu_set_rows_shader_decisions>();
|
|
541
1379
|
decisions->vec4 = key.vec4;
|
|
542
1380
|
decisions->i64_idx = key.i64_idx;
|
|
1381
|
+
decisions->pair_blocks = key.pair_blocks;
|
|
543
1382
|
decisions->wg_size = context.max_wg_size;
|
|
544
1383
|
set_rows_pipelines[key] = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
545
1384
|
set_rows_pipelines[key].context = decisions;
|
|
546
1385
|
return set_rows_pipelines[key];
|
|
547
1386
|
}
|
|
548
1387
|
|
|
1388
|
+
webgpu_pipeline get_set_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1389
|
+
ggml_webgpu_set_pipeline_key key = {};
|
|
1390
|
+
key.type = context.dst->type;
|
|
1391
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
1392
|
+
|
|
1393
|
+
auto it = set_pipelines.find(key);
|
|
1394
|
+
if (it != set_pipelines.end()) {
|
|
1395
|
+
return it->second;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
std::vector<std::string> defines;
|
|
1399
|
+
std::string variant = "set";
|
|
1400
|
+
|
|
1401
|
+
switch (key.type) {
|
|
1402
|
+
case GGML_TYPE_F32:
|
|
1403
|
+
defines.push_back("TYPE_F32");
|
|
1404
|
+
variant += "_f32";
|
|
1405
|
+
break;
|
|
1406
|
+
case GGML_TYPE_I32:
|
|
1407
|
+
defines.push_back("TYPE_I32");
|
|
1408
|
+
variant += "_i32";
|
|
1409
|
+
break;
|
|
1410
|
+
default:
|
|
1411
|
+
GGML_ABORT("Unsupported type for set shader");
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
if (key.inplace) {
|
|
1415
|
+
defines.push_back("INPLACE");
|
|
1416
|
+
variant += "_inplace";
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
1420
|
+
|
|
1421
|
+
auto processed = preprocessor.preprocess(wgsl_set, defines);
|
|
1422
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
1423
|
+
decisions->wg_size = context.max_wg_size;
|
|
1424
|
+
decisions->inplace = key.inplace;
|
|
1425
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1426
|
+
pipeline.context = decisions;
|
|
1427
|
+
set_pipelines[key] = pipeline;
|
|
1428
|
+
return set_pipelines[key];
|
|
1429
|
+
}
|
|
1430
|
+
|
|
549
1431
|
webgpu_pipeline get_cumsum_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
550
1432
|
auto it = cumsum_pipelines.find(1);
|
|
551
1433
|
if (it != cumsum_pipelines.end()) {
|
|
@@ -614,10 +1496,9 @@ class ggml_webgpu_shader_lib {
|
|
|
614
1496
|
|
|
615
1497
|
webgpu_pipeline get_get_rows_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
616
1498
|
const bool vectorized = context.src0->type == GGML_TYPE_F32 && context.dst->ne[0] % 4 == 0;
|
|
617
|
-
ggml_webgpu_get_rows_pipeline_key key = {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
};
|
|
1499
|
+
ggml_webgpu_get_rows_pipeline_key key = {};
|
|
1500
|
+
key.src_type = context.src0->type;
|
|
1501
|
+
key.vectorized = (int) vectorized;
|
|
621
1502
|
|
|
622
1503
|
auto it = get_rows_pipelines.find(key);
|
|
623
1504
|
if (it != get_rows_pipelines.end()) {
|
|
@@ -632,6 +1513,7 @@ class ggml_webgpu_shader_lib {
|
|
|
632
1513
|
|
|
633
1514
|
switch (key.src_type) {
|
|
634
1515
|
case GGML_TYPE_F32:
|
|
1516
|
+
defines.push_back("FLOAT_PARALLEL");
|
|
635
1517
|
if (key.vectorized) {
|
|
636
1518
|
defines.push_back("F32_VEC");
|
|
637
1519
|
defines.push_back("SRC_TYPE=vec4<f32>");
|
|
@@ -646,6 +1528,7 @@ class ggml_webgpu_shader_lib {
|
|
|
646
1528
|
variant += "_f32";
|
|
647
1529
|
break;
|
|
648
1530
|
case GGML_TYPE_F16:
|
|
1531
|
+
defines.push_back("FLOAT_PARALLEL");
|
|
649
1532
|
defines.push_back("F16");
|
|
650
1533
|
defines.push_back("SRC_TYPE=f16");
|
|
651
1534
|
defines.push_back("DST_TYPE=f32");
|
|
@@ -653,6 +1536,7 @@ class ggml_webgpu_shader_lib {
|
|
|
653
1536
|
variant += "_f16";
|
|
654
1537
|
break;
|
|
655
1538
|
case GGML_TYPE_I32:
|
|
1539
|
+
defines.push_back("FLOAT_PARALLEL");
|
|
656
1540
|
defines.push_back("I32");
|
|
657
1541
|
defines.push_back("SRC_TYPE=i32");
|
|
658
1542
|
defines.push_back("DST_TYPE=i32");
|
|
@@ -664,22 +1548,54 @@ class ggml_webgpu_shader_lib {
|
|
|
664
1548
|
std::string type_upper = type_str;
|
|
665
1549
|
std::transform(type_upper.begin(), type_upper.end(), type_upper.begin(), ::toupper);
|
|
666
1550
|
|
|
1551
|
+
switch (key.src_type) {
|
|
1552
|
+
case GGML_TYPE_Q1_0:
|
|
1553
|
+
case GGML_TYPE_Q4_0:
|
|
1554
|
+
case GGML_TYPE_Q5_0:
|
|
1555
|
+
case GGML_TYPE_Q8_0:
|
|
1556
|
+
case GGML_TYPE_Q3_K:
|
|
1557
|
+
case GGML_TYPE_Q6_K:
|
|
1558
|
+
case GGML_TYPE_IQ2_XXS:
|
|
1559
|
+
case GGML_TYPE_IQ2_XS:
|
|
1560
|
+
case GGML_TYPE_IQ2_S:
|
|
1561
|
+
case GGML_TYPE_IQ3_XXS:
|
|
1562
|
+
case GGML_TYPE_IQ3_S:
|
|
1563
|
+
case GGML_TYPE_IQ1_S:
|
|
1564
|
+
case GGML_TYPE_IQ4_NL:
|
|
1565
|
+
case GGML_TYPE_MXFP4:
|
|
1566
|
+
case GGML_TYPE_NVFP4:
|
|
1567
|
+
{
|
|
1568
|
+
// Quantized types using u32 buffers for portability.
|
|
1569
|
+
defines.push_back("SRC_TYPE=u32");
|
|
1570
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
1571
|
+
break;
|
|
1572
|
+
}
|
|
1573
|
+
default:
|
|
1574
|
+
{
|
|
1575
|
+
defines.push_back(std::string("SRC_TYPE=") + type_str);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
|
|
667
1579
|
defines.push_back("BYTE_HELPERS");
|
|
668
1580
|
defines.push_back(type_upper + "_T");
|
|
669
1581
|
defines.push_back(type_upper);
|
|
670
1582
|
defines.push_back(type_upper + "_SCALE_MIN");
|
|
671
1583
|
defines.push_back(type_upper + "_TABLES");
|
|
672
1584
|
defines.push_back(type_upper + "_GRID");
|
|
1585
|
+
defines.push_back(type_upper + "_LUT");
|
|
673
1586
|
|
|
674
1587
|
variant += "_";
|
|
675
1588
|
variant += type_str;
|
|
676
1589
|
|
|
677
|
-
defines.push_back(std::string("SRC_TYPE=") + type_str);
|
|
678
1590
|
defines.push_back("DST_TYPE=f32");
|
|
679
1591
|
|
|
680
|
-
if (
|
|
681
|
-
|
|
1592
|
+
if (key.src_type == GGML_TYPE_Q1_0) {
|
|
1593
|
+
defines.push_back("BLOCK_SIZE=128u");
|
|
1594
|
+
} else if ((key.src_type >= GGML_TYPE_Q4_0 && key.src_type <= GGML_TYPE_Q8_1) ||
|
|
1595
|
+
key.src_type == GGML_TYPE_IQ4_NL || key.src_type == GGML_TYPE_MXFP4) {
|
|
682
1596
|
defines.push_back("BLOCK_SIZE=32u");
|
|
1597
|
+
} else if (key.src_type == GGML_TYPE_NVFP4) {
|
|
1598
|
+
defines.push_back("BLOCK_SIZE=64u");
|
|
683
1599
|
} else if (key.src_type >= GGML_TYPE_Q2_K) {
|
|
684
1600
|
defines.push_back("BLOCK_SIZE=256u");
|
|
685
1601
|
} else {
|
|
@@ -705,7 +1621,8 @@ class ggml_webgpu_shader_lib {
|
|
|
705
1621
|
}
|
|
706
1622
|
|
|
707
1623
|
webgpu_pipeline get_scale_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
708
|
-
ggml_webgpu_scale_pipeline_key key = {
|
|
1624
|
+
ggml_webgpu_scale_pipeline_key key = {};
|
|
1625
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
709
1626
|
|
|
710
1627
|
auto it = scale_pipelines.find(key);
|
|
711
1628
|
if (it != scale_pipelines.end()) {
|
|
@@ -725,14 +1642,189 @@ class ggml_webgpu_shader_lib {
|
|
|
725
1642
|
auto processed = preprocessor.preprocess(wgsl_scale, defines);
|
|
726
1643
|
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
727
1644
|
decisions->wg_size = context.max_wg_size;
|
|
1645
|
+
decisions->inplace = key.inplace;
|
|
728
1646
|
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
729
1647
|
pipeline.context = decisions;
|
|
730
1648
|
scale_pipelines[key] = pipeline;
|
|
731
1649
|
return scale_pipelines[key];
|
|
732
1650
|
}
|
|
733
1651
|
|
|
1652
|
+
webgpu_pipeline get_solve_tri_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1653
|
+
ggml_webgpu_solve_tri_pipeline_key key = {};
|
|
1654
|
+
key.type = context.dst->type;
|
|
1655
|
+
key.n = (int) context.src0->ne[0];
|
|
1656
|
+
key.k = (int) context.src1->ne[0];
|
|
1657
|
+
|
|
1658
|
+
auto it = solve_tri_pipelines.find(key);
|
|
1659
|
+
if (it != solve_tri_pipelines.end()) {
|
|
1660
|
+
return it->second;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
std::vector<std::string> defines;
|
|
1664
|
+
std::string variant = "solve_tri";
|
|
1665
|
+
|
|
1666
|
+
switch (key.type) {
|
|
1667
|
+
case GGML_TYPE_F32:
|
|
1668
|
+
variant += "_f32";
|
|
1669
|
+
break;
|
|
1670
|
+
default:
|
|
1671
|
+
GGML_ABORT("Unsupported type for solve_tri shader");
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
const uint32_t wg_size = std::min((uint32_t) key.n, context.max_wg_size);
|
|
1675
|
+
const uint32_t k_tile = wg_size;
|
|
1676
|
+
const uint32_t bytes_per_row = ((uint32_t) key.n + wg_size) * GGML_WEBGPU_F32_SIZE_BYTES;
|
|
1677
|
+
const uint32_t batch_n = (uint32_t) (context.wg_mem_limit_bytes / bytes_per_row);
|
|
1678
|
+
|
|
1679
|
+
defines.push_back(std::string("N=") + std::to_string(key.n));
|
|
1680
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
1681
|
+
defines.push_back(std::string("K_TILE=") + std::to_string(k_tile));
|
|
1682
|
+
defines.push_back(std::string("BATCH_N=") + std::to_string(batch_n));
|
|
1683
|
+
|
|
1684
|
+
auto processed = preprocessor.preprocess(wgsl_solve_tri, defines);
|
|
1685
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
1686
|
+
decisions->wg_size = wg_size;
|
|
1687
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1688
|
+
pipeline.context = decisions;
|
|
1689
|
+
solve_tri_pipelines[key] = pipeline;
|
|
1690
|
+
return solve_tri_pipelines[key];
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
webgpu_pipeline get_ssm_conv_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1694
|
+
ggml_webgpu_ssm_conv_pipeline_key key = {};
|
|
1695
|
+
key.type = context.dst->type;
|
|
1696
|
+
key.vectorized = context.src1->ne[0] == 4;
|
|
1697
|
+
|
|
1698
|
+
auto it = ssm_conv_pipelines.find(key);
|
|
1699
|
+
if (it != ssm_conv_pipelines.end()) {
|
|
1700
|
+
return it->second;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
std::vector<std::string> defines;
|
|
1704
|
+
std::string variant = "ssm_conv";
|
|
1705
|
+
|
|
1706
|
+
switch (key.type) {
|
|
1707
|
+
case GGML_TYPE_F32:
|
|
1708
|
+
variant += "_f32";
|
|
1709
|
+
break;
|
|
1710
|
+
default:
|
|
1711
|
+
GGML_ABORT("Unsupported type for ssm_conv shader");
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
if (key.vectorized) {
|
|
1715
|
+
defines.push_back("VECTORIZED");
|
|
1716
|
+
variant += "_vec4";
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
constexpr uint32_t block_size = 32u;
|
|
1720
|
+
constexpr uint32_t tokens_per_wg = 8u;
|
|
1721
|
+
|
|
1722
|
+
defines.push_back("BLOCK_SIZE=" + std::to_string(block_size) + "u");
|
|
1723
|
+
defines.push_back("TOKENS_PER_WG=" + std::to_string(tokens_per_wg) + "u");
|
|
1724
|
+
|
|
1725
|
+
auto processed = preprocessor.preprocess(wgsl_ssm_conv, defines);
|
|
1726
|
+
auto decisions = std::make_shared<ggml_webgpu_ssm_conv_shader_decisions>();
|
|
1727
|
+
decisions->block_size = block_size;
|
|
1728
|
+
decisions->tokens_per_wg = tokens_per_wg;
|
|
1729
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1730
|
+
pipeline.context = decisions;
|
|
1731
|
+
ssm_conv_pipelines[key] = pipeline;
|
|
1732
|
+
return ssm_conv_pipelines[key];
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
webgpu_pipeline get_ssm_scan_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1736
|
+
ggml_webgpu_ssm_scan_pipeline_key key = {};
|
|
1737
|
+
key.type = context.dst->type;
|
|
1738
|
+
key.d_state = (int) context.src0->ne[0];
|
|
1739
|
+
key.xbc_overlap = ggml_webgpu_tensor_overlap(context.src1, context.src4) &&
|
|
1740
|
+
ggml_webgpu_tensor_overlap(context.src1, context.src5);
|
|
1741
|
+
|
|
1742
|
+
auto it = ssm_scan_pipelines.find(key);
|
|
1743
|
+
if (it != ssm_scan_pipelines.end()) {
|
|
1744
|
+
return it->second;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
std::vector<std::string> defines;
|
|
1748
|
+
std::string variant = "ssm_scan";
|
|
1749
|
+
|
|
1750
|
+
switch (key.type) {
|
|
1751
|
+
case GGML_TYPE_F32:
|
|
1752
|
+
variant += "_f32";
|
|
1753
|
+
break;
|
|
1754
|
+
default:
|
|
1755
|
+
GGML_ABORT("Unsupported type for ssm_scan shader");
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
const uint32_t wg_size = (uint32_t) key.d_state;
|
|
1759
|
+
|
|
1760
|
+
constexpr uint32_t tokens_per_tile = 4u;
|
|
1761
|
+
|
|
1762
|
+
defines.push_back("WG_SIZE=" + std::to_string(wg_size) + "u");
|
|
1763
|
+
defines.push_back("TOKENS_PER_TILE=" + std::to_string(tokens_per_tile) + "u");
|
|
1764
|
+
|
|
1765
|
+
if (context.supports_subgroups) {
|
|
1766
|
+
defines.push_back("USE_SUBGROUP_REDUCTION");
|
|
1767
|
+
variant += "_sg_reduce";
|
|
1768
|
+
} else {
|
|
1769
|
+
variant += "_wg_reduce";
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
if (key.xbc_overlap) {
|
|
1773
|
+
defines.push_back("XBC_OVERLAP");
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
variant += "_d" + std::to_string(key.d_state);
|
|
1777
|
+
|
|
1778
|
+
auto processed = preprocessor.preprocess(wgsl_ssm_scan, defines);
|
|
1779
|
+
auto decisions = std::make_shared<ggml_webgpu_ssm_scan_shader_decisions>();
|
|
1780
|
+
decisions->wg_size = wg_size;
|
|
1781
|
+
decisions->tokens_per_tile = tokens_per_tile;
|
|
1782
|
+
decisions->xbc_overlap = key.xbc_overlap;
|
|
1783
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1784
|
+
pipeline.context = decisions;
|
|
1785
|
+
ssm_scan_pipelines[key] = pipeline;
|
|
1786
|
+
return ssm_scan_pipelines[key];
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
webgpu_pipeline get_gated_delta_net_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1790
|
+
ggml_webgpu_gated_delta_net_pipeline_key key = {};
|
|
1791
|
+
key.type = context.dst->type;
|
|
1792
|
+
key.s_v = (int) context.src2->ne[0];
|
|
1793
|
+
key.kda = context.src3->ne[0] == context.src2->ne[0];
|
|
1794
|
+
|
|
1795
|
+
auto it = gated_delta_net_pipelines.find(key);
|
|
1796
|
+
if (it != gated_delta_net_pipelines.end()) {
|
|
1797
|
+
return it->second;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
std::vector<std::string> defines;
|
|
1801
|
+
std::string variant = "gated_delta_net";
|
|
1802
|
+
|
|
1803
|
+
switch (key.type) {
|
|
1804
|
+
case GGML_TYPE_F32:
|
|
1805
|
+
variant += "_f32";
|
|
1806
|
+
break;
|
|
1807
|
+
default:
|
|
1808
|
+
GGML_ABORT("Unsupported type for gated_delta_net shader");
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
if (key.kda) {
|
|
1812
|
+
defines.push_back("KDA");
|
|
1813
|
+
variant += "_kda";
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
defines.push_back("S_V=" + std::to_string(key.s_v) + "u");
|
|
1817
|
+
defines.push_back("WG_SIZE=" + std::to_string(key.s_v) + "u");
|
|
1818
|
+
|
|
1819
|
+
auto processed = preprocessor.preprocess(wgsl_gated_delta_net, defines);
|
|
1820
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1821
|
+
gated_delta_net_pipelines[key] = pipeline;
|
|
1822
|
+
return gated_delta_net_pipelines[key];
|
|
1823
|
+
}
|
|
1824
|
+
|
|
734
1825
|
webgpu_pipeline get_pad_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
735
|
-
ggml_webgpu_pad_pipeline_key key = {
|
|
1826
|
+
ggml_webgpu_pad_pipeline_key key = {};
|
|
1827
|
+
key.circular = ggml_get_op_params_i32(context.dst, 8) != 0;
|
|
736
1828
|
|
|
737
1829
|
auto it = pad_pipelines.find(key);
|
|
738
1830
|
if (it != pad_pipelines.end()) {
|
|
@@ -758,16 +1850,55 @@ class ggml_webgpu_shader_lib {
|
|
|
758
1850
|
return pad_pipelines[key];
|
|
759
1851
|
}
|
|
760
1852
|
|
|
1853
|
+
webgpu_pipeline get_quantize_q8_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1854
|
+
ggml_webgpu_quantize_q8_pipeline_key key = {};
|
|
1855
|
+
key.src0_type = context.src0->type;
|
|
1856
|
+
|
|
1857
|
+
auto it = quantize_q8_pipelines.find(key);
|
|
1858
|
+
if (it != quantize_q8_pipelines.end()) {
|
|
1859
|
+
return it->second;
|
|
1860
|
+
}
|
|
1861
|
+
const char * shader_src = wgsl_quantize_q8;
|
|
1862
|
+
std::vector<std::string> defines;
|
|
1863
|
+
std::string variant = "quantize_q8";
|
|
1864
|
+
|
|
1865
|
+
uint32_t wg_size = WEBGPU_MUL_MAT_VEC_WG_SIZE;
|
|
1866
|
+
|
|
1867
|
+
defines.push_back("SRC1_INNER_TYPE=f32");
|
|
1868
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
1869
|
+
|
|
1870
|
+
const struct ggml_type_traits * src0_traits = ggml_get_type_traits(context.src0->type);
|
|
1871
|
+
std::string src0_name = src0_traits->type_name;
|
|
1872
|
+
std::string type_upper = src0_name;
|
|
1873
|
+
variant += "_" + src0_name;
|
|
1874
|
+
std::transform(type_upper.begin(), type_upper.end(), type_upper.begin(), ::toupper);
|
|
1875
|
+
|
|
1876
|
+
defines.push_back("MUL_ACC_" + type_upper);
|
|
1877
|
+
defines.push_back("Q8_1_T");
|
|
1878
|
+
|
|
1879
|
+
defines.push_back(context.supports_subgroups ? "USE_SUBGROUP_REDUCTION" : "USE_WORKGROUP_REDUCTION");
|
|
1880
|
+
variant += context.supports_subgroups ? "_sg_reduce" : "_wg_reduce";
|
|
1881
|
+
|
|
1882
|
+
auto processed = preprocessor.preprocess(shader_src, defines);
|
|
1883
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
1884
|
+
decisions->wg_size = wg_size;
|
|
1885
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1886
|
+
pipeline.context = decisions;
|
|
1887
|
+
quantize_q8_pipelines[key] = pipeline;
|
|
1888
|
+
return quantize_q8_pipelines[key];
|
|
1889
|
+
}
|
|
1890
|
+
|
|
761
1891
|
webgpu_pipeline get_mul_mat_vec_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
762
|
-
ggml_webgpu_mul_mat_vec_pipeline_key key = {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
1892
|
+
ggml_webgpu_mul_mat_vec_pipeline_key key = {};
|
|
1893
|
+
key.src0_type = context.src0->type;
|
|
1894
|
+
key.src1_type = context.src1->type;
|
|
1895
|
+
key.vectorized = (context.src0->ne[0] % 4 == 0 &&
|
|
1896
|
+
(context.src0->type == GGML_TYPE_F32 || context.src0->type == GGML_TYPE_F16)) ?
|
|
1897
|
+
1 :
|
|
1898
|
+
0;
|
|
1899
|
+
key.num_cols = context.dst->ne[1];
|
|
1900
|
+
key.use_mmvq =
|
|
1901
|
+
ggml_webgpu_can_use_mmvq(context.src0, context.src1, context.supports_dot_product, context.vendor);
|
|
771
1902
|
|
|
772
1903
|
auto it = mul_mat_vec_pipelines.find(key);
|
|
773
1904
|
if (it != mul_mat_vec_pipelines.end()) {
|
|
@@ -775,7 +1906,8 @@ class ggml_webgpu_shader_lib {
|
|
|
775
1906
|
}
|
|
776
1907
|
|
|
777
1908
|
std::vector<std::string> defines;
|
|
778
|
-
std::string variant
|
|
1909
|
+
std::string variant = "mul_mat_vec";
|
|
1910
|
+
const char * shader_src = wgsl_mul_mat_vec;
|
|
779
1911
|
|
|
780
1912
|
// src0 type (matrix row)
|
|
781
1913
|
switch (context.src0->type) {
|
|
@@ -800,9 +1932,43 @@ class ggml_webgpu_shader_lib {
|
|
|
800
1932
|
|
|
801
1933
|
defines.push_back("BYTE_HELPERS");
|
|
802
1934
|
defines.push_back("MUL_ACC_" + type_upper);
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
1935
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
1936
|
+
defines.push_back("SRC0_INNER_TYPE=u32");
|
|
1937
|
+
switch (context.src0->type) {
|
|
1938
|
+
case GGML_TYPE_Q8_0:
|
|
1939
|
+
case GGML_TYPE_Q4_0:
|
|
1940
|
+
case GGML_TYPE_Q4_1:
|
|
1941
|
+
if (key.use_mmvq) {
|
|
1942
|
+
defines.push_back("LEGACY_QUANTS");
|
|
1943
|
+
}
|
|
1944
|
+
break;
|
|
1945
|
+
case GGML_TYPE_Q2_K:
|
|
1946
|
+
case GGML_TYPE_Q4_K:
|
|
1947
|
+
if (key.use_mmvq) {
|
|
1948
|
+
defines.push_back("K_QUANTS");
|
|
1949
|
+
}
|
|
1950
|
+
break;
|
|
1951
|
+
case GGML_TYPE_IQ1_S:
|
|
1952
|
+
case GGML_TYPE_IQ1_M:
|
|
1953
|
+
case GGML_TYPE_IQ2_S:
|
|
1954
|
+
case GGML_TYPE_IQ3_S:
|
|
1955
|
+
case GGML_TYPE_IQ4_NL:
|
|
1956
|
+
case GGML_TYPE_IQ4_XS:
|
|
1957
|
+
defines.push_back(type_upper + "_GRID");
|
|
1958
|
+
break;
|
|
1959
|
+
case GGML_TYPE_IQ2_XXS:
|
|
1960
|
+
case GGML_TYPE_IQ2_XS:
|
|
1961
|
+
case GGML_TYPE_IQ3_XXS:
|
|
1962
|
+
defines.push_back(type_upper + "_GRID");
|
|
1963
|
+
defines.push_back(type_upper + "_TABLES");
|
|
1964
|
+
break;
|
|
1965
|
+
case GGML_TYPE_MXFP4:
|
|
1966
|
+
case GGML_TYPE_NVFP4:
|
|
1967
|
+
defines.push_back(type_upper + "_LUT");
|
|
1968
|
+
break;
|
|
1969
|
+
default:
|
|
1970
|
+
break;
|
|
1971
|
+
}
|
|
806
1972
|
break;
|
|
807
1973
|
}
|
|
808
1974
|
}
|
|
@@ -825,25 +1991,33 @@ class ggml_webgpu_shader_lib {
|
|
|
825
1991
|
defines.push_back(key.vectorized ? "VEC" : "SCALAR");
|
|
826
1992
|
|
|
827
1993
|
uint32_t wg_size = WEBGPU_MUL_MAT_VEC_WG_SIZE;
|
|
828
|
-
uint32_t tile_k = WEBGPU_MUL_MAT_VEC_FLOAT_TILE_K;
|
|
829
1994
|
uint32_t outputs_per_wg = WEBGPU_MUL_MAT_VEC_FLOAT_OUTPUTS_PER_WG;
|
|
830
1995
|
|
|
831
|
-
if (key.src0_type
|
|
832
|
-
|
|
1996
|
+
if (key.src0_type == GGML_TYPE_Q1_0) {
|
|
1997
|
+
outputs_per_wg = WEBGPU_MUL_MAT_VEC_LEGACY_Q_OUTPUTS_PER_WG;
|
|
1998
|
+
} else if (key.src0_type >= GGML_TYPE_Q2_K) {
|
|
833
1999
|
outputs_per_wg = WEBGPU_MUL_MAT_VEC_K_Q_OUTPUTS_PER_WG;
|
|
834
2000
|
} else if (key.src0_type >= GGML_TYPE_Q4_0) {
|
|
835
|
-
tile_k = WEBGPU_MUL_MAT_VEC_LEGACY_Q_TILE_K;
|
|
836
2001
|
outputs_per_wg = WEBGPU_MUL_MAT_VEC_LEGACY_Q_OUTPUTS_PER_WG;
|
|
837
2002
|
}
|
|
838
2003
|
|
|
2004
|
+
if (key.use_mmvq) {
|
|
2005
|
+
defines.push_back("MMVQ");
|
|
2006
|
+
defines.push_back("Q8_1_T");
|
|
2007
|
+
}
|
|
2008
|
+
|
|
839
2009
|
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
840
|
-
defines.push_back(std::string("TILE_K=") + std::to_string(tile_k));
|
|
841
2010
|
defines.push_back(std::string("OUTPUTS_PER_WG=") + std::to_string(outputs_per_wg));
|
|
2011
|
+
defines.push_back(context.supports_subgroups ? "USE_SUBGROUP_REDUCTION" : "USE_WORKGROUP_REDUCTION");
|
|
2012
|
+
variant += context.supports_subgroups ? "_sg_reduce" : "_wg_reduce";
|
|
2013
|
+
if (key.vectorized) {
|
|
2014
|
+
variant += "_vectorized";
|
|
2015
|
+
}
|
|
2016
|
+
defines.push_back(std::string("NUM_COLS=") + std::to_string(key.num_cols));
|
|
842
2017
|
|
|
843
|
-
auto processed = preprocessor.preprocess(
|
|
2018
|
+
auto processed = preprocessor.preprocess(shader_src, defines);
|
|
844
2019
|
auto decisions = std::make_shared<ggml_webgpu_mul_mat_vec_shader_decisions>();
|
|
845
2020
|
decisions->wg_size = wg_size;
|
|
846
|
-
decisions->tile_k = tile_k;
|
|
847
2021
|
decisions->outputs_per_wg = outputs_per_wg;
|
|
848
2022
|
decisions->vec_size = key.vectorized ? 4 : 1;
|
|
849
2023
|
|
|
@@ -854,15 +2028,14 @@ class ggml_webgpu_shader_lib {
|
|
|
854
2028
|
}
|
|
855
2029
|
|
|
856
2030
|
webgpu_pipeline get_mul_mat_fast_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
857
|
-
ggml_webgpu_mul_mat_pipeline_key key = {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
};
|
|
2031
|
+
ggml_webgpu_mul_mat_pipeline_key key = {};
|
|
2032
|
+
key.src0_type = context.src0->type;
|
|
2033
|
+
key.src1_type = context.src1->type;
|
|
2034
|
+
key.vectorized = (context.src0->ne[0] % 4 == 0 && context.dst->ne[0] % 4 == 0 &&
|
|
2035
|
+
(context.src0->type == GGML_TYPE_F32 || context.src0->type == GGML_TYPE_F16)) ?
|
|
2036
|
+
1 :
|
|
2037
|
+
0;
|
|
2038
|
+
key.use_subgroup_matrix = context.supports_subgroup_matrix;
|
|
866
2039
|
|
|
867
2040
|
auto it = mul_mat_fast_pipelines.find(key);
|
|
868
2041
|
if (it != mul_mat_fast_pipelines.end()) {
|
|
@@ -915,9 +2088,31 @@ class ggml_webgpu_shader_lib {
|
|
|
915
2088
|
defines.push_back("MUL_ACC_" + type_upper);
|
|
916
2089
|
defines.push_back("INIT_SRC0_SHMEM_" + type_upper);
|
|
917
2090
|
defines.push_back("INIT_SRC1_SHMEM_FLOAT");
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
2091
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
2092
|
+
defines.push_back("SRC0_INNER_TYPE=u32");
|
|
2093
|
+
|
|
2094
|
+
switch (context.src0->type) {
|
|
2095
|
+
case GGML_TYPE_IQ1_S:
|
|
2096
|
+
case GGML_TYPE_IQ1_M:
|
|
2097
|
+
case GGML_TYPE_IQ4_NL:
|
|
2098
|
+
case GGML_TYPE_IQ4_XS:
|
|
2099
|
+
defines.push_back(type_upper + "_GRID");
|
|
2100
|
+
break;
|
|
2101
|
+
case GGML_TYPE_IQ2_XXS:
|
|
2102
|
+
case GGML_TYPE_IQ2_XS:
|
|
2103
|
+
case GGML_TYPE_IQ2_S:
|
|
2104
|
+
case GGML_TYPE_IQ3_XXS:
|
|
2105
|
+
case GGML_TYPE_IQ3_S:
|
|
2106
|
+
defines.push_back(type_upper + "_GRID");
|
|
2107
|
+
defines.push_back(type_upper + "_TABLES");
|
|
2108
|
+
break;
|
|
2109
|
+
case GGML_TYPE_MXFP4:
|
|
2110
|
+
case GGML_TYPE_NVFP4:
|
|
2111
|
+
defines.push_back(type_upper + "_LUT");
|
|
2112
|
+
break;
|
|
2113
|
+
default:
|
|
2114
|
+
break;
|
|
2115
|
+
}
|
|
921
2116
|
|
|
922
2117
|
variant += std::string("_") + src0_name;
|
|
923
2118
|
break;
|
|
@@ -927,13 +2122,22 @@ class ggml_webgpu_shader_lib {
|
|
|
927
2122
|
// VEC/SCALAR controls
|
|
928
2123
|
defines.push_back(key.vectorized ? "VEC" : "SCALAR");
|
|
929
2124
|
|
|
2125
|
+
const bool is_quant = ggml_is_quantized(context.src0->type);
|
|
2126
|
+
|
|
2127
|
+
uint32_t tile_k;
|
|
2128
|
+
if (key.use_subgroup_matrix) {
|
|
2129
|
+
tile_k = is_quant ? WEBGPU_MUL_MAT_SUBGROUP_TILE_K_QUANT : WEBGPU_MUL_MAT_SUBGROUP_TILE_K_FLOAT;
|
|
2130
|
+
} else {
|
|
2131
|
+
tile_k = is_quant ? WEBGPU_MUL_MAT_REG_TILE_K_QUANT : WEBGPU_MUL_MAT_REG_TILE_K_FLOAT;
|
|
2132
|
+
}
|
|
2133
|
+
|
|
930
2134
|
// Tiles
|
|
931
2135
|
defines.push_back("TILE_M=" + std::to_string(WEBGPU_MUL_MAT_TILE_M) + "u");
|
|
932
2136
|
defines.push_back("TILE_N=" + std::to_string(WEBGPU_MUL_MAT_TILE_N) + "u");
|
|
933
|
-
defines.push_back("TILE_K=" + std::to_string(WEBGPU_MUL_MAT_TILE_K) + "u");
|
|
934
2137
|
|
|
935
2138
|
// Subgroup matrix specifics
|
|
936
2139
|
if (key.use_subgroup_matrix) {
|
|
2140
|
+
defines.push_back("TILE_K=" + std::to_string(tile_k) + "u");
|
|
937
2141
|
defines.push_back("MAX_SUBGROUP_SIZE=" + std::to_string(context.max_subgroup_size) + "u");
|
|
938
2142
|
defines.push_back("SUBGROUP_M=" + std::to_string(WEBGPU_MUL_MAT_SUBGROUP_M) + "u");
|
|
939
2143
|
defines.push_back("SUBGROUP_N=" + std::to_string(WEBGPU_MUL_MAT_SUBGROUP_N) + "u");
|
|
@@ -953,12 +2157,13 @@ class ggml_webgpu_shader_lib {
|
|
|
953
2157
|
if (!key.use_subgroup_matrix) {
|
|
954
2158
|
defines.push_back("WORKGROUP_SIZE_M=" + std::to_string(WEBGPU_MUL_MAT_WG_SIZE_M) + "u");
|
|
955
2159
|
defines.push_back("WORKGROUP_SIZE_N=" + std::to_string(WEBGPU_MUL_MAT_WG_SIZE_N) + "u");
|
|
2160
|
+
defines.push_back("TILE_K=" + std::to_string(tile_k) + "u");
|
|
956
2161
|
}
|
|
957
2162
|
|
|
958
2163
|
auto processed = preprocessor.preprocess(shader_src, defines);
|
|
959
2164
|
|
|
960
2165
|
auto decisions = std::make_shared<ggml_webgpu_mul_mat_shader_decisions>();
|
|
961
|
-
decisions->tile_k =
|
|
2166
|
+
decisions->tile_k = tile_k;
|
|
962
2167
|
decisions->tile_m = WEBGPU_MUL_MAT_TILE_M;
|
|
963
2168
|
decisions->tile_n = WEBGPU_MUL_MAT_TILE_N;
|
|
964
2169
|
decisions->use_subgroup_matrix = key.use_subgroup_matrix;
|
|
@@ -981,84 +2186,279 @@ class ggml_webgpu_shader_lib {
|
|
|
981
2186
|
return mul_mat_fast_pipelines[key];
|
|
982
2187
|
}
|
|
983
2188
|
|
|
984
|
-
webgpu_pipeline
|
|
985
|
-
|
|
986
|
-
|
|
2189
|
+
webgpu_pipeline get_mul_mat_id_gather_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2190
|
+
auto it = mul_mat_id_gather_pipelines.find(1);
|
|
2191
|
+
if (it != mul_mat_id_gather_pipelines.end()) {
|
|
2192
|
+
return it->second;
|
|
2193
|
+
}
|
|
2194
|
+
std::vector<std::string> defines;
|
|
2195
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
987
2196
|
|
|
988
|
-
auto
|
|
989
|
-
|
|
2197
|
+
auto processed = preprocessor.preprocess(wgsl_mul_mat_id_gather, defines);
|
|
2198
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
2199
|
+
decisions->wg_size = context.max_wg_size;
|
|
2200
|
+
|
|
2201
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, "mul_mat_id_gather");
|
|
2202
|
+
pipeline.context = decisions;
|
|
2203
|
+
mul_mat_id_gather_pipelines[1] = pipeline;
|
|
2204
|
+
return pipeline;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
webgpu_pipeline get_mul_mat_id_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2208
|
+
ggml_webgpu_mul_mat_id_pipeline_key key = {};
|
|
2209
|
+
key.src0_type = context.src0->type;
|
|
2210
|
+
key.src1_type = context.src1->type;
|
|
2211
|
+
key.n_experts = context.src0->ne[2];
|
|
2212
|
+
key.vectorized = (context.src0->ne[0] % 4 == 0 && context.src0->ne[1] % 4 == 0 &&
|
|
2213
|
+
(context.src0->type == GGML_TYPE_F32 || context.src0->type == GGML_TYPE_F16)) ?
|
|
2214
|
+
1 :
|
|
2215
|
+
0;
|
|
2216
|
+
|
|
2217
|
+
auto it = mul_mat_id_pipelines.find(key);
|
|
2218
|
+
if (it != mul_mat_id_pipelines.end()) {
|
|
990
2219
|
return it->second;
|
|
991
2220
|
}
|
|
992
2221
|
|
|
993
2222
|
std::vector<std::string> defines;
|
|
994
|
-
std::string variant = "
|
|
2223
|
+
std::string variant = "mul_mat_id";
|
|
2224
|
+
defines.push_back("MUL_MAT_ID");
|
|
995
2225
|
|
|
2226
|
+
// src1 type
|
|
996
2227
|
switch (context.src1->type) {
|
|
997
2228
|
case GGML_TYPE_F32:
|
|
998
|
-
defines.push_back("
|
|
999
|
-
variant += "_f32";
|
|
2229
|
+
defines.push_back("SRC1_INNER_TYPE=f32");
|
|
1000
2230
|
break;
|
|
1001
2231
|
case GGML_TYPE_F16:
|
|
1002
|
-
defines.push_back("
|
|
1003
|
-
variant += "_f16";
|
|
2232
|
+
defines.push_back("SRC1_INNER_TYPE=f16");
|
|
1004
2233
|
break;
|
|
1005
2234
|
default:
|
|
1006
|
-
GGML_ABORT("Unsupported src1 type for mul_mat
|
|
2235
|
+
GGML_ABORT("Unsupported src1 type for mul_mat fast shader");
|
|
1007
2236
|
}
|
|
1008
2237
|
|
|
2238
|
+
// src0 type
|
|
1009
2239
|
const struct ggml_type_traits * src0_traits = ggml_get_type_traits(context.src0->type);
|
|
1010
2240
|
const char * src0_name = src0_traits->type_name;
|
|
1011
2241
|
|
|
1012
2242
|
switch (context.src0->type) {
|
|
1013
2243
|
case GGML_TYPE_F32:
|
|
1014
|
-
defines.push_back("
|
|
1015
|
-
defines.push_back("
|
|
2244
|
+
defines.push_back("SRC0_INNER_TYPE=f32");
|
|
2245
|
+
defines.push_back("INIT_SRC0_SHMEM_FLOAT");
|
|
2246
|
+
defines.push_back("INIT_SRC1_SHMEM_FLOAT");
|
|
1016
2247
|
variant += "_f32";
|
|
1017
2248
|
break;
|
|
1018
2249
|
case GGML_TYPE_F16:
|
|
1019
|
-
defines.push_back("
|
|
1020
|
-
defines.push_back("
|
|
2250
|
+
defines.push_back("SRC0_INNER_TYPE=f16");
|
|
2251
|
+
defines.push_back("INIT_SRC0_SHMEM_FLOAT");
|
|
2252
|
+
defines.push_back("INIT_SRC1_SHMEM_FLOAT");
|
|
1021
2253
|
variant += "_f16";
|
|
1022
2254
|
break;
|
|
1023
2255
|
default:
|
|
1024
2256
|
{
|
|
1025
|
-
// quantized types
|
|
1026
2257
|
std::string type_upper = src0_name;
|
|
1027
2258
|
std::transform(type_upper.begin(), type_upper.end(), type_upper.begin(), ::toupper);
|
|
1028
2259
|
|
|
1029
|
-
defines.push_back(std::string("SRC0_TYPE=") + src0_name);
|
|
1030
2260
|
defines.push_back("BYTE_HELPERS");
|
|
1031
|
-
defines.push_back(
|
|
1032
|
-
defines.push_back(
|
|
1033
|
-
defines.push_back(
|
|
1034
|
-
defines.push_back(
|
|
1035
|
-
|
|
2261
|
+
defines.push_back("INIT_SRC0_SHMEM_" + type_upper);
|
|
2262
|
+
defines.push_back("INIT_SRC1_SHMEM_FLOAT");
|
|
2263
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
2264
|
+
defines.push_back("SRC0_INNER_TYPE=u32");
|
|
2265
|
+
|
|
2266
|
+
switch (context.src0->type) {
|
|
2267
|
+
case GGML_TYPE_IQ1_S:
|
|
2268
|
+
case GGML_TYPE_IQ1_M:
|
|
2269
|
+
case GGML_TYPE_IQ4_NL:
|
|
2270
|
+
case GGML_TYPE_IQ4_XS:
|
|
2271
|
+
defines.push_back(type_upper + "_GRID");
|
|
2272
|
+
break;
|
|
2273
|
+
case GGML_TYPE_IQ2_XXS:
|
|
2274
|
+
case GGML_TYPE_IQ2_XS:
|
|
2275
|
+
case GGML_TYPE_IQ2_S:
|
|
2276
|
+
case GGML_TYPE_IQ3_XXS:
|
|
2277
|
+
case GGML_TYPE_IQ3_S:
|
|
2278
|
+
defines.push_back(type_upper + "_GRID");
|
|
2279
|
+
defines.push_back(type_upper + "_TABLES");
|
|
2280
|
+
break;
|
|
2281
|
+
case GGML_TYPE_MXFP4:
|
|
2282
|
+
case GGML_TYPE_NVFP4:
|
|
2283
|
+
defines.push_back(type_upper + "_LUT");
|
|
2284
|
+
break;
|
|
2285
|
+
default:
|
|
2286
|
+
break;
|
|
2287
|
+
}
|
|
1036
2288
|
|
|
1037
2289
|
variant += std::string("_") + src0_name;
|
|
1038
2290
|
break;
|
|
1039
2291
|
}
|
|
1040
2292
|
}
|
|
1041
2293
|
|
|
1042
|
-
|
|
2294
|
+
// VEC/SCALAR controls
|
|
2295
|
+
defines.push_back(key.vectorized ? "VEC" : "SCALAR");
|
|
1043
2296
|
|
|
1044
|
-
|
|
1045
|
-
|
|
2297
|
+
// mul_mat_id is register-tile only.
|
|
2298
|
+
const uint32_t tile_k =
|
|
2299
|
+
ggml_is_quantized(context.src0->type) ? WEBGPU_MUL_MAT_REG_TILE_K_QUANT : WEBGPU_MUL_MAT_REG_TILE_K_FLOAT;
|
|
2300
|
+
|
|
2301
|
+
// Tiles
|
|
2302
|
+
defines.push_back("TILE_M=" + std::to_string(WEBGPU_MUL_MAT_TILE_M) + "u");
|
|
2303
|
+
defines.push_back("TILE_N=" + std::to_string(WEBGPU_MUL_MAT_TILE_N) + "u");
|
|
2304
|
+
defines.push_back("TILE_K=" + std::to_string(tile_k) + "u");
|
|
2305
|
+
|
|
2306
|
+
defines.push_back("WORKGROUP_SIZE_M=" + std::to_string(WEBGPU_MUL_MAT_WG_SIZE_M) + "u");
|
|
2307
|
+
defines.push_back("WORKGROUP_SIZE_N=" + std::to_string(WEBGPU_MUL_MAT_WG_SIZE_N) + "u");
|
|
2308
|
+
|
|
2309
|
+
// variant suffix for src1 type
|
|
2310
|
+
variant += std::string("_") + (context.src1->type == GGML_TYPE_F32 ? "f32" : "f16");
|
|
2311
|
+
if (key.vectorized) {
|
|
2312
|
+
variant += "_vectorized";
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
auto processed = preprocessor.preprocess(wgsl_mul_mat_id, defines);
|
|
2316
|
+
|
|
2317
|
+
auto decisions = std::make_shared<ggml_webgpu_mul_mat_shader_decisions>();
|
|
2318
|
+
decisions->tile_k = tile_k;
|
|
2319
|
+
decisions->tile_m = WEBGPU_MUL_MAT_TILE_M;
|
|
2320
|
+
decisions->tile_n = WEBGPU_MUL_MAT_TILE_N;
|
|
2321
|
+
decisions->wg_size_m = WEBGPU_MUL_MAT_WG_SIZE_M;
|
|
2322
|
+
decisions->wg_size_n = WEBGPU_MUL_MAT_WG_SIZE_N;
|
|
2323
|
+
decisions->wg_size = WEBGPU_MUL_MAT_WG_SIZE_M * WEBGPU_MUL_MAT_WG_SIZE_N;
|
|
2324
|
+
|
|
2325
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
2326
|
+
pipeline.context = decisions;
|
|
2327
|
+
mul_mat_id_pipelines[key] = pipeline;
|
|
2328
|
+
return mul_mat_id_pipelines[key];
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
webgpu_pipeline get_mul_mat_id_vec_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2332
|
+
ggml_webgpu_mul_mat_id_pipeline_key key = {};
|
|
2333
|
+
key.src0_type = context.src0->type;
|
|
2334
|
+
key.src1_type = context.src1->type;
|
|
2335
|
+
key.n_experts = context.src0->ne[2];
|
|
2336
|
+
key.vectorized = (context.src0->ne[0] % 4 == 0 &&
|
|
2337
|
+
(context.src0->type == GGML_TYPE_F32 || context.src0->type == GGML_TYPE_F16)) ?
|
|
2338
|
+
1 :
|
|
2339
|
+
0;
|
|
2340
|
+
|
|
2341
|
+
auto it = mul_mat_id_vec_pipelines.find(key);
|
|
2342
|
+
if (it != mul_mat_id_vec_pipelines.end()) {
|
|
2343
|
+
return it->second;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
std::vector<std::string> defines;
|
|
2347
|
+
std::string variant = "mul_mat_id_vec";
|
|
2348
|
+
const char * shader_src = wgsl_mul_mat_id_vec;
|
|
2349
|
+
|
|
2350
|
+
// src1 type
|
|
2351
|
+
switch (context.src1->type) {
|
|
2352
|
+
case GGML_TYPE_F32:
|
|
2353
|
+
defines.push_back("SRC1_INNER_TYPE=f32");
|
|
2354
|
+
break;
|
|
2355
|
+
case GGML_TYPE_F16:
|
|
2356
|
+
defines.push_back("SRC1_INNER_TYPE=f16");
|
|
2357
|
+
break;
|
|
2358
|
+
default:
|
|
2359
|
+
GGML_ABORT("Unsupported src1 type for mul_mat fast shader");
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// src0 type
|
|
2363
|
+
switch (context.src0->type) {
|
|
2364
|
+
case GGML_TYPE_F32:
|
|
2365
|
+
defines.push_back("SRC0_INNER_TYPE=f32");
|
|
2366
|
+
defines.push_back("MUL_ACC_FLOAT");
|
|
2367
|
+
variant += "_f32";
|
|
2368
|
+
break;
|
|
2369
|
+
case GGML_TYPE_F16:
|
|
2370
|
+
defines.push_back("SRC0_INNER_TYPE=f16");
|
|
2371
|
+
defines.push_back("MUL_ACC_FLOAT");
|
|
2372
|
+
variant += "_f16";
|
|
2373
|
+
break;
|
|
2374
|
+
default:
|
|
2375
|
+
{
|
|
2376
|
+
// Quantized types: use helpers but accumulate in f16
|
|
2377
|
+
const struct ggml_type_traits * src0_traits = ggml_get_type_traits(context.src0->type);
|
|
2378
|
+
std::string src0_name = src0_traits->type_name;
|
|
2379
|
+
std::string type_upper = src0_name;
|
|
2380
|
+
variant += "_" + src0_name;
|
|
2381
|
+
std::transform(type_upper.begin(), type_upper.end(), type_upper.begin(), ::toupper);
|
|
2382
|
+
|
|
2383
|
+
defines.push_back("BYTE_HELPERS");
|
|
2384
|
+
defines.push_back("MUL_ACC_" + type_upper);
|
|
2385
|
+
defines.push_back("U32_DEQUANT_HELPERS");
|
|
2386
|
+
defines.push_back("SRC0_INNER_TYPE=u32");
|
|
2387
|
+
switch (context.src0->type) {
|
|
2388
|
+
case GGML_TYPE_IQ1_S:
|
|
2389
|
+
case GGML_TYPE_IQ1_M:
|
|
2390
|
+
case GGML_TYPE_IQ2_S:
|
|
2391
|
+
case GGML_TYPE_IQ3_S:
|
|
2392
|
+
case GGML_TYPE_IQ4_NL:
|
|
2393
|
+
case GGML_TYPE_IQ4_XS:
|
|
2394
|
+
defines.push_back(type_upper + "_GRID");
|
|
2395
|
+
break;
|
|
2396
|
+
case GGML_TYPE_IQ2_XXS:
|
|
2397
|
+
case GGML_TYPE_IQ2_XS:
|
|
2398
|
+
case GGML_TYPE_IQ3_XXS:
|
|
2399
|
+
defines.push_back(type_upper + "_GRID");
|
|
2400
|
+
defines.push_back(type_upper + "_TABLES");
|
|
2401
|
+
break;
|
|
2402
|
+
case GGML_TYPE_MXFP4:
|
|
2403
|
+
case GGML_TYPE_NVFP4:
|
|
2404
|
+
defines.push_back(type_upper + "_LUT");
|
|
2405
|
+
break;
|
|
2406
|
+
default:
|
|
2407
|
+
break;
|
|
2408
|
+
}
|
|
2409
|
+
break;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
// VEC/SCALAR controls
|
|
2414
|
+
defines.push_back(key.vectorized ? "VEC" : "SCALAR");
|
|
2415
|
+
|
|
2416
|
+
uint32_t wg_size = WEBGPU_MUL_MAT_VEC_WG_SIZE;
|
|
2417
|
+
uint32_t outputs_per_wg = WEBGPU_MUL_MAT_VEC_FLOAT_OUTPUTS_PER_WG;
|
|
2418
|
+
|
|
2419
|
+
if (key.src0_type == GGML_TYPE_Q1_0) {
|
|
2420
|
+
outputs_per_wg = WEBGPU_MUL_MAT_VEC_LEGACY_Q_OUTPUTS_PER_WG;
|
|
2421
|
+
} else if (key.src0_type >= GGML_TYPE_Q2_K) {
|
|
2422
|
+
outputs_per_wg = WEBGPU_MUL_MAT_VEC_K_Q_OUTPUTS_PER_WG;
|
|
2423
|
+
} else if (key.src0_type >= GGML_TYPE_Q4_0) {
|
|
2424
|
+
outputs_per_wg = WEBGPU_MUL_MAT_VEC_LEGACY_Q_OUTPUTS_PER_WG;
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
// variant suffix for src1 type
|
|
2428
|
+
variant += std::string("_") + (context.src1->type == GGML_TYPE_F32 ? "f32" : "f16");
|
|
2429
|
+
|
|
2430
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
2431
|
+
defines.push_back(std::string("OUTPUTS_PER_WG=") + std::to_string(outputs_per_wg));
|
|
2432
|
+
defines.push_back(context.supports_subgroups ? "USE_SUBGROUP_REDUCTION" : "USE_WORKGROUP_REDUCTION");
|
|
2433
|
+
variant += context.supports_subgroups ? "_sg_reduce" : "_wg_reduce";
|
|
2434
|
+
if (key.vectorized) {
|
|
2435
|
+
variant += "_vectorized";
|
|
2436
|
+
}
|
|
2437
|
+
defines.push_back(std::string("NUM_COLS=1"));
|
|
2438
|
+
|
|
2439
|
+
defines.push_back(std::string("N_EXPERTS=") + std::to_string(key.n_experts));
|
|
2440
|
+
|
|
2441
|
+
auto processed = preprocessor.preprocess(shader_src, defines);
|
|
2442
|
+
|
|
2443
|
+
auto decisions = std::make_shared<ggml_webgpu_mul_mat_vec_shader_decisions>();
|
|
2444
|
+
decisions->wg_size = wg_size;
|
|
2445
|
+
decisions->outputs_per_wg = outputs_per_wg;
|
|
1046
2446
|
|
|
1047
2447
|
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1048
2448
|
pipeline.context = decisions;
|
|
1049
|
-
|
|
1050
|
-
return
|
|
2449
|
+
mul_mat_id_vec_pipelines[key] = pipeline;
|
|
2450
|
+
return mul_mat_id_vec_pipelines[key];
|
|
1051
2451
|
}
|
|
1052
2452
|
|
|
1053
2453
|
webgpu_pipeline get_unary_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1054
2454
|
const bool is_unary = context.dst->op == GGML_OP_UNARY;
|
|
1055
2455
|
const int op = is_unary ? (int) ggml_get_unary_op(context.dst) : context.dst->op;
|
|
1056
|
-
ggml_webgpu_unary_pipeline_key key = {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
2456
|
+
ggml_webgpu_unary_pipeline_key key = {};
|
|
2457
|
+
key.type = context.dst->type;
|
|
2458
|
+
key.op = op;
|
|
2459
|
+
key.is_unary = is_unary;
|
|
2460
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst) || context.dst->op == GGML_OP_FILL;
|
|
2461
|
+
key.ttype = (ggml_tri_type) ggml_get_op_params_i32(context.dst, 0);
|
|
1062
2462
|
|
|
1063
2463
|
auto it = unary_pipelines.find(key);
|
|
1064
2464
|
if (it != unary_pipelines.end()) {
|
|
@@ -1088,25 +2488,88 @@ class ggml_webgpu_shader_lib {
|
|
|
1088
2488
|
variant += "_inplace";
|
|
1089
2489
|
}
|
|
1090
2490
|
|
|
2491
|
+
if (op == GGML_OP_TRI) {
|
|
2492
|
+
switch (key.ttype) {
|
|
2493
|
+
case GGML_TRI_TYPE_LOWER:
|
|
2494
|
+
defines.push_back("TRI_TYPE_LOWER");
|
|
2495
|
+
variant += "_tri_type_lower";
|
|
2496
|
+
break;
|
|
2497
|
+
case GGML_TRI_TYPE_LOWER_DIAG:
|
|
2498
|
+
defines.push_back("TRI_TYPE_LOWER_DIAG");
|
|
2499
|
+
variant += "_tri_type_lower_diag";
|
|
2500
|
+
break;
|
|
2501
|
+
case GGML_TRI_TYPE_UPPER:
|
|
2502
|
+
defines.push_back("TRI_TYPE_UPPER");
|
|
2503
|
+
variant += "_tri_type_upper";
|
|
2504
|
+
break;
|
|
2505
|
+
case GGML_TRI_TYPE_UPPER_DIAG:
|
|
2506
|
+
defines.push_back("TRI_TYPE_UPPER_DIAG");
|
|
2507
|
+
variant += "_tri_upper_diag";
|
|
2508
|
+
break;
|
|
2509
|
+
default:
|
|
2510
|
+
GGML_ABORT("Unsupported ggml_tri_type for unary shader");
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
|
|
1091
2514
|
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
1092
2515
|
|
|
1093
2516
|
auto processed = preprocessor.preprocess(wgsl_unary, defines);
|
|
1094
2517
|
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
1095
2518
|
decisions->wg_size = context.max_wg_size;
|
|
2519
|
+
decisions->inplace = key.inplace;
|
|
1096
2520
|
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1097
2521
|
pipeline.context = decisions;
|
|
1098
2522
|
unary_pipelines[key] = pipeline;
|
|
1099
2523
|
return unary_pipelines[key];
|
|
1100
2524
|
}
|
|
1101
2525
|
|
|
2526
|
+
webgpu_pipeline get_rms_norm_mul_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2527
|
+
ggml_webgpu_rms_norm_mul_pipeline_key key = {};
|
|
2528
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
2529
|
+
key.overlap = ggml_webgpu_tensor_equal(context.src1, context.dst);
|
|
2530
|
+
key.src_overlap = ggml_webgpu_tensor_overlap(context.src0, context.src1);
|
|
2531
|
+
|
|
2532
|
+
auto it = rms_norm_mul_pipelines.find(key);
|
|
2533
|
+
if (it != rms_norm_mul_pipelines.end()) {
|
|
2534
|
+
return it->second;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
std::vector<std::string> defines;
|
|
2538
|
+
std::string op_name = "RMS_NORM_MUL";
|
|
2539
|
+
std::string variant = op_name;
|
|
2540
|
+
|
|
2541
|
+
if (key.inplace) {
|
|
2542
|
+
defines.push_back("INPLACE");
|
|
2543
|
+
variant += "_inplace";
|
|
2544
|
+
} else if (key.overlap) {
|
|
2545
|
+
defines.push_back("OVERLAP");
|
|
2546
|
+
variant += "_overlap";
|
|
2547
|
+
} else if (key.src_overlap) {
|
|
2548
|
+
defines.push_back("SRC_OVERLAP");
|
|
2549
|
+
variant += "_src_overlap";
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
2553
|
+
|
|
2554
|
+
auto processed = preprocessor.preprocess(wgsl_rms_norm_mul, defines);
|
|
2555
|
+
auto pipeline_decisions = std::make_shared<ggml_webgpu_rms_norm_mul_shader_decisions>();
|
|
2556
|
+
pipeline_decisions->wg_size = context.max_wg_size;
|
|
2557
|
+
pipeline_decisions->inplace = key.inplace;
|
|
2558
|
+
pipeline_decisions->overlap = key.overlap;
|
|
2559
|
+
pipeline_decisions->src_overlap = key.src_overlap;
|
|
2560
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
2561
|
+
pipeline.context = pipeline_decisions;
|
|
2562
|
+
rms_norm_mul_pipelines[key] = pipeline;
|
|
2563
|
+
return rms_norm_mul_pipelines[key];
|
|
2564
|
+
}
|
|
2565
|
+
|
|
1102
2566
|
webgpu_pipeline get_binary_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1103
|
-
ggml_webgpu_binary_pipeline_key key = {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
};
|
|
2567
|
+
ggml_webgpu_binary_pipeline_key key = {};
|
|
2568
|
+
key.type = context.dst->type;
|
|
2569
|
+
key.op = context.dst->op;
|
|
2570
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
2571
|
+
key.overlap = ggml_webgpu_tensor_equal(context.src1, context.dst);
|
|
2572
|
+
key.src_overlap = ggml_webgpu_tensor_overlap(context.src0, context.src1);
|
|
1110
2573
|
|
|
1111
2574
|
auto it = binary_pipelines.find(key);
|
|
1112
2575
|
if (it != binary_pipelines.end()) {
|
|
@@ -1145,19 +2608,54 @@ class ggml_webgpu_shader_lib {
|
|
|
1145
2608
|
|
|
1146
2609
|
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
1147
2610
|
|
|
1148
|
-
auto processed
|
|
1149
|
-
auto
|
|
1150
|
-
|
|
2611
|
+
auto processed = preprocessor.preprocess(wgsl_binary, defines);
|
|
2612
|
+
auto pipeline_decisions = std::make_shared<ggml_webgpu_binary_shader_decisions>();
|
|
2613
|
+
pipeline_decisions->wg_size = context.max_wg_size;
|
|
2614
|
+
pipeline_decisions->inplace = key.inplace;
|
|
2615
|
+
pipeline_decisions->overlap = key.overlap;
|
|
2616
|
+
pipeline_decisions->src_overlap = key.src_overlap;
|
|
2617
|
+
|
|
1151
2618
|
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1152
|
-
pipeline.context =
|
|
2619
|
+
pipeline.context = pipeline_decisions;
|
|
1153
2620
|
binary_pipelines[key] = pipeline;
|
|
1154
2621
|
return binary_pipelines[key];
|
|
1155
2622
|
}
|
|
1156
2623
|
|
|
2624
|
+
webgpu_pipeline get_add_id_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2625
|
+
ggml_webgpu_add_id_pipeline_key key = {};
|
|
2626
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
2627
|
+
|
|
2628
|
+
auto it = add_id_pipelines.find(key);
|
|
2629
|
+
if (it != add_id_pipelines.end()) {
|
|
2630
|
+
return it->second;
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2633
|
+
std::vector<std::string> defines;
|
|
2634
|
+
std::string variant = "add_id";
|
|
2635
|
+
const char * shader_src = wgsl_add_id;
|
|
2636
|
+
|
|
2637
|
+
if (key.inplace) {
|
|
2638
|
+
defines.push_back("INPLACE");
|
|
2639
|
+
variant += "_inplace";
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
2643
|
+
|
|
2644
|
+
auto processed = preprocessor.preprocess(shader_src, defines);
|
|
2645
|
+
auto pipeline_decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
2646
|
+
pipeline_decisions->wg_size = context.max_wg_size;
|
|
2647
|
+
pipeline_decisions->inplace = key.inplace;
|
|
2648
|
+
|
|
2649
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
2650
|
+
pipeline.context = pipeline_decisions;
|
|
2651
|
+
add_id_pipelines[key] = pipeline;
|
|
2652
|
+
return pipeline;
|
|
2653
|
+
}
|
|
2654
|
+
|
|
1157
2655
|
webgpu_pipeline get_concat_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1158
|
-
ggml_webgpu_concat_pipeline_key key = {
|
|
1159
|
-
|
|
1160
|
-
|
|
2656
|
+
ggml_webgpu_concat_pipeline_key key = {};
|
|
2657
|
+
key.type = context.dst->type;
|
|
2658
|
+
key.src_overlap = ggml_webgpu_tensor_overlap(context.src0, context.src1);
|
|
1161
2659
|
|
|
1162
2660
|
auto it = concat_pipelines.find(key);
|
|
1163
2661
|
if (it != concat_pipelines.end()) {
|
|
@@ -1180,11 +2678,17 @@ class ggml_webgpu_shader_lib {
|
|
|
1180
2678
|
GGML_ABORT("Unsupported type for concat shader");
|
|
1181
2679
|
}
|
|
1182
2680
|
|
|
2681
|
+
if (key.src_overlap) {
|
|
2682
|
+
defines.push_back("SRC_OVERLAP");
|
|
2683
|
+
variant += "_src_overlap";
|
|
2684
|
+
}
|
|
2685
|
+
|
|
1183
2686
|
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
1184
2687
|
|
|
1185
2688
|
auto processed = preprocessor.preprocess(wgsl_concat, defines);
|
|
1186
|
-
auto decisions = std::make_shared<
|
|
2689
|
+
auto decisions = std::make_shared<ggml_webgpu_binary_shader_decisions>();
|
|
1187
2690
|
decisions->wg_size = context.max_wg_size;
|
|
2691
|
+
decisions->src_overlap = key.src_overlap;
|
|
1188
2692
|
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
1189
2693
|
pipeline.context = decisions;
|
|
1190
2694
|
concat_pipelines[key] = pipeline;
|
|
@@ -1192,9 +2696,8 @@ class ggml_webgpu_shader_lib {
|
|
|
1192
2696
|
}
|
|
1193
2697
|
|
|
1194
2698
|
webgpu_pipeline get_repeat_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1195
|
-
ggml_webgpu_repeat_pipeline_key key = {
|
|
1196
|
-
|
|
1197
|
-
};
|
|
2699
|
+
ggml_webgpu_repeat_pipeline_key key = {};
|
|
2700
|
+
key.type = context.dst->type;
|
|
1198
2701
|
|
|
1199
2702
|
auto it = repeat_pipelines.find(key);
|
|
1200
2703
|
if (it != repeat_pipelines.end()) {
|
|
@@ -1233,102 +2736,544 @@ class ggml_webgpu_shader_lib {
|
|
|
1233
2736
|
}
|
|
1234
2737
|
|
|
1235
2738
|
webgpu_pipeline get_flash_attn_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
1236
|
-
const bool
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
ggml_webgpu_flash_attn_pipeline_key key = {
|
|
1243
|
-
|
|
1244
|
-
.
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
.
|
|
1250
|
-
|
|
2739
|
+
const bool can_use_subgroup_matrix = ggml_webgpu_flash_attn_can_use_subgroup_matrix_path(
|
|
2740
|
+
context.supports_subgroup_matrix, context.sg_mat_k, context.sg_mat_n, context.src0, context.src2);
|
|
2741
|
+
ggml_webgpu_flash_attn_decisions decisions = {};
|
|
2742
|
+
decisions.use_sg_matrix = can_use_subgroup_matrix;
|
|
2743
|
+
decisions.q_tile = decisions.use_sg_matrix ? context.sg_mat_m : GGML_WEBGPU_FLASH_ATTN_TILE_Q_TILE;
|
|
2744
|
+
|
|
2745
|
+
ggml_webgpu_flash_attn_pipeline_key key = {};
|
|
2746
|
+
key.common =
|
|
2747
|
+
ggml_webgpu_flash_attn_make_common_pipeline_key(context, decisions.use_sg_matrix ? context.sg_mat_k : 1u);
|
|
2748
|
+
key.common.kv_direct = decisions.use_sg_matrix && key.common.kv_direct;
|
|
2749
|
+
key.use_sg_matrix = decisions.use_sg_matrix;
|
|
2750
|
+
|
|
2751
|
+
const uint32_t max_kv_tile = ggml_webgpu_flash_attn_max_kv_tile(
|
|
2752
|
+
context.wg_mem_limit_bytes, decisions.q_tile, decisions.use_sg_matrix ? context.sg_mat_n : 1u,
|
|
2753
|
+
key.common.head_dim_qk, key.common.head_dim_v, key.common.has_mask, key.common.kv_direct);
|
|
2754
|
+
GGML_ASSERT(max_kv_tile > 0);
|
|
2755
|
+
|
|
2756
|
+
decisions.kv_tile = decisions.use_sg_matrix ?
|
|
2757
|
+
std::min(max_kv_tile, context.sg_mat_n * GGML_WEBGPU_FLASH_ATTN_PREFERRED_KV_SG_TILES) :
|
|
2758
|
+
std::min(GGML_WEBGPU_FLASH_ATTN_TILE_MAX_KV_TILE, max_kv_tile);
|
|
2759
|
+
decisions.wg_size =
|
|
2760
|
+
decisions.use_sg_matrix ?
|
|
2761
|
+
std::max(context.max_subgroup_size, GGML_WEBGPU_FLASH_ATTN_PREFERRED_WG_SIZE) :
|
|
2762
|
+
std::min(context.max_wg_size, std::max(GGML_WEBGPU_FLASH_ATTN_PREFERRED_WG_SIZE,
|
|
2763
|
+
GGML_WEBGPU_FLASH_ATTN_TILE_Q_TILE * context.max_subgroup_size));
|
|
2764
|
+
|
|
2765
|
+
if (key.common.kv_direct) {
|
|
2766
|
+
decisions.kv_tile = std::min(decisions.kv_tile, GGML_WEBGPU_KV_SEQ_PAD);
|
|
2767
|
+
while (GGML_WEBGPU_KV_SEQ_PAD % decisions.kv_tile != 0) {
|
|
2768
|
+
decisions.kv_tile -= decisions.use_sg_matrix ? context.sg_mat_n : context.min_subgroup_size;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
1251
2771
|
|
|
1252
2772
|
auto it = flash_attn_pipelines.find(key);
|
|
1253
2773
|
if (it != flash_attn_pipelines.end()) {
|
|
1254
2774
|
return it->second;
|
|
1255
2775
|
}
|
|
1256
2776
|
|
|
2777
|
+
std::string variant = decisions.use_sg_matrix ? "flash_attn" : "flash_attn_tile";
|
|
2778
|
+
std::vector<std::string> defines = ggml_webgpu_flash_attn_common_defines(key.common, variant, decisions.q_tile,
|
|
2779
|
+
decisions.kv_tile, decisions.wg_size);
|
|
2780
|
+
const char * shader_src = nullptr;
|
|
2781
|
+
if (!key.use_sg_matrix) {
|
|
2782
|
+
shader_src = wgsl_flash_attn_tile;
|
|
2783
|
+
defines.push_back("MIN_SUBGROUP_SIZE=" + std::to_string(context.min_subgroup_size) + "u");
|
|
2784
|
+
defines.push_back("MAX_SUBGROUP_SIZE=" + std::to_string(context.max_subgroup_size) + "u");
|
|
2785
|
+
variant += "_tile_sg" + std::to_string(context.min_subgroup_size) + "_" +
|
|
2786
|
+
std::to_string(context.max_subgroup_size);
|
|
2787
|
+
} else {
|
|
2788
|
+
shader_src = wgsl_flash_attn;
|
|
2789
|
+
defines.push_back(std::string("SG_MAT_M=") + std::to_string(context.sg_mat_m));
|
|
2790
|
+
defines.push_back(std::string("SG_MAT_N=") + std::to_string(context.sg_mat_n));
|
|
2791
|
+
defines.push_back(std::string("SG_MAT_K=") + std::to_string(context.sg_mat_k));
|
|
2792
|
+
}
|
|
2793
|
+
auto pipeline_decisions = std::make_shared<ggml_webgpu_flash_attn_decisions>(decisions);
|
|
2794
|
+
webgpu_pipeline pipeline =
|
|
2795
|
+
ggml_webgpu_create_pipeline(device, preprocessor.preprocess(shader_src, defines), variant);
|
|
2796
|
+
pipeline.context = pipeline_decisions;
|
|
2797
|
+
flash_attn_pipelines[key] = pipeline;
|
|
2798
|
+
return flash_attn_pipelines[key];
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2801
|
+
webgpu_pipeline get_flash_attn_vec_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2802
|
+
ggml_webgpu_flash_attn_vec_pipeline_key key = {};
|
|
2803
|
+
key.common = ggml_webgpu_flash_attn_make_common_pipeline_key(context, GGML_WEBGPU_FLASH_ATTN_TILE_KV_VEC_WIDTH);
|
|
2804
|
+
|
|
2805
|
+
auto it = flash_attn_vec_pipelines.find(key);
|
|
2806
|
+
if (it != flash_attn_vec_pipelines.end()) {
|
|
2807
|
+
return it->second;
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
ggml_webgpu_flash_attn_vec_decisions decisions = {};
|
|
2811
|
+
decisions.kv_tile =
|
|
2812
|
+
ggml_webgpu_flash_attn_get_vec_kv_tile(context.wg_mem_limit_bytes, key.common.head_dim_qk,
|
|
2813
|
+
key.common.head_dim_v, key.common.has_mask, key.common.kv_direct);
|
|
2814
|
+
decisions.wg_size = context.max_subgroup_size;
|
|
2815
|
+
|
|
2816
|
+
std::string variant = "flash_attn_vec";
|
|
2817
|
+
std::vector<std::string> defines =
|
|
2818
|
+
ggml_webgpu_flash_attn_common_defines(key.common, variant, 1u, decisions.kv_tile, decisions.wg_size);
|
|
2819
|
+
if (key.common.has_mask) {
|
|
2820
|
+
defines.push_back("BLK");
|
|
2821
|
+
variant.resize(variant.size() - (sizeof("_mask") - 1));
|
|
2822
|
+
variant += "_mask_blk";
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
uint32_t d_split = context.min_subgroup_size;
|
|
2826
|
+
if (key.common.k_type == GGML_TYPE_F16 && key.common.v_type == GGML_TYPE_F16) {
|
|
2827
|
+
const uint32_t D = key.common.head_dim_qk | key.common.head_dim_v;
|
|
2828
|
+
const uint32_t D_lsb = D & (~(D - 1u));
|
|
2829
|
+
d_split = std::min(std::min(context.min_subgroup_size, 4u), std::max(D_lsb / 4u, 1u));
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2832
|
+
defines.push_back(std::string("D_SPLIT=") + std::to_string(d_split));
|
|
2833
|
+
variant += "_dsplit" + std::to_string(d_split);
|
|
2834
|
+
|
|
2835
|
+
auto pipeline_decisions = std::make_shared<ggml_webgpu_flash_attn_vec_decisions>(decisions);
|
|
2836
|
+
webgpu_pipeline pipeline =
|
|
2837
|
+
ggml_webgpu_create_pipeline(device, preprocessor.preprocess(wgsl_flash_attn_vec_split, defines), variant);
|
|
2838
|
+
pipeline.context = pipeline_decisions;
|
|
2839
|
+
flash_attn_vec_pipelines[key] = pipeline;
|
|
2840
|
+
return flash_attn_vec_pipelines[key];
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
webgpu_pipeline get_flash_attn_blk_pipeline(const ggml_webgpu_shader_lib_context & context, uint32_t kv_tile) {
|
|
2844
|
+
ggml_webgpu_flash_attn_blk_pipeline_key key = {};
|
|
2845
|
+
key.kv_tile = kv_tile;
|
|
2846
|
+
auto it = flash_attn_blk_pipelines.find(key);
|
|
2847
|
+
if (it != flash_attn_blk_pipelines.end()) {
|
|
2848
|
+
return it->second;
|
|
2849
|
+
}
|
|
2850
|
+
|
|
1257
2851
|
std::vector<std::string> defines;
|
|
1258
|
-
std::string variant = "
|
|
2852
|
+
std::string variant = "flash_attn_vec_blk";
|
|
1259
2853
|
|
|
1260
|
-
|
|
2854
|
+
defines.push_back(std::string("KV_TILE=") + std::to_string(key.kv_tile));
|
|
2855
|
+
variant += std::string("_kvt") + std::to_string(key.kv_tile);
|
|
2856
|
+
|
|
2857
|
+
uint32_t wg_size = 1;
|
|
2858
|
+
while ((wg_size << 1) <= context.max_wg_size) {
|
|
2859
|
+
wg_size <<= 1;
|
|
2860
|
+
}
|
|
2861
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(wg_size));
|
|
2862
|
+
variant += std::string("_wg") + std::to_string(wg_size);
|
|
2863
|
+
|
|
2864
|
+
webgpu_pipeline pipeline =
|
|
2865
|
+
ggml_webgpu_create_pipeline(device, preprocessor.preprocess(wgsl_flash_attn_vec_blk, defines), variant);
|
|
2866
|
+
flash_attn_blk_pipelines[key] = pipeline;
|
|
2867
|
+
return flash_attn_blk_pipelines[key];
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
webgpu_pipeline get_flash_attn_vec_reduce_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2871
|
+
ggml_webgpu_flash_attn_vec_reduce_pipeline_key key = {};
|
|
2872
|
+
key.head_dim_v = (uint32_t) context.src2->ne[0];
|
|
2873
|
+
key.dst_type = context.dst->type;
|
|
2874
|
+
key.wg_size = context.max_wg_size;
|
|
2875
|
+
auto it = flash_attn_vec_reduce_pipelines.find(key);
|
|
2876
|
+
if (it != flash_attn_vec_reduce_pipelines.end()) {
|
|
2877
|
+
return it->second;
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2880
|
+
std::vector<std::string> defines;
|
|
2881
|
+
std::string variant = "flash_attn_vec_reduce";
|
|
2882
|
+
|
|
2883
|
+
switch (key.dst_type) {
|
|
1261
2884
|
case GGML_TYPE_F32:
|
|
1262
|
-
defines.push_back("
|
|
2885
|
+
defines.push_back("DST_F32");
|
|
1263
2886
|
break;
|
|
1264
2887
|
case GGML_TYPE_F16:
|
|
1265
|
-
defines.push_back("
|
|
2888
|
+
defines.push_back("DST_F16");
|
|
1266
2889
|
break;
|
|
1267
|
-
|
|
1268
|
-
|
|
2890
|
+
default:
|
|
2891
|
+
GGML_ABORT("Unsupported dst type for flash attention vec reduce shader");
|
|
2892
|
+
}
|
|
2893
|
+
variant += std::string("_dst") + ggml_type_name(key.dst_type);
|
|
2894
|
+
|
|
2895
|
+
defines.push_back(std::string("HEAD_DIM_V=") + std::to_string(key.head_dim_v));
|
|
2896
|
+
variant += std::string("_hsv") + std::to_string(key.head_dim_v);
|
|
2897
|
+
|
|
2898
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
2899
|
+
variant += std::string("_wg") + std::to_string(context.max_wg_size);
|
|
2900
|
+
|
|
2901
|
+
webgpu_pipeline pipeline =
|
|
2902
|
+
ggml_webgpu_create_pipeline(device, preprocessor.preprocess(wgsl_flash_attn_vec_reduce, defines), variant);
|
|
2903
|
+
flash_attn_vec_reduce_pipelines[key] = pipeline;
|
|
2904
|
+
return flash_attn_vec_reduce_pipelines[key];
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
webgpu_pipeline get_cpy_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2908
|
+
ggml_webgpu_cpy_pipeline_key key = {};
|
|
2909
|
+
key.src_type = context.src0->type;
|
|
2910
|
+
key.dst_type = context.dst->type;
|
|
2911
|
+
|
|
2912
|
+
auto it = cpy_pipelines.find(key);
|
|
2913
|
+
if (it != cpy_pipelines.end()) {
|
|
2914
|
+
return it->second;
|
|
2915
|
+
}
|
|
2916
|
+
|
|
2917
|
+
std::vector<std::string> defines;
|
|
2918
|
+
std::string variant = "cpy";
|
|
2919
|
+
|
|
2920
|
+
switch (key.src_type) {
|
|
2921
|
+
case GGML_TYPE_F32:
|
|
2922
|
+
defines.push_back("SRC_F32");
|
|
2923
|
+
variant += "_f32";
|
|
1269
2924
|
break;
|
|
1270
|
-
case
|
|
1271
|
-
defines.push_back("
|
|
2925
|
+
case GGML_TYPE_F16:
|
|
2926
|
+
defines.push_back("SRC_F16");
|
|
2927
|
+
variant += "_f16";
|
|
2928
|
+
break;
|
|
2929
|
+
default:
|
|
2930
|
+
GGML_ABORT("Unsupported src type for cpy shader");
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
switch (key.dst_type) {
|
|
2934
|
+
case GGML_TYPE_F32:
|
|
2935
|
+
defines.push_back("DST_F32");
|
|
2936
|
+
variant += "_f32";
|
|
2937
|
+
break;
|
|
2938
|
+
case GGML_TYPE_F16:
|
|
2939
|
+
defines.push_back("DST_F16");
|
|
2940
|
+
variant += "_f16";
|
|
2941
|
+
break;
|
|
2942
|
+
case GGML_TYPE_I32:
|
|
2943
|
+
defines.push_back("DST_I32");
|
|
2944
|
+
variant += "_i32";
|
|
2945
|
+
break;
|
|
2946
|
+
default:
|
|
2947
|
+
GGML_ABORT("Unsupported dst type for cpy shader");
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
2951
|
+
|
|
2952
|
+
auto processed = preprocessor.preprocess(wgsl_cpy, defines);
|
|
2953
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
2954
|
+
decisions->wg_size = context.max_wg_size;
|
|
2955
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
2956
|
+
pipeline.context = decisions;
|
|
2957
|
+
cpy_pipelines[key] = pipeline;
|
|
2958
|
+
return cpy_pipelines[key];
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
webgpu_pipeline get_glu_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
2962
|
+
ggml_webgpu_glu_pipeline_key key = {};
|
|
2963
|
+
key.glu_op = ggml_get_glu_op(context.dst);
|
|
2964
|
+
key.type = context.dst->type;
|
|
2965
|
+
key.split = (context.src1 != nullptr);
|
|
2966
|
+
|
|
2967
|
+
auto it = glu_pipelines.find(key);
|
|
2968
|
+
if (it != glu_pipelines.end()) {
|
|
2969
|
+
return it->second;
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
std::vector<std::string> defines;
|
|
2973
|
+
std::string variant = "glu";
|
|
2974
|
+
|
|
2975
|
+
switch (key.glu_op) {
|
|
2976
|
+
case GGML_GLU_OP_REGLU:
|
|
2977
|
+
defines.push_back("OP_REGLU");
|
|
2978
|
+
variant += "_reglu";
|
|
2979
|
+
break;
|
|
2980
|
+
case GGML_GLU_OP_GEGLU:
|
|
2981
|
+
defines.push_back("OP_GEGLU");
|
|
2982
|
+
variant += "_geglu";
|
|
2983
|
+
break;
|
|
2984
|
+
case GGML_GLU_OP_SWIGLU:
|
|
2985
|
+
defines.push_back("OP_SWIGLU");
|
|
2986
|
+
variant += "_swiglu";
|
|
2987
|
+
break;
|
|
2988
|
+
case GGML_GLU_OP_SWIGLU_OAI:
|
|
2989
|
+
defines.push_back("OP_SWIGLU_OAI");
|
|
2990
|
+
variant += "_swiglu_oai";
|
|
2991
|
+
break;
|
|
2992
|
+
case GGML_GLU_OP_GEGLU_ERF:
|
|
2993
|
+
defines.push_back("OP_GEGLU_ERF");
|
|
2994
|
+
variant += "_geglu_erf";
|
|
2995
|
+
break;
|
|
2996
|
+
case GGML_GLU_OP_GEGLU_QUICK:
|
|
2997
|
+
defines.push_back("OP_GEGLU_QUICK");
|
|
2998
|
+
variant += "_geglu_quick";
|
|
2999
|
+
break;
|
|
3000
|
+
default:
|
|
3001
|
+
GGML_ABORT("Unsupported GLU op");
|
|
3002
|
+
}
|
|
3003
|
+
switch (key.type) {
|
|
3004
|
+
case GGML_TYPE_F32:
|
|
3005
|
+
defines.push_back("TYPE_F32");
|
|
3006
|
+
variant += "_f32";
|
|
3007
|
+
break;
|
|
3008
|
+
case GGML_TYPE_F16:
|
|
3009
|
+
defines.push_back("TYPE_F16");
|
|
3010
|
+
variant += "_f16";
|
|
3011
|
+
break;
|
|
3012
|
+
default:
|
|
3013
|
+
GGML_ABORT("Unsupported type for GLU shader");
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
if (key.split) {
|
|
3017
|
+
variant += "_split";
|
|
3018
|
+
} else {
|
|
3019
|
+
defines.push_back("NO_SPLIT");
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
3023
|
+
|
|
3024
|
+
auto processed = preprocessor.preprocess(wgsl_glu, defines);
|
|
3025
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3026
|
+
decisions->wg_size = context.max_wg_size;
|
|
3027
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3028
|
+
pipeline.context = decisions;
|
|
3029
|
+
glu_pipelines[key] = pipeline;
|
|
3030
|
+
return glu_pipelines[key];
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
webgpu_pipeline get_rope_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
3034
|
+
ggml_webgpu_rope_pipeline_key key = {};
|
|
3035
|
+
key.type = context.dst->type;
|
|
3036
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
3037
|
+
key.has_ff = (context.src2 != nullptr);
|
|
3038
|
+
|
|
3039
|
+
auto it = rope_pipelines.find(key);
|
|
3040
|
+
if (it != rope_pipelines.end()) {
|
|
3041
|
+
return it->second;
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
std::vector<std::string> defines;
|
|
3045
|
+
std::string variant = "rope";
|
|
3046
|
+
|
|
3047
|
+
switch (key.type) {
|
|
3048
|
+
case GGML_TYPE_F32:
|
|
3049
|
+
defines.push_back("TYPE_F32");
|
|
3050
|
+
variant += "_f32";
|
|
3051
|
+
break;
|
|
3052
|
+
case GGML_TYPE_F16:
|
|
3053
|
+
defines.push_back("TYPE_F16");
|
|
3054
|
+
variant += "_f16";
|
|
1272
3055
|
break;
|
|
1273
3056
|
default:
|
|
1274
|
-
GGML_ABORT("Unsupported
|
|
3057
|
+
GGML_ABORT("Unsupported type for ROPE shader");
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
if (key.inplace) {
|
|
3061
|
+
defines.push_back("INPLACE");
|
|
3062
|
+
variant += "_inplace";
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
if (key.has_ff) {
|
|
3066
|
+
defines.push_back("FF_FUNC");
|
|
3067
|
+
variant += "_ff";
|
|
1275
3068
|
}
|
|
1276
|
-
|
|
3069
|
+
|
|
3070
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
3071
|
+
|
|
3072
|
+
auto processed = preprocessor.preprocess(wgsl_rope, defines);
|
|
3073
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3074
|
+
decisions->wg_size = context.max_wg_size;
|
|
3075
|
+
decisions->inplace = key.inplace;
|
|
3076
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3077
|
+
pipeline.context = decisions;
|
|
3078
|
+
rope_pipelines[key] = pipeline;
|
|
3079
|
+
return rope_pipelines[key];
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
webgpu_pipeline get_soft_max_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
3083
|
+
ggml_webgpu_soft_max_pipeline_key key = {};
|
|
3084
|
+
key.mask_type = context.src1 ? context.src1->type : GGML_TYPE_F32;
|
|
3085
|
+
key.has_mask = (context.src1 != nullptr);
|
|
3086
|
+
key.has_sink = (context.src2 != nullptr);
|
|
3087
|
+
key.inplace = ggml_webgpu_tensor_equal(context.src0, context.dst);
|
|
3088
|
+
|
|
3089
|
+
auto it = soft_max_pipelines.find(key);
|
|
3090
|
+
if (it != soft_max_pipelines.end()) {
|
|
3091
|
+
return it->second;
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
std::vector<std::string> defines;
|
|
3095
|
+
std::string variant = "soft_max";
|
|
1277
3096
|
|
|
1278
3097
|
if (key.has_mask) {
|
|
1279
|
-
defines.push_back("
|
|
1280
|
-
|
|
3098
|
+
defines.push_back("HAS_MASK");
|
|
3099
|
+
switch (key.mask_type) {
|
|
3100
|
+
case GGML_TYPE_F32:
|
|
3101
|
+
defines.push_back("MASK_F32");
|
|
3102
|
+
variant += "_mask_f32";
|
|
3103
|
+
break;
|
|
3104
|
+
case GGML_TYPE_F16:
|
|
3105
|
+
defines.push_back("MASK_F16");
|
|
3106
|
+
variant += "_mask_f16";
|
|
3107
|
+
break;
|
|
3108
|
+
default:
|
|
3109
|
+
GGML_ABORT("Unsupported type for SOFT_MAX shader");
|
|
3110
|
+
}
|
|
1281
3111
|
}
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
3112
|
+
|
|
3113
|
+
if (key.has_sink) {
|
|
3114
|
+
defines.push_back("HAS_SINK");
|
|
3115
|
+
variant += "_sink";
|
|
1285
3116
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
3117
|
+
|
|
3118
|
+
if (key.inplace) {
|
|
3119
|
+
defines.push_back("INPLACE");
|
|
3120
|
+
variant += "_inplace";
|
|
1289
3121
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
3122
|
+
|
|
3123
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
3124
|
+
|
|
3125
|
+
auto processed = preprocessor.preprocess(wgsl_soft_max, defines);
|
|
3126
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3127
|
+
decisions->wg_size = context.max_wg_size;
|
|
3128
|
+
decisions->inplace = key.inplace;
|
|
3129
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3130
|
+
pipeline.context = decisions;
|
|
3131
|
+
soft_max_pipelines[key] = pipeline;
|
|
3132
|
+
return soft_max_pipelines[key];
|
|
3133
|
+
}
|
|
3134
|
+
|
|
3135
|
+
webgpu_pipeline get_conv2d_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
3136
|
+
ggml_webgpu_conv2d_pipeline_key key = {};
|
|
3137
|
+
key.weight_type = context.src0->type;
|
|
3138
|
+
key.input_type = context.src1->type;
|
|
3139
|
+
key.output_type = context.dst->type;
|
|
3140
|
+
|
|
3141
|
+
auto it = conv2d_pipelines.find(key);
|
|
3142
|
+
if (it != conv2d_pipelines.end()) {
|
|
3143
|
+
return it->second;
|
|
1293
3144
|
}
|
|
1294
3145
|
|
|
1295
|
-
|
|
1296
|
-
variant
|
|
3146
|
+
std::vector<std::string> defines;
|
|
3147
|
+
std::string variant = "conv_2d";
|
|
3148
|
+
|
|
3149
|
+
auto push_type_defines = [&](const char * prefix, ggml_type type) {
|
|
3150
|
+
std::string s_prefix = prefix;
|
|
3151
|
+
if (type == GGML_TYPE_F32) {
|
|
3152
|
+
defines.push_back(s_prefix + "_F32");
|
|
3153
|
+
} else if (type == GGML_TYPE_F16) {
|
|
3154
|
+
defines.push_back(s_prefix + "_F16");
|
|
3155
|
+
} else {
|
|
3156
|
+
GGML_ABORT("Unsupported type for CONV_2D shader");
|
|
3157
|
+
}
|
|
3158
|
+
};
|
|
1297
3159
|
|
|
1298
|
-
|
|
1299
|
-
|
|
3160
|
+
push_type_defines("WEIGHT", key.weight_type);
|
|
3161
|
+
push_type_defines("INPUT", key.input_type);
|
|
3162
|
+
push_type_defines("OUTPUT", key.output_type);
|
|
3163
|
+
|
|
3164
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
1300
3165
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
3166
|
+
auto processed = preprocessor.preprocess(wgsl_conv2d, defines);
|
|
3167
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3168
|
+
decisions->wg_size = context.max_wg_size;
|
|
3169
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3170
|
+
pipeline.context = decisions;
|
|
3171
|
+
conv2d_pipelines[key] = pipeline;
|
|
3172
|
+
return conv2d_pipelines[key];
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
webgpu_pipeline get_im2col_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
3176
|
+
ggml_webgpu_im2col_pipeline_key key = {};
|
|
3177
|
+
key.input_type = context.src1->type;
|
|
3178
|
+
key.output_type = context.dst->type;
|
|
3179
|
+
|
|
3180
|
+
auto it = im2col_pipelines.find(key);
|
|
3181
|
+
if (it != im2col_pipelines.end()) {
|
|
3182
|
+
return it->second;
|
|
3183
|
+
}
|
|
3184
|
+
|
|
3185
|
+
std::vector<std::string> defines;
|
|
3186
|
+
std::string variant = "im2col";
|
|
3187
|
+
|
|
3188
|
+
auto push_type_defines = [&](const char * prefix, ggml_type type) {
|
|
3189
|
+
std::string s_prefix = prefix;
|
|
3190
|
+
if (type == GGML_TYPE_F32) {
|
|
3191
|
+
defines.push_back(s_prefix + "_F32");
|
|
3192
|
+
} else if (type == GGML_TYPE_F16) {
|
|
3193
|
+
defines.push_back(s_prefix + "_F16");
|
|
3194
|
+
} else {
|
|
3195
|
+
GGML_ABORT("Unsupported type for IM2COL shader");
|
|
1313
3196
|
}
|
|
3197
|
+
};
|
|
3198
|
+
|
|
3199
|
+
push_type_defines("INPUT", key.input_type);
|
|
3200
|
+
push_type_defines("OUTPUT", key.output_type);
|
|
3201
|
+
|
|
3202
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
3203
|
+
|
|
3204
|
+
auto processed = preprocessor.preprocess(wgsl_im2col, defines);
|
|
3205
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3206
|
+
decisions->wg_size = context.max_wg_size;
|
|
3207
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3208
|
+
pipeline.context = decisions;
|
|
3209
|
+
im2col_pipelines[key] = pipeline;
|
|
3210
|
+
return im2col_pipelines[key];
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
webgpu_pipeline get_upscale_pipeline(const ggml_webgpu_shader_lib_context & context) {
|
|
3214
|
+
const uint32_t mode_flags = (uint32_t) ggml_get_op_params_i32(context.dst, 0);
|
|
3215
|
+
const uint32_t base_mode = mode_flags & 0xFFu;
|
|
3216
|
+
const bool antialias = (mode_flags & GGML_SCALE_FLAG_ANTIALIAS) != 0u;
|
|
3217
|
+
|
|
3218
|
+
ggml_webgpu_upscale_pipeline_key key = {};
|
|
3219
|
+
key.input_type = context.src0->type;
|
|
3220
|
+
key.output_type = context.dst->type;
|
|
3221
|
+
key.base_mode = base_mode;
|
|
3222
|
+
key.antialias = antialias;
|
|
3223
|
+
|
|
3224
|
+
auto it = upscale_pipelines.find(key);
|
|
3225
|
+
if (it != upscale_pipelines.end()) {
|
|
3226
|
+
return it->second;
|
|
1314
3227
|
}
|
|
1315
3228
|
|
|
1316
|
-
|
|
1317
|
-
|
|
3229
|
+
std::vector<std::string> defines;
|
|
3230
|
+
std::string variant = "upscale";
|
|
1318
3231
|
|
|
1319
|
-
|
|
1320
|
-
|
|
3232
|
+
if (key.input_type == GGML_TYPE_F16) {
|
|
3233
|
+
defines.push_back("SRC_F16");
|
|
3234
|
+
variant += "_src_f16";
|
|
3235
|
+
} else {
|
|
3236
|
+
variant += "_src_f32";
|
|
3237
|
+
}
|
|
1321
3238
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
3239
|
+
if (key.output_type == GGML_TYPE_F16) {
|
|
3240
|
+
defines.push_back("DST_F16");
|
|
3241
|
+
variant += "_dst_f16";
|
|
3242
|
+
} else {
|
|
3243
|
+
variant += "_dst_f32";
|
|
3244
|
+
}
|
|
1327
3245
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
3246
|
+
switch (base_mode) {
|
|
3247
|
+
case GGML_SCALE_MODE_NEAREST:
|
|
3248
|
+
defines.push_back("NEAREST");
|
|
3249
|
+
variant += "_nearest";
|
|
3250
|
+
break;
|
|
3251
|
+
case GGML_SCALE_MODE_BILINEAR:
|
|
3252
|
+
defines.push_back("BILINEAR");
|
|
3253
|
+
variant += "_bilinear";
|
|
3254
|
+
break;
|
|
3255
|
+
case GGML_SCALE_MODE_BICUBIC:
|
|
3256
|
+
defines.push_back("BICUBIC");
|
|
3257
|
+
variant += "_bicubic";
|
|
3258
|
+
break;
|
|
3259
|
+
default:
|
|
3260
|
+
GGML_ABORT("Unsupported upscale mode");
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
if (antialias) {
|
|
3264
|
+
defines.push_back("ANTIALIAS");
|
|
3265
|
+
variant += "_aa";
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
defines.push_back(std::string("WG_SIZE=") + std::to_string(context.max_wg_size));
|
|
3269
|
+
|
|
3270
|
+
auto processed = preprocessor.preprocess(wgsl_upscale, defines);
|
|
3271
|
+
auto decisions = std::make_shared<ggml_webgpu_generic_shader_decisions>();
|
|
3272
|
+
decisions->wg_size = context.max_wg_size;
|
|
3273
|
+
webgpu_pipeline pipeline = ggml_webgpu_create_pipeline(device, processed, variant);
|
|
3274
|
+
pipeline.context = decisions;
|
|
3275
|
+
upscale_pipelines[key] = pipeline;
|
|
3276
|
+
return upscale_pipelines[key];
|
|
1332
3277
|
}
|
|
1333
3278
|
|
|
1334
3279
|
private:
|
|
@@ -1350,25 +3295,6 @@ class ggml_webgpu_shader_lib {
|
|
|
1350
3295
|
pipeline_desc.layout = nullptr; // nullptr means auto layout
|
|
1351
3296
|
return { device.CreateComputePipeline(&pipeline_desc), label };
|
|
1352
3297
|
}
|
|
1353
|
-
|
|
1354
|
-
static uint32_t ggml_webgpu_flash_attn_max_kv_tile(const ggml_webgpu_flash_attn_shader_lib_context & context) {
|
|
1355
|
-
const size_t limit_bytes = context.wg_mem_limit_bytes;
|
|
1356
|
-
const size_t q_tile = context.sg_mat_m;
|
|
1357
|
-
const size_t base_q_bytes =
|
|
1358
|
-
(context.key.head_dim_qk + context.key.head_dim_v) * q_tile * GGML_WEBGPU_F16_SIZE_BYTES +
|
|
1359
|
-
2 * q_tile * GGML_WEBGPU_F32_SIZE_BYTES;
|
|
1360
|
-
size_t bytes_per_kv = 0;
|
|
1361
|
-
if (!context.key.kv_direct) {
|
|
1362
|
-
bytes_per_kv += std::max(context.key.head_dim_qk, context.key.head_dim_v);
|
|
1363
|
-
}
|
|
1364
|
-
if (context.key.has_mask) {
|
|
1365
|
-
bytes_per_kv += q_tile;
|
|
1366
|
-
}
|
|
1367
|
-
bytes_per_kv += q_tile;
|
|
1368
|
-
bytes_per_kv *= GGML_WEBGPU_F16_SIZE_BYTES;
|
|
1369
|
-
const uint32_t max_kv_tile = (limit_bytes - base_q_bytes) / bytes_per_kv;
|
|
1370
|
-
return (max_kv_tile / context.sg_mat_n) * context.sg_mat_n;
|
|
1371
|
-
}
|
|
1372
3298
|
};
|
|
1373
3299
|
|
|
1374
3300
|
#endif // GGML_WEBGPU_SHADER_LIB_HPP
|