whispercpp 1.3.7 → 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/README.md +5 -4
- data/ext/options.rb +1 -1
- data/ext/ruby_whisper.c +0 -1
- data/ext/ruby_whisper.h +7 -1
- data/ext/ruby_whisper_context.c +50 -1
- data/ext/ruby_whisper_log_settable.h +1 -2
- data/ext/ruby_whisper_params.c +9 -8
- data/ext/ruby_whisper_transcribe.cpp +0 -19
- 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 +2 -1
- data/ext/sources/cmake/parakeet.pc.in +2 -2
- data/ext/sources/cmake/whisper.pc.in +2 -2
- data/ext/sources/examples/cli/cli.cpp +9 -1
- data/ext/sources/examples/common-ggml.cpp +2 -0
- data/ext/sources/examples/vad-speech-segments/speech.cpp +3 -2
- data/ext/sources/ggml/CMakeLists.txt +3 -4
- data/ext/sources/ggml/include/ggml-cuda.h +0 -3
- data/ext/sources/ggml/include/ggml-sycl.h +8 -0
- data/ext/sources/ggml/include/ggml.h +3 -1
- data/ext/sources/ggml/src/CMakeLists.txt +8 -1
- data/ext/sources/ggml/src/ggml-backend-meta.cpp +7 -4
- data/ext/sources/ggml/src/ggml-common.h +13 -2
- data/ext/sources/ggml/src/ggml-cpu/CMakeLists.txt +1 -1
- data/ext/sources/ggml/src/ggml-cpu/amx/mmq.cpp +5 -6
- data/ext/sources/ggml/src/ggml-cpu/arch/arm/quants.c +78 -4
- data/ext/sources/ggml/src/ggml-cpu/arch/x86/quants.c +142 -4
- data/ext/sources/ggml/src/ggml-cpu/arch-fallback.h +7 -2
- data/ext/sources/ggml/src/ggml-cpu/ggml-cpu.c +14 -0
- data/ext/sources/ggml/src/ggml-cpu/llamafile/sgemm.cpp +26 -19
- data/ext/sources/ggml/src/ggml-cpu/ops.cpp +129 -46
- data/ext/sources/ggml/src/ggml-cpu/quants.c +51 -0
- data/ext/sources/ggml/src/ggml-cpu/quants.h +3 -0
- data/ext/sources/ggml/src/ggml-cpu/simd-gemm.h +1 -1
- data/ext/sources/ggml/src/ggml-cpu/simd-mappings.h +11 -0
- data/ext/sources/ggml/src/ggml-cpu/vec.cpp +2 -2
- data/ext/sources/ggml/src/ggml-cuda/binbcast.cu +90 -46
- 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 +4 -0
- data/ext/sources/ggml/src/ggml-cuda/concat.cu +33 -21
- data/ext/sources/ggml/src/ggml-cuda/conv-transpose-1d.cu +14 -12
- data/ext/sources/ggml/src/ggml-cuda/convert.cu +86 -34
- data/ext/sources/ggml/src/ggml-cuda/cpy.cu +80 -29
- data/ext/sources/ggml/src/ggml-cuda/fattn-common.cuh +9 -5
- data/ext/sources/ggml/src/ggml-cuda/fattn-mma-f16.cuh +4 -0
- data/ext/sources/ggml/src/ggml-cuda/fattn-tile.cuh +9 -5
- data/ext/sources/ggml/src/ggml-cuda/fattn.cu +27 -21
- data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cu +40 -25
- data/ext/sources/ggml/src/ggml-cuda/gated_delta_net.cuh +10 -0
- data/ext/sources/ggml/src/ggml-cuda/getrows.cu +15 -12
- data/ext/sources/ggml/src/ggml-cuda/ggml-cuda.cu +718 -1248
- data/ext/sources/ggml/src/ggml-cuda/mmq.cu +7 -0
- data/ext/sources/ggml/src/ggml-cuda/mmvq.cu +77 -40
- data/ext/sources/ggml/src/ggml-cuda/out-prod.cu +55 -12
- data/ext/sources/ggml/src/ggml-cuda/set-rows.cu +64 -4
- 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_32-ncols2_2.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_8-ncols2_2.cu +1 -0
- data/ext/sources/ggml/src/ggml-cuda/topk-moe.cu +7 -1
- data/ext/sources/ggml/src/ggml-cuda/vendors/hip.h +1 -0
- data/ext/sources/ggml/src/ggml-cuda/vendors/musa.h +1 -0
- data/ext/sources/ggml/src/ggml-hexagon/CMakeLists.txt +0 -5
- data/ext/sources/ggml/src/ggml-hexagon/ggml-hexagon.cpp +1634 -1293
- data/ext/sources/ggml/src/ggml-hexagon/htp/CMakeLists.txt +11 -40
- data/ext/sources/ggml/src/ggml-hexagon/htp/cmake-toolchain.cmake +13 -15
- data/ext/sources/ggml/src/ggml-hexagon/htp/concat-ops.c +1 -1
- data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.c +1749 -399
- data/ext/sources/ggml/src/ggml-hexagon/htp/flash-attn-ops.h +303 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-common.h +80 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-dma.h +26 -23
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-profile.h +64 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hex-utils.h +1 -83
- 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 +9 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-queue.h +27 -4
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-utils.h +59 -37
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ctx.h +11 -3
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-ops.h +52 -12
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp-vtcm.h +19 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/htp_iface.idl +2 -1
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-base.h +14 -30
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-exp.h +39 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/hvx-fa-kernels.h +232 -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-sigmoid.h +39 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/main.c +127 -32
- data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.c +3023 -4425
- data/ext/sources/ggml/src/ggml-hexagon/htp/matmul-ops.h +650 -0
- data/ext/sources/ggml/src/ggml-hexagon/htp/rope-ops.c +48 -13
- data/ext/sources/ggml/src/ggml-hexagon/htp/ssm-conv.c +10 -9
- 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 +168 -50
- data/ext/sources/ggml/src/ggml-hexagon/libggml-htp.inf +0 -4
- data/ext/sources/ggml/src/ggml-hip/CMakeLists.txt +5 -0
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.cpp +69 -5
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.h +4 -1
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-device.m +27 -6
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-impl.h +38 -0
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.cpp +132 -2
- data/ext/sources/ggml/src/ggml-metal/ggml-metal-ops.h +2 -0
- data/ext/sources/ggml/src/ggml-metal/ggml-metal.metal +345 -87
- data/ext/sources/ggml/src/ggml-opencl/CMakeLists.txt +13 -0
- data/ext/sources/ggml/src/ggml-opencl/fa_tune.h +92 -0
- data/ext/sources/ggml/src/ggml-opencl/ggml-opencl.cpp +4060 -357
- data/ext/sources/ggml/src/ggml-opencl/kernels/cvt.cl +198 -0
- 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/gemm_moe_mxfp4_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_0_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_1_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q4_k_f32_ns.cl +71 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_0_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_1_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q5_k_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_moe_q6_k_f32_ns.cl +74 -6
- data/ext/sources/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q1_0_f32.cl +94 -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_q8_0_f32.cl +1 -1
- 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_mv_f16_f32_l4.cl +1149 -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/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 +733 -130
- data/ext/sources/ggml/src/ggml-openvino/ggml-decoder.h +76 -23
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.cpp +57 -3
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino-extra.h +29 -8
- data/ext/sources/ggml/src/ggml-openvino/ggml-openvino.cpp +307 -59
- data/ext/sources/ggml/src/ggml-openvino/ggml-quants.cpp +66 -0
- 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 +134 -38
- 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 -23
- data/ext/sources/ggml/src/ggml-openvino/openvino/op_table.h +18 -5
- 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/translate_session.cpp +43 -40
- data/ext/sources/ggml/src/ggml-openvino/openvino/translate_session.h +5 -4
- data/ext/sources/ggml/src/ggml-openvino/openvino/utils.cpp +548 -3
- data/ext/sources/ggml/src/ggml-openvino/openvino/utils.h +28 -26
- data/ext/sources/ggml/src/ggml-openvino/utils.cpp +383 -94
- data/ext/sources/ggml/src/ggml-openvino/utils.h +11 -8
- data/ext/sources/ggml/src/ggml-quants.c +76 -0
- data/ext/sources/ggml/src/ggml-quants.h +3 -0
- data/ext/sources/ggml/src/ggml-sycl/CMakeLists.txt +5 -5
- data/ext/sources/ggml/src/ggml-sycl/backend.hpp +2 -0
- 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 +6 -8
- data/ext/sources/ggml/src/ggml-sycl/common.hpp +19 -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 +6 -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/dequantize.hpp +15 -0
- data/ext/sources/ggml/src/ggml-sycl/dmmv.cpp +492 -319
- data/ext/sources/ggml/src/ggml-sycl/dpct/helper.hpp +15 -7
- data/ext/sources/ggml/src/ggml-sycl/element_wise.cpp +215 -115
- data/ext/sources/ggml/src/ggml-sycl/element_wise.hpp +2 -0
- data/ext/sources/ggml/src/ggml-sycl/ggml-sycl.cpp +1006 -336
- data/ext/sources/ggml/src/ggml-sycl/mmvq.cpp +252 -67
- data/ext/sources/ggml/src/ggml-sycl/mmvq.hpp +17 -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/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/set_rows.cpp +10 -2
- data/ext/sources/ggml/src/ggml-sycl/softmax.cpp +9 -10
- data/ext/sources/ggml/src/ggml-sycl/vecdotq.hpp +35 -0
- data/ext/sources/ggml/src/ggml-vulkan/CMakeLists.txt +5 -0
- data/ext/sources/ggml/src/ggml-vulkan/ggml-vulkan.cpp +833 -215
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/col2im_1d.comp +61 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_mm.comp +1 -1
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/conv3d_mm.comp +431 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/diag.comp +3 -3
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn.comp +1 -0
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm1.comp +1 -0
- 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 +23 -4
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/glu_main.glsl +14 -18
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/l2_norm.comp +4 -7
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq.comp +21 -24
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +31 -23
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_cm2.comp +6 -5
- data/ext/sources/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_funcs.glsl +84 -67
- 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/tri.comp +3 -3
- 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 +121 -74
- data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu-shader-lib.hpp +26 -19
- data/ext/sources/ggml/src/ggml-webgpu/ggml-webgpu.cpp +31 -36
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/common_decls.tmpl +16 -2
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_split.wgsl +7 -7
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/get_rows.wgsl +21 -0
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_decls.tmpl +439 -320
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_vec.wgsl +2 -2
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec.wgsl +45 -39
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_acc.tmpl +586 -465
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_q_acc.tmpl +63 -69
- data/ext/sources/ggml/src/ggml-webgpu/wgsl-shaders/quantize_q8.wgsl +14 -9
- data/ext/sources/ggml/src/ggml.c +36 -14
- data/ext/sources/include/whisper.h +21 -0
- data/ext/sources/src/whisper.cpp +164 -14
- data/lib/whisper/log_settable.rb +5 -8
- data/lib/whisper/model/uri.rb +0 -7
- data/sig/whisper.rbs +6 -0
- data/test/test_vad.rb +9 -0
- data/test/test_vad_context.rb +2 -2
- data/whispercpp.gemspec +1 -1
- metadata +62 -37
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-flash-attn-ops.c +0 -1878
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-matmul-ops.c +0 -2066
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-ops.c +0 -6
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-ops.h +0 -88
- data/ext/sources/ggml/src/ggml-hexagon/htp/hmx-profile.h +0 -34
- data/ext/sources/ggml/src/ggml-hexagon/htp/vtcm-utils.h +0 -16
- data/ext/sources/ggml/src/ggml-openvino/openvino/op/unary_gelu.cpp +0 -25
- 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 -20
- 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/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
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
|
|
2
|
+
|
|
3
|
+
__kernel void flash_attn_kv_pad_f16(
|
|
4
|
+
const global void * k_void, ulong k_offset,
|
|
5
|
+
const global void * v_void, ulong v_offset,
|
|
6
|
+
global void * k_pad_void,
|
|
7
|
+
global void * v_pad_void,
|
|
8
|
+
const int n_kv,
|
|
9
|
+
const int n_head_kv,
|
|
10
|
+
const int n_batch,
|
|
11
|
+
const ulong k_nb1, const ulong k_nb2, const ulong k_nb3,
|
|
12
|
+
const ulong v_nb1, const ulong v_nb2, const ulong v_nb3
|
|
13
|
+
) {
|
|
14
|
+
const int row_idx = get_global_id(0);
|
|
15
|
+
const int head_kv_idx = get_global_id(1);
|
|
16
|
+
const int batch_idx = get_global_id(2);
|
|
17
|
+
|
|
18
|
+
if (row_idx >= BLOCK_N || head_kv_idx >= n_head_kv || batch_idx >= n_batch) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const int tail_start = n_kv - (n_kv % BLOCK_N);
|
|
23
|
+
const int src_row_idx = tail_start + row_idx;
|
|
24
|
+
|
|
25
|
+
const global char * k_src = (const global char *) k_void + k_offset;
|
|
26
|
+
const global char * v_src = (const global char *) v_void + v_offset;
|
|
27
|
+
global char * k_pad = (global char *) k_pad_void;
|
|
28
|
+
global char * v_pad = (global char *) v_pad_void;
|
|
29
|
+
|
|
30
|
+
const ulong k_dst_offset = ((ulong) batch_idx * (ulong) n_head_kv + (ulong) head_kv_idx) * ((ulong) BLOCK_N * k_nb1) + (ulong) row_idx * k_nb1;
|
|
31
|
+
const ulong v_dst_offset = ((ulong) batch_idx * (ulong) n_head_kv + (ulong) head_kv_idx) * ((ulong) BLOCK_N * v_nb1) + (ulong) row_idx * v_nb1;
|
|
32
|
+
|
|
33
|
+
if (src_row_idx < n_kv) {
|
|
34
|
+
const ulong k_src_offset = (ulong) batch_idx * k_nb3 + (ulong) head_kv_idx * k_nb2 + (ulong) src_row_idx * k_nb1;
|
|
35
|
+
const ulong v_src_offset = (ulong) batch_idx * v_nb3 + (ulong) head_kv_idx * v_nb2 + (ulong) src_row_idx * v_nb1;
|
|
36
|
+
|
|
37
|
+
for (ulong i = 0; i < k_nb1; ++i) {
|
|
38
|
+
k_pad[k_dst_offset + i] = k_src[k_src_offset + i];
|
|
39
|
+
}
|
|
40
|
+
for (ulong i = 0; i < v_nb1; ++i) {
|
|
41
|
+
v_pad[v_dst_offset + i] = v_src[v_src_offset + i];
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
for (ulong i = 0; i < k_nb1; ++i) {
|
|
45
|
+
k_pad[k_dst_offset + i] = 0;
|
|
46
|
+
}
|
|
47
|
+
for (ulong i = 0; i < v_nb1; ++i) {
|
|
48
|
+
v_pad[v_dst_offset + i] = 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
__kernel void flash_attn_mask_pad_f16(
|
|
54
|
+
const global void * mask_void, ulong mask_offset,
|
|
55
|
+
global void * mask_pad_void,
|
|
56
|
+
const int n_q,
|
|
57
|
+
const int n_kv,
|
|
58
|
+
const ulong mask_nb1,
|
|
59
|
+
const ulong mask_nb2,
|
|
60
|
+
const ulong mask_nb3,
|
|
61
|
+
const int mask_ne2,
|
|
62
|
+
const int mask_ne3
|
|
63
|
+
) {
|
|
64
|
+
const int col_idx = get_global_id(0);
|
|
65
|
+
const int q_row = get_global_id(1);
|
|
66
|
+
const int mask_slice = get_global_id(2);
|
|
67
|
+
|
|
68
|
+
if (col_idx >= BLOCK_N || q_row >= n_q || mask_slice >= mask_ne2 * mask_ne3) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const int tail_start = n_kv - (n_kv % BLOCK_N);
|
|
73
|
+
const int src_col_idx = tail_start + col_idx;
|
|
74
|
+
const int mask_head_idx = mask_slice % mask_ne2;
|
|
75
|
+
const int mask_batch_idx = mask_slice / mask_ne2;
|
|
76
|
+
|
|
77
|
+
const global char * mask_src_base = (const global char *) mask_void + mask_offset +
|
|
78
|
+
(ulong) mask_batch_idx * mask_nb3 +
|
|
79
|
+
(ulong) mask_head_idx * mask_nb2 +
|
|
80
|
+
(ulong) q_row * mask_nb1;
|
|
81
|
+
const global half * mask_src = (const global half *) mask_src_base;
|
|
82
|
+
|
|
83
|
+
global half * mask_pad = (global half *) mask_pad_void;
|
|
84
|
+
const ulong dst_idx =
|
|
85
|
+
(((ulong) mask_batch_idx * (ulong) mask_ne2 + (ulong) mask_head_idx) * (ulong) n_q + (ulong) q_row) * (ulong) BLOCK_N +
|
|
86
|
+
(ulong) col_idx;
|
|
87
|
+
|
|
88
|
+
mask_pad[dst_idx] = src_col_idx < n_kv ? mask_src[src_col_idx] : (half) (-INFINITY);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Per-KV-tile mask class. 0=all -inf (skip tile), 1=mixed (apply mask),
|
|
92
|
+
// 2=all zero, no -inf (skip mask lookup). Causal diagonal tiles are class 1.
|
|
93
|
+
__kernel void flash_attn_blk_f16(
|
|
94
|
+
const global void * mask_void, ulong mask_offset,
|
|
95
|
+
global char * blk,
|
|
96
|
+
const int n_q,
|
|
97
|
+
const int n_kv,
|
|
98
|
+
const ulong mask_nb1,
|
|
99
|
+
const ulong mask_nb2,
|
|
100
|
+
const ulong mask_nb3,
|
|
101
|
+
const int mask_ne2,
|
|
102
|
+
const int mask_ne3
|
|
103
|
+
) {
|
|
104
|
+
const int kv_block_idx = get_global_id(0);
|
|
105
|
+
const int q_block_idx = get_global_id(1);
|
|
106
|
+
const int mask_slice = get_global_id(2);
|
|
107
|
+
|
|
108
|
+
const int n_q_blocks = (n_q + BLOCK_M - 1) / BLOCK_M;
|
|
109
|
+
const int n_kv_blocks = (n_kv + BLOCK_N - 1) / BLOCK_N;
|
|
110
|
+
if (kv_block_idx >= n_kv_blocks || q_block_idx >= n_q_blocks || mask_slice >= mask_ne2 * mask_ne3) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const int mask_head_idx = mask_slice % mask_ne2;
|
|
115
|
+
const int mask_batch_idx = mask_slice / mask_ne2;
|
|
116
|
+
const int q_start = q_block_idx * BLOCK_M;
|
|
117
|
+
const int k_start = kv_block_idx * BLOCK_N;
|
|
118
|
+
const int q_count = min(BLOCK_M, n_q - q_start);
|
|
119
|
+
const int k_count = min(BLOCK_N, n_kv - k_start);
|
|
120
|
+
|
|
121
|
+
const half neg_max_half = (half) (-65504.0f);
|
|
122
|
+
char has_unmasked = 0;
|
|
123
|
+
char has_masked = 0;
|
|
124
|
+
char has_nonzero = 0;
|
|
125
|
+
|
|
126
|
+
const global char * mask_base = (const global char *) mask_void + mask_offset +
|
|
127
|
+
(ulong) mask_batch_idx * mask_nb3 +
|
|
128
|
+
(ulong) mask_head_idx * mask_nb2;
|
|
129
|
+
|
|
130
|
+
for (int qi = 0; qi < q_count; ++qi) {
|
|
131
|
+
const global half * mask_row = (const global half *) (mask_base + (ulong) (q_start + qi) * mask_nb1) + k_start;
|
|
132
|
+
for (int ki = 0; ki < k_count; ++ki) {
|
|
133
|
+
const half v = mask_row[ki];
|
|
134
|
+
if (v <= neg_max_half) {
|
|
135
|
+
has_masked = 1;
|
|
136
|
+
} else {
|
|
137
|
+
has_unmasked = 1;
|
|
138
|
+
if (v != (half) 0.0f) {
|
|
139
|
+
has_nonzero = 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (has_masked && has_unmasked) break; // mixed tile — short-circuit.
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
char res;
|
|
147
|
+
if (has_unmasked == 0) {
|
|
148
|
+
res = 0;
|
|
149
|
+
} else if (has_masked || has_nonzero) {
|
|
150
|
+
res = 1;
|
|
151
|
+
} else {
|
|
152
|
+
res = 2;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
blk[((ulong) mask_slice * (ulong) n_q_blocks + (ulong) q_block_idx) * (ulong) n_kv_blocks + (ulong) kv_block_idx] = res;
|
|
156
|
+
}
|
|
@@ -132,6 +132,46 @@ static inline half8 mxfp4_to_fp16_packed8(ushort2 fp4x8) {
|
|
|
132
132
|
c_reg.lo += convert_float8(acc.lo); \
|
|
133
133
|
c_reg.hi += convert_float8(acc.hi); \
|
|
134
134
|
|
|
135
|
+
// Quarter-tile variant: computes 8 output columns (one skip-group) into a float8
|
|
136
|
+
// accumulator. Same reduction order / flush cadence as dotx16_reduce8, so the
|
|
137
|
+
// non-skipped path is byte-identical; it just lets the caller skip empty
|
|
138
|
+
// 8-column groups at finer granularity. Uses a private half8 `acc8`.
|
|
139
|
+
#define dotx8_reduce4(a_reg, b_lm, c_reg, lm_offset) \
|
|
140
|
+
acc8.s0 = dot(a_reg.s0123, b_lm[lm_offset + 0]); \
|
|
141
|
+
acc8.s1 = dot(a_reg.s0123, b_lm[lm_offset + 1]); \
|
|
142
|
+
acc8.s2 = dot(a_reg.s0123, b_lm[lm_offset + 2]); \
|
|
143
|
+
acc8.s3 = dot(a_reg.s0123, b_lm[lm_offset + 3]); \
|
|
144
|
+
acc8.s4 = dot(a_reg.s0123, b_lm[lm_offset + 4]); \
|
|
145
|
+
acc8.s5 = dot(a_reg.s0123, b_lm[lm_offset + 5]); \
|
|
146
|
+
acc8.s6 = dot(a_reg.s0123, b_lm[lm_offset + 6]); \
|
|
147
|
+
acc8.s7 = dot(a_reg.s0123, b_lm[lm_offset + 7]); \
|
|
148
|
+
acc8.s0 += dot(a_reg.s4567, b_lm[lm_offset + 32]); \
|
|
149
|
+
acc8.s1 += dot(a_reg.s4567, b_lm[lm_offset + 33]); \
|
|
150
|
+
acc8.s2 += dot(a_reg.s4567, b_lm[lm_offset + 34]); \
|
|
151
|
+
acc8.s3 += dot(a_reg.s4567, b_lm[lm_offset + 35]); \
|
|
152
|
+
acc8.s4 += dot(a_reg.s4567, b_lm[lm_offset + 36]); \
|
|
153
|
+
acc8.s5 += dot(a_reg.s4567, b_lm[lm_offset + 37]); \
|
|
154
|
+
acc8.s6 += dot(a_reg.s4567, b_lm[lm_offset + 38]); \
|
|
155
|
+
acc8.s7 += dot(a_reg.s4567, b_lm[lm_offset + 39]); \
|
|
156
|
+
c_reg += convert_float8(acc8); \
|
|
157
|
+
acc8.s0 = dot(a_reg.s89ab, b_lm[lm_offset + 64]); \
|
|
158
|
+
acc8.s1 = dot(a_reg.s89ab, b_lm[lm_offset + 65]); \
|
|
159
|
+
acc8.s2 = dot(a_reg.s89ab, b_lm[lm_offset + 66]); \
|
|
160
|
+
acc8.s3 = dot(a_reg.s89ab, b_lm[lm_offset + 67]); \
|
|
161
|
+
acc8.s4 = dot(a_reg.s89ab, b_lm[lm_offset + 68]); \
|
|
162
|
+
acc8.s5 = dot(a_reg.s89ab, b_lm[lm_offset + 69]); \
|
|
163
|
+
acc8.s6 = dot(a_reg.s89ab, b_lm[lm_offset + 70]); \
|
|
164
|
+
acc8.s7 = dot(a_reg.s89ab, b_lm[lm_offset + 71]); \
|
|
165
|
+
acc8.s0 += dot(a_reg.scdef, b_lm[lm_offset + 96]); \
|
|
166
|
+
acc8.s1 += dot(a_reg.scdef, b_lm[lm_offset + 97]); \
|
|
167
|
+
acc8.s2 += dot(a_reg.scdef, b_lm[lm_offset + 98]); \
|
|
168
|
+
acc8.s3 += dot(a_reg.scdef, b_lm[lm_offset + 99]); \
|
|
169
|
+
acc8.s4 += dot(a_reg.scdef, b_lm[lm_offset + 100]); \
|
|
170
|
+
acc8.s5 += dot(a_reg.scdef, b_lm[lm_offset + 101]); \
|
|
171
|
+
acc8.s6 += dot(a_reg.scdef, b_lm[lm_offset + 102]); \
|
|
172
|
+
acc8.s7 += dot(a_reg.scdef, b_lm[lm_offset + 103]); \
|
|
173
|
+
c_reg += convert_float8(acc8); \
|
|
174
|
+
|
|
135
175
|
|
|
136
176
|
static inline half e8m0_to_fp16(uchar x) {
|
|
137
177
|
ushort bits;
|
|
@@ -157,7 +197,9 @@ kernel void kernel_gemm_moe_mxfp4_f32_ns(
|
|
|
157
197
|
__write_only image1d_buffer_t dst,
|
|
158
198
|
__global int * total_tiles,
|
|
159
199
|
uint ne00,
|
|
160
|
-
uint ne01
|
|
200
|
+
uint ne01,
|
|
201
|
+
uint is_ragged,
|
|
202
|
+
uint skip_gran
|
|
161
203
|
) {
|
|
162
204
|
uint block_id_m = get_global_id(1); // m_tile
|
|
163
205
|
uint block_id_n = get_global_id(2); // n_tile
|
|
@@ -167,6 +209,28 @@ kernel void kernel_gemm_moe_mxfp4_f32_ns(
|
|
|
167
209
|
return;
|
|
168
210
|
}
|
|
169
211
|
|
|
212
|
+
// Ragged tile-skip: when is_ragged and the upper 16 token-slots of this tile are all
|
|
213
|
+
// padding (router 0xFFFFFFFF), skip the second (reg_c.hi) dotx16_reduce8 half -> ~half
|
|
214
|
+
// the GEMM dot for sparse tiles. Numerically identical (the skipped lanes are padding).
|
|
215
|
+
// Ragged tile-skip: tokens are packed contiguously per expert (moe_scatter fills
|
|
216
|
+
// lanes 0..V-1, moe_fill pre-pads the rest), so router padding (0xFFFFFFFF) is always
|
|
217
|
+
// trailing. Find the valid-token count V and round it UP to the skip granularity
|
|
218
|
+
// skip_gran (columns per skip-group: 8 = quarter, 16 = half/legacy, 32 = disabled).
|
|
219
|
+
// A 8-column group g is all-padding iff its first column (8*g) >= n_active, so its
|
|
220
|
+
// dotx8_reduce4 is skipped. Numerically identical (skipped lanes are padding).
|
|
221
|
+
uint n_active = TILESIZE_N;
|
|
222
|
+
if (is_ragged && skip_gran < TILESIZE_N) {
|
|
223
|
+
uint n_valid = TILESIZE_N;
|
|
224
|
+
for (uint _t = 0; _t < TILESIZE_N; ++_t) {
|
|
225
|
+
if (src2[block_id_n * TILESIZE_N + _t] == 0xFFFFFFFFu) { n_valid = _t; break; }
|
|
226
|
+
}
|
|
227
|
+
n_active = min((uint)TILESIZE_N, ((n_valid + skip_gran - 1) / skip_gran) * skip_gran);
|
|
228
|
+
}
|
|
229
|
+
// Group 0 (cols 0-7) always runs; groups 1-3 skip when fully padding.
|
|
230
|
+
bool skip_g1 = (8u >= n_active);
|
|
231
|
+
bool skip_g2 = (16u >= n_active);
|
|
232
|
+
bool skip_g3 = (24u >= n_active);
|
|
233
|
+
|
|
170
234
|
__private half16 reg_a;
|
|
171
235
|
__private float32 reg_c = (float32)(0);
|
|
172
236
|
__local half4 shared_b[128];
|
|
@@ -216,9 +280,11 @@ kernel void kernel_gemm_moe_mxfp4_f32_ns(
|
|
|
216
280
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
217
281
|
|
|
218
282
|
// 32 16x16 fp16 dot product with 8 elements reduction for better precision
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
283
|
+
half8 acc8;
|
|
284
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
285
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
286
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
287
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
222
288
|
|
|
223
289
|
// Repeat for second sub-block
|
|
224
290
|
uint half_step = step + TILESIZE_K;
|
|
@@ -244,8 +310,10 @@ kernel void kernel_gemm_moe_mxfp4_f32_ns(
|
|
|
244
310
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
245
311
|
|
|
246
312
|
// 32 16x16 fp16 dot product with 3-levels reduction for better precision
|
|
247
|
-
|
|
248
|
-
|
|
313
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
314
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
315
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
316
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
249
317
|
}
|
|
250
318
|
|
|
251
319
|
if ((get_global_id(0) + block_id_m * TILESIZE_M) >= ne01) {
|
|
@@ -98,6 +98,46 @@
|
|
|
98
98
|
c_reg.lo += convert_float8(acc.lo); \
|
|
99
99
|
c_reg.hi += convert_float8(acc.hi); \
|
|
100
100
|
|
|
101
|
+
// Quarter-tile variant: computes 8 output columns (one skip-group) into a float8
|
|
102
|
+
// accumulator. Same reduction order / flush cadence as dotx16_reduce8, so the
|
|
103
|
+
// non-skipped path is byte-identical; it just lets the caller skip empty
|
|
104
|
+
// 8-column groups at finer granularity. Uses a private half8 `acc8`.
|
|
105
|
+
#define dotx8_reduce4(a_reg, b_lm, c_reg, lm_offset) \
|
|
106
|
+
acc8.s0 = dot(a_reg.s0123, b_lm[lm_offset + 0]); \
|
|
107
|
+
acc8.s1 = dot(a_reg.s0123, b_lm[lm_offset + 1]); \
|
|
108
|
+
acc8.s2 = dot(a_reg.s0123, b_lm[lm_offset + 2]); \
|
|
109
|
+
acc8.s3 = dot(a_reg.s0123, b_lm[lm_offset + 3]); \
|
|
110
|
+
acc8.s4 = dot(a_reg.s0123, b_lm[lm_offset + 4]); \
|
|
111
|
+
acc8.s5 = dot(a_reg.s0123, b_lm[lm_offset + 5]); \
|
|
112
|
+
acc8.s6 = dot(a_reg.s0123, b_lm[lm_offset + 6]); \
|
|
113
|
+
acc8.s7 = dot(a_reg.s0123, b_lm[lm_offset + 7]); \
|
|
114
|
+
acc8.s0 += dot(a_reg.s4567, b_lm[lm_offset + 32]); \
|
|
115
|
+
acc8.s1 += dot(a_reg.s4567, b_lm[lm_offset + 33]); \
|
|
116
|
+
acc8.s2 += dot(a_reg.s4567, b_lm[lm_offset + 34]); \
|
|
117
|
+
acc8.s3 += dot(a_reg.s4567, b_lm[lm_offset + 35]); \
|
|
118
|
+
acc8.s4 += dot(a_reg.s4567, b_lm[lm_offset + 36]); \
|
|
119
|
+
acc8.s5 += dot(a_reg.s4567, b_lm[lm_offset + 37]); \
|
|
120
|
+
acc8.s6 += dot(a_reg.s4567, b_lm[lm_offset + 38]); \
|
|
121
|
+
acc8.s7 += dot(a_reg.s4567, b_lm[lm_offset + 39]); \
|
|
122
|
+
c_reg += convert_float8(acc8); \
|
|
123
|
+
acc8.s0 = dot(a_reg.s89ab, b_lm[lm_offset + 64]); \
|
|
124
|
+
acc8.s1 = dot(a_reg.s89ab, b_lm[lm_offset + 65]); \
|
|
125
|
+
acc8.s2 = dot(a_reg.s89ab, b_lm[lm_offset + 66]); \
|
|
126
|
+
acc8.s3 = dot(a_reg.s89ab, b_lm[lm_offset + 67]); \
|
|
127
|
+
acc8.s4 = dot(a_reg.s89ab, b_lm[lm_offset + 68]); \
|
|
128
|
+
acc8.s5 = dot(a_reg.s89ab, b_lm[lm_offset + 69]); \
|
|
129
|
+
acc8.s6 = dot(a_reg.s89ab, b_lm[lm_offset + 70]); \
|
|
130
|
+
acc8.s7 = dot(a_reg.s89ab, b_lm[lm_offset + 71]); \
|
|
131
|
+
acc8.s0 += dot(a_reg.scdef, b_lm[lm_offset + 96]); \
|
|
132
|
+
acc8.s1 += dot(a_reg.scdef, b_lm[lm_offset + 97]); \
|
|
133
|
+
acc8.s2 += dot(a_reg.scdef, b_lm[lm_offset + 98]); \
|
|
134
|
+
acc8.s3 += dot(a_reg.scdef, b_lm[lm_offset + 99]); \
|
|
135
|
+
acc8.s4 += dot(a_reg.scdef, b_lm[lm_offset + 100]); \
|
|
136
|
+
acc8.s5 += dot(a_reg.scdef, b_lm[lm_offset + 101]); \
|
|
137
|
+
acc8.s6 += dot(a_reg.scdef, b_lm[lm_offset + 102]); \
|
|
138
|
+
acc8.s7 += dot(a_reg.scdef, b_lm[lm_offset + 103]); \
|
|
139
|
+
c_reg += convert_float8(acc8); \
|
|
140
|
+
|
|
101
141
|
|
|
102
142
|
__attribute__((qcom_wave_pair_mode(1))) // 1=force single 2=force pair
|
|
103
143
|
kernel void kernel_gemm_moe_q4_0_f32_ns(
|
|
@@ -109,7 +149,9 @@ kernel void kernel_gemm_moe_q4_0_f32_ns(
|
|
|
109
149
|
__write_only image1d_buffer_t dst,
|
|
110
150
|
__global int * total_tiles,
|
|
111
151
|
uint ne00,
|
|
112
|
-
uint ne01
|
|
152
|
+
uint ne01,
|
|
153
|
+
uint is_ragged,
|
|
154
|
+
uint skip_gran
|
|
113
155
|
) {
|
|
114
156
|
uint block_id_m = get_global_id(1); // m_tile
|
|
115
157
|
uint block_id_n = get_global_id(2); // n_tile
|
|
@@ -119,6 +161,28 @@ kernel void kernel_gemm_moe_q4_0_f32_ns(
|
|
|
119
161
|
return;
|
|
120
162
|
}
|
|
121
163
|
|
|
164
|
+
// Ragged tile-skip: when is_ragged and the upper 16 token-slots of this tile are all
|
|
165
|
+
// padding (router 0xFFFFFFFF), skip the second (reg_c.hi) dotx16_reduce8 half -> ~half
|
|
166
|
+
// the GEMM dot for sparse tiles. Numerically identical (the skipped lanes are padding).
|
|
167
|
+
// Ragged tile-skip: tokens are packed contiguously per expert (moe_scatter fills
|
|
168
|
+
// lanes 0..V-1, moe_fill pre-pads the rest), so router padding (0xFFFFFFFF) is always
|
|
169
|
+
// trailing. Find the valid-token count V and round it UP to the skip granularity
|
|
170
|
+
// skip_gran (columns per skip-group: 8 = quarter, 16 = half/legacy, 32 = disabled).
|
|
171
|
+
// A 8-column group g is all-padding iff its first column (8*g) >= n_active, so its
|
|
172
|
+
// dotx8_reduce4 is skipped. Numerically identical (skipped lanes are padding).
|
|
173
|
+
uint n_active = TILESIZE_N;
|
|
174
|
+
if (is_ragged && skip_gran < TILESIZE_N) {
|
|
175
|
+
uint n_valid = TILESIZE_N;
|
|
176
|
+
for (uint _t = 0; _t < TILESIZE_N; ++_t) {
|
|
177
|
+
if (src2[block_id_n * TILESIZE_N + _t] == 0xFFFFFFFFu) { n_valid = _t; break; }
|
|
178
|
+
}
|
|
179
|
+
n_active = min((uint)TILESIZE_N, ((n_valid + skip_gran - 1) / skip_gran) * skip_gran);
|
|
180
|
+
}
|
|
181
|
+
// Group 0 (cols 0-7) always runs; groups 1-3 skip when fully padding.
|
|
182
|
+
bool skip_g1 = (8u >= n_active);
|
|
183
|
+
bool skip_g2 = (16u >= n_active);
|
|
184
|
+
bool skip_g3 = (24u >= n_active);
|
|
185
|
+
|
|
122
186
|
__private half16 reg_a;
|
|
123
187
|
__private float32 reg_c = (float32)(0);
|
|
124
188
|
__local half4 shared_b[128];
|
|
@@ -167,9 +231,11 @@ kernel void kernel_gemm_moe_q4_0_f32_ns(
|
|
|
167
231
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
168
232
|
|
|
169
233
|
// 32 16x16 fp16 dot product with 8 elements reduction for better precision
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
234
|
+
half8 acc8;
|
|
235
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
236
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
237
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
238
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
173
239
|
|
|
174
240
|
// Repeat for second sub-block
|
|
175
241
|
uint half_step = step + TILESIZE_K;
|
|
@@ -194,8 +260,10 @@ kernel void kernel_gemm_moe_q4_0_f32_ns(
|
|
|
194
260
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
195
261
|
|
|
196
262
|
// 32 16x16 fp16 dot product with 3-levels reduction for better precision
|
|
197
|
-
|
|
198
|
-
|
|
263
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
264
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
265
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
266
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
199
267
|
}
|
|
200
268
|
|
|
201
269
|
if ((get_global_id(0) + block_id_m * TILESIZE_M) >= ne01) {
|
|
@@ -98,6 +98,46 @@
|
|
|
98
98
|
c_reg.lo += convert_float8(acc.lo); \
|
|
99
99
|
c_reg.hi += convert_float8(acc.hi); \
|
|
100
100
|
|
|
101
|
+
// Quarter-tile variant: computes 8 output columns (one skip-group) into a float8
|
|
102
|
+
// accumulator. Same reduction order / flush cadence as dotx16_reduce8, so the
|
|
103
|
+
// non-skipped path is byte-identical; it just lets the caller skip empty
|
|
104
|
+
// 8-column groups at finer granularity. Uses a private half8 `acc8`.
|
|
105
|
+
#define dotx8_reduce4(a_reg, b_lm, c_reg, lm_offset) \
|
|
106
|
+
acc8.s0 = dot(a_reg.s0123, b_lm[lm_offset + 0]); \
|
|
107
|
+
acc8.s1 = dot(a_reg.s0123, b_lm[lm_offset + 1]); \
|
|
108
|
+
acc8.s2 = dot(a_reg.s0123, b_lm[lm_offset + 2]); \
|
|
109
|
+
acc8.s3 = dot(a_reg.s0123, b_lm[lm_offset + 3]); \
|
|
110
|
+
acc8.s4 = dot(a_reg.s0123, b_lm[lm_offset + 4]); \
|
|
111
|
+
acc8.s5 = dot(a_reg.s0123, b_lm[lm_offset + 5]); \
|
|
112
|
+
acc8.s6 = dot(a_reg.s0123, b_lm[lm_offset + 6]); \
|
|
113
|
+
acc8.s7 = dot(a_reg.s0123, b_lm[lm_offset + 7]); \
|
|
114
|
+
acc8.s0 += dot(a_reg.s4567, b_lm[lm_offset + 32]); \
|
|
115
|
+
acc8.s1 += dot(a_reg.s4567, b_lm[lm_offset + 33]); \
|
|
116
|
+
acc8.s2 += dot(a_reg.s4567, b_lm[lm_offset + 34]); \
|
|
117
|
+
acc8.s3 += dot(a_reg.s4567, b_lm[lm_offset + 35]); \
|
|
118
|
+
acc8.s4 += dot(a_reg.s4567, b_lm[lm_offset + 36]); \
|
|
119
|
+
acc8.s5 += dot(a_reg.s4567, b_lm[lm_offset + 37]); \
|
|
120
|
+
acc8.s6 += dot(a_reg.s4567, b_lm[lm_offset + 38]); \
|
|
121
|
+
acc8.s7 += dot(a_reg.s4567, b_lm[lm_offset + 39]); \
|
|
122
|
+
c_reg += convert_float8(acc8); \
|
|
123
|
+
acc8.s0 = dot(a_reg.s89ab, b_lm[lm_offset + 64]); \
|
|
124
|
+
acc8.s1 = dot(a_reg.s89ab, b_lm[lm_offset + 65]); \
|
|
125
|
+
acc8.s2 = dot(a_reg.s89ab, b_lm[lm_offset + 66]); \
|
|
126
|
+
acc8.s3 = dot(a_reg.s89ab, b_lm[lm_offset + 67]); \
|
|
127
|
+
acc8.s4 = dot(a_reg.s89ab, b_lm[lm_offset + 68]); \
|
|
128
|
+
acc8.s5 = dot(a_reg.s89ab, b_lm[lm_offset + 69]); \
|
|
129
|
+
acc8.s6 = dot(a_reg.s89ab, b_lm[lm_offset + 70]); \
|
|
130
|
+
acc8.s7 = dot(a_reg.s89ab, b_lm[lm_offset + 71]); \
|
|
131
|
+
acc8.s0 += dot(a_reg.scdef, b_lm[lm_offset + 96]); \
|
|
132
|
+
acc8.s1 += dot(a_reg.scdef, b_lm[lm_offset + 97]); \
|
|
133
|
+
acc8.s2 += dot(a_reg.scdef, b_lm[lm_offset + 98]); \
|
|
134
|
+
acc8.s3 += dot(a_reg.scdef, b_lm[lm_offset + 99]); \
|
|
135
|
+
acc8.s4 += dot(a_reg.scdef, b_lm[lm_offset + 100]); \
|
|
136
|
+
acc8.s5 += dot(a_reg.scdef, b_lm[lm_offset + 101]); \
|
|
137
|
+
acc8.s6 += dot(a_reg.scdef, b_lm[lm_offset + 102]); \
|
|
138
|
+
acc8.s7 += dot(a_reg.scdef, b_lm[lm_offset + 103]); \
|
|
139
|
+
c_reg += convert_float8(acc8); \
|
|
140
|
+
|
|
101
141
|
|
|
102
142
|
__attribute__((qcom_wave_pair_mode(1))) // 1=force single 2=force pair
|
|
103
143
|
kernel void kernel_gemm_moe_q4_1_f32_ns(
|
|
@@ -110,7 +150,9 @@ kernel void kernel_gemm_moe_q4_1_f32_ns(
|
|
|
110
150
|
__write_only image1d_buffer_t dst,
|
|
111
151
|
__global int * total_tiles,
|
|
112
152
|
uint ne00,
|
|
113
|
-
uint ne01
|
|
153
|
+
uint ne01,
|
|
154
|
+
uint is_ragged,
|
|
155
|
+
uint skip_gran
|
|
114
156
|
) {
|
|
115
157
|
uint block_id_m = get_global_id(1); // m_tile
|
|
116
158
|
uint block_id_n = get_global_id(2); // n_tile
|
|
@@ -120,6 +162,28 @@ kernel void kernel_gemm_moe_q4_1_f32_ns(
|
|
|
120
162
|
return;
|
|
121
163
|
}
|
|
122
164
|
|
|
165
|
+
// Ragged tile-skip: when is_ragged and the upper 16 token-slots of this tile are all
|
|
166
|
+
// padding (router 0xFFFFFFFF), skip the second (reg_c.hi) dotx16_reduce8 half -> ~half
|
|
167
|
+
// the GEMM dot for sparse tiles. Numerically identical (the skipped lanes are padding).
|
|
168
|
+
// Ragged tile-skip: tokens are packed contiguously per expert (moe_scatter fills
|
|
169
|
+
// lanes 0..V-1, moe_fill pre-pads the rest), so router padding (0xFFFFFFFF) is always
|
|
170
|
+
// trailing. Find the valid-token count V and round it UP to the skip granularity
|
|
171
|
+
// skip_gran (columns per skip-group: 8 = quarter, 16 = half/legacy, 32 = disabled).
|
|
172
|
+
// A 8-column group g is all-padding iff its first column (8*g) >= n_active, so its
|
|
173
|
+
// dotx8_reduce4 is skipped. Numerically identical (skipped lanes are padding).
|
|
174
|
+
uint n_active = TILESIZE_N;
|
|
175
|
+
if (is_ragged && skip_gran < TILESIZE_N) {
|
|
176
|
+
uint n_valid = TILESIZE_N;
|
|
177
|
+
for (uint _t = 0; _t < TILESIZE_N; ++_t) {
|
|
178
|
+
if (src2[block_id_n * TILESIZE_N + _t] == 0xFFFFFFFFu) { n_valid = _t; break; }
|
|
179
|
+
}
|
|
180
|
+
n_active = min((uint)TILESIZE_N, ((n_valid + skip_gran - 1) / skip_gran) * skip_gran);
|
|
181
|
+
}
|
|
182
|
+
// Group 0 (cols 0-7) always runs; groups 1-3 skip when fully padding.
|
|
183
|
+
bool skip_g1 = (8u >= n_active);
|
|
184
|
+
bool skip_g2 = (16u >= n_active);
|
|
185
|
+
bool skip_g3 = (24u >= n_active);
|
|
186
|
+
|
|
123
187
|
__private half16 reg_a;
|
|
124
188
|
__private float32 reg_c = (float32)(0);
|
|
125
189
|
__local half4 shared_b[128];
|
|
@@ -169,9 +233,11 @@ kernel void kernel_gemm_moe_q4_1_f32_ns(
|
|
|
169
233
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
170
234
|
|
|
171
235
|
// 32 16x16 fp16 dot product with 8 elements reduction for better precision
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
236
|
+
half8 acc8;
|
|
237
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
238
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
239
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
240
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
175
241
|
|
|
176
242
|
// Repeat for second sub-block
|
|
177
243
|
uint half_step = step + TILESIZE_K;
|
|
@@ -196,8 +262,10 @@ kernel void kernel_gemm_moe_q4_1_f32_ns(
|
|
|
196
262
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
197
263
|
|
|
198
264
|
// 32 16x16 fp16 dot product with 3-levels reduction for better precision
|
|
199
|
-
|
|
200
|
-
|
|
265
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
266
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
267
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
268
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
201
269
|
}
|
|
202
270
|
|
|
203
271
|
if ((get_global_id(0) + block_id_m * TILESIZE_M) >= ne01) {
|
|
@@ -114,6 +114,46 @@ inline void get_scale_min_k4(
|
|
|
114
114
|
c_reg.lo += convert_float8(acc.lo); \
|
|
115
115
|
c_reg.hi += convert_float8(acc.hi); \
|
|
116
116
|
|
|
117
|
+
// Quarter-tile variant: computes 8 output columns (one skip-group) into a float8
|
|
118
|
+
// accumulator. Same reduction order / flush cadence as dotx16_reduce8, so the
|
|
119
|
+
// non-skipped path is byte-identical; it just lets the caller skip empty
|
|
120
|
+
// 8-column groups at finer granularity. Uses a private half8 `acc8`.
|
|
121
|
+
#define dotx8_reduce4(a_reg, b_lm, c_reg, lm_offset) \
|
|
122
|
+
acc8.s0 = dot(a_reg.s0123, b_lm[lm_offset + 0]); \
|
|
123
|
+
acc8.s1 = dot(a_reg.s0123, b_lm[lm_offset + 1]); \
|
|
124
|
+
acc8.s2 = dot(a_reg.s0123, b_lm[lm_offset + 2]); \
|
|
125
|
+
acc8.s3 = dot(a_reg.s0123, b_lm[lm_offset + 3]); \
|
|
126
|
+
acc8.s4 = dot(a_reg.s0123, b_lm[lm_offset + 4]); \
|
|
127
|
+
acc8.s5 = dot(a_reg.s0123, b_lm[lm_offset + 5]); \
|
|
128
|
+
acc8.s6 = dot(a_reg.s0123, b_lm[lm_offset + 6]); \
|
|
129
|
+
acc8.s7 = dot(a_reg.s0123, b_lm[lm_offset + 7]); \
|
|
130
|
+
acc8.s0 += dot(a_reg.s4567, b_lm[lm_offset + 32]); \
|
|
131
|
+
acc8.s1 += dot(a_reg.s4567, b_lm[lm_offset + 33]); \
|
|
132
|
+
acc8.s2 += dot(a_reg.s4567, b_lm[lm_offset + 34]); \
|
|
133
|
+
acc8.s3 += dot(a_reg.s4567, b_lm[lm_offset + 35]); \
|
|
134
|
+
acc8.s4 += dot(a_reg.s4567, b_lm[lm_offset + 36]); \
|
|
135
|
+
acc8.s5 += dot(a_reg.s4567, b_lm[lm_offset + 37]); \
|
|
136
|
+
acc8.s6 += dot(a_reg.s4567, b_lm[lm_offset + 38]); \
|
|
137
|
+
acc8.s7 += dot(a_reg.s4567, b_lm[lm_offset + 39]); \
|
|
138
|
+
c_reg += convert_float8(acc8); \
|
|
139
|
+
acc8.s0 = dot(a_reg.s89ab, b_lm[lm_offset + 64]); \
|
|
140
|
+
acc8.s1 = dot(a_reg.s89ab, b_lm[lm_offset + 65]); \
|
|
141
|
+
acc8.s2 = dot(a_reg.s89ab, b_lm[lm_offset + 66]); \
|
|
142
|
+
acc8.s3 = dot(a_reg.s89ab, b_lm[lm_offset + 67]); \
|
|
143
|
+
acc8.s4 = dot(a_reg.s89ab, b_lm[lm_offset + 68]); \
|
|
144
|
+
acc8.s5 = dot(a_reg.s89ab, b_lm[lm_offset + 69]); \
|
|
145
|
+
acc8.s6 = dot(a_reg.s89ab, b_lm[lm_offset + 70]); \
|
|
146
|
+
acc8.s7 = dot(a_reg.s89ab, b_lm[lm_offset + 71]); \
|
|
147
|
+
acc8.s0 += dot(a_reg.scdef, b_lm[lm_offset + 96]); \
|
|
148
|
+
acc8.s1 += dot(a_reg.scdef, b_lm[lm_offset + 97]); \
|
|
149
|
+
acc8.s2 += dot(a_reg.scdef, b_lm[lm_offset + 98]); \
|
|
150
|
+
acc8.s3 += dot(a_reg.scdef, b_lm[lm_offset + 99]); \
|
|
151
|
+
acc8.s4 += dot(a_reg.scdef, b_lm[lm_offset + 100]); \
|
|
152
|
+
acc8.s5 += dot(a_reg.scdef, b_lm[lm_offset + 101]); \
|
|
153
|
+
acc8.s6 += dot(a_reg.scdef, b_lm[lm_offset + 102]); \
|
|
154
|
+
acc8.s7 += dot(a_reg.scdef, b_lm[lm_offset + 103]); \
|
|
155
|
+
c_reg += convert_float8(acc8); \
|
|
156
|
+
|
|
117
157
|
|
|
118
158
|
__attribute__((qcom_wave_pair_mode(1)))
|
|
119
159
|
kernel void kernel_gemm_moe_q4_k_f32_ns(
|
|
@@ -127,7 +167,9 @@ kernel void kernel_gemm_moe_q4_k_f32_ns(
|
|
|
127
167
|
__write_only image1d_buffer_t dst,
|
|
128
168
|
__global int * total_tiles,
|
|
129
169
|
uint ne00,
|
|
130
|
-
uint ne01
|
|
170
|
+
uint ne01,
|
|
171
|
+
uint is_ragged,
|
|
172
|
+
uint skip_gran
|
|
131
173
|
) {
|
|
132
174
|
uint block_id_m = get_global_id(1); // m_tile
|
|
133
175
|
uint block_id_n = get_global_id(2); // n_tile
|
|
@@ -137,6 +179,25 @@ kernel void kernel_gemm_moe_q4_k_f32_ns(
|
|
|
137
179
|
return;
|
|
138
180
|
}
|
|
139
181
|
|
|
182
|
+
// Ragged tile-skip: tokens are packed contiguously per expert (moe_scatter fills
|
|
183
|
+
// lanes 0..V-1, moe_fill pre-pads the rest), so router padding (0xFFFFFFFF) is always
|
|
184
|
+
// trailing. Find the valid-token count V and round it UP to the skip granularity
|
|
185
|
+
// skip_gran (columns per skip-group: 8 = quarter, 16 = half/legacy, 32 = disabled).
|
|
186
|
+
// A 8-column group g is all-padding iff its first column (8*g) >= n_active, so its
|
|
187
|
+
// dotx8_reduce4 is skipped. Numerically identical (skipped lanes are padding).
|
|
188
|
+
uint n_active = TILESIZE_N;
|
|
189
|
+
if (is_ragged && skip_gran < TILESIZE_N) {
|
|
190
|
+
uint n_valid = TILESIZE_N;
|
|
191
|
+
for (uint _t = 0; _t < TILESIZE_N; ++_t) {
|
|
192
|
+
if (src2[block_id_n * TILESIZE_N + _t] == 0xFFFFFFFFu) { n_valid = _t; break; }
|
|
193
|
+
}
|
|
194
|
+
n_active = min((uint)TILESIZE_N, ((n_valid + skip_gran - 1) / skip_gran) * skip_gran);
|
|
195
|
+
}
|
|
196
|
+
// Group 0 (cols 0-7) always runs; groups 1-3 skip when fully padding.
|
|
197
|
+
bool skip_g1 = (8u >= n_active);
|
|
198
|
+
bool skip_g2 = (16u >= n_active);
|
|
199
|
+
bool skip_g3 = (24u >= n_active);
|
|
200
|
+
|
|
140
201
|
__private half16 reg_a;
|
|
141
202
|
__private float32 reg_c = (float32)(0);
|
|
142
203
|
__local half4 shared_b[128];
|
|
@@ -199,9 +260,11 @@ kernel void kernel_gemm_moe_q4_k_f32_ns(
|
|
|
199
260
|
|
|
200
261
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
201
262
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
263
|
+
half8 acc8;
|
|
264
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
265
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
266
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
267
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
205
268
|
|
|
206
269
|
// Second half (next 16 elements, same sub-block scale)
|
|
207
270
|
uint half_step = step + TILESIZE_K;
|
|
@@ -221,8 +284,10 @@ kernel void kernel_gemm_moe_q4_k_f32_ns(
|
|
|
221
284
|
|
|
222
285
|
sub_group_barrier(CLK_LOCAL_MEM_FENCE);
|
|
223
286
|
|
|
224
|
-
|
|
225
|
-
|
|
287
|
+
dotx8_reduce4(reg_a, shared_b, reg_c.lo.lo, 0);
|
|
288
|
+
if (!skip_g1) { dotx8_reduce4(reg_a, shared_b, reg_c.lo.hi, 8); }
|
|
289
|
+
if (!skip_g2) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.lo, 16); }
|
|
290
|
+
if (!skip_g3) { dotx8_reduce4(reg_a, shared_b, reg_c.hi.hi, 24); }
|
|
226
291
|
}
|
|
227
292
|
|
|
228
293
|
if ((get_global_id(0) + block_id_m * TILESIZE_M) >= ne01) {
|