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
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
#include <sycl/sycl.hpp>
|
|
34
34
|
#include <sycl/backend.hpp>
|
|
35
|
-
#ifdef
|
|
35
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
36
36
|
#include <level_zero/ze_api.h>
|
|
37
37
|
#endif
|
|
38
38
|
#if defined(GGML_SYCL_GRAPH) && SYCL_EXT_ONEAPI_ASYNC_MEMORY_ALLOC
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
#if SYCL_EXT_ONEAPI_VIRTUAL_MEM
|
|
42
42
|
# include <sycl/ext/oneapi/virtual_mem/physical_mem.hpp>
|
|
43
43
|
# include <sycl/ext/oneapi/virtual_mem/virtual_mem.hpp>
|
|
44
|
-
# define
|
|
44
|
+
# define GGML_SYCL_SUPPORT_VMM
|
|
45
45
|
#endif
|
|
46
46
|
#include <sycl/half_type.hpp>
|
|
47
47
|
|
|
@@ -62,6 +62,9 @@
|
|
|
62
62
|
#include "ggml-sycl/repeat_back.hpp"
|
|
63
63
|
#include "ggml-sycl/set_rows.hpp"
|
|
64
64
|
#include "ggml-sycl/set.hpp"
|
|
65
|
+
#include "ggml-sycl/conv2d.hpp"
|
|
66
|
+
#include "ggml-sycl/conv2d-dw.hpp"
|
|
67
|
+
#include "ggml-sycl/conv2d-transpose.hpp"
|
|
65
68
|
#include "ggml-sycl/ssm_conv.hpp"
|
|
66
69
|
#include "ggml-sycl/sycl_hw.hpp"
|
|
67
70
|
#include "ggml-sycl/ssm_scan.hpp"
|
|
@@ -70,19 +73,25 @@
|
|
|
70
73
|
#include "ggml-sycl/diag.hpp"
|
|
71
74
|
#include "ggml-sycl/solve_tri.hpp"
|
|
72
75
|
#include "ggml-sycl/gated_delta_net.hpp"
|
|
76
|
+
#include "ggml-sycl/pool.hpp"
|
|
77
|
+
#include "ggml-sycl/cross_entropy_loss.hpp"
|
|
78
|
+
|
|
79
|
+
#define MEM_SIZE_2M 0x00200000
|
|
80
|
+
#define MEM_SIZE_1G 0x40000000
|
|
73
81
|
|
|
74
82
|
static bool g_sycl_loaded = false;
|
|
75
83
|
int g_ggml_sycl_debug = 0;
|
|
76
|
-
int
|
|
77
|
-
int
|
|
78
|
-
int
|
|
84
|
+
int g_ggml_sycl_enable_optimize = 1;
|
|
85
|
+
int g_ggml_sycl_enable_graph = 0;
|
|
86
|
+
int g_ggml_sycl_enable_dnn = 1;
|
|
79
87
|
int g_ggml_sycl_enable_vmm = 1;
|
|
80
88
|
int g_ggml_sycl_prioritize_dmmv = 0;
|
|
81
89
|
int g_ggml_sycl_use_async_mem_op = 0;
|
|
82
90
|
int g_ggml_sycl_use_async_mem_op_requested = 1;
|
|
83
|
-
int
|
|
91
|
+
int g_ggml_sycl_use_level_zero_api = 0;
|
|
84
92
|
int g_ggml_sycl_enable_flash_attention = 1;
|
|
85
|
-
|
|
93
|
+
int g_ggml_sycl_dev2dev_memcpy = DEV2DEV_MEMCPY_SYCL;
|
|
94
|
+
int g_ggml_sycl_usm_system = 0;
|
|
86
95
|
|
|
87
96
|
static ggml_sycl_device_info ggml_sycl_init() {
|
|
88
97
|
ggml_sycl_device_info info = {};
|
|
@@ -109,7 +118,7 @@ static ggml_sycl_device_info ggml_sycl_init() {
|
|
|
109
118
|
SYCL_CHECK(CHECK_TRY_ERROR(dpct::get_device_info(
|
|
110
119
|
prop, device)));
|
|
111
120
|
|
|
112
|
-
#if !defined(
|
|
121
|
+
#if !defined(GGML_SYCL_SUPPORT_VMM)
|
|
113
122
|
info.devices[i].vmm = 0;
|
|
114
123
|
#else
|
|
115
124
|
info.devices[i].vmm = device.has(sycl::aspect::ext_oneapi_virtual_mem);
|
|
@@ -136,6 +145,7 @@ static ggml_sycl_device_info ggml_sycl_init() {
|
|
|
136
145
|
info.devices[i].opt_feature.reorder = device.ext_oneapi_architecture_is(syclex::arch_category::intel_gpu);
|
|
137
146
|
info.devices[i].smpbo = prop.get_local_mem_size();
|
|
138
147
|
info.devices[i].warp_size = WARP_SIZE;
|
|
148
|
+
info.devices[i].usm_system_support = device.has(sycl::aspect::usm_system_allocations);
|
|
139
149
|
|
|
140
150
|
info.max_work_group_sizes[i] = prop.get_max_work_group_size();
|
|
141
151
|
info.devices[i].max_wg_per_cu = info.max_work_group_sizes[i] / prop.get_max_compute_units();
|
|
@@ -147,11 +157,31 @@ static ggml_sycl_device_info ggml_sycl_init() {
|
|
|
147
157
|
GGML_LOG_WARN("SYCL GPU device %d does not use Level Zero backend, disabling Level Zero memory API\n", i);
|
|
148
158
|
info.ext_oneapi_level_zero = false;
|
|
149
159
|
}
|
|
160
|
+
|
|
161
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
162
|
+
if (info.ext_oneapi_level_zero && device.is_gpu() && device.default_queue().get_backend() == sycl::backend::ext_oneapi_level_zero) {
|
|
163
|
+
ze_device_handle_t ze_dev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(device.default_queue().get_device());
|
|
164
|
+
ze_device_properties_t props = {};
|
|
165
|
+
props.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
|
|
166
|
+
ze_result_t r = zeDeviceGetProperties(ze_dev, &props);
|
|
167
|
+
info.devices[i].l0_discrete_gpu = r == ZE_RESULT_SUCCESS && !(props.flags & ZE_DEVICE_PROPERTY_FLAG_INTEGRATED);
|
|
168
|
+
}
|
|
169
|
+
#endif
|
|
150
170
|
}
|
|
151
171
|
|
|
152
172
|
for (int id = 0; id < info.device_count; ++id) {
|
|
153
173
|
info.default_tensor_split[id] /= total_vram;
|
|
154
174
|
}
|
|
175
|
+
|
|
176
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
177
|
+
// Large buffers can be allocated before ggml_check_sycl() initializes other
|
|
178
|
+
// g_ggml_sycl_enable_* globals, so initialize this one as early as we can.
|
|
179
|
+
g_ggml_sycl_use_level_zero_api =
|
|
180
|
+
info.ext_oneapi_level_zero && ggml_sycl_get_env("GGML_SYCL_USE_LEVEL_ZERO_API", 1);
|
|
181
|
+
#else
|
|
182
|
+
g_ggml_sycl_use_level_zero_api = 0;
|
|
183
|
+
#endif
|
|
184
|
+
|
|
155
185
|
return info;
|
|
156
186
|
}
|
|
157
187
|
|
|
@@ -236,110 +266,128 @@ void ggml_backend_sycl_print_sycl_devices() {
|
|
|
236
266
|
print_device_opt_feature(device_count);
|
|
237
267
|
}
|
|
238
268
|
|
|
239
|
-
static
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (user_device_string != NULL &&
|
|
245
|
-
sscanf(user_device_string, " %u", &n) == 1) {
|
|
246
|
-
user_number = (int)n;
|
|
269
|
+
static const char* dev2dev_int2str(int dev2dev) {
|
|
270
|
+
if (dev2dev == DEV2DEV_MEMCPY_SYCL) {
|
|
271
|
+
return "SYCL API";
|
|
272
|
+
} else if (dev2dev == DEV2DEV_MEMCPY_L0) {
|
|
273
|
+
return "Level Zero API";
|
|
247
274
|
} else {
|
|
248
|
-
|
|
275
|
+
return "Unknown";
|
|
249
276
|
}
|
|
250
|
-
return user_number;
|
|
251
277
|
}
|
|
252
278
|
|
|
253
279
|
static void ggml_check_sycl() try {
|
|
254
280
|
static bool initialized = false;
|
|
255
281
|
|
|
256
282
|
if (!initialized) {
|
|
257
|
-
g_ggml_sycl_debug =
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
g_ggml_sycl_enable_vmm =
|
|
262
|
-
g_ggml_sycl_prioritize_dmmv =
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
283
|
+
g_ggml_sycl_debug = ggml_sycl_get_env("GGML_SYCL_DEBUG", 0);
|
|
284
|
+
g_ggml_sycl_enable_optimize = ggml_sycl_get_env("GGML_SYCL_ENABLE_OPT", 1);
|
|
285
|
+
g_ggml_sycl_enable_graph = ggml_sycl_get_env("GGML_SYCL_ENABLE_GRAPH", 0);
|
|
286
|
+
g_ggml_sycl_enable_dnn = ggml_sycl_get_env("GGML_SYCL_ENABLE_DNN", 1);
|
|
287
|
+
g_ggml_sycl_enable_vmm = ggml_sycl_get_env("GGML_SYCL_ENABLE_VMM", 1);
|
|
288
|
+
g_ggml_sycl_prioritize_dmmv = ggml_sycl_get_env("GGML_SYCL_PRIORITIZE_DMMV", 0);
|
|
289
|
+
|
|
290
|
+
g_ggml_sycl_dev2dev_memcpy = ggml_sycl_get_env("GGML_SYCL_DEV2DEV_MEMCPY", DEV2DEV_MEMCPY_SYCL);
|
|
291
|
+
if (g_ggml_sycl_use_level_zero_api == 0) {
|
|
292
|
+
g_ggml_sycl_dev2dev_memcpy = DEV2DEV_MEMCPY_SYCL;
|
|
293
|
+
}
|
|
268
294
|
|
|
269
295
|
#ifdef SYCL_FLASH_ATTN
|
|
270
|
-
g_ggml_sycl_enable_flash_attention =
|
|
296
|
+
g_ggml_sycl_enable_flash_attention = ggml_sycl_get_env("GGML_SYCL_ENABLE_FLASH_ATTN", 1);
|
|
271
297
|
#else
|
|
272
298
|
g_ggml_sycl_enable_flash_attention = 0;
|
|
273
299
|
#endif
|
|
274
300
|
|
|
301
|
+
g_ggml_sycl_usm_system = ggml_sycl_get_env("GGML_SYCL_USM_SYSTEM", 0);
|
|
302
|
+
|
|
275
303
|
GGML_SYCL_DEBUG("[SYCL] call ggml_check_sycl\n");
|
|
276
304
|
|
|
277
305
|
GGML_LOG_INFO("Build with Macros:\n");
|
|
278
|
-
#if defined(
|
|
279
|
-
GGML_LOG_INFO("
|
|
306
|
+
#if defined(GGML_SYCL_DNNL)
|
|
307
|
+
GGML_LOG_INFO(" GGML_SYCL_DNNL: yes\n");
|
|
280
308
|
#else
|
|
281
|
-
GGML_LOG_INFO("
|
|
309
|
+
GGML_LOG_INFO(" GGML_SYCL_DNNL: no\n");
|
|
282
310
|
#endif
|
|
311
|
+
|
|
283
312
|
#if defined(GGML_SYCL_F16)
|
|
284
313
|
GGML_LOG_INFO(" GGML_SYCL_F16: yes\n");
|
|
285
314
|
#else
|
|
286
315
|
GGML_LOG_INFO(" GGML_SYCL_F16: no\n");
|
|
287
316
|
#endif
|
|
317
|
+
|
|
318
|
+
#if defined(GGML_SYCL_FORCE_MMQ)
|
|
319
|
+
GGML_LOG_INFO(" GGML_SYCL_FORCE_MMQ: yes\n");
|
|
320
|
+
#else
|
|
321
|
+
GGML_LOG_INFO(" GGML_SYCL_FORCE_MMQ: no\n");
|
|
322
|
+
#endif
|
|
323
|
+
|
|
288
324
|
#if defined(GGML_SYCL_GRAPH)
|
|
289
325
|
GGML_LOG_INFO(" GGML_SYCL_GRAPH: yes\n");
|
|
290
326
|
#else
|
|
291
327
|
GGML_LOG_INFO(" GGML_SYCL_GRAPH: no\n");
|
|
292
328
|
#endif
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
GGML_LOG_INFO(" GGML_SYCL_DNNL: no\n");
|
|
297
|
-
#endif
|
|
298
|
-
#if defined(GGML_SYCL_SUPPORT_LEVEL_ZERO)
|
|
299
|
-
GGML_LOG_INFO(" GGML_SYCL_SUPPORT_LEVEL_ZERO: yes\n");
|
|
329
|
+
|
|
330
|
+
#if defined(GGML_SYCL_SUPPORT_LEVEL_ZERO_API)
|
|
331
|
+
GGML_LOG_INFO(" GGML_SYCL_SUPPORT_LEVEL_ZERO_API: yes\n");
|
|
300
332
|
#else
|
|
301
|
-
GGML_LOG_INFO("
|
|
333
|
+
GGML_LOG_INFO(" GGML_SYCL_SUPPORT_LEVEL_ZERO_API: no\n");
|
|
302
334
|
#endif
|
|
303
|
-
#if defined(
|
|
304
|
-
GGML_LOG_INFO("
|
|
335
|
+
#if defined(GGML_SYCL_SUPPORT_VMM)
|
|
336
|
+
GGML_LOG_INFO(" GGML_SYCL_SUPPORT_VMM: yes\n");
|
|
305
337
|
#else
|
|
306
|
-
GGML_LOG_INFO("
|
|
338
|
+
GGML_LOG_INFO(" GGML_SYCL_SUPPORT_VMM: no\n");
|
|
307
339
|
#endif
|
|
308
340
|
|
|
309
341
|
GGML_LOG_INFO("Running with Environment Variables:\n");
|
|
310
342
|
GGML_LOG_INFO(" GGML_SYCL_DEBUG: %d\n", g_ggml_sycl_debug);
|
|
311
|
-
|
|
312
|
-
#ifdef
|
|
313
|
-
GGML_LOG_INFO("
|
|
343
|
+
|
|
344
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
345
|
+
GGML_LOG_INFO(" GGML_SYCL_DEV2DEV_MEMCPY: %d (%s)\n", g_ggml_sycl_dev2dev_memcpy, dev2dev_int2str(g_ggml_sycl_dev2dev_memcpy));
|
|
314
346
|
#else
|
|
315
|
-
GGML_LOG_INFO("
|
|
347
|
+
GGML_LOG_INFO(" GGML_SYCL_DEV2DEV_MEMCPY: %d (%s), enable to SYCL API since missing GGML_SYCL_SUPPORT_LEVEL_ZERO_API\n",
|
|
348
|
+
g_ggml_sycl_dev2dev_memcpy, dev2dev_int2str(g_ggml_sycl_dev2dev_memcpy));
|
|
316
349
|
#endif
|
|
317
|
-
|
|
318
|
-
|
|
350
|
+
|
|
351
|
+
#if defined(GGML_SYCL_DNNL)
|
|
352
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_DNN: %d\n", g_ggml_sycl_enable_dnn);
|
|
319
353
|
#else
|
|
320
|
-
GGML_LOG_INFO("
|
|
354
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_DNN: DNN disabled by compile flag\n");
|
|
321
355
|
#endif
|
|
322
|
-
|
|
323
|
-
|
|
356
|
+
|
|
357
|
+
#ifdef SYCL_FLASH_ATTN
|
|
358
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_FLASH_ATTN: %d\n", g_ggml_sycl_enable_flash_attention);
|
|
359
|
+
#else
|
|
360
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_FLASH_ATTN: %d disabled by compile flag\n",
|
|
361
|
+
g_ggml_sycl_enable_flash_attention);
|
|
362
|
+
#endif
|
|
363
|
+
|
|
364
|
+
#ifdef GGML_SYCL_GRAPH
|
|
365
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_GRAPH: %d\n", g_ggml_sycl_enable_graph);
|
|
324
366
|
#else
|
|
325
|
-
GGML_LOG_INFO("
|
|
367
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_GRAPH: graph disabled by compile flag\n");
|
|
326
368
|
#endif
|
|
327
|
-
|
|
369
|
+
|
|
370
|
+
GGML_LOG_INFO(" GGML_SYCL_ENABLE_OPT: %d\n", g_ggml_sycl_enable_optimize);
|
|
371
|
+
|
|
372
|
+
#if defined(GGML_SYCL_SUPPORT_VMM)
|
|
328
373
|
GGML_LOG_INFO(" GGML_SYCL_ENABLE_VMM: %d\n", g_ggml_sycl_enable_vmm);
|
|
329
374
|
#else
|
|
330
375
|
GGML_LOG_INFO(" GGML_SYCL_ENABLE_VMM: virtual memory extension is not available\n");
|
|
331
376
|
#endif
|
|
377
|
+
|
|
332
378
|
GGML_LOG_INFO(" GGML_SYCL_PRIORITIZE_DMMV: %d\n", g_ggml_sycl_prioritize_dmmv);
|
|
333
|
-
|
|
379
|
+
|
|
380
|
+
g_ggml_sycl_use_async_mem_op_requested = ggml_sycl_get_env("GGML_SYCL_USE_ASYNC_MEM_OP", 1);
|
|
334
381
|
GGML_LOG_INFO(" GGML_SYCL_USE_ASYNC_MEM_OP: %d\n", g_ggml_sycl_use_async_mem_op_requested);
|
|
335
382
|
|
|
336
|
-
#ifdef
|
|
337
|
-
GGML_LOG_INFO("
|
|
383
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
384
|
+
GGML_LOG_INFO(" GGML_SYCL_USE_LEVEL_ZERO_API: %d\n", g_ggml_sycl_use_level_zero_api);
|
|
338
385
|
#else
|
|
339
|
-
GGML_LOG_INFO("
|
|
340
|
-
g_ggml_sycl_enable_flash_attention);
|
|
386
|
+
GGML_LOG_INFO(" GGML_SYCL_USE_LEVEL_ZERO_API: Disable Level Zero API usage by compile flag\n");
|
|
341
387
|
#endif
|
|
342
388
|
|
|
389
|
+
GGML_LOG_INFO(" GGML_SYCL_USM_SYSTEM: %d\n", g_ggml_sycl_usm_system);
|
|
390
|
+
|
|
343
391
|
/* NOT REMOVE, keep it for next optimize for XMX.
|
|
344
392
|
#if defined(SYCL_USE_XMX)
|
|
345
393
|
fprintf(stderr, "%s: SYCL_USE_XMX: yes\n", __func__);
|
|
@@ -351,7 +399,7 @@ static void ggml_check_sycl() try {
|
|
|
351
399
|
// staging path while preserving queue ordering semantics. Graph support still depends on the extension being
|
|
352
400
|
// available, but it no longer needs to control the non-graph fast path.
|
|
353
401
|
#if defined(GGML_SYCL_GRAPH) && SYCL_EXT_ONEAPI_ASYNC_MEMORY_ALLOC
|
|
354
|
-
g_ggml_sycl_use_async_mem_op = g_ggml_sycl_use_async_mem_op_requested ||
|
|
402
|
+
g_ggml_sycl_use_async_mem_op = g_ggml_sycl_use_async_mem_op_requested || g_ggml_sycl_enable_graph;
|
|
355
403
|
if (g_ggml_sycl_use_async_mem_op) {
|
|
356
404
|
for (unsigned int i = 0; i < dpct::dev_mgr::instance().device_count(); ++i) {
|
|
357
405
|
if (!dpct::dev_mgr::instance().get_device(i).has(sycl::aspect::ext_oneapi_async_memory_alloc)) {
|
|
@@ -415,6 +463,14 @@ catch (sycl::exception const &exc) {
|
|
|
415
463
|
std::exit(1);
|
|
416
464
|
}
|
|
417
465
|
|
|
466
|
+
inline void free_aligned_mem_host(void * memblock) {
|
|
467
|
+
#ifdef _WIN32
|
|
468
|
+
_aligned_free(memblock);
|
|
469
|
+
#else
|
|
470
|
+
free(memblock);
|
|
471
|
+
#endif
|
|
472
|
+
}
|
|
473
|
+
|
|
418
474
|
// sycl buffer
|
|
419
475
|
|
|
420
476
|
struct ggml_backend_sycl_buffer_context {
|
|
@@ -424,9 +480,10 @@ struct ggml_backend_sycl_buffer_context {
|
|
|
424
480
|
std::string name;
|
|
425
481
|
optimize_feature opt_feature;
|
|
426
482
|
std::vector<ggml_tensor_extra_gpu *> tensor_extras;
|
|
483
|
+
bool is_usm_system;
|
|
427
484
|
|
|
428
|
-
ggml_backend_sycl_buffer_context(int device, void * dev_ptr, queue_ptr stream) :
|
|
429
|
-
device(device), dev_ptr(dev_ptr), stream(stream) {
|
|
485
|
+
ggml_backend_sycl_buffer_context(int device, void * dev_ptr, queue_ptr stream, bool is_usm_system) :
|
|
486
|
+
device(device), dev_ptr(dev_ptr), stream(stream), is_usm_system(is_usm_system) {
|
|
430
487
|
check_allow_gpu_index(device);
|
|
431
488
|
name = (GGML_SYCL_NAME + std::to_string(device));
|
|
432
489
|
opt_feature = ggml_sycl_info().devices[device].opt_feature;
|
|
@@ -435,7 +492,10 @@ struct ggml_backend_sycl_buffer_context {
|
|
|
435
492
|
~ggml_backend_sycl_buffer_context() {
|
|
436
493
|
if (dev_ptr != nullptr) {
|
|
437
494
|
ggml_sycl_set_device(device);
|
|
438
|
-
|
|
495
|
+
if (is_usm_system)
|
|
496
|
+
free_aligned_mem_host(dev_ptr);
|
|
497
|
+
else
|
|
498
|
+
SYCL_CHECK(CHECK_TRY_ERROR(ggml_sycl_free_device(dev_ptr, *stream)));
|
|
439
499
|
}
|
|
440
500
|
|
|
441
501
|
//release extra used by tensors
|
|
@@ -482,12 +542,14 @@ ggml_backend_sycl_buffer_init_tensor(ggml_backend_buffer_t buffer,
|
|
|
482
542
|
return GGML_STATUS_SUCCESS;
|
|
483
543
|
}
|
|
484
544
|
|
|
485
|
-
if (
|
|
545
|
+
if (g_ggml_sycl_enable_optimize) {
|
|
486
546
|
// set reorder extra buffer based on supported type
|
|
487
547
|
switch (tensor->type) {
|
|
488
548
|
case GGML_TYPE_Q4_0:
|
|
489
549
|
case GGML_TYPE_Q8_0:
|
|
550
|
+
case GGML_TYPE_Q3_K:
|
|
490
551
|
case GGML_TYPE_Q4_K:
|
|
552
|
+
case GGML_TYPE_Q5_K:
|
|
491
553
|
case GGML_TYPE_Q6_K:{
|
|
492
554
|
ggml_tensor_extra_gpu * extra = new ggml_tensor_extra_gpu{};
|
|
493
555
|
tensor->extra = extra;
|
|
@@ -568,43 +630,50 @@ catch (sycl::exception const &exc) {
|
|
|
568
630
|
std::exit(1);
|
|
569
631
|
}
|
|
570
632
|
|
|
571
|
-
#ifdef
|
|
572
|
-
static bool ggml_sycl_is_l0_discrete_gpu(
|
|
573
|
-
|
|
574
|
-
return false;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
ze_device_handle_t ze_dev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q.get_device());
|
|
578
|
-
ze_device_properties_t props = {};
|
|
579
|
-
props.stype = ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
|
|
580
|
-
ze_result_t r = zeDeviceGetProperties(ze_dev, &props);
|
|
581
|
-
return r == ZE_RESULT_SUCCESS && !(props.flags & ZE_DEVICE_PROPERTY_FLAG_INTEGRATED);
|
|
633
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
634
|
+
static bool ggml_sycl_is_l0_discrete_gpu(int device) {
|
|
635
|
+
return ggml_sycl_info().devices[device].l0_discrete_gpu;
|
|
582
636
|
}
|
|
583
637
|
#endif
|
|
584
638
|
|
|
585
|
-
static void dev2dev_memcpy(sycl::queue &q_dst, sycl::queue &q_src, void *ptr_dst,
|
|
639
|
+
static void dev2dev_memcpy(int device_dst, sycl::queue &q_dst, int device_src, sycl::queue &q_src, void *ptr_dst,
|
|
586
640
|
const void *ptr_src, size_t size) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
r =
|
|
600
|
-
zeCommandListDestroy(cl);
|
|
641
|
+
|
|
642
|
+
#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
|
|
643
|
+
if (g_ggml_sycl_dev2dev_memcpy == DEV2DEV_MEMCPY_L0) {
|
|
644
|
+
// Use Level Zero direct copy for dGPU-to-dGPU transfers.
|
|
645
|
+
const bool l0_copy_supported =
|
|
646
|
+
ggml_sycl_is_l0_discrete_gpu(device_dst) && ggml_sycl_is_l0_discrete_gpu(device_src);
|
|
647
|
+
if (g_ggml_sycl_use_level_zero_api && l0_copy_supported) {
|
|
648
|
+
auto ze_ctx = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q_dst.get_context());
|
|
649
|
+
auto ze_dev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q_dst.get_device());
|
|
650
|
+
ze_command_queue_desc_t cq_desc = {ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC, nullptr, 0, 0,
|
|
651
|
+
0, ZE_COMMAND_QUEUE_MODE_SYNCHRONOUS, ZE_COMMAND_QUEUE_PRIORITY_NORMAL};
|
|
652
|
+
ze_command_list_handle_t cl;
|
|
653
|
+
ze_result_t r = zeCommandListCreateImmediate(ze_ctx, ze_dev, &cq_desc, &cl);
|
|
601
654
|
if (r == ZE_RESULT_SUCCESS) {
|
|
602
|
-
|
|
655
|
+
GGML_SYCL_DEBUG("[SYCL] dev2dev memcpy by L0\n");
|
|
656
|
+
r = zeCommandListAppendMemoryCopy(cl, ptr_dst, ptr_src, size, nullptr, 0, nullptr);
|
|
657
|
+
zeCommandListDestroy(cl);
|
|
658
|
+
if (r == ZE_RESULT_SUCCESS) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
603
661
|
}
|
|
604
662
|
}
|
|
605
663
|
}
|
|
606
664
|
#endif
|
|
665
|
+
|
|
666
|
+
if (g_ggml_sycl_dev2dev_memcpy == DEV2DEV_MEMCPY_SYCL) {
|
|
667
|
+
if (q_dst.get_device().ext_oneapi_can_access_peer(q_src.get_device(),
|
|
668
|
+
sycl::ext::oneapi::peer_access::access_supported)) {
|
|
669
|
+
GGML_SYCL_DEBUG("[SYCL] dev2dev memcpy by SYCL\n");
|
|
670
|
+
SYCL_CHECK(CHECK_TRY_ERROR(q_dst.memcpy(ptr_dst, ptr_src, size).wait()));
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
607
675
|
// Host-staged copy
|
|
676
|
+
GGML_SYCL_DEBUG("[SYCL] dev2dev memcpy by host forward\n");
|
|
608
677
|
char *host_buf = (char *)malloc(size);
|
|
609
678
|
q_src.memcpy(host_buf, (const char *)ptr_src, size).wait();
|
|
610
679
|
q_dst.memcpy((char *)ptr_dst, host_buf, size).wait();
|
|
@@ -651,7 +720,7 @@ ggml_backend_sycl_buffer_cpy_tensor(ggml_backend_buffer_t buffer,
|
|
|
651
720
|
size_t size = ggml_nbytes(src);
|
|
652
721
|
|
|
653
722
|
//todo. it's dirty solutino to walkaroud known issue:device2device cross GPUs.
|
|
654
|
-
dev2dev_memcpy(*stream_dst, *stream_src, dst->data, src->data, size);
|
|
723
|
+
dev2dev_memcpy(dst_ctx->device, *stream_dst, src_ctx->device, *stream_src, dst->data, src->data, size);
|
|
655
724
|
|
|
656
725
|
//todo, it's known issue:error in device2device cross GPUs. reused when the issue is fixed. DON"T remove
|
|
657
726
|
#if 0
|
|
@@ -765,21 +834,59 @@ static const char * ggml_backend_sycl_buffer_type_get_name(ggml_backend_buffer_t
|
|
|
765
834
|
return ctx->name.c_str();
|
|
766
835
|
}
|
|
767
836
|
|
|
837
|
+
static bool check_usm_system(int device, size_t size) {
|
|
838
|
+
bool use_usm_system = g_ggml_sycl_usm_system && size >= MEM_SIZE_1G;
|
|
839
|
+
|
|
840
|
+
if (use_usm_system && !ggml_sycl_info().devices[device].usm_system_support) {
|
|
841
|
+
GGML_LOG_INFO("Device does not support USM system allocations\n");
|
|
842
|
+
use_usm_system = false;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
return use_usm_system;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
inline void * aligned_malloc_host(size_t alignment, size_t size) {
|
|
849
|
+
#ifdef _WIN32
|
|
850
|
+
return _aligned_malloc(size, alignment);
|
|
851
|
+
#else
|
|
852
|
+
return aligned_alloc(alignment, size);
|
|
853
|
+
#endif
|
|
854
|
+
}
|
|
855
|
+
|
|
768
856
|
static ggml_backend_buffer_t
|
|
769
857
|
ggml_backend_sycl_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft,
|
|
770
858
|
size_t size) try {
|
|
859
|
+
ggml_check_sycl();
|
|
860
|
+
|
|
771
861
|
ggml_backend_sycl_buffer_type_context * buft_ctx = (ggml_backend_sycl_buffer_type_context *)buft->context;
|
|
772
862
|
ggml_sycl_set_device(buft_ctx->device);
|
|
773
863
|
const queue_ptr stream = buft_ctx->stream;
|
|
774
864
|
size = std::max(size, (size_t)1); // syclMalloc returns null for size 0
|
|
865
|
+
/*
|
|
866
|
+
Alignment below ensures best performance. While in theory it could lead to
|
|
867
|
+
wasting memory, this is acceptable because in practice only few buffers are
|
|
868
|
+
allocated and even less exceed the minimum size accepted here for USM system
|
|
869
|
+
allocations.
|
|
870
|
+
*/
|
|
871
|
+
size_t alignment = MEM_SIZE_2M;
|
|
872
|
+
size_t aligned_size = ((size + alignment - 1) / alignment) * alignment;
|
|
873
|
+
bool use_usm_system = check_usm_system(buft_ctx->device, aligned_size);
|
|
775
874
|
|
|
776
875
|
void * dev_ptr;
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
876
|
+
if (use_usm_system) {
|
|
877
|
+
dev_ptr = (void *)aligned_malloc_host(alignment, aligned_size);
|
|
878
|
+
if (!dev_ptr) {
|
|
879
|
+
GGML_LOG_ERROR("%s: can't allocate %lu Bytes of memory on host\n", __func__, size);
|
|
880
|
+
return nullptr;
|
|
881
|
+
}
|
|
882
|
+
} else {
|
|
883
|
+
SYCL_CHECK(CHECK_TRY_ERROR(dev_ptr = (void *)ggml_sycl_malloc_device(size, *stream)));
|
|
884
|
+
if (!dev_ptr) {
|
|
885
|
+
GGML_LOG_ERROR("%s: can't allocate %lu Bytes of memory on device\n", __func__, size);
|
|
886
|
+
return nullptr;
|
|
887
|
+
}
|
|
781
888
|
}
|
|
782
|
-
ggml_backend_sycl_buffer_context * ctx = new ggml_backend_sycl_buffer_context(buft_ctx->device, dev_ptr, buft_ctx->stream);
|
|
889
|
+
ggml_backend_sycl_buffer_context * ctx = new ggml_backend_sycl_buffer_context(buft_ctx->device, dev_ptr, buft_ctx->stream, use_usm_system);
|
|
783
890
|
return ggml_backend_buffer_init(buft, ggml_backend_sycl_buffer_interface, ctx, size);
|
|
784
891
|
}
|
|
785
892
|
catch (sycl::exception const &exc) {
|
|
@@ -897,6 +1004,7 @@ static int64_t get_row_rounding(ggml_type type, const std::array<float, GGML_SYC
|
|
|
897
1004
|
}
|
|
898
1005
|
|
|
899
1006
|
switch(type) {
|
|
1007
|
+
case GGML_TYPE_Q1_0:
|
|
900
1008
|
case GGML_TYPE_Q4_0:
|
|
901
1009
|
case GGML_TYPE_Q4_1:
|
|
902
1010
|
return max_compute_capability >= VER_GEN9 ? 128 : 64;
|
|
@@ -1306,22 +1414,6 @@ static const char * ggml_backend_sycl_host_buffer_type_name(ggml_backend_buffer_
|
|
|
1306
1414
|
GGML_UNUSED(buft);
|
|
1307
1415
|
}
|
|
1308
1416
|
|
|
1309
|
-
inline void * aligned_malloc_host(size_t alignment, size_t size) {
|
|
1310
|
-
#ifdef _WIN32
|
|
1311
|
-
return _aligned_malloc(size, alignment);
|
|
1312
|
-
#else
|
|
1313
|
-
return aligned_alloc(alignment, size);
|
|
1314
|
-
#endif
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
inline void free_aligned_mem_host(void * memblock) {
|
|
1318
|
-
#ifdef _WIN32
|
|
1319
|
-
_aligned_free(memblock);
|
|
1320
|
-
#else
|
|
1321
|
-
free(memblock);
|
|
1322
|
-
#endif
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
1417
|
static void ggml_backend_sycl_host_buffer_free_buffer(ggml_backend_buffer_t buffer) {
|
|
1326
1418
|
free_aligned_mem_host((void *)buffer->context);
|
|
1327
1419
|
}
|
|
@@ -1498,7 +1590,7 @@ struct ggml_sycl_pool_leg : public ggml_sycl_pool {
|
|
|
1498
1590
|
};
|
|
1499
1591
|
|
|
1500
1592
|
// pool with virtual memory management
|
|
1501
|
-
#if defined(
|
|
1593
|
+
#if defined(GGML_SYCL_SUPPORT_VMM)
|
|
1502
1594
|
struct ggml_sycl_pool_vmm : public ggml_sycl_pool {
|
|
1503
1595
|
static const size_t SYCL_POOL_VMM_MAX_SIZE = 1ull << 35; // 32 GB
|
|
1504
1596
|
|
|
@@ -1610,7 +1702,7 @@ struct ggml_sycl_pool_vmm : public ggml_sycl_pool {
|
|
|
1610
1702
|
GGML_ASSERT(ptr == reinterpret_cast<void *>(pool_addr + pool_used));
|
|
1611
1703
|
}
|
|
1612
1704
|
};
|
|
1613
|
-
#endif // defined(
|
|
1705
|
+
#endif // defined(GGML_SYCL_SUPPORT_VMM)
|
|
1614
1706
|
|
|
1615
1707
|
struct ggml_sycl_pool_host : public ggml_sycl_pool {
|
|
1616
1708
|
queue_ptr qptr;
|
|
@@ -1692,11 +1784,11 @@ std::unique_ptr<ggml_sycl_pool> ggml_backend_sycl_context::new_pool_for_host(que
|
|
|
1692
1784
|
}
|
|
1693
1785
|
|
|
1694
1786
|
std::unique_ptr<ggml_sycl_pool> ggml_backend_sycl_context::new_pool_for_device(queue_ptr qptr, int device) {
|
|
1695
|
-
#if defined(
|
|
1787
|
+
#if defined(GGML_SYCL_SUPPORT_VMM)
|
|
1696
1788
|
if (g_ggml_sycl_enable_vmm && ggml_sycl_info().devices[device].vmm) {
|
|
1697
1789
|
return std::unique_ptr<ggml_sycl_pool>(new ggml_sycl_pool_vmm(qptr, device));
|
|
1698
1790
|
}
|
|
1699
|
-
#endif // defined(
|
|
1791
|
+
#endif // defined(GGML_SYCL_SUPPORT_VMM)
|
|
1700
1792
|
return std::unique_ptr<ggml_sycl_pool>(new ggml_sycl_pool_leg(qptr, device));
|
|
1701
1793
|
}
|
|
1702
1794
|
|
|
@@ -1947,69 +2039,6 @@ static void scale_f32(const float * x, float * dst, const float scale, const flo
|
|
|
1947
2039
|
}
|
|
1948
2040
|
|
|
1949
2041
|
|
|
1950
|
-
template <typename Ti, typename To>
|
|
1951
|
-
static void pool2d_nchw_kernel(
|
|
1952
|
-
const int ih, const int iw, const int oh, const int ow,
|
|
1953
|
-
const int kh, const int kw, const int sh, const int sw,
|
|
1954
|
-
const int ph, const int pw, const int parallel_elements,
|
|
1955
|
-
const Ti* src, To* dst, const enum ggml_op_pool op,
|
|
1956
|
-
const sycl::nd_item<3> &item_ct1) {
|
|
1957
|
-
int idx = item_ct1.get_local_id(2) +
|
|
1958
|
-
item_ct1.get_group(2) * item_ct1.get_local_range(2);
|
|
1959
|
-
if (idx >= parallel_elements) {
|
|
1960
|
-
return;
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
const int I_HW = ih * iw;
|
|
1964
|
-
const int O_HW = oh * ow;
|
|
1965
|
-
const int nc = idx / O_HW;
|
|
1966
|
-
const int cur_oh = idx % O_HW / ow;
|
|
1967
|
-
const int cur_ow = idx % O_HW % ow;
|
|
1968
|
-
const Ti* i_ptr = src + nc * I_HW;
|
|
1969
|
-
To* o_ptr = dst + nc * O_HW;
|
|
1970
|
-
const int start_h = cur_oh * sh - ph;
|
|
1971
|
-
const int bh = sycl::max(0, start_h);
|
|
1972
|
-
const int eh = sycl::min(ih, start_h + kh);
|
|
1973
|
-
const int start_w = cur_ow * sw - pw;
|
|
1974
|
-
const int bw = sycl::max(0, start_w);
|
|
1975
|
-
const int ew = sycl::min(iw, start_w + kw);
|
|
1976
|
-
|
|
1977
|
-
To res = 0;
|
|
1978
|
-
|
|
1979
|
-
switch (op) {
|
|
1980
|
-
case GGML_OP_POOL_AVG: res = 0; break;
|
|
1981
|
-
case GGML_OP_POOL_MAX: res = -FLT_MAX; break;
|
|
1982
|
-
default:
|
|
1983
|
-
res = (To) sycl::nan(uint32_t(0));
|
|
1984
|
-
break;
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
for (int i = bh; i < eh; i += 1) {
|
|
1988
|
-
for (int j = bw; j < ew; j += 1) {
|
|
1989
|
-
#if DPCT_COMPATIBILITY_TEMP >= 350
|
|
1990
|
-
/*
|
|
1991
|
-
DPCT1098:106: The '*' expression is used instead of the __ldg
|
|
1992
|
-
call. These two expressions do not provide the exact same
|
|
1993
|
-
functionality. Check the generated code for potential precision
|
|
1994
|
-
and/or performance issues.
|
|
1995
|
-
*/
|
|
1996
|
-
Ti cur = *(i_ptr + i * iw + j);
|
|
1997
|
-
#else
|
|
1998
|
-
Ti cur = i_ptr[i * iw + j];
|
|
1999
|
-
#endif
|
|
2000
|
-
switch (op) {
|
|
2001
|
-
case GGML_OP_POOL_AVG: res += (cur / (kh * kw)); break;
|
|
2002
|
-
case GGML_OP_POOL_MAX: res = sycl::max(res, (To)cur); break;
|
|
2003
|
-
default:
|
|
2004
|
-
res = (To) sycl::nan(uint32_t(0));
|
|
2005
|
-
break;
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
}
|
|
2009
|
-
o_ptr[cur_oh * ow + cur_ow] = res;
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
2042
|
static void ggml_mul_mat_p021_f16_f32_sycl(const void *vx, const float *y,
|
|
2014
2043
|
float *dst, const int ncols_x,
|
|
2015
2044
|
const int nrows_x,
|
|
@@ -2087,11 +2116,148 @@ static int next_power_of_2(int x) {
|
|
|
2087
2116
|
return n;
|
|
2088
2117
|
}
|
|
2089
2118
|
|
|
2119
|
+
static void init_argsort_indices_padded(
|
|
2120
|
+
int * idx,
|
|
2121
|
+
const int nrows,
|
|
2122
|
+
const int ncols_pad,
|
|
2123
|
+
const sycl::nd_item<1> & item_ct1) {
|
|
2124
|
+
const size_t gid = item_ct1.get_local_range(0) * item_ct1.get_group(0) + item_ct1.get_local_id(0);
|
|
2125
|
+
const size_t total = (size_t) nrows * (size_t) ncols_pad;
|
|
2126
|
+
|
|
2127
|
+
if (gid >= total) {
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
idx[gid] = (int) (gid % (size_t) ncols_pad);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
template <ggml_sort_order order>
|
|
2135
|
+
static void argsort_f32_i32_global_pass(const float * x,
|
|
2136
|
+
int * idx,
|
|
2137
|
+
const int ncols,
|
|
2138
|
+
const int nrows,
|
|
2139
|
+
const int ncols_pad,
|
|
2140
|
+
const int j,
|
|
2141
|
+
const int k,
|
|
2142
|
+
const sycl::nd_item<1> & item_ct1) {
|
|
2143
|
+
const size_t gid = item_ct1.get_local_range(0) * item_ct1.get_group(0) + item_ct1.get_local_id(0);
|
|
2144
|
+
const size_t total = (size_t) nrows * (size_t) ncols_pad;
|
|
2145
|
+
|
|
2146
|
+
if (gid >= total) {
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
const int row = (int) (gid / (size_t) ncols_pad);
|
|
2151
|
+
const int col = (int) (gid % (size_t) ncols_pad);
|
|
2152
|
+
const int ixj = col ^ j;
|
|
2153
|
+
|
|
2154
|
+
if (ixj <= col || ixj >= ncols_pad) {
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
const size_t base = (size_t) row * (size_t) ncols_pad;
|
|
2159
|
+
const size_t pos_a = base + (size_t) col;
|
|
2160
|
+
const size_t pos_b = base + (size_t) ixj;
|
|
2161
|
+
|
|
2162
|
+
const int a = idx[pos_a];
|
|
2163
|
+
const int b = idx[pos_b];
|
|
2164
|
+
|
|
2165
|
+
bool do_swap = false;
|
|
2166
|
+
|
|
2167
|
+
if ((col & k) == 0) {
|
|
2168
|
+
if (a >= ncols ||
|
|
2169
|
+
(b < ncols &&
|
|
2170
|
+
(order == GGML_SORT_ORDER_ASC ?
|
|
2171
|
+
x[(size_t) row * (size_t) ncols + (size_t) a] > x[(size_t) row * (size_t) ncols + (size_t) b] :
|
|
2172
|
+
x[(size_t) row * (size_t) ncols + (size_t) a] < x[(size_t) row * (size_t) ncols + (size_t) b]))) {
|
|
2173
|
+
do_swap = true;
|
|
2174
|
+
}
|
|
2175
|
+
} else {
|
|
2176
|
+
if (b >= ncols ||
|
|
2177
|
+
(a < ncols &&
|
|
2178
|
+
(order == GGML_SORT_ORDER_ASC ?
|
|
2179
|
+
x[(size_t) row * (size_t) ncols + (size_t) a] < x[(size_t) row * (size_t) ncols + (size_t) b] :
|
|
2180
|
+
x[(size_t) row * (size_t) ncols + (size_t) a] > x[(size_t) row * (size_t) ncols + (size_t) b]))) {
|
|
2181
|
+
do_swap = true;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
if (do_swap) {
|
|
2186
|
+
idx[pos_a] = b;
|
|
2187
|
+
idx[pos_b] = a;
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
static void copy_argsort_indices_unpadded(const int * idx_padded,
|
|
2192
|
+
int * dst,
|
|
2193
|
+
const int nrows,
|
|
2194
|
+
const int ncols,
|
|
2195
|
+
const int ncols_pad,
|
|
2196
|
+
const sycl::nd_item<1> & item_ct1) {
|
|
2197
|
+
const size_t gid = item_ct1.get_local_range(0) * item_ct1.get_group(0) + item_ct1.get_local_id(0);
|
|
2198
|
+
const size_t total = (size_t) nrows * (size_t) ncols;
|
|
2199
|
+
|
|
2200
|
+
if (gid >= total) {
|
|
2201
|
+
return;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
const int row = (int) (gid / (size_t) ncols);
|
|
2205
|
+
const int col = (int) (gid % (size_t) ncols);
|
|
2206
|
+
|
|
2207
|
+
dst[(size_t) row * (size_t) ncols + (size_t) col] = idx_padded[(size_t) row * (size_t) ncols_pad + (size_t) col];
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2090
2210
|
static void argsort_f32_i32_sycl(const float *x, int *dst, const int ncols,
|
|
2091
2211
|
const int nrows, ggml_sort_order order,
|
|
2092
|
-
queue_ptr stream, int device) {
|
|
2212
|
+
queue_ptr stream, int device, ggml_sycl_pool & pool) {
|
|
2093
2213
|
// bitonic sort requires ncols to be power of 2
|
|
2094
2214
|
const int ncols_pad = next_power_of_2(ncols);
|
|
2215
|
+
const size_t shared_mem = (size_t) ncols_pad * sizeof(int);
|
|
2216
|
+
const size_t smpbo = ggml_sycl_info().devices[device].smpbo;
|
|
2217
|
+
|
|
2218
|
+
if (shared_mem > smpbo) {
|
|
2219
|
+
ggml_sycl_pool_alloc<int> idx_padded_alloc(pool, (size_t) nrows * (size_t) ncols_pad);
|
|
2220
|
+
int * idx_padded = idx_padded_alloc.get();
|
|
2221
|
+
|
|
2222
|
+
constexpr size_t block_size = 256;
|
|
2223
|
+
const size_t total_padded = (size_t) nrows * (size_t) ncols_pad;
|
|
2224
|
+
const size_t nblocks_padded = (total_padded + block_size - 1) / block_size;
|
|
2225
|
+
|
|
2226
|
+
stream->parallel_for(
|
|
2227
|
+
sycl::nd_range<1>(sycl::range<1>(nblocks_padded * block_size), sycl::range<1>(block_size)),
|
|
2228
|
+
[=](sycl::nd_item<1> item_ct1) { init_argsort_indices_padded(idx_padded, nrows, ncols_pad, item_ct1); });
|
|
2229
|
+
|
|
2230
|
+
for (int k = 2; k <= ncols_pad; k *= 2) {
|
|
2231
|
+
for (int j = k / 2; j > 0; j /= 2) {
|
|
2232
|
+
if (order == GGML_SORT_ORDER_ASC) {
|
|
2233
|
+
stream->parallel_for(
|
|
2234
|
+
sycl::nd_range<1>(sycl::range<1>(nblocks_padded * block_size), sycl::range<1>(block_size)),
|
|
2235
|
+
[=](sycl::nd_item<1> item_ct1) {
|
|
2236
|
+
argsort_f32_i32_global_pass<GGML_SORT_ORDER_ASC>(x, idx_padded, ncols, nrows, ncols_pad, j,
|
|
2237
|
+
k, item_ct1);
|
|
2238
|
+
});
|
|
2239
|
+
} else if (order == GGML_SORT_ORDER_DESC) {
|
|
2240
|
+
stream->parallel_for(
|
|
2241
|
+
sycl::nd_range<1>(sycl::range<1>(nblocks_padded * block_size), sycl::range<1>(block_size)),
|
|
2242
|
+
[=](sycl::nd_item<1> item_ct1) {
|
|
2243
|
+
argsort_f32_i32_global_pass<GGML_SORT_ORDER_DESC>(x, idx_padded, ncols, nrows, ncols_pad, j,
|
|
2244
|
+
k, item_ct1);
|
|
2245
|
+
});
|
|
2246
|
+
} else {
|
|
2247
|
+
GGML_ABORT("invalid sort order");
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
const size_t total = (size_t) nrows * (size_t) ncols;
|
|
2253
|
+
const size_t nblocks = (total + block_size - 1) / block_size;
|
|
2254
|
+
stream->parallel_for(sycl::nd_range<1>(sycl::range<1>(nblocks * block_size), sycl::range<1>(block_size)),
|
|
2255
|
+
[=](sycl::nd_item<1> item_ct1) {
|
|
2256
|
+
copy_argsort_indices_unpadded(idx_padded, dst, nrows, ncols, ncols_pad, item_ct1);
|
|
2257
|
+
});
|
|
2258
|
+
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2095
2261
|
|
|
2096
2262
|
int nth = 1;
|
|
2097
2263
|
int max_block_size = ggml_sycl_info().max_work_group_sizes[device];
|
|
@@ -2104,8 +2270,6 @@ static void argsort_f32_i32_sycl(const float *x, int *dst, const int ncols,
|
|
|
2104
2270
|
|
|
2105
2271
|
const sycl::range<3> block_dims(1, 1, nth);
|
|
2106
2272
|
const sycl::range<3> block_nums(1, nrows, 1);
|
|
2107
|
-
const size_t shared_mem = ncols_pad * sizeof(int);
|
|
2108
|
-
GGML_ASSERT(shared_mem<=ggml_sycl_info().devices[device].smpbo);
|
|
2109
2273
|
|
|
2110
2274
|
if (order == GGML_SORT_ORDER_ASC) {
|
|
2111
2275
|
stream->submit([&](sycl::handler &cgh) {
|
|
@@ -2428,7 +2592,7 @@ inline void ggml_sycl_op_mul_mat_sycl(
|
|
|
2428
2592
|
|
|
2429
2593
|
#if GGML_SYCL_DNNL && defined(GGML_SYCL_HAS_BF16)
|
|
2430
2594
|
// Fast path for bf16 src0
|
|
2431
|
-
if (src0->type == GGML_TYPE_BF16 &&
|
|
2595
|
+
if (src0->type == GGML_TYPE_BF16 && g_ggml_sycl_enable_dnn && ggml_is_contiguous(src0) &&
|
|
2432
2596
|
row_diff == src0->ne[1]) {
|
|
2433
2597
|
using bf16_t = sycl::ext::oneapi::bfloat16;
|
|
2434
2598
|
ggml_sycl_pool_alloc<bf16_t> src1_as_bf16(ctx.pool(), src1_ncols*ne10);
|
|
@@ -2481,7 +2645,7 @@ inline void ggml_sycl_op_mul_mat_sycl(
|
|
|
2481
2645
|
: src1_as_f16.get();
|
|
2482
2646
|
|
|
2483
2647
|
#if GGML_SYCL_DNNL
|
|
2484
|
-
if (
|
|
2648
|
+
if (g_ggml_sycl_enable_dnn) {
|
|
2485
2649
|
DnnlGemmWrapper::row_gemm(ctx,row_diff, src1_ncols , ne10, src0_ptr,
|
|
2486
2650
|
DnnlGemmWrapper::to_dt<sycl::half>(), src1_ptr, DnnlGemmWrapper::to_dt<sycl::half>(),
|
|
2487
2651
|
dst_dd_i, DnnlGemmWrapper::to_dt<float>(), stream);
|
|
@@ -2531,7 +2695,7 @@ inline void ggml_sycl_op_mul_mat_sycl(
|
|
|
2531
2695
|
const int64_t gemm_flops = (int64_t)row_diff * src1_ncols * ne10;
|
|
2532
2696
|
const bool use_mkl_direct = gemm_flops < 256 * 256 * 256;
|
|
2533
2697
|
#if GGML_SYCL_DNNL
|
|
2534
|
-
if (
|
|
2698
|
+
if (g_ggml_sycl_enable_dnn && !use_mkl_direct) {
|
|
2535
2699
|
DnnlGemmWrapper::row_gemm(ctx, row_diff, src1_ncols, ne10, src0_ddf_i,
|
|
2536
2700
|
DnnlGemmWrapper::to_dt<float>(), src1_ddf1_i, DnnlGemmWrapper::to_dt<float>(),
|
|
2537
2701
|
dst_dd_i, DnnlGemmWrapper::to_dt<float>(), stream);
|
|
@@ -2558,45 +2722,6 @@ catch (sycl::exception const &exc) {
|
|
|
2558
2722
|
std::exit(1);
|
|
2559
2723
|
}
|
|
2560
2724
|
|
|
2561
|
-
static void ggml_sycl_op_pool2d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
2562
|
-
GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32);
|
|
2563
|
-
GGML_ASSERT( dst->type == GGML_TYPE_F32);
|
|
2564
|
-
dpct::queue_ptr main_stream = ctx.stream();
|
|
2565
|
-
SYCL_CHECK(ggml_sycl_set_device(ctx.device));
|
|
2566
|
-
const float * src0_dd = static_cast<const float *>(dst->src[0]->data);
|
|
2567
|
-
float * dst_dd = static_cast<float *>(dst->data);
|
|
2568
|
-
|
|
2569
|
-
const int32_t * opts = (const int32_t *)dst->op_params;
|
|
2570
|
-
enum ggml_op_pool op = static_cast<ggml_op_pool>(opts[0]);
|
|
2571
|
-
const int k0 = opts[1];
|
|
2572
|
-
const int k1 = opts[2];
|
|
2573
|
-
const int s0 = opts[3];
|
|
2574
|
-
const int s1 = opts[4];
|
|
2575
|
-
const int p0 = opts[5];
|
|
2576
|
-
const int p1 = opts[6];
|
|
2577
|
-
|
|
2578
|
-
const int64_t IH = dst->src[0]->ne[1];
|
|
2579
|
-
const int64_t IW = dst->src[0]->ne[0];
|
|
2580
|
-
|
|
2581
|
-
const int64_t N = dst->ne[3];
|
|
2582
|
-
const int64_t OC = dst->ne[2];
|
|
2583
|
-
const int64_t OH = dst->ne[1];
|
|
2584
|
-
const int64_t OW = dst->ne[0];
|
|
2585
|
-
|
|
2586
|
-
const int parallel_elements = N * OC * OH * OW;
|
|
2587
|
-
const int num_blocks = (parallel_elements + SYCL_POOL2D_BLOCK_SIZE - 1) / SYCL_POOL2D_BLOCK_SIZE;
|
|
2588
|
-
sycl::range<3> block_nums(1, 1, num_blocks);
|
|
2589
|
-
main_stream->parallel_for(
|
|
2590
|
-
sycl::nd_range<3>(block_nums *
|
|
2591
|
-
sycl::range<3>(1, 1, SYCL_IM2COL_BLOCK_SIZE),
|
|
2592
|
-
sycl::range<3>(1, 1, SYCL_IM2COL_BLOCK_SIZE)),
|
|
2593
|
-
[=](sycl::nd_item<3> item_ct1) {
|
|
2594
|
-
pool2d_nchw_kernel(IH, IW, OH, OW, k1, k0, s1, s0, p1, p0,
|
|
2595
|
-
parallel_elements, src0_dd, dst_dd, op,
|
|
2596
|
-
item_ct1);
|
|
2597
|
-
});
|
|
2598
|
-
}
|
|
2599
|
-
|
|
2600
2725
|
inline void ggml_sycl_op_sum(ggml_backend_sycl_context & ctx, ggml_tensor *dst) {
|
|
2601
2726
|
GGML_ASSERT(dst->src[0]->type == GGML_TYPE_F32);
|
|
2602
2727
|
GGML_ASSERT( dst->type == GGML_TYPE_F32);
|
|
@@ -2663,7 +2788,7 @@ inline void ggml_sycl_op_argsort(ggml_backend_sycl_context & ctx, ggml_tensor *
|
|
|
2663
2788
|
enum ggml_sort_order order = (enum ggml_sort_order) dst->op_params[0];
|
|
2664
2789
|
|
|
2665
2790
|
argsort_f32_i32_sycl(src0_dd, (int *)dst_dd, ncols, nrows, order,
|
|
2666
|
-
main_stream, ctx.device);
|
|
2791
|
+
main_stream, ctx.device, ctx.pool());
|
|
2667
2792
|
}
|
|
2668
2793
|
|
|
2669
2794
|
static void ggml_sycl_op_top_k(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
@@ -3056,7 +3181,7 @@ static void ggml_sycl_op_mul_mat(ggml_backend_sycl_context & ctx, const ggml_ten
|
|
|
3056
3181
|
src1_ddf_i_source += (i0 * ne11 + src1_col_0) * ne10;
|
|
3057
3182
|
|
|
3058
3183
|
SYCL_CHECK(
|
|
3059
|
-
CHECK_TRY_ERROR(dev2dev_memcpy(*stream, *main_stream, src1_ddf_i, src1_ddf_i_source,
|
|
3184
|
+
CHECK_TRY_ERROR(dev2dev_memcpy(i, *stream, ctx.device, *main_stream, src1_ddf_i, src1_ddf_i_source,
|
|
3060
3185
|
src1_ncols * ne10 * sizeof(float))));
|
|
3061
3186
|
}
|
|
3062
3187
|
}
|
|
@@ -3390,7 +3515,7 @@ static void ggml_sycl_mul_mat_batched_sycl(ggml_backend_sycl_context & ctx, cons
|
|
|
3390
3515
|
const int64_t r3 = ne13 / ne03;
|
|
3391
3516
|
|
|
3392
3517
|
#if GGML_SYCL_DNNL
|
|
3393
|
-
if (
|
|
3518
|
+
if (g_ggml_sycl_enable_dnn) {
|
|
3394
3519
|
int64_t str_a0 = nb00 / type_size_src0;
|
|
3395
3520
|
int64_t str_a1 = nb01 / type_size_src0;
|
|
3396
3521
|
int64_t str_a2 = nb02 / type_size_src0;
|
|
@@ -3546,6 +3671,7 @@ inline bool ggml_sycl_supports_mmq(enum ggml_type type) {
|
|
|
3546
3671
|
|
|
3547
3672
|
inline bool ggml_sycl_supports_reorder_mul_mat_sycl(enum ggml_type type) {
|
|
3548
3673
|
switch (type) {
|
|
3674
|
+
case GGML_TYPE_Q1_0:
|
|
3549
3675
|
case GGML_TYPE_Q4_0:
|
|
3550
3676
|
case GGML_TYPE_Q8_0:
|
|
3551
3677
|
return true;
|
|
@@ -3561,8 +3687,13 @@ inline bool ggml_sycl_supports_reorder_mul_mat_sycl(enum ggml_type type) {
|
|
|
3561
3687
|
|
|
3562
3688
|
inline bool ggml_sycl_supports_reorder_dmmv(enum ggml_type type) {
|
|
3563
3689
|
switch (type) {
|
|
3690
|
+
case GGML_TYPE_Q1_0:
|
|
3564
3691
|
case GGML_TYPE_Q4_0:
|
|
3565
3692
|
case GGML_TYPE_Q8_0:
|
|
3693
|
+
case GGML_TYPE_Q3_K:
|
|
3694
|
+
case GGML_TYPE_Q4_K:
|
|
3695
|
+
case GGML_TYPE_Q5_K:
|
|
3696
|
+
case GGML_TYPE_Q6_K:
|
|
3566
3697
|
return true;
|
|
3567
3698
|
default:
|
|
3568
3699
|
return false;
|
|
@@ -3571,6 +3702,7 @@ inline bool ggml_sycl_supports_reorder_dmmv(enum ggml_type type) {
|
|
|
3571
3702
|
|
|
3572
3703
|
inline bool ggml_sycl_supports_reorder_mmvq(enum ggml_type type) {
|
|
3573
3704
|
switch (type) {
|
|
3705
|
+
case GGML_TYPE_Q1_0:
|
|
3574
3706
|
case GGML_TYPE_Q4_0:
|
|
3575
3707
|
case GGML_TYPE_Q8_0:
|
|
3576
3708
|
case GGML_TYPE_Q3_K:
|
|
@@ -3585,6 +3717,7 @@ inline bool ggml_sycl_supports_reorder_mmvq(enum ggml_type type) {
|
|
|
3585
3717
|
|
|
3586
3718
|
static bool ggml_sycl_supports_dmmv(enum ggml_type type) {
|
|
3587
3719
|
switch (type) {
|
|
3720
|
+
case GGML_TYPE_Q1_0:
|
|
3588
3721
|
case GGML_TYPE_Q4_0:
|
|
3589
3722
|
case GGML_TYPE_Q4_1:
|
|
3590
3723
|
case GGML_TYPE_Q5_0:
|
|
@@ -3793,6 +3926,149 @@ static bool reorder_qw_q4_k(uint8_t * data_device, size_t size, size_t offset, d
|
|
|
3793
3926
|
return true;
|
|
3794
3927
|
}
|
|
3795
3928
|
|
|
3929
|
+
// Reorder each expert slice into a self-contained SoA layout.
|
|
3930
|
+
static bool reorder_qw_q4_k_moe(uint8_t * data_device, size_t expert_bytes, int64_t n_expert, dpct::queue_ptr stream) {
|
|
3931
|
+
GGML_ASSERT(expert_bytes % sizeof(block_q4_K) == 0);
|
|
3932
|
+
const int blocks_per_expert = (int) (expert_bytes / sizeof(block_q4_K));
|
|
3933
|
+
const size_t total_bytes = expert_bytes * (size_t) n_expert;
|
|
3934
|
+
|
|
3935
|
+
sycl_reorder_temp_buffer tmp(stream, total_bytes);
|
|
3936
|
+
if (!tmp) {
|
|
3937
|
+
GGML_LOG_WARN("%s: failed to allocate %zu bytes for reorder temp buffer, skipping reorder\n", __func__, total_bytes);
|
|
3938
|
+
return false;
|
|
3939
|
+
}
|
|
3940
|
+
uint8_t * tmp_buf = static_cast<uint8_t *>(tmp.ptr);
|
|
3941
|
+
|
|
3942
|
+
sycl::event copy_event;
|
|
3943
|
+
SYCL_CHECK(CHECK_TRY_ERROR(copy_event = stream->memcpy(tmp_buf, data_device, total_bytes)));
|
|
3944
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
3945
|
+
copy_event.wait();
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
const int total_blocks = blocks_per_expert * (int) n_expert;
|
|
3949
|
+
auto reorder_event = stream->parallel_for(total_blocks, [=](auto gb_) {
|
|
3950
|
+
const int gb = gb_;
|
|
3951
|
+
const int e = gb / blocks_per_expert;
|
|
3952
|
+
const int ib = gb % blocks_per_expert;
|
|
3953
|
+
const block_q4_K * x = (const block_q4_K *) (tmp_buf + (size_t) e * expert_bytes);
|
|
3954
|
+
uint8_t * base = data_device + (size_t) e * expert_bytes;
|
|
3955
|
+
|
|
3956
|
+
auto * qs_ptr = base;
|
|
3957
|
+
auto * scales_ptr = qs_ptr + QK_K / 2 * blocks_per_expert;
|
|
3958
|
+
auto * dm_ptr = (sycl::half2 *) (scales_ptr + K_SCALE_SIZE * blocks_per_expert);
|
|
3959
|
+
|
|
3960
|
+
for (int j = 0; j < QK_K / 2; ++j) {
|
|
3961
|
+
qs_ptr[ib * (QK_K / 2) + j] = x[ib].qs[j];
|
|
3962
|
+
}
|
|
3963
|
+
for (int j = 0; j < K_SCALE_SIZE; ++j) {
|
|
3964
|
+
scales_ptr[ib * K_SCALE_SIZE + j] = x[ib].scales[j];
|
|
3965
|
+
}
|
|
3966
|
+
dm_ptr[ib] = x[ib].dm;
|
|
3967
|
+
});
|
|
3968
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
3969
|
+
reorder_event.wait_and_throw();
|
|
3970
|
+
}
|
|
3971
|
+
return true;
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3974
|
+
// Reorder each Q5_K expert slice into [qs][qh][scales][dm].
|
|
3975
|
+
static bool reorder_qw_q5_k_moe(uint8_t * data_device, size_t expert_bytes, int64_t n_expert, dpct::queue_ptr stream) {
|
|
3976
|
+
GGML_ASSERT(expert_bytes % sizeof(block_q5_K) == 0);
|
|
3977
|
+
const int blocks_per_expert = (int) (expert_bytes / sizeof(block_q5_K));
|
|
3978
|
+
const size_t total_bytes = expert_bytes * (size_t) n_expert;
|
|
3979
|
+
|
|
3980
|
+
sycl_reorder_temp_buffer tmp(stream, total_bytes);
|
|
3981
|
+
if (!tmp) {
|
|
3982
|
+
GGML_LOG_WARN("%s: failed to allocate %zu bytes for reorder temp buffer, skipping reorder\n", __func__, total_bytes);
|
|
3983
|
+
return false;
|
|
3984
|
+
}
|
|
3985
|
+
uint8_t * tmp_buf = static_cast<uint8_t *>(tmp.ptr);
|
|
3986
|
+
|
|
3987
|
+
sycl::event copy_event;
|
|
3988
|
+
SYCL_CHECK(CHECK_TRY_ERROR(copy_event = stream->memcpy(tmp_buf, data_device, total_bytes)));
|
|
3989
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
3990
|
+
copy_event.wait();
|
|
3991
|
+
}
|
|
3992
|
+
|
|
3993
|
+
const int total_blocks = blocks_per_expert * (int) n_expert;
|
|
3994
|
+
auto reorder_event = stream->parallel_for(total_blocks, [=](auto gb_) {
|
|
3995
|
+
const int gb = gb_;
|
|
3996
|
+
const int e = gb / blocks_per_expert;
|
|
3997
|
+
const int ib = gb % blocks_per_expert;
|
|
3998
|
+
const block_q5_K * x = (const block_q5_K *) (tmp_buf + (size_t) e * expert_bytes);
|
|
3999
|
+
uint8_t * base = data_device + (size_t) e * expert_bytes;
|
|
4000
|
+
|
|
4001
|
+
auto * qs_ptr = base;
|
|
4002
|
+
auto * qh_ptr = qs_ptr + (QK_K / 2) * blocks_per_expert;
|
|
4003
|
+
auto * scales_ptr = qh_ptr + (QK_K / 8) * blocks_per_expert;
|
|
4004
|
+
auto * dm_ptr = (sycl::half2 *) (scales_ptr + K_SCALE_SIZE * blocks_per_expert);
|
|
4005
|
+
|
|
4006
|
+
for (int j = 0; j < QK_K / 2; ++j) {
|
|
4007
|
+
qs_ptr[ib * (QK_K / 2) + j] = x[ib].qs[j];
|
|
4008
|
+
}
|
|
4009
|
+
for (int j = 0; j < QK_K / 8; ++j) {
|
|
4010
|
+
qh_ptr[ib * (QK_K / 8) + j] = x[ib].qh[j];
|
|
4011
|
+
}
|
|
4012
|
+
for (int j = 0; j < K_SCALE_SIZE; ++j) {
|
|
4013
|
+
scales_ptr[ib * K_SCALE_SIZE + j] = x[ib].scales[j];
|
|
4014
|
+
}
|
|
4015
|
+
dm_ptr[ib] = x[ib].dm;
|
|
4016
|
+
});
|
|
4017
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
4018
|
+
reorder_event.wait_and_throw();
|
|
4019
|
+
}
|
|
4020
|
+
return true;
|
|
4021
|
+
}
|
|
4022
|
+
|
|
4023
|
+
// Reorder each Q6_K expert slice into [ql][qh][scales][d].
|
|
4024
|
+
static bool reorder_qw_q6_k_moe(uint8_t * data_device, size_t expert_bytes, int64_t n_expert, dpct::queue_ptr stream) {
|
|
4025
|
+
GGML_ASSERT(expert_bytes % sizeof(block_q6_K) == 0);
|
|
4026
|
+
const int blocks_per_expert = (int) (expert_bytes / sizeof(block_q6_K));
|
|
4027
|
+
const size_t total_bytes = expert_bytes * (size_t) n_expert;
|
|
4028
|
+
|
|
4029
|
+
sycl_reorder_temp_buffer tmp(stream, total_bytes);
|
|
4030
|
+
if (!tmp) {
|
|
4031
|
+
GGML_LOG_WARN("%s: failed to allocate %zu bytes for reorder temp buffer, skipping reorder\n", __func__, total_bytes);
|
|
4032
|
+
return false;
|
|
4033
|
+
}
|
|
4034
|
+
uint8_t * tmp_buf = static_cast<uint8_t *>(tmp.ptr);
|
|
4035
|
+
|
|
4036
|
+
sycl::event copy_event;
|
|
4037
|
+
SYCL_CHECK(CHECK_TRY_ERROR(copy_event = stream->memcpy(tmp_buf, data_device, total_bytes)));
|
|
4038
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
4039
|
+
copy_event.wait();
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4042
|
+
const int total_blocks = blocks_per_expert * (int) n_expert;
|
|
4043
|
+
auto reorder_event = stream->parallel_for(total_blocks, [=](auto gb_) {
|
|
4044
|
+
const int gb = gb_;
|
|
4045
|
+
const int e = gb / blocks_per_expert;
|
|
4046
|
+
const int ib = gb % blocks_per_expert;
|
|
4047
|
+
const block_q6_K * x = (const block_q6_K *) (tmp_buf + (size_t) e * expert_bytes);
|
|
4048
|
+
uint8_t * base = data_device + (size_t) e * expert_bytes;
|
|
4049
|
+
|
|
4050
|
+
auto * ql_ptr = base;
|
|
4051
|
+
auto * qh_ptr = ql_ptr + (QK_K / 2) * blocks_per_expert;
|
|
4052
|
+
auto * scales_ptr = qh_ptr + (QK_K / 4) * blocks_per_expert;
|
|
4053
|
+
auto * d_ptr = (sycl::half *) (scales_ptr + (QK_K / 16) * blocks_per_expert);
|
|
4054
|
+
|
|
4055
|
+
for (int j = 0; j < QK_K / 2; ++j) {
|
|
4056
|
+
ql_ptr[ib * (QK_K / 2) + j] = x[ib].ql[j];
|
|
4057
|
+
}
|
|
4058
|
+
for (int j = 0; j < QK_K / 4; ++j) {
|
|
4059
|
+
qh_ptr[ib * (QK_K / 4) + j] = x[ib].qh[j];
|
|
4060
|
+
}
|
|
4061
|
+
for (int j = 0; j < QK_K / 16; ++j) {
|
|
4062
|
+
scales_ptr[ib * (QK_K / 16) + j] = x[ib].scales[j];
|
|
4063
|
+
}
|
|
4064
|
+
d_ptr[ib] = x[ib].d;
|
|
4065
|
+
});
|
|
4066
|
+
if (!g_ggml_sycl_use_async_mem_op) {
|
|
4067
|
+
reorder_event.wait_and_throw();
|
|
4068
|
+
}
|
|
4069
|
+
return true;
|
|
4070
|
+
}
|
|
4071
|
+
|
|
3796
4072
|
static bool reorder_qw_q3_k(uint8_t * data_device, size_t size, size_t offset, dpct::queue_ptr stream) {
|
|
3797
4073
|
GGML_ASSERT(size % sizeof(block_q3_K) == 0);
|
|
3798
4074
|
GGML_ASSERT(offset % sizeof(block_q3_K) == 0);
|
|
@@ -3948,6 +4224,22 @@ static bool reorder_qw(const ggml_tensor * src0, dpct::queue_ptr stream) {
|
|
|
3948
4224
|
size_t nrows = src0->ne[1];
|
|
3949
4225
|
size_t size = ggml_nbytes(src0);
|
|
3950
4226
|
|
|
4227
|
+
// MoE expert weights are addressed per expert via nb[2], so each slice must
|
|
4228
|
+
// remain self-contained after reorder.
|
|
4229
|
+
if (src0->ne[2] > 1) {
|
|
4230
|
+
GGML_ASSERT((size_t) size == (size_t) src0->ne[2] * src0->nb[2]);
|
|
4231
|
+
switch (src0->type) {
|
|
4232
|
+
case GGML_TYPE_Q4_K:
|
|
4233
|
+
return reorder_qw_q4_k_moe(data_device, src0->nb[2], src0->ne[2], stream);
|
|
4234
|
+
case GGML_TYPE_Q5_K:
|
|
4235
|
+
return reorder_qw_q5_k_moe(data_device, src0->nb[2], src0->ne[2], stream);
|
|
4236
|
+
case GGML_TYPE_Q6_K:
|
|
4237
|
+
return reorder_qw_q6_k_moe(data_device, src0->nb[2], src0->ne[2], stream);
|
|
4238
|
+
default:
|
|
4239
|
+
return false;
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
|
|
3951
4243
|
switch (src0->type) {
|
|
3952
4244
|
case GGML_TYPE_Q4_0:
|
|
3953
4245
|
return reorder_qw_q4_0(data_device, ncols, nrows, size, 0, stream);
|
|
@@ -3962,18 +4254,17 @@ static bool reorder_qw(const ggml_tensor * src0, dpct::queue_ptr stream) {
|
|
|
3962
4254
|
case GGML_TYPE_Q6_K:
|
|
3963
4255
|
return reorder_qw_q6_k(data_device, size, 0, stream);
|
|
3964
4256
|
default:
|
|
3965
|
-
GGML_ABORT("reorder_qw() called with unsupported type");
|
|
3966
4257
|
return false;
|
|
3967
4258
|
}
|
|
3968
4259
|
}
|
|
3969
4260
|
|
|
3970
4261
|
static bool should_reorder_tensor(ggml_backend_sycl_context& ctx, const ggml_tensor * dst) {
|
|
3971
|
-
return
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
4262
|
+
return g_ggml_sycl_enable_optimize && //allow optimize, controlled by $GGML_SYCL_ENABLE_OPT
|
|
4263
|
+
ctx.opt_feature.reorder && //allow this device due to good perf, skip the devices with bad perf.
|
|
4264
|
+
dst->op == GGML_OP_MUL_MAT && //limit to some supported cases of Q4_0, to do for more cases.
|
|
4265
|
+
// ne[1] <= 8 so multi-column decode (spec / MTP verify) also bootstraps the reorder;
|
|
4266
|
+
// all reorderable types have a _switch_ncols kernel.
|
|
4267
|
+
dst->src[1]->ne[1] <= 8 && dst->src[1]->ne[2]==1 && dst->src[1]->ne[3]==1;
|
|
3977
4268
|
}
|
|
3978
4269
|
|
|
3979
4270
|
static void opt_for_reorder(ggml_backend_sycl_context * ctx, const ggml_tensor * src0, const ggml_tensor * /* src1 */,
|
|
@@ -4010,6 +4301,23 @@ static void opt_for_reorder(ggml_backend_sycl_context * ctx, const ggml_tensor *
|
|
|
4010
4301
|
}
|
|
4011
4302
|
}
|
|
4012
4303
|
|
|
4304
|
+
// Lazily reorder supported MoE expert weights once their fused path is used.
|
|
4305
|
+
static void opt_for_reorder_id(ggml_backend_sycl_context * ctx, const ggml_tensor * src0) {
|
|
4306
|
+
if (!g_ggml_sycl_enable_optimize || !ctx->opt_feature.reorder) {
|
|
4307
|
+
return;
|
|
4308
|
+
}
|
|
4309
|
+
if (src0->type != GGML_TYPE_Q4_K && src0->type != GGML_TYPE_Q5_K && src0->type != GGML_TYPE_Q6_K) {
|
|
4310
|
+
return;
|
|
4311
|
+
}
|
|
4312
|
+
ggml_tensor_extra_gpu * extra = static_cast<ggml_tensor_extra_gpu *>(src0->extra);
|
|
4313
|
+
if (!extra || extra->optimized_feature.reorder) {
|
|
4314
|
+
return;
|
|
4315
|
+
}
|
|
4316
|
+
if (reorder_qw(src0, ctx->stream())) {
|
|
4317
|
+
extra->optimized_feature.reorder = true;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
|
|
4013
4321
|
|
|
4014
4322
|
static bool can_use_dequantize_mul_mat_vec(const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
|
|
4015
4323
|
// The F16/BF16 qk=1 kernel iterates with stride 2*DMMV_X, requiring ne[0] to be
|
|
@@ -4115,11 +4423,6 @@ static void ggml_sycl_mul_mat(ggml_backend_sycl_context & ctx, const ggml_tensor
|
|
|
4115
4423
|
}
|
|
4116
4424
|
|
|
4117
4425
|
|
|
4118
|
-
struct mmid_row_mapping {
|
|
4119
|
-
int32_t i1;
|
|
4120
|
-
int32_t i2;
|
|
4121
|
-
};
|
|
4122
|
-
|
|
4123
4426
|
__dpct_inline__ static void k_copy_src1_to_contiguous(
|
|
4124
4427
|
const char *__restrict__ src1_original, char *__restrict__ src1_contiguous,
|
|
4125
4428
|
const mmid_row_mapping *__restrict__ row_mapping,
|
|
@@ -4175,11 +4478,6 @@ static bool ggml_sycl_mul_mat_id_mmvq_fused(
|
|
|
4175
4478
|
if (ne10 != src0->ne[0] || ne10 % QK8_1 != 0) return false;
|
|
4176
4479
|
if (!ggml_is_contiguous(src1)) return false;
|
|
4177
4480
|
|
|
4178
|
-
// Reorder layout not supported; fall back.
|
|
4179
|
-
const ggml_tensor_extra_gpu * src0_extra =
|
|
4180
|
-
static_cast<const ggml_tensor_extra_gpu *>(src0->extra);
|
|
4181
|
-
if (src0_extra && src0_extra->optimized_feature.reorder) return false;
|
|
4182
|
-
|
|
4183
4481
|
const int64_t n_ids_per_group = ids->ne[0];
|
|
4184
4482
|
if (ids->ne[1] != 1) return false;
|
|
4185
4483
|
if (ne11 != 1 && ne11 != n_ids_per_group) return false;
|
|
@@ -4189,16 +4487,37 @@ static bool ggml_sycl_mul_mat_id_mmvq_fused(
|
|
|
4189
4487
|
const int n_experts_used = (int) n_ids_per_group;
|
|
4190
4488
|
const int nrows = (int) src0->ne[1];
|
|
4191
4489
|
|
|
4490
|
+
// Lazily reorder the (Q4_K) expert weights into a per-expert SoA layout, then run the reorder
|
|
4491
|
+
// GEMV. Placed after the bail checks so a non-dispatchable op does not pay the reorder cost.
|
|
4492
|
+
opt_for_reorder_id(&ctx, src0);
|
|
4493
|
+
const ggml_tensor_extra_gpu * src0_extra =
|
|
4494
|
+
static_cast<const ggml_tensor_extra_gpu *>(src0->extra);
|
|
4495
|
+
const bool use_reorder = src0_extra && src0_extra->optimized_feature.reorder;
|
|
4496
|
+
|
|
4192
4497
|
ggml_sycl_pool_alloc<char> src1_q8_alloc(ctx.pool(),
|
|
4193
4498
|
(size_t) ne11 * src1_padded_cols * sizeof(block_q8_1) / QK8_1);
|
|
4194
4499
|
char * src1_ddq = src1_q8_alloc.get();
|
|
4195
|
-
|
|
4196
|
-
(
|
|
4197
|
-
|
|
4500
|
+
if (use_reorder) {
|
|
4501
|
+
quantize_row_q8_1_sycl<quantize_and_reorder_q8_1_soa>(
|
|
4502
|
+
(const float *) src1->data, src1_ddq, (int) ne10, (int) ne11,
|
|
4503
|
+
src1_padded_cols, stream);
|
|
4504
|
+
} else {
|
|
4505
|
+
quantize_row_q8_1_sycl<quantize_q8_1>(
|
|
4506
|
+
(const float *) src1->data, src1_ddq, (int) ne10, (int) ne11,
|
|
4507
|
+
src1_padded_cols, stream);
|
|
4508
|
+
}
|
|
4198
4509
|
|
|
4199
4510
|
const size_t bytes_per_qrow = (size_t) src1_padded_cols * sizeof(block_q8_1) / QK8_1;
|
|
4200
4511
|
const size_t src1_row_stride = (ne11 == 1) ? 0 : bytes_per_qrow;
|
|
4201
4512
|
|
|
4513
|
+
if (use_reorder) {
|
|
4514
|
+
return ggml_sycl_mul_mat_vec_q_id_reorder(
|
|
4515
|
+
src0->type, src0->data, src1_ddq, (const int32_t *) ids->data,
|
|
4516
|
+
(float *) dst->data, (int) ne10, nrows, n_experts_used,
|
|
4517
|
+
/*expert_weight_stride=*/ src0->nb[2],
|
|
4518
|
+
/*dst_row_stride=*/ dst->nb[1],
|
|
4519
|
+
src1_row_stride, stream);
|
|
4520
|
+
}
|
|
4202
4521
|
return ggml_sycl_mul_mat_vec_q_id(
|
|
4203
4522
|
src0->type, src0->data, src1_ddq, (const int32_t *) ids->data,
|
|
4204
4523
|
(float *) dst->data, (int) ne10, nrows, n_experts_used,
|
|
@@ -4274,6 +4593,8 @@ static void ggml_sycl_mul_mat_id(ggml_backend_sycl_context & ctx,
|
|
|
4274
4593
|
|
|
4275
4594
|
SYCL_CHECK(CHECK_TRY_ERROR(
|
|
4276
4595
|
stream->memcpy(ids_host.data(), ids_dev, ggml_nbytes(ids))));
|
|
4596
|
+
|
|
4597
|
+
// also ensures ctx.mmid_row_mapping_host is drained before we use it again
|
|
4277
4598
|
SYCL_CHECK(CHECK_TRY_ERROR(stream->wait()));
|
|
4278
4599
|
|
|
4279
4600
|
ggml_tensor src0_row = *src0;
|
|
@@ -4331,7 +4652,7 @@ static void ggml_sycl_mul_mat_id(ggml_backend_sycl_context & ctx,
|
|
|
4331
4652
|
// where each expert's slice starts and the previous ends (row indices, right-exclusive)
|
|
4332
4653
|
std::vector<int64_t> expert_row_offsets;
|
|
4333
4654
|
// the sources (slot/token pairs) of contiguous rows to guide k_copy_src1_to_contiguous
|
|
4334
|
-
std::vector<mmid_row_mapping> routed_row_src;
|
|
4655
|
+
std::vector<mmid_row_mapping> & routed_row_src = ctx.mmid_row_mapping_host;
|
|
4335
4656
|
|
|
4336
4657
|
mmid_counting_sort_rows(ids, ids_host.data(), n_ids, n_as, n_routed_rows,
|
|
4337
4658
|
expert_row_counts, expert_row_offsets, routed_row_src);
|
|
@@ -4435,6 +4756,11 @@ static void ggml_sycl_pool2d(ggml_backend_sycl_context & ctx, ggml_tensor * dst)
|
|
|
4435
4756
|
ggml_sycl_op_pool2d(ctx, dst);
|
|
4436
4757
|
}
|
|
4437
4758
|
|
|
4759
|
+
static void ggml_sycl_pool1d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
4760
|
+
scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1);
|
|
4761
|
+
ggml_sycl_op_pool1d(ctx, dst);
|
|
4762
|
+
}
|
|
4763
|
+
|
|
4438
4764
|
static void ggml_sycl_im2col(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
4439
4765
|
scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2);
|
|
4440
4766
|
ggml_sycl_op_im2col(ctx, dst);
|
|
@@ -4445,6 +4771,16 @@ static void ggml_sycl_im2col_3d(ggml_backend_sycl_context & ctx, ggml_tensor * d
|
|
|
4445
4771
|
ggml_sycl_op_im2col_3d(ctx, dst);
|
|
4446
4772
|
}
|
|
4447
4773
|
|
|
4774
|
+
static void ggml_sycl_col2im_1d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
4775
|
+
scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1);
|
|
4776
|
+
ggml_sycl_op_col2im_1d(ctx, dst);
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
static void ggml_sycl_conv_3d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
4780
|
+
scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2);
|
|
4781
|
+
ggml_sycl_op_conv_3d(ctx, dst);
|
|
4782
|
+
}
|
|
4783
|
+
|
|
4448
4784
|
static void ggml_sycl_sum(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
|
|
4449
4785
|
scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/1);
|
|
4450
4786
|
GGML_ASSERT(ggml_is_contiguous(dst->src[0]));
|
|
@@ -4508,9 +4844,21 @@ static bool ggml_sycl_compute_forward(ggml_backend_sycl_context & ctx, struct gg
|
|
|
4508
4844
|
case GGML_OP_ARGMAX:
|
|
4509
4845
|
ggml_sycl_argmax(ctx, dst);
|
|
4510
4846
|
break;
|
|
4847
|
+
case GGML_OP_CONV_2D:
|
|
4848
|
+
ggml_sycl_op_conv2d(ctx, dst);
|
|
4849
|
+
break;
|
|
4850
|
+
case GGML_OP_CONV_2D_DW:
|
|
4851
|
+
ggml_sycl_op_conv2d_dw(ctx, dst);
|
|
4852
|
+
break;
|
|
4853
|
+
case GGML_OP_CONV_3D:
|
|
4854
|
+
ggml_sycl_conv_3d(ctx, dst);
|
|
4855
|
+
break;
|
|
4511
4856
|
case GGML_OP_CONV_TRANSPOSE_1D:
|
|
4512
4857
|
ggml_sycl_op_conv_transpose_1d(ctx, dst);
|
|
4513
4858
|
break;
|
|
4859
|
+
case GGML_OP_CONV_TRANSPOSE_2D:
|
|
4860
|
+
ggml_sycl_op_conv2d_transpose(ctx, dst);
|
|
4861
|
+
break;
|
|
4514
4862
|
case GGML_OP_REPEAT:
|
|
4515
4863
|
ggml_sycl_repeat(ctx, dst);
|
|
4516
4864
|
break;
|
|
@@ -4592,6 +4940,9 @@ static bool ggml_sycl_compute_forward(ggml_backend_sycl_context & ctx, struct gg
|
|
|
4592
4940
|
case GGML_UNARY_OP_EXP:
|
|
4593
4941
|
ggml_sycl_exp(ctx, dst);
|
|
4594
4942
|
break;
|
|
4943
|
+
case GGML_UNARY_OP_EXPM1:
|
|
4944
|
+
ggml_sycl_expm1(ctx, dst);
|
|
4945
|
+
break;
|
|
4595
4946
|
case GGML_UNARY_OP_SOFTPLUS:
|
|
4596
4947
|
ggml_sycl_softplus(ctx, dst);
|
|
4597
4948
|
break;
|
|
@@ -4733,6 +5084,12 @@ static bool ggml_sycl_compute_forward(ggml_backend_sycl_context & ctx, struct gg
|
|
|
4733
5084
|
case GGML_OP_SOFT_MAX_BACK:
|
|
4734
5085
|
ggml_sycl_op_soft_max_back(ctx, dst);
|
|
4735
5086
|
break;
|
|
5087
|
+
case GGML_OP_CROSS_ENTROPY_LOSS:
|
|
5088
|
+
ggml_sycl_cross_entropy_loss(ctx, dst);
|
|
5089
|
+
break;
|
|
5090
|
+
case GGML_OP_CROSS_ENTROPY_LOSS_BACK:
|
|
5091
|
+
ggml_sycl_cross_entropy_loss_back(ctx, dst);
|
|
5092
|
+
break;
|
|
4736
5093
|
case GGML_OP_ROPE:
|
|
4737
5094
|
ggml_sycl_rope(ctx, dst);
|
|
4738
5095
|
break;
|
|
@@ -4745,9 +5102,15 @@ static bool ggml_sycl_compute_forward(ggml_backend_sycl_context & ctx, struct gg
|
|
|
4745
5102
|
case GGML_OP_IM2COL_3D:
|
|
4746
5103
|
ggml_sycl_im2col_3d(ctx, dst);
|
|
4747
5104
|
break;
|
|
5105
|
+
case GGML_OP_COL2IM_1D:
|
|
5106
|
+
ggml_sycl_col2im_1d(ctx, dst);
|
|
5107
|
+
break;
|
|
4748
5108
|
case GGML_OP_POOL_2D:
|
|
4749
5109
|
ggml_sycl_pool2d(ctx, dst);
|
|
4750
5110
|
break;
|
|
5111
|
+
case GGML_OP_POOL_1D:
|
|
5112
|
+
ggml_sycl_pool1d(ctx, dst);
|
|
5113
|
+
break;
|
|
4751
5114
|
case GGML_OP_SUM:
|
|
4752
5115
|
ggml_sycl_sum(ctx, dst);
|
|
4753
5116
|
break;
|
|
@@ -5022,7 +5385,10 @@ static ggml_status ggml_backend_sycl_graph_compute(ggml_backend_t backend, ggml_
|
|
|
5022
5385
|
auto * sycl_ctx = static_cast<ggml_backend_sycl_context *>(backend->context);
|
|
5023
5386
|
|
|
5024
5387
|
#ifdef GGML_SYCL_GRAPH
|
|
5025
|
-
bool use_sycl_graph =
|
|
5388
|
+
bool use_sycl_graph = false;
|
|
5389
|
+
if (g_ggml_sycl_enable_graph) {
|
|
5390
|
+
use_sycl_graph = check_graph_compatibility(cgraph);
|
|
5391
|
+
}
|
|
5026
5392
|
if (use_sycl_graph) {
|
|
5027
5393
|
const bool graph_support = dpct::get_device(sycl_ctx->device).has(sycl::aspect::ext_oneapi_limited_graph);
|
|
5028
5394
|
if (!graph_support) {
|
|
@@ -5208,7 +5574,7 @@ static ggml_backend_buffer_t ggml_backend_sycl_device_buffer_from_host_ptr(ggml_
|
|
|
5208
5574
|
return nullptr;
|
|
5209
5575
|
}
|
|
5210
5576
|
|
|
5211
|
-
static bool
|
|
5577
|
+
static bool do_ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const ggml_tensor * op) {
|
|
5212
5578
|
ggml_backend_sycl_device_context *sycl_ctx =
|
|
5213
5579
|
(ggml_backend_sycl_device_context *)dev->context;
|
|
5214
5580
|
int device = sycl_ctx->device;
|
|
@@ -5222,6 +5588,10 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5222
5588
|
}
|
|
5223
5589
|
return false;
|
|
5224
5590
|
}
|
|
5591
|
+
case GGML_OP_CONV_2D:
|
|
5592
|
+
case GGML_OP_CONV_2D_DW:
|
|
5593
|
+
case GGML_OP_CONV_TRANSPOSE_2D:
|
|
5594
|
+
return true;
|
|
5225
5595
|
case GGML_OP_UNARY:
|
|
5226
5596
|
switch (ggml_get_unary_op(op)) {
|
|
5227
5597
|
case GGML_UNARY_OP_SGN:
|
|
@@ -5238,6 +5608,7 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5238
5608
|
case GGML_UNARY_OP_GELU_QUICK:
|
|
5239
5609
|
case GGML_UNARY_OP_GELU_ERF:
|
|
5240
5610
|
case GGML_UNARY_OP_EXP:
|
|
5611
|
+
case GGML_UNARY_OP_EXPM1:
|
|
5241
5612
|
case GGML_UNARY_OP_SOFTPLUS:
|
|
5242
5613
|
case GGML_UNARY_OP_ELU:
|
|
5243
5614
|
case GGML_UNARY_OP_CEIL:
|
|
@@ -5245,11 +5616,7 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5245
5616
|
case GGML_UNARY_OP_FLOOR:
|
|
5246
5617
|
case GGML_UNARY_OP_ROUND:
|
|
5247
5618
|
case GGML_UNARY_OP_TRUNC:
|
|
5248
|
-
|
|
5249
|
-
return ggml_is_contiguous(op->src[0]) && (op->type == op->src[0]->type);
|
|
5250
|
-
#else
|
|
5251
|
-
return ggml_is_contiguous(op->src[0]) && (op->src[0]->type == GGML_TYPE_F32 && op->type == GGML_TYPE_F32) && (op->type == op->src[0]->type);
|
|
5252
|
-
#endif
|
|
5619
|
+
return true;
|
|
5253
5620
|
default:
|
|
5254
5621
|
return false;
|
|
5255
5622
|
}
|
|
@@ -5272,19 +5639,12 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5272
5639
|
struct ggml_tensor * a = op->src[0];
|
|
5273
5640
|
struct ggml_tensor * b = op->src[1];
|
|
5274
5641
|
|
|
5275
|
-
// disable Q1_0 until implementation
|
|
5276
|
-
if (a->type == GGML_TYPE_Q1_0 || b->type == GGML_TYPE_Q1_0) {
|
|
5277
|
-
return false;
|
|
5278
|
-
}
|
|
5279
|
-
|
|
5280
5642
|
if (a->ne[3] != b->ne[3]) {
|
|
5281
5643
|
return false;
|
|
5282
5644
|
}
|
|
5283
5645
|
|
|
5284
5646
|
ggml_type src0_type = op->src[0]->type;
|
|
5285
5647
|
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
5648
|
// TODO: The configuration below needs more work to be supported with oneDNN
|
|
5289
5649
|
if (ggml_is_permuted(a) && !ggml_is_contiguous(a) &&
|
|
5290
5650
|
a->ne[2] > 1 && a->ne[3] > 1 && src0_type == GGML_TYPE_F16) {
|
|
@@ -5299,7 +5659,11 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5299
5659
|
return true;
|
|
5300
5660
|
}
|
|
5301
5661
|
case GGML_OP_OUT_PROD:
|
|
5302
|
-
return op->type == GGML_TYPE_F32 &&
|
|
5662
|
+
return op->type == GGML_TYPE_F32 &&
|
|
5663
|
+
(op->src[0]->type == GGML_TYPE_F32 ||
|
|
5664
|
+
(op->src[0]->type == GGML_TYPE_Q1_0 && op->src[0]->ne[2] == op->src[1]->ne[2] &&
|
|
5665
|
+
op->src[0]->ne[3] == op->src[1]->ne[3])) &&
|
|
5666
|
+
op->src[1]->type == GGML_TYPE_F32;
|
|
5303
5667
|
case GGML_OP_GET_ROWS:
|
|
5304
5668
|
{
|
|
5305
5669
|
switch (op->src[0]->type) {
|
|
@@ -5342,80 +5706,114 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5342
5706
|
|
|
5343
5707
|
case GGML_OP_SET_ROWS:
|
|
5344
5708
|
{
|
|
5345
|
-
|
|
5709
|
+
|
|
5710
|
+
auto res = ((op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16 || op->type == GGML_TYPE_BF16 ||
|
|
5346
5711
|
op->type == GGML_TYPE_Q8_0 || op->type == GGML_TYPE_Q5_1 || op->type == GGML_TYPE_Q5_0 ||
|
|
5347
|
-
op->type ==
|
|
5712
|
+
op->type == GGML_TYPE_Q1_0 ||
|
|
5713
|
+
op->type == GGML_TYPE_Q4_1 || op->type == GGML_TYPE_Q4_0 || op->type == GGML_TYPE_IQ4_NL ||
|
|
5714
|
+
op->type == GGML_TYPE_MXFP4 || op->type == GGML_TYPE_NVFP4) &&
|
|
5715
|
+
op->src[0]->type == GGML_TYPE_F32 &&
|
|
5348
5716
|
(op->src[1]->type == GGML_TYPE_I64 || op->src[1]->type == GGML_TYPE_I32));
|
|
5717
|
+
return res;
|
|
5349
5718
|
}
|
|
5350
5719
|
break;
|
|
5351
5720
|
case GGML_OP_CPY:
|
|
5352
5721
|
{
|
|
5353
5722
|
ggml_type src0_type = op->src[0]->type;
|
|
5354
5723
|
ggml_type src1_type = op->src[1]->type;
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
}
|
|
5373
|
-
if (src0_type == GGML_TYPE_F16 && src1_type == GGML_TYPE_F16) {
|
|
5374
|
-
return true;
|
|
5375
|
-
}
|
|
5376
|
-
if (src0_type == GGML_TYPE_F16 && src1_type == GGML_TYPE_F32) {
|
|
5377
|
-
return true;
|
|
5378
|
-
}
|
|
5379
|
-
if (src0_type == GGML_TYPE_Q8_0 && src1_type == GGML_TYPE_F32) {
|
|
5380
|
-
return true;
|
|
5381
|
-
}
|
|
5382
|
-
if (src0_type == GGML_TYPE_Q4_0 && src1_type == GGML_TYPE_F32) {
|
|
5383
|
-
return true;
|
|
5384
|
-
}
|
|
5385
|
-
if (src0_type == GGML_TYPE_Q4_1 && src1_type == GGML_TYPE_F32) {
|
|
5386
|
-
return true;
|
|
5387
|
-
}
|
|
5388
|
-
if (src0_type == GGML_TYPE_F32 && src1_type == GGML_TYPE_Q5_0) {
|
|
5389
|
-
return true;
|
|
5390
|
-
}
|
|
5391
|
-
if (src0_type == GGML_TYPE_Q5_0 && src1_type == GGML_TYPE_F32) {
|
|
5392
|
-
return true;
|
|
5393
|
-
}
|
|
5394
|
-
if (src0_type == GGML_TYPE_F32 && src1_type == GGML_TYPE_Q5_1) {
|
|
5395
|
-
return true;
|
|
5396
|
-
}
|
|
5397
|
-
if (src0_type == GGML_TYPE_Q5_1 && src1_type == GGML_TYPE_F32) {
|
|
5398
|
-
return true;
|
|
5399
|
-
}
|
|
5400
|
-
if (src0_type == GGML_TYPE_F32 && src1_type == GGML_TYPE_IQ4_NL) {
|
|
5401
|
-
return true;
|
|
5402
|
-
}
|
|
5403
|
-
if(src0_type == GGML_TYPE_Q8_0 && src1_type == GGML_TYPE_Q8_0) {
|
|
5404
|
-
return true;
|
|
5724
|
+
|
|
5725
|
+
if (src0_type == GGML_TYPE_F16) {
|
|
5726
|
+
if (src1_type == GGML_TYPE_Q2_K ||
|
|
5727
|
+
src1_type == GGML_TYPE_Q3_K ||
|
|
5728
|
+
src1_type == GGML_TYPE_Q4_K ||
|
|
5729
|
+
src1_type == GGML_TYPE_Q5_K ||
|
|
5730
|
+
src1_type == GGML_TYPE_Q6_K ||
|
|
5731
|
+
src1_type == GGML_TYPE_IQ2_XXS ||
|
|
5732
|
+
src1_type == GGML_TYPE_IQ2_XS ||
|
|
5733
|
+
src1_type == GGML_TYPE_IQ2_S ||
|
|
5734
|
+
src1_type == GGML_TYPE_IQ3_XXS ||
|
|
5735
|
+
src1_type == GGML_TYPE_IQ1_S ||
|
|
5736
|
+
src1_type == GGML_TYPE_IQ1_M ||
|
|
5737
|
+
src1_type == GGML_TYPE_IQ3_S ||
|
|
5738
|
+
src1_type == GGML_TYPE_IQ4_XS) {
|
|
5739
|
+
return false;
|
|
5740
|
+
}
|
|
5405
5741
|
}
|
|
5406
|
-
|
|
5407
|
-
|
|
5742
|
+
|
|
5743
|
+
if (src0_type == GGML_TYPE_BF16) {
|
|
5744
|
+
if (src1_type == GGML_TYPE_Q4_0 || //big error in ut
|
|
5745
|
+
src1_type == GGML_TYPE_Q4_1 || //big error in ut
|
|
5746
|
+
src1_type == GGML_TYPE_Q8_0 || //big error in ut
|
|
5747
|
+
src1_type == GGML_TYPE_Q2_K ||
|
|
5748
|
+
src1_type == GGML_TYPE_Q3_K ||
|
|
5749
|
+
src1_type == GGML_TYPE_Q4_K ||
|
|
5750
|
+
src1_type == GGML_TYPE_Q5_K ||
|
|
5751
|
+
src1_type == GGML_TYPE_Q6_K ||
|
|
5752
|
+
src1_type == GGML_TYPE_IQ2_XXS ||
|
|
5753
|
+
src1_type == GGML_TYPE_IQ2_XS ||
|
|
5754
|
+
src1_type == GGML_TYPE_IQ2_S ||
|
|
5755
|
+
src1_type == GGML_TYPE_IQ3_XXS ||
|
|
5756
|
+
src1_type == GGML_TYPE_IQ1_S ||
|
|
5757
|
+
src1_type == GGML_TYPE_IQ1_M ||
|
|
5758
|
+
src1_type == GGML_TYPE_IQ3_S ||
|
|
5759
|
+
src1_type == GGML_TYPE_IQ4_XS) {
|
|
5760
|
+
return false;
|
|
5761
|
+
}
|
|
5408
5762
|
}
|
|
5409
|
-
|
|
5410
|
-
|
|
5763
|
+
|
|
5764
|
+
if (src0_type == GGML_TYPE_F32) {
|
|
5765
|
+
if (src1_type == GGML_TYPE_Q2_K ||
|
|
5766
|
+
src1_type == GGML_TYPE_Q3_K ||
|
|
5767
|
+
src1_type == GGML_TYPE_Q4_K ||
|
|
5768
|
+
src1_type == GGML_TYPE_Q5_K ||
|
|
5769
|
+
src1_type == GGML_TYPE_Q6_K ||
|
|
5770
|
+
src1_type == GGML_TYPE_IQ2_XXS ||
|
|
5771
|
+
src1_type == GGML_TYPE_IQ2_XS ||
|
|
5772
|
+
src1_type == GGML_TYPE_IQ2_S ||
|
|
5773
|
+
src1_type == GGML_TYPE_IQ3_XXS ||
|
|
5774
|
+
src1_type == GGML_TYPE_IQ1_S ||
|
|
5775
|
+
src1_type == GGML_TYPE_IQ1_M ||
|
|
5776
|
+
src1_type == GGML_TYPE_IQ3_S ||
|
|
5777
|
+
src1_type == GGML_TYPE_IQ4_XS) {
|
|
5778
|
+
return false;
|
|
5779
|
+
}
|
|
5411
5780
|
}
|
|
5412
|
-
|
|
5413
|
-
|
|
5781
|
+
|
|
5782
|
+
if (src1_type == GGML_TYPE_F32) {
|
|
5783
|
+
if (src0_type == GGML_TYPE_Q1_0 ||
|
|
5784
|
+
src0_type == GGML_TYPE_NVFP4 ||
|
|
5785
|
+
src0_type == GGML_TYPE_Q2_K ||
|
|
5786
|
+
src0_type == GGML_TYPE_Q3_K ||
|
|
5787
|
+
src0_type == GGML_TYPE_Q4_K ||
|
|
5788
|
+
src0_type == GGML_TYPE_Q5_K ||
|
|
5789
|
+
src0_type == GGML_TYPE_Q6_K ||
|
|
5790
|
+
src0_type == GGML_TYPE_IQ2_XXS ||
|
|
5791
|
+
src0_type == GGML_TYPE_IQ2_XS ||
|
|
5792
|
+
src0_type == GGML_TYPE_IQ2_S ||
|
|
5793
|
+
src0_type == GGML_TYPE_IQ3_XXS ||
|
|
5794
|
+
src0_type == GGML_TYPE_IQ1_S ||
|
|
5795
|
+
src0_type == GGML_TYPE_IQ1_M ||
|
|
5796
|
+
src0_type == GGML_TYPE_IQ3_S ||
|
|
5797
|
+
src0_type == GGML_TYPE_IQ4_NL ||
|
|
5798
|
+
src0_type == GGML_TYPE_IQ4_XS
|
|
5799
|
+
) {
|
|
5800
|
+
return false;
|
|
5801
|
+
}
|
|
5414
5802
|
}
|
|
5415
|
-
|
|
5416
|
-
|
|
5803
|
+
|
|
5804
|
+
if (src0_type == src1_type) {
|
|
5805
|
+
if (src1_type == GGML_TYPE_IQ2_XXS ||
|
|
5806
|
+
src1_type == GGML_TYPE_IQ2_XS ||
|
|
5807
|
+
src1_type == GGML_TYPE_IQ2_S ||
|
|
5808
|
+
src1_type == GGML_TYPE_IQ3_XXS ||
|
|
5809
|
+
src1_type == GGML_TYPE_IQ3_S ||
|
|
5810
|
+
src1_type == GGML_TYPE_IQ1_S ||
|
|
5811
|
+
src1_type == GGML_TYPE_IQ1_M) {
|
|
5812
|
+
return false;
|
|
5813
|
+
}
|
|
5417
5814
|
}
|
|
5418
|
-
|
|
5815
|
+
|
|
5816
|
+
return true;
|
|
5419
5817
|
}
|
|
5420
5818
|
case GGML_OP_REPEAT_BACK:
|
|
5421
5819
|
{
|
|
@@ -5447,11 +5845,6 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5447
5845
|
case GGML_OP_COS:
|
|
5448
5846
|
case GGML_OP_CLAMP:
|
|
5449
5847
|
case GGML_OP_LOG:
|
|
5450
|
-
#if defined (GGML_SYCL_F16)
|
|
5451
|
-
return ((op->type == GGML_TYPE_F32 || op->type == GGML_SYCL_F16) && (op->src[0]->type == GGML_TYPE_F32 || op->src[0]->type == GGML_SYCL_F16) && (op->type == op->src[0]->type));
|
|
5452
|
-
#else
|
|
5453
|
-
return (op->type == GGML_TYPE_F32 && op->src[0]->type == GGML_TYPE_F32) && (op->type == op->src[0]->type);
|
|
5454
|
-
#endif
|
|
5455
5848
|
case GGML_OP_NORM:
|
|
5456
5849
|
case GGML_OP_L2_NORM:
|
|
5457
5850
|
case GGML_OP_GROUP_NORM:
|
|
@@ -5462,7 +5855,7 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5462
5855
|
case GGML_OP_SCALE:
|
|
5463
5856
|
return true;
|
|
5464
5857
|
case GGML_OP_CONT:
|
|
5465
|
-
return
|
|
5858
|
+
return true;
|
|
5466
5859
|
case GGML_OP_TRI:
|
|
5467
5860
|
{
|
|
5468
5861
|
const ggml_tensor * src0 = op->src[0];
|
|
@@ -5485,13 +5878,26 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5485
5878
|
case GGML_OP_IM2COL_3D:
|
|
5486
5879
|
case GGML_OP_UPSCALE:
|
|
5487
5880
|
return true;
|
|
5881
|
+
case GGML_OP_COL2IM_1D:
|
|
5882
|
+
return ggml_is_contiguous(op->src[0]) &&
|
|
5883
|
+
(op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16
|
|
5884
|
+
#ifdef GGML_SYCL_HAS_BF16
|
|
5885
|
+
|| op->type == GGML_TYPE_BF16
|
|
5886
|
+
#endif
|
|
5887
|
+
) &&
|
|
5888
|
+
op->src[0]->type == op->type;
|
|
5889
|
+
case GGML_OP_CONV_3D:
|
|
5890
|
+
return op->type == GGML_TYPE_F32 &&
|
|
5891
|
+
(op->src[0]->type == GGML_TYPE_F32 || op->src[0]->type == GGML_TYPE_F16) &&
|
|
5892
|
+
op->src[1]->type == GGML_TYPE_F32 &&
|
|
5893
|
+
ggml_is_contiguous(op->src[0]) &&
|
|
5894
|
+
ggml_is_contiguous(op->src[1]);
|
|
5488
5895
|
case GGML_OP_SUM:
|
|
5489
5896
|
case GGML_OP_SUM_ROWS:
|
|
5490
5897
|
case GGML_OP_MEAN:
|
|
5491
5898
|
return ggml_is_contiguous(op->src[0]);
|
|
5492
5899
|
case GGML_OP_ARGSORT:
|
|
5493
|
-
return
|
|
5494
|
-
ggml_sycl_info().devices[device].smpbo;
|
|
5900
|
+
return true;
|
|
5495
5901
|
case GGML_OP_TOP_K: {
|
|
5496
5902
|
const ggml_tensor * src0 = op->src[0];
|
|
5497
5903
|
const int k = op->ne[0];
|
|
@@ -5502,9 +5908,9 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5502
5908
|
k > 0 && k <= 32;
|
|
5503
5909
|
}
|
|
5504
5910
|
case GGML_OP_POOL_2D:
|
|
5505
|
-
|
|
5911
|
+
case GGML_OP_POOL_1D:
|
|
5506
5912
|
case GGML_OP_ACC:
|
|
5507
|
-
return
|
|
5913
|
+
return true;
|
|
5508
5914
|
case GGML_OP_PAD:
|
|
5509
5915
|
if (ggml_get_op_params_i32(op, 8) != 0) {
|
|
5510
5916
|
return false;
|
|
@@ -5537,6 +5943,8 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5537
5943
|
case GGML_OP_FILL:
|
|
5538
5944
|
case GGML_OP_CUMSUM:
|
|
5539
5945
|
case GGML_OP_DIAG:
|
|
5946
|
+
case GGML_OP_CROSS_ENTROPY_LOSS:
|
|
5947
|
+
case GGML_OP_CROSS_ENTROPY_LOSS_BACK:
|
|
5540
5948
|
return true;
|
|
5541
5949
|
case GGML_OP_SOLVE_TRI:
|
|
5542
5950
|
return op->src[0]->ne[0] <= SYCL_SOLVE_TRI_MAX_N && op->src[1]->ne[0] <= SYCL_SOLVE_TRI_MAX_K;
|
|
@@ -5549,6 +5957,13 @@ static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const g
|
|
|
5549
5957
|
GGML_UNUSED(dev);
|
|
5550
5958
|
}
|
|
5551
5959
|
|
|
5960
|
+
static bool ggml_backend_sycl_device_supports_op(ggml_backend_dev_t dev, const ggml_tensor * op) {
|
|
5961
|
+
bool res = do_ggml_backend_sycl_device_supports_op(dev, op);
|
|
5962
|
+
GGML_SYCL_DEBUG("[SYCL] call %s op->op=%s op->type=%s -> %s\n", __func__, ggml_op_name(op->op),
|
|
5963
|
+
ggml_type_name(op->type), res ? "true" : "false");
|
|
5964
|
+
return res;
|
|
5965
|
+
}
|
|
5966
|
+
|
|
5552
5967
|
static bool ggml_backend_sycl_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) {
|
|
5553
5968
|
if (buft->iface.get_name != ggml_backend_sycl_buffer_type_get_name) {
|
|
5554
5969
|
return false;
|
|
@@ -5664,6 +6079,250 @@ static ggml_backend_dev_t ggml_backend_sycl_reg_get_device(ggml_backend_reg_t re
|
|
|
5664
6079
|
return ctx->devices[index];
|
|
5665
6080
|
}
|
|
5666
6081
|
|
|
6082
|
+
// ==========================================================================
|
|
6083
|
+
// Tensor parallelism (--split-mode tensor) for the SYCL backend.
|
|
6084
|
+
//
|
|
6085
|
+
// The meta-backend invokes these three entry points via get_proc_address:
|
|
6086
|
+
// * ggml_backend_sycl_comm_init - one-time per-graph setup
|
|
6087
|
+
// * ggml_backend_sycl_comm_allreduce_tensor - per-allreduce step
|
|
6088
|
+
// * ggml_backend_sycl_comm_free - tear-down
|
|
6089
|
+
//
|
|
6090
|
+
// For N=2 (dual-GPU), this is a degenerate ring allreduce with dual paths
|
|
6091
|
+
// chosen by tensor size:
|
|
6092
|
+
//
|
|
6093
|
+
// * Small (nelem < 32K): FP32 direct memcpy + per-device ADD
|
|
6094
|
+
// kernel. The kernel depends_on() its corresponding memcpy event
|
|
6095
|
+
// so it doesn't read partial data. Both devices run in parallel.
|
|
6096
|
+
//
|
|
6097
|
+
// * Large (nelem >= 32K): BF16-compressed. Each device compresses
|
|
6098
|
+
// its FP32 partial to BF16 locally, cross-device memcpys
|
|
6099
|
+
// to the peer (half the PCI bandwidth), where it is decompressed
|
|
6100
|
+
// and added into the local FP32 partial. 6 SYCL submissions per
|
|
6101
|
+
// allreduce (2 compress + 2 memcpy + 2 decompress-add) vs the
|
|
6102
|
+
// 4 for the small path, but the bandwidth saving > 6 GB/s PCIe x 2
|
|
6103
|
+
// dominates for larger tensors.
|
|
6104
|
+
//
|
|
6105
|
+
// Storage: A persistent uint8_t buffer per device, sized to
|
|
6106
|
+
// 4 * nelem bytes. Both paths reinterpret the same bytes (small path
|
|
6107
|
+
// as nelem floats; large path as outbox + inbox = 2*nelem uint16_t
|
|
6108
|
+
// each, using the full 4*nelem byte budget either way). Single
|
|
6109
|
+
// alloc+free per device keeps the SYCL pool's strict-LIFO invariant
|
|
6110
|
+
// trivial.
|
|
6111
|
+
//
|
|
6112
|
+
// For non-(N=2 FP32 contiguous) cases, comm_init or comm_allreduce_tensor
|
|
6113
|
+
// returns null/false, causing the meta-backend to use its generic
|
|
6114
|
+
// butterfly all-reduce fallback.
|
|
6115
|
+
// ==========================================================================
|
|
6116
|
+
|
|
6117
|
+
struct ggml_backend_sycl_comm_context {
|
|
6118
|
+
std::vector<ggml_backend_t> backends;
|
|
6119
|
+
// ONE persistent per-device byte buffer, 4*nelem bytes. Both the
|
|
6120
|
+
// FP32 small-tensor path and the BF16 large-tensor path share it
|
|
6121
|
+
// by reinterpreting.
|
|
6122
|
+
std::unique_ptr<ggml_sycl_pool_alloc<uint8_t>> buf0;
|
|
6123
|
+
std::unique_ptr<ggml_sycl_pool_alloc<uint8_t>> buf1;
|
|
6124
|
+
int64_t buf_nelem = 0;
|
|
6125
|
+
};
|
|
6126
|
+
|
|
6127
|
+
void * ggml_backend_sycl_comm_init(ggml_backend_t * backends, size_t n_backends) try {
|
|
6128
|
+
for (size_t i = 0; i < n_backends; ++i) {
|
|
6129
|
+
if (!ggml_backend_is_sycl(backends[i])) {
|
|
6130
|
+
return nullptr;
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
6133
|
+
|
|
6134
|
+
// Initial version: N=2 only. For N!=2, returning null makes the
|
|
6135
|
+
// meta-backend skip this backend-specific allreduce entirely.
|
|
6136
|
+
if (n_backends != 2) {
|
|
6137
|
+
return nullptr;
|
|
6138
|
+
}
|
|
6139
|
+
|
|
6140
|
+
auto * ctx = new ggml_backend_sycl_comm_context;
|
|
6141
|
+
ctx->backends.assign(backends, backends + n_backends);
|
|
6142
|
+
auto * sctx0 = (ggml_backend_sycl_context *) backends[0]->context;
|
|
6143
|
+
auto * sctx1 = (ggml_backend_sycl_context *) backends[1]->context;
|
|
6144
|
+
ctx->buf0 = std::make_unique<ggml_sycl_pool_alloc<uint8_t>>(sctx0->pool());
|
|
6145
|
+
ctx->buf1 = std::make_unique<ggml_sycl_pool_alloc<uint8_t>>(sctx1->pool());
|
|
6146
|
+
return ctx;
|
|
6147
|
+
}
|
|
6148
|
+
catch (const sycl::exception &) { return nullptr; }
|
|
6149
|
+
catch (...) { return nullptr; }
|
|
6150
|
+
|
|
6151
|
+
void ggml_backend_sycl_comm_free(void * comm_ctx_v) {
|
|
6152
|
+
auto * comm_ctx = static_cast<ggml_backend_sycl_comm_context *>(comm_ctx_v);
|
|
6153
|
+
if (comm_ctx == nullptr) {
|
|
6154
|
+
return;
|
|
6155
|
+
}
|
|
6156
|
+
|
|
6157
|
+
// Sync both per-device queues so the pool_alloc destructors don't
|
|
6158
|
+
// return memory still in use by the last kernel.
|
|
6159
|
+
if (comm_ctx->backends.size() == 2) {
|
|
6160
|
+
auto * sctx0 = (ggml_backend_sycl_context *) comm_ctx->backends[0]->context;
|
|
6161
|
+
auto * sctx1 = (ggml_backend_sycl_context *) comm_ctx->backends[1]->context;
|
|
6162
|
+
try {
|
|
6163
|
+
sctx0->stream()->wait();
|
|
6164
|
+
sctx1->stream()->wait();
|
|
6165
|
+
} catch (...) { /* best effort during shutdown */ }
|
|
6166
|
+
}
|
|
6167
|
+
|
|
6168
|
+
delete comm_ctx;
|
|
6169
|
+
}
|
|
6170
|
+
|
|
6171
|
+
bool ggml_backend_sycl_comm_allreduce_tensor(void * comm_ctx_v, struct ggml_tensor ** tensors) try {
|
|
6172
|
+
if (comm_ctx_v == nullptr) {
|
|
6173
|
+
return false;
|
|
6174
|
+
}
|
|
6175
|
+
|
|
6176
|
+
auto * comm_ctx = static_cast<ggml_backend_sycl_comm_context *>(comm_ctx_v);
|
|
6177
|
+
const size_t n_backends = comm_ctx->backends.size();
|
|
6178
|
+
|
|
6179
|
+
// Fast path: N=2, F32/F16, contiguous, matching shapes.
|
|
6180
|
+
if (n_backends != 2) {
|
|
6181
|
+
return false;
|
|
6182
|
+
}
|
|
6183
|
+
// Accept F32 or F16 inputs natively (types must match). F16 takes the
|
|
6184
|
+
// direct 2-byte memcpy + add path below; other types return false so the
|
|
6185
|
+
// meta-backend uses its generic all-reduce.
|
|
6186
|
+
if (tensors[0]->type != tensors[1]->type) {
|
|
6187
|
+
return false;
|
|
6188
|
+
}
|
|
6189
|
+
if (tensors[0]->type != GGML_TYPE_F32 && tensors[0]->type != GGML_TYPE_F16) {
|
|
6190
|
+
return false;
|
|
6191
|
+
}
|
|
6192
|
+
if (!ggml_is_contiguous(tensors[0]) || !ggml_is_contiguous(tensors[1])) {
|
|
6193
|
+
return false;
|
|
6194
|
+
}
|
|
6195
|
+
if (ggml_nelements(tensors[0]) != ggml_nelements(tensors[1])) {
|
|
6196
|
+
return false;
|
|
6197
|
+
}
|
|
6198
|
+
|
|
6199
|
+
const int64_t nelem = ggml_nelements(tensors[0]);
|
|
6200
|
+
const size_t nbytes = ggml_nbytes(tensors[0]);
|
|
6201
|
+
if (nelem == 0) {
|
|
6202
|
+
return true;
|
|
6203
|
+
}
|
|
6204
|
+
|
|
6205
|
+
auto * ctx0 = (ggml_backend_sycl_context *) comm_ctx->backends[0]->context;
|
|
6206
|
+
auto * ctx1 = (ggml_backend_sycl_context *) comm_ctx->backends[1]->context;
|
|
6207
|
+
queue_ptr q0 = ctx0->stream();
|
|
6208
|
+
queue_ptr q1 = ctx1->stream();
|
|
6209
|
+
|
|
6210
|
+
// Grow per-device byte buffers if needed (4 * nelem bytes each).
|
|
6211
|
+
if (comm_ctx->buf_nelem < nelem) {
|
|
6212
|
+
comm_ctx->buf0->realloc(nelem * 4);
|
|
6213
|
+
comm_ctx->buf1->realloc(nelem * 4);
|
|
6214
|
+
comm_ctx->buf_nelem = nelem;
|
|
6215
|
+
}
|
|
6216
|
+
uint8_t * buf0 = comm_ctx->buf0->get();
|
|
6217
|
+
uint8_t * buf1 = comm_ctx->buf1->get();
|
|
6218
|
+
|
|
6219
|
+
// F16 native path: direct 2-byte cross-device copy + add, skipping the
|
|
6220
|
+
// F32 round-trip the meta-backend fallback would force. Cross-device copies
|
|
6221
|
+
// go through dev2dev_memcpy because the two devices are in separate SYCL
|
|
6222
|
+
// contexts (a raw peer-USM q->memcpy would be a silent no-op).
|
|
6223
|
+
if (tensors[0]->type == GGML_TYPE_F16) {
|
|
6224
|
+
sycl::half * f16_out0 = (sycl::half *) tensors[0]->data;
|
|
6225
|
+
sycl::half * f16_out1 = (sycl::half *) tensors[1]->data;
|
|
6226
|
+
sycl::half * f16_tmp0 = (sycl::half *) buf0;
|
|
6227
|
+
sycl::half * f16_tmp1 = (sycl::half *) buf1;
|
|
6228
|
+
|
|
6229
|
+
q0->wait();
|
|
6230
|
+
q1->wait();
|
|
6231
|
+
dev2dev_memcpy(ctx0->device, *q0, ctx1->device, *q1, f16_tmp0, tensors[1]->data, nbytes);
|
|
6232
|
+
dev2dev_memcpy(ctx1->device, *q1, ctx0->device, *q0, f16_tmp1, tensors[0]->data, nbytes);
|
|
6233
|
+
|
|
6234
|
+
q0->submit([&](sycl::handler & h) {
|
|
6235
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6236
|
+
f16_out0[i] = (sycl::half) ((float) f16_out0[i] + (float) f16_tmp0[i]);
|
|
6237
|
+
});
|
|
6238
|
+
});
|
|
6239
|
+
q1->submit([&](sycl::handler & h) {
|
|
6240
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6241
|
+
f16_out1[i] = (sycl::half) ((float) f16_out1[i] + (float) f16_tmp1[i]);
|
|
6242
|
+
});
|
|
6243
|
+
});
|
|
6244
|
+
return true;
|
|
6245
|
+
}
|
|
6246
|
+
|
|
6247
|
+
float * out0 = (float *) tensors[0]->data;
|
|
6248
|
+
float * out1 = (float *) tensors[1]->data;
|
|
6249
|
+
|
|
6250
|
+
// BF16 threshold: above this, the PCIe savings from halving the
|
|
6251
|
+
// cross-device bytes outweigh the 2 extra compress kernels.
|
|
6252
|
+
// Below: stay on the FP32 fast path. Threshold mirrors the CUDA
|
|
6253
|
+
// NCCL allreduce pattern for n_backends=2.
|
|
6254
|
+
static constexpr int64_t BF16_THRESHOLD = 32768;
|
|
6255
|
+
|
|
6256
|
+
if (nelem < BF16_THRESHOLD) {
|
|
6257
|
+
// FP32 small path: 4 SYCL submissions per allreduce.
|
|
6258
|
+
float * tmp0 = (float *) buf0;
|
|
6259
|
+
float * tmp1 = (float *) buf1;
|
|
6260
|
+
|
|
6261
|
+
// COMM-D2D-FIX: the two devices are in SEPARATE SYCL contexts, so a raw
|
|
6262
|
+
// q->memcpy of a peer USM pointer is a silent no-op. Route cross-device
|
|
6263
|
+
// copies through dev2dev_memcpy (L0 direct copy / host staging). It is
|
|
6264
|
+
// synchronous, so wait for the local partials to be produced first.
|
|
6265
|
+
q0->wait();
|
|
6266
|
+
q1->wait();
|
|
6267
|
+
dev2dev_memcpy(ctx0->device, *q0, ctx1->device, *q1, tmp0, tensors[1]->data, nbytes);
|
|
6268
|
+
dev2dev_memcpy(ctx1->device, *q1, ctx0->device, *q0, tmp1, tensors[0]->data, nbytes);
|
|
6269
|
+
|
|
6270
|
+
q0->submit([&](sycl::handler & h) {
|
|
6271
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6272
|
+
out0[i] += tmp0[i];
|
|
6273
|
+
});
|
|
6274
|
+
});
|
|
6275
|
+
q1->submit([&](sycl::handler & h) {
|
|
6276
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6277
|
+
out1[i] += tmp1[i];
|
|
6278
|
+
});
|
|
6279
|
+
});
|
|
6280
|
+
return true;
|
|
6281
|
+
}
|
|
6282
|
+
|
|
6283
|
+
// BF16 large path: 6 SYCL submissions per allreduce, but the
|
|
6284
|
+
// cross-device memcpy is HALF the bytes. Pure bit-shift
|
|
6285
|
+
// conversion (no rounding) — matches ggml's truncating fp32->bf16.
|
|
6286
|
+
uint16_t * outbox0 = (uint16_t *) buf0;
|
|
6287
|
+
uint16_t * inbox0 = outbox0 + nelem;
|
|
6288
|
+
uint16_t * outbox1 = (uint16_t *) buf1;
|
|
6289
|
+
uint16_t * inbox1 = outbox1 + nelem;
|
|
6290
|
+
|
|
6291
|
+
// Phase A: compress each device's local partial in parallel.
|
|
6292
|
+
sycl::event c0 = q0->parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6293
|
+
outbox0[i] = (uint16_t) (sycl::bit_cast<uint32_t>(out0[i]) >> 16);
|
|
6294
|
+
});
|
|
6295
|
+
|
|
6296
|
+
sycl::event c1 = q1->parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6297
|
+
outbox1[i] = (uint16_t) (sycl::bit_cast<uint32_t>(out1[i]) >> 16);
|
|
6298
|
+
});
|
|
6299
|
+
|
|
6300
|
+
// Phase B: COMM-D2D-FIX-BF16 cross-device copy of compressed bytes via
|
|
6301
|
+
// dev2dev_memcpy (separate SYCL contexts; sync copy after compress).
|
|
6302
|
+
const size_t bf16_bytes = nelem * sizeof(uint16_t);
|
|
6303
|
+
c0.wait();
|
|
6304
|
+
c1.wait();
|
|
6305
|
+
dev2dev_memcpy(ctx0->device, *q0, ctx1->device, *q1, inbox0, outbox1, bf16_bytes);
|
|
6306
|
+
dev2dev_memcpy(ctx1->device, *q1, ctx0->device, *q0, inbox1, outbox0, bf16_bytes);
|
|
6307
|
+
|
|
6308
|
+
// Phase C: decompress + add into local FP32 partial.
|
|
6309
|
+
q0->submit([&](sycl::handler & h) {
|
|
6310
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6311
|
+
out0[i] += sycl::bit_cast<float>(((uint32_t) inbox0[i]) << 16);
|
|
6312
|
+
});
|
|
6313
|
+
});
|
|
6314
|
+
|
|
6315
|
+
q1->submit([&](sycl::handler & h) {
|
|
6316
|
+
h.parallel_for(sycl::range<1>(nelem), [=](sycl::id<1> i) {
|
|
6317
|
+
out1[i] += sycl::bit_cast<float>(((uint32_t) inbox1[i]) << 16);
|
|
6318
|
+
});
|
|
6319
|
+
});
|
|
6320
|
+
|
|
6321
|
+
return true;
|
|
6322
|
+
}
|
|
6323
|
+
catch (const sycl::exception &) { return false; }
|
|
6324
|
+
catch (...) { return false; }
|
|
6325
|
+
|
|
5667
6326
|
static void *ggml_backend_sycl_reg_get_proc_address(ggml_backend_reg_t reg, const char *name) {
|
|
5668
6327
|
GGML_UNUSED(reg);
|
|
5669
6328
|
|
|
@@ -5671,6 +6330,17 @@ static void *ggml_backend_sycl_reg_get_proc_address(ggml_backend_reg_t reg, cons
|
|
|
5671
6330
|
return (void *)ggml_backend_sycl_split_buffer_type;
|
|
5672
6331
|
}
|
|
5673
6332
|
|
|
6333
|
+
// Tensor parallelism (--split-mode tensor) entry points.
|
|
6334
|
+
if (strcmp(name, "ggml_backend_comm_init") == 0) {
|
|
6335
|
+
return (void *)ggml_backend_sycl_comm_init;
|
|
6336
|
+
}
|
|
6337
|
+
if (strcmp(name, "ggml_backend_comm_free") == 0) {
|
|
6338
|
+
return (void *)ggml_backend_sycl_comm_free;
|
|
6339
|
+
}
|
|
6340
|
+
if (strcmp(name, "ggml_backend_comm_allreduce_tensor") == 0) {
|
|
6341
|
+
return (void *)ggml_backend_sycl_comm_allreduce_tensor;
|
|
6342
|
+
}
|
|
6343
|
+
|
|
5674
6344
|
// SYCL doesn't support registering host memory, left here for reference
|
|
5675
6345
|
// "ggml_backend_register_host_buffer"
|
|
5676
6346
|
// "ggml_backend_unregister_host_buffer"
|