toy 0.8.0
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 +7 -0
- data/CHANGELOG.md +1124 -0
- data/LICENSE +21 -0
- data/Makefile +2022 -0
- data/README.md +154 -0
- data/bin/toy +10 -0
- data/lib/toy/compute.rb +135 -0
- data/lib/toy/compute_cuda.rb +104 -0
- data/lib/toy/compute_metal.rb +97 -0
- data/lib/toy/core/cli/describe.rb +188 -0
- data/lib/toy/core/cli/eval.rb +385 -0
- data/lib/toy/core/cli/exit_codes.rb +15 -0
- data/lib/toy/core/cli/fetch.rb +238 -0
- data/lib/toy/core/cli/infer.rb +268 -0
- data/lib/toy/core/cli/install.rb +228 -0
- data/lib/toy/core/cli/list.rb +86 -0
- data/lib/toy/core/cli/manifest.rb +49 -0
- data/lib/toy/core/cli/new.rb +594 -0
- data/lib/toy/core/cli/serve.rb +237 -0
- data/lib/toy/core/cli/train.rb +471 -0
- data/lib/toy/core/cli.rb +165 -0
- data/lib/toy/core/config.rb +64 -0
- data/lib/toy/core/gguf_meta.rb +161 -0
- data/lib/toy/core/model_scan.rb +221 -0
- data/lib/toy/core/run_log.rb +94 -0
- data/lib/toy/core/toy_root.rb +95 -0
- data/lib/toy/dev/toy_card.rb +299 -0
- data/lib/toy/dev/toy_describe_flow.rb +412 -0
- data/lib/toy/dev/toy_logprobs.rb +86 -0
- data/lib/toy/dev/toy_tap.rb +183 -0
- data/lib/toy/dev/toy_token_drift.rb +121 -0
- data/lib/toy/ffi/tinynn.rb +1491 -0
- data/lib/toy/ffi/tinynn_cuda.rb +1124 -0
- data/lib/toy/ffi/tinynn_metal.rb +359 -0
- data/lib/toy/ffi_manifest.rb +84 -0
- data/lib/toy/io/bpe.rb +325 -0
- data/lib/toy/io/gguf_kv.rb +35 -0
- data/lib/toy/io/gguf_load.rb +331 -0
- data/lib/toy/io/loaders/toy_gpt2_loader.rb +70 -0
- data/lib/toy/io/loaders/toy_smollm2_loader.rb +754 -0
- data/lib/toy/io/model_index.rb +206 -0
- data/lib/toy/io/run_bundle.rb +280 -0
- data/lib/toy/io/tokenizer.rb +613 -0
- data/lib/toy/io/toy_corpus_loader.rb +52 -0
- data/lib/toy/io/toy_events.rb +56 -0
- data/lib/toy/io/toy_image_loader.rb +48 -0
- data/lib/toy/llm/adamw.rb +169 -0
- data/lib/toy/llm/archs/llama_arch.rb +233 -0
- data/lib/toy/llm/archs/llama_arch_cuda.rb +237 -0
- data/lib/toy/llm/archs/llama_arch_metal.rb +237 -0
- data/lib/toy/llm/blocks/transformer_block.rb +876 -0
- data/lib/toy/llm/blocks/transformer_block_cuda.rb +880 -0
- data/lib/toy/llm/blocks/transformer_block_metal.rb +880 -0
- data/lib/toy/llm/classify_batch.rb +88 -0
- data/lib/toy/llm/engine/gpt2_fwd_engine.rb +360 -0
- data/lib/toy/llm/engine/gpt2_fwd_engine_cuda.rb +362 -0
- data/lib/toy/llm/engine/gpt2_fwd_engine_metal.rb +362 -0
- data/lib/toy/llm/engine/gpt2_kv_engine.rb +346 -0
- data/lib/toy/llm/engine/gpt2_kv_engine_cuda.rb +348 -0
- data/lib/toy/llm/engine/gpt2_kv_engine_metal.rb +348 -0
- data/lib/toy/llm/engine/gpt2_seq_engine.rb +289 -0
- data/lib/toy/llm/engine/gpt2_seq_engine_cuda.rb +293 -0
- data/lib/toy/llm/engine/gpt2_seq_engine_metal.rb +293 -0
- data/lib/toy/llm/engine/llama_kv_engine.rb +1593 -0
- data/lib/toy/llm/engine/llama_kv_engine_cuda.rb +1526 -0
- data/lib/toy/llm/engine/llama_kv_engine_metal.rb +1526 -0
- data/lib/toy/llm/engine/llama_seq_engine.rb +1233 -0
- data/lib/toy/llm/engine/llama_seq_engine_cuda.rb +1238 -0
- data/lib/toy/llm/engine/llama_seq_engine_metal.rb +1238 -0
- data/lib/toy/llm/engine/vit_tiny_engine.rb +467 -0
- data/lib/toy/llm/labels.rb +142 -0
- data/lib/toy/llm/primitives/gqa.rb +62 -0
- data/lib/toy/llm/primitives/gqa_cuda.rb +66 -0
- data/lib/toy/llm/primitives/gqa_metal.rb +66 -0
- data/lib/toy/llm/primitives/rms_norm.rb +39 -0
- data/lib/toy/llm/primitives/rms_norm_cuda.rb +43 -0
- data/lib/toy/llm/primitives/rms_norm_metal.rb +43 -0
- data/lib/toy/llm/primitives/rope.rb +68 -0
- data/lib/toy/llm/primitives/rope_cuda.rb +72 -0
- data/lib/toy/llm/primitives/rope_metal.rb +72 -0
- data/lib/toy/llm/primitives/swiglu.rb +41 -0
- data/lib/toy/llm/primitives/swiglu_cuda.rb +45 -0
- data/lib/toy/llm/primitives/swiglu_metal.rb +45 -0
- data/lib/toy/llm/recipe_options.rb +71 -0
- data/lib/toy/llm/recipes/from_scratch.rb +105 -0
- data/lib/toy/llm/recipes/from_scratch_cuda.rb +109 -0
- data/lib/toy/llm/recipes/from_scratch_metal.rb +109 -0
- data/lib/toy/llm/recipes/lora.rb +110 -0
- data/lib/toy/llm/recipes/lora_cuda.rb +114 -0
- data/lib/toy/llm/recipes/lora_metal.rb +114 -0
- data/lib/toy/llm/recipes/vit_tiny.rb +75 -0
- data/lib/toy/llm/recipes/warm_start.rb +235 -0
- data/lib/toy/llm/recipes/warm_start_cuda.rb +239 -0
- data/lib/toy/llm/recipes/warm_start_metal.rb +239 -0
- data/lib/toy/llm/training_batch.rb +133 -0
- data/lib/toy/models/arch.rb +253 -0
- data/lib/toy/models/gpt2.rb +311 -0
- data/lib/toy/models/toy_gpt2.rb +177 -0
- data/lib/toy/models/toy_smollm2.rb +393 -0
- data/lib/toy/models/toy_vit.rb +83 -0
- data/lib/toy/models/transformer.rb +1494 -0
- data/lib/toy/models/transformer_lm.rb +298 -0
- data/lib/toy/models/transformer_lm_cuda.rb +159 -0
- data/lib/toy/models/transformer_lm_metal.rb +142 -0
- data/lib/toy/mri.rb +300 -0
- data/lib/toy/run/eval.rb +76 -0
- data/lib/toy/run/eval_cuda.rb +66 -0
- data/lib/toy/run/eval_lmc.rb +334 -0
- data/lib/toy/run/eval_metal.rb +67 -0
- data/lib/toy/run/infer.rb +130 -0
- data/lib/toy/run/infer_cuda.rb +118 -0
- data/lib/toy/run/infer_metal.rb +119 -0
- data/lib/toy/run/infer_trace.rb +37 -0
- data/lib/toy/run/serve.rb +144 -0
- data/lib/toy/run/train.rb +404 -0
- data/lib/toy/run/train_cuda.rb +397 -0
- data/lib/toy/run/train_gpt2.rb +103 -0
- data/lib/toy/run/train_gpt2_cuda.rb +85 -0
- data/lib/toy/run/train_gpt2_metal.rb +85 -0
- data/lib/toy/run/train_lora.rb +207 -0
- data/lib/toy/run/train_lora_cuda.rb +219 -0
- data/lib/toy/run/train_metal.rb +227 -0
- data/lib/toy/run/train_vit.rb +251 -0
- data/lib/toy/serve/openai/embeddings_handler.rb +92 -0
- data/lib/toy/serve/openai/handlers.rb +143 -0
- data/lib/toy/serve/openai/server.rb +159 -0
- data/lib/toy/train/sampler.rb +314 -0
- data/lib/toy/train/toy_chat_template.rb +179 -0
- data/lib/toy/train/toy_drift_grad.rb +176 -0
- data/lib/toy/train/toy_gguf_fuse.rb +428 -0
- data/lib/toy/train/toy_gguf_writer.rb +100 -0
- data/lib/toy/train/toy_lr_schedule.rb +39 -0
- data/lib/toy/train/toy_sample.rb +125 -0
- data/lib/toy/train/toy_trainer.rb +86 -0
- data/lib/toy/train/training.rb +160 -0
- data/lib/toy/version.rb +11 -0
- data/lib/toy.rb +902 -0
- data/prep/progress +118 -0
- data/prep/quietly +64 -0
- data/sig/toy.rbs +397 -0
- data/sig/toy_compute.rbs +450 -0
- data/spinel-ext.json +122 -0
- data/tinynn/Makefile +71 -0
- data/tinynn/tinynn_backend_cuda.c +99 -0
- data/tinynn/tinynn_backend_metal.m +75 -0
- data/tinynn/tinynn_events.c +122 -0
- data/tinynn/tinynn_events.h +83 -0
- data/tinynn/tinynn_ggml.c +2460 -0
- data/tinynn/tinynn_ggml.h +545 -0
- data/tinynn/tinynn_gguf.c +783 -0
- data/tinynn/tinynn_gguf.h +167 -0
- data/tinynn/tinynn_trace.c +180 -0
- data/tinynn/tinynn_trace.h +85 -0
- data/vendor/ggml/AUTHORS +335 -0
- data/vendor/ggml/CMakeLists.txt +505 -0
- data/vendor/ggml/CONTRIBUTING.md +3 -0
- data/vendor/ggml/LICENSE +21 -0
- data/vendor/ggml/README.md +50 -0
- data/vendor/ggml/ci/run.sh +395 -0
- data/vendor/ggml/cmake/FindNCCL.cmake +36 -0
- data/vendor/ggml/cmake/GitVars.cmake +22 -0
- data/vendor/ggml/cmake/common.cmake +50 -0
- data/vendor/ggml/cmake/ggml-config.cmake.in +191 -0
- data/vendor/ggml/docs/gguf.md +828 -0
- data/vendor/ggml/examples/CMakeLists.txt +34 -0
- data/vendor/ggml/examples/common-ggml.cpp +244 -0
- data/vendor/ggml/examples/common-ggml.h +18 -0
- data/vendor/ggml/examples/common.cpp +675 -0
- data/vendor/ggml/examples/common.h +322 -0
- data/vendor/ggml/examples/gpt-2/CMakeLists.txt +32 -0
- data/vendor/ggml/examples/gpt-2/README.md +225 -0
- data/vendor/ggml/examples/gpt-2/convert-cerebras-to-ggml.py +183 -0
- data/vendor/ggml/examples/gpt-2/convert-ckpt-to-ggml.py +159 -0
- data/vendor/ggml/examples/gpt-2/convert-h5-to-ggml.py +195 -0
- data/vendor/ggml/examples/gpt-2/download-ggml-model.sh +69 -0
- data/vendor/ggml/examples/gpt-2/download-model.sh +48 -0
- data/vendor/ggml/examples/gpt-2/main-alloc.cpp +880 -0
- data/vendor/ggml/examples/gpt-2/main-backend.cpp +946 -0
- data/vendor/ggml/examples/gpt-2/main-batched.cpp +1210 -0
- data/vendor/ggml/examples/gpt-2/main-ctx.cpp +840 -0
- data/vendor/ggml/examples/gpt-2/main-sched.cpp +1079 -0
- data/vendor/ggml/examples/gpt-2/quantize.cpp +184 -0
- data/vendor/ggml/examples/gpt-j/CMakeLists.txt +13 -0
- data/vendor/ggml/examples/gpt-j/README.md +239 -0
- data/vendor/ggml/examples/gpt-j/convert-h5-to-ggml.py +173 -0
- data/vendor/ggml/examples/gpt-j/download-ggml-model.sh +69 -0
- data/vendor/ggml/examples/gpt-j/download-model.sh +11 -0
- data/vendor/ggml/examples/gpt-j/main.cpp +755 -0
- data/vendor/ggml/examples/gpt-j/quantize.cpp +182 -0
- data/vendor/ggml/examples/magika/CMakeLists.txt +17 -0
- data/vendor/ggml/examples/magika/README.md +23 -0
- data/vendor/ggml/examples/magika/convert.py +32 -0
- data/vendor/ggml/examples/magika/main.cpp +374 -0
- data/vendor/ggml/examples/mnist/CMakeLists.txt +58 -0
- data/vendor/ggml/examples/mnist/README.md +206 -0
- data/vendor/ggml/examples/mnist/mnist-common.cpp +496 -0
- data/vendor/ggml/examples/mnist/mnist-common.h +166 -0
- data/vendor/ggml/examples/mnist/mnist-eval.cpp +67 -0
- data/vendor/ggml/examples/mnist/mnist-train-cnn.py +91 -0
- data/vendor/ggml/examples/mnist/mnist-train-fc.py +131 -0
- data/vendor/ggml/examples/mnist/mnist-train.cpp +39 -0
- data/vendor/ggml/examples/mnist/server.py +36 -0
- data/vendor/ggml/examples/mnist/web/index.html +178 -0
- data/vendor/ggml/examples/perf-metal/CMakeLists.txt +7 -0
- data/vendor/ggml/examples/perf-metal/perf-metal.cpp +152 -0
- data/vendor/ggml/examples/prompts/dolly-v2.txt +100 -0
- data/vendor/ggml/examples/prompts/gpt-2-chinese.txt +1 -0
- data/vendor/ggml/examples/prompts/gpt-2.txt +100 -0
- data/vendor/ggml/examples/prompts/gpt-j.txt +100 -0
- data/vendor/ggml/examples/prompts/gpt-neox-japanese.txt +1 -0
- data/vendor/ggml/examples/prompts/gpt-neox.txt +100 -0
- data/vendor/ggml/examples/prompts/polyglot-ko.txt +3 -0
- data/vendor/ggml/examples/prompts/replit.txt +100 -0
- data/vendor/ggml/examples/prompts/starcoder.txt +100 -0
- data/vendor/ggml/examples/prompts/test-cases.txt +110 -0
- data/vendor/ggml/examples/prompts/tokenize_huggingface.py +65 -0
- data/vendor/ggml/examples/prompts/whisper.txt +100 -0
- data/vendor/ggml/examples/python/README.md +115 -0
- data/vendor/ggml/examples/python/api.h +14 -0
- data/vendor/ggml/examples/python/example_add_quant.py +25 -0
- data/vendor/ggml/examples/python/example_test_all_quants.py +68 -0
- data/vendor/ggml/examples/python/ggml/__init__.py +58 -0
- data/vendor/ggml/examples/python/ggml/__init__.pyi +2406 -0
- data/vendor/ggml/examples/python/ggml/cffi.py +11 -0
- data/vendor/ggml/examples/python/ggml/ffi/__init__.pyi +7 -0
- data/vendor/ggml/examples/python/ggml/utils.py +182 -0
- data/vendor/ggml/examples/python/regenerate.py +42 -0
- data/vendor/ggml/examples/python/stubs.py +128 -0
- data/vendor/ggml/examples/python/test_tensor.py +258 -0
- data/vendor/ggml/examples/sam/CMakeLists.txt +13 -0
- data/vendor/ggml/examples/sam/README.md +95 -0
- data/vendor/ggml/examples/sam/convert-pth-to-ggml.py +147 -0
- data/vendor/ggml/examples/sam/example.jpg +0 -0
- data/vendor/ggml/examples/sam/sam.cpp +2370 -0
- data/vendor/ggml/examples/simple/CMakeLists.txt +21 -0
- data/vendor/ggml/examples/simple/README.md +61 -0
- data/vendor/ggml/examples/simple/simple-backend.cpp +153 -0
- data/vendor/ggml/examples/simple/simple-ctx.cpp +127 -0
- data/vendor/ggml/examples/stb_image.h +7987 -0
- data/vendor/ggml/examples/stb_image_write.h +1724 -0
- data/vendor/ggml/examples/test-cmake/CMakeLists.txt +10 -0
- data/vendor/ggml/examples/test-cmake/README.md +3 -0
- data/vendor/ggml/examples/test-cmake/test-cmake.cpp +6 -0
- data/vendor/ggml/examples/yolo/CMakeLists.txt +6 -0
- data/vendor/ggml/examples/yolo/README.md +59 -0
- data/vendor/ggml/examples/yolo/convert-yolov3-tiny.py +53 -0
- data/vendor/ggml/examples/yolo/data/coco.names +80 -0
- data/vendor/ggml/examples/yolo/data/labels/100_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/100_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/101_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/102_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/103_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/104_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/105_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/106_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/107_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/108_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/109_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/110_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/111_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/112_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/113_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/114_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/115_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/116_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/117_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/118_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/119_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/120_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/121_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/122_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/123_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/124_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/125_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/126_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/32_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/33_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/34_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/35_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/36_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/37_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/38_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/39_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/40_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/41_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/42_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/43_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/44_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/45_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/46_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/47_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/48_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/49_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/50_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/51_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/52_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/53_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/54_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/55_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/56_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/57_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/58_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/59_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/60_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/61_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/62_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/63_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/64_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/65_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/66_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/67_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/68_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/69_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/70_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/71_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/72_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/73_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/74_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/75_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/76_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/77_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/78_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/79_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/80_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/81_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/82_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/83_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/84_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/85_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/86_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/87_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/88_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/89_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/90_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/91_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/92_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/93_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/94_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/95_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/96_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/97_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/98_7.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_0.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_1.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_2.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_3.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_4.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_5.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_6.png +0 -0
- data/vendor/ggml/examples/yolo/data/labels/99_7.png +0 -0
- data/vendor/ggml/examples/yolo/yolo-image.cpp +210 -0
- data/vendor/ggml/examples/yolo/yolo-image.h +39 -0
- data/vendor/ggml/examples/yolo/yolov3-tiny.cpp +661 -0
- data/vendor/ggml/ggml.pc.in +10 -0
- data/vendor/ggml/include/ggml-alloc.h +85 -0
- data/vendor/ggml/include/ggml-backend.h +431 -0
- data/vendor/ggml/include/ggml-blas.h +25 -0
- data/vendor/ggml/include/ggml-cann.h +123 -0
- data/vendor/ggml/include/ggml-cpp.h +39 -0
- data/vendor/ggml/include/ggml-cpu.h +151 -0
- data/vendor/ggml/include/ggml-cuda.h +50 -0
- data/vendor/ggml/include/ggml-hexagon.h +19 -0
- data/vendor/ggml/include/ggml-metal.h +61 -0
- data/vendor/ggml/include/ggml-opencl.h +26 -0
- data/vendor/ggml/include/ggml-openvino.h +37 -0
- data/vendor/ggml/include/ggml-opt.h +256 -0
- data/vendor/ggml/include/ggml-rpc.h +35 -0
- data/vendor/ggml/include/ggml-sycl.h +49 -0
- data/vendor/ggml/include/ggml-virtgpu.h +14 -0
- data/vendor/ggml/include/ggml-vulkan.h +29 -0
- data/vendor/ggml/include/ggml-webgpu.h +19 -0
- data/vendor/ggml/include/ggml-zdnn.h +17 -0
- data/vendor/ggml/include/ggml-zendnn.h +22 -0
- data/vendor/ggml/include/ggml.h +2845 -0
- data/vendor/ggml/include/gguf.h +204 -0
- data/vendor/ggml/requirements.txt +12 -0
- data/vendor/ggml/scripts/gen-authors.sh +9 -0
- data/vendor/ggml/scripts/release.sh +296 -0
- data/vendor/ggml/scripts/sync-llama-am.sh +167 -0
- data/vendor/ggml/scripts/sync-llama.last +1 -0
- data/vendor/ggml/scripts/sync-llama.sh +21 -0
- data/vendor/ggml/scripts/sync-whisper-am.sh +138 -0
- data/vendor/ggml/scripts/sync-whisper.last +1 -0
- data/vendor/ggml/scripts/sync-whisper.sh +17 -0
- data/vendor/ggml/src/CMakeLists.txt +493 -0
- data/vendor/ggml/src/ggml-alloc.c +1248 -0
- data/vendor/ggml/src/ggml-backend-dl.cpp +48 -0
- data/vendor/ggml/src/ggml-backend-dl.h +45 -0
- data/vendor/ggml/src/ggml-backend-impl.h +275 -0
- data/vendor/ggml/src/ggml-backend-meta.cpp +2144 -0
- data/vendor/ggml/src/ggml-backend-reg.cpp +586 -0
- data/vendor/ggml/src/ggml-backend.cpp +2371 -0
- data/vendor/ggml/src/ggml-blas/CMakeLists.txt +101 -0
- data/vendor/ggml/src/ggml-blas/ggml-blas.cpp +522 -0
- data/vendor/ggml/src/ggml-cann/CMakeLists.txt +89 -0
- data/vendor/ggml/src/ggml-cann/acl_tensor.cpp +195 -0
- data/vendor/ggml/src/ggml-cann/acl_tensor.h +349 -0
- data/vendor/ggml/src/ggml-cann/aclnn_ops.cpp +4436 -0
- data/vendor/ggml/src/ggml-cann/aclnn_ops.h +1190 -0
- data/vendor/ggml/src/ggml-cann/common.h +651 -0
- data/vendor/ggml/src/ggml-cann/ggml-cann.cpp +3062 -0
- data/vendor/ggml/src/ggml-common.h +1900 -0
- data/vendor/ggml/src/ggml-cpu/CMakeLists.txt +731 -0
- data/vendor/ggml/src/ggml-cpu/amx/amx.cpp +249 -0
- data/vendor/ggml/src/ggml-cpu/amx/amx.h +8 -0
- data/vendor/ggml/src/ggml-cpu/amx/common.h +115 -0
- data/vendor/ggml/src/ggml-cpu/amx/mmq.cpp +2512 -0
- data/vendor/ggml/src/ggml-cpu/amx/mmq.h +10 -0
- data/vendor/ggml/src/ggml-cpu/arch/arm/cpu-feats.cpp +98 -0
- data/vendor/ggml/src/ggml-cpu/arch/arm/quants.c +4245 -0
- data/vendor/ggml/src/ggml-cpu/arch/arm/repack.cpp +5156 -0
- data/vendor/ggml/src/ggml-cpu/arch/loongarch/quants.c +2158 -0
- data/vendor/ggml/src/ggml-cpu/arch/powerpc/cpu-feats.cpp +82 -0
- data/vendor/ggml/src/ggml-cpu/arch/powerpc/quants.c +2304 -0
- data/vendor/ggml/src/ggml-cpu/arch/riscv/cpu-feats.cpp +38 -0
- data/vendor/ggml/src/ggml-cpu/arch/riscv/quants.c +4553 -0
- data/vendor/ggml/src/ggml-cpu/arch/riscv/repack.cpp +1703 -0
- data/vendor/ggml/src/ggml-cpu/arch/s390/cpu-feats.cpp +50 -0
- data/vendor/ggml/src/ggml-cpu/arch/s390/quants.c +1465 -0
- data/vendor/ggml/src/ggml-cpu/arch/wasm/quants.c +1220 -0
- data/vendor/ggml/src/ggml-cpu/arch/x86/cpu-feats.cpp +327 -0
- data/vendor/ggml/src/ggml-cpu/arch/x86/quants.c +3970 -0
- data/vendor/ggml/src/ggml-cpu/arch/x86/repack.cpp +6407 -0
- data/vendor/ggml/src/ggml-cpu/arch-fallback.h +348 -0
- data/vendor/ggml/src/ggml-cpu/binary-ops.cpp +154 -0
- data/vendor/ggml/src/ggml-cpu/binary-ops.h +16 -0
- data/vendor/ggml/src/ggml-cpu/cmake/FindSIMD.cmake +100 -0
- data/vendor/ggml/src/ggml-cpu/cmake/FindSMTIME.cmake +32 -0
- data/vendor/ggml/src/ggml-cpu/common.h +95 -0
- data/vendor/ggml/src/ggml-cpu/ggml-cpu-impl.h +539 -0
- data/vendor/ggml/src/ggml-cpu/ggml-cpu.c +3835 -0
- data/vendor/ggml/src/ggml-cpu/ggml-cpu.cpp +703 -0
- data/vendor/ggml/src/ggml-cpu/hbm.cpp +55 -0
- data/vendor/ggml/src/ggml-cpu/hbm.h +8 -0
- data/vendor/ggml/src/ggml-cpu/kleidiai/kernels.cpp +939 -0
- data/vendor/ggml/src/ggml-cpu/kleidiai/kernels.h +90 -0
- data/vendor/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +1513 -0
- data/vendor/ggml/src/ggml-cpu/kleidiai/kleidiai.h +17 -0
- data/vendor/ggml/src/ggml-cpu/llamafile/sgemm.cpp +4051 -0
- data/vendor/ggml/src/ggml-cpu/llamafile/sgemm.h +25 -0
- data/vendor/ggml/src/ggml-cpu/ops.cpp +11373 -0
- data/vendor/ggml/src/ggml-cpu/ops.h +119 -0
- data/vendor/ggml/src/ggml-cpu/quants.c +1288 -0
- data/vendor/ggml/src/ggml-cpu/quants.h +103 -0
- data/vendor/ggml/src/ggml-cpu/repack.cpp +4836 -0
- data/vendor/ggml/src/ggml-cpu/repack.h +245 -0
- data/vendor/ggml/src/ggml-cpu/simd-gemm.h +226 -0
- data/vendor/ggml/src/ggml-cpu/simd-mappings.h +1319 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime.cpp +1740 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime.h +21 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime1_kernels.cpp +1027 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime2_kernels.cpp +5768 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime_env.cpp +320 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime_env.h +55 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/ime_kernels.h +189 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/repack.cpp +1795 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/repack.h +14 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/rvv_kernels.cpp +3178 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/rvv_kernels.h +95 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/spine_barrier.h +34 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/spine_mem_pool.cpp +760 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/spine_mem_pool.h +32 -0
- data/vendor/ggml/src/ggml-cpu/spacemit/spine_tcm.h +409 -0
- data/vendor/ggml/src/ggml-cpu/traits.cpp +36 -0
- data/vendor/ggml/src/ggml-cpu/traits.h +38 -0
- data/vendor/ggml/src/ggml-cpu/unary-ops.cpp +337 -0
- data/vendor/ggml/src/ggml-cpu/unary-ops.h +35 -0
- data/vendor/ggml/src/ggml-cpu/vec.cpp +629 -0
- data/vendor/ggml/src/ggml-cpu/vec.h +1588 -0
- data/vendor/ggml/src/ggml-cuda/CMakeLists.txt +268 -0
- data/vendor/ggml/src/ggml-cuda/acc.cu +61 -0
- data/vendor/ggml/src/ggml-cuda/acc.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/add-id.cu +58 -0
- data/vendor/ggml/src/ggml-cuda/add-id.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/allreduce.cu +971 -0
- data/vendor/ggml/src/ggml-cuda/allreduce.cuh +29 -0
- data/vendor/ggml/src/ggml-cuda/arange.cu +34 -0
- data/vendor/ggml/src/ggml-cuda/arange.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/argmax.cu +91 -0
- data/vendor/ggml/src/ggml-cuda/argmax.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/argsort.cu +266 -0
- data/vendor/ggml/src/ggml-cuda/argsort.cuh +19 -0
- data/vendor/ggml/src/ggml-cuda/binbcast.cu +534 -0
- data/vendor/ggml/src/ggml-cuda/binbcast.cuh +12 -0
- data/vendor/ggml/src/ggml-cuda/clamp.cu +45 -0
- data/vendor/ggml/src/ggml-cuda/clamp.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/common.cuh +1489 -0
- data/vendor/ggml/src/ggml-cuda/concat.cu +204 -0
- data/vendor/ggml/src/ggml-cuda/concat.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/conv-transpose-1d.cu +86 -0
- data/vendor/ggml/src/ggml-cuda/conv-transpose-1d.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/conv2d-dw.cu +161 -0
- data/vendor/ggml/src/ggml-cuda/conv2d-dw.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/conv2d-transpose.cu +115 -0
- data/vendor/ggml/src/ggml-cuda/conv2d-transpose.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/conv2d.cu +166 -0
- data/vendor/ggml/src/ggml-cuda/conv2d.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/convert.cu +892 -0
- data/vendor/ggml/src/ggml-cuda/convert.cuh +66 -0
- data/vendor/ggml/src/ggml-cuda/count-equal.cu +64 -0
- data/vendor/ggml/src/ggml-cuda/count-equal.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/cp-async.cuh +57 -0
- data/vendor/ggml/src/ggml-cuda/cpy-utils.cuh +217 -0
- data/vendor/ggml/src/ggml-cuda/cpy.cu +558 -0
- data/vendor/ggml/src/ggml-cuda/cpy.cuh +7 -0
- data/vendor/ggml/src/ggml-cuda/cross-entropy-loss.cu +177 -0
- data/vendor/ggml/src/ggml-cuda/cross-entropy-loss.cuh +7 -0
- data/vendor/ggml/src/ggml-cuda/cumsum.cu +307 -0
- data/vendor/ggml/src/ggml-cuda/cumsum.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/dequantize.cuh +99 -0
- data/vendor/ggml/src/ggml-cuda/diag.cu +77 -0
- data/vendor/ggml/src/ggml-cuda/diag.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/diagmask.cu +40 -0
- data/vendor/ggml/src/ggml-cuda/diagmask.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/fattn-common.cuh +1212 -0
- data/vendor/ggml/src/ggml-cuda/fattn-mma-f16.cuh +2020 -0
- data/vendor/ggml/src/ggml-cuda/fattn-tile.cu +61 -0
- data/vendor/ggml/src/ggml-cuda/fattn-tile.cuh +1347 -0
- data/vendor/ggml/src/ggml-cuda/fattn-vec.cuh +600 -0
- data/vendor/ggml/src/ggml-cuda/fattn-wmma-f16.cu +696 -0
- data/vendor/ggml/src/ggml-cuda/fattn-wmma-f16.cuh +51 -0
- data/vendor/ggml/src/ggml-cuda/fattn.cu +562 -0
- data/vendor/ggml/src/ggml-cuda/fattn.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/fill.cu +37 -0
- data/vendor/ggml/src/ggml-cuda/fill.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/gated_delta_net.cu +311 -0
- data/vendor/ggml/src/ggml-cuda/gated_delta_net.cuh +4 -0
- data/vendor/ggml/src/ggml-cuda/getrows.cu +300 -0
- data/vendor/ggml/src/ggml-cuda/getrows.cuh +15 -0
- data/vendor/ggml/src/ggml-cuda/ggml-cuda.cu +5684 -0
- data/vendor/ggml/src/ggml-cuda/gla.cu +93 -0
- data/vendor/ggml/src/ggml-cuda/gla.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/im2col.cu +267 -0
- data/vendor/ggml/src/ggml-cuda/im2col.cuh +6 -0
- data/vendor/ggml/src/ggml-cuda/mean.cu +75 -0
- data/vendor/ggml/src/ggml-cuda/mean.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/mma.cuh +1456 -0
- data/vendor/ggml/src/ggml-cuda/mmf.cu +191 -0
- data/vendor/ggml/src/ggml-cuda/mmf.cuh +908 -0
- data/vendor/ggml/src/ggml-cuda/mmid.cu +164 -0
- data/vendor/ggml/src/ggml-cuda/mmid.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/mmq.cu +372 -0
- data/vendor/ggml/src/ggml-cuda/mmq.cuh +4176 -0
- data/vendor/ggml/src/ggml-cuda/mmvf.cu +862 -0
- data/vendor/ggml/src/ggml-cuda/mmvf.cuh +14 -0
- data/vendor/ggml/src/ggml-cuda/mmvq.cu +1161 -0
- data/vendor/ggml/src/ggml-cuda/mmvq.cuh +16 -0
- data/vendor/ggml/src/ggml-cuda/norm.cu +672 -0
- data/vendor/ggml/src/ggml-cuda/norm.cuh +18 -0
- data/vendor/ggml/src/ggml-cuda/opt-step-adamw.cu +78 -0
- data/vendor/ggml/src/ggml-cuda/opt-step-adamw.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/opt-step-sgd.cu +49 -0
- data/vendor/ggml/src/ggml-cuda/opt-step-sgd.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/out-prod.cu +84 -0
- data/vendor/ggml/src/ggml-cuda/out-prod.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/pad.cu +106 -0
- data/vendor/ggml/src/ggml-cuda/pad.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/pad_reflect_1d.cu +91 -0
- data/vendor/ggml/src/ggml-cuda/pad_reflect_1d.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/pool2d.cu +94 -0
- data/vendor/ggml/src/ggml-cuda/pool2d.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/quantize.cu +443 -0
- data/vendor/ggml/src/ggml-cuda/quantize.cuh +41 -0
- data/vendor/ggml/src/ggml-cuda/reduce_rows.cuh +39 -0
- data/vendor/ggml/src/ggml-cuda/roll.cu +67 -0
- data/vendor/ggml/src/ggml-cuda/roll.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/rope.cu +665 -0
- data/vendor/ggml/src/ggml-cuda/rope.cuh +9 -0
- data/vendor/ggml/src/ggml-cuda/scale.cu +34 -0
- data/vendor/ggml/src/ggml-cuda/scale.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/set-rows.cu +330 -0
- data/vendor/ggml/src/ggml-cuda/set-rows.cuh +7 -0
- data/vendor/ggml/src/ggml-cuda/set.cu +39 -0
- data/vendor/ggml/src/ggml-cuda/set.cuh +7 -0
- data/vendor/ggml/src/ggml-cuda/snake.cu +72 -0
- data/vendor/ggml/src/ggml-cuda/snake.cuh +8 -0
- data/vendor/ggml/src/ggml-cuda/softcap.cu +34 -0
- data/vendor/ggml/src/ggml-cuda/softcap.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/softmax.cu +472 -0
- data/vendor/ggml/src/ggml-cuda/softmax.cuh +7 -0
- data/vendor/ggml/src/ggml-cuda/solve_tri.cu +275 -0
- data/vendor/ggml/src/ggml-cuda/solve_tri.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/ssm-conv.cu +197 -0
- data/vendor/ggml/src/ggml-cuda/ssm-conv.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/ssm-scan.cu +342 -0
- data/vendor/ggml/src/ggml-cuda/ssm-scan.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/sum.cu +41 -0
- data/vendor/ggml/src/ggml-cuda/sum.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/sumrows.cu +43 -0
- data/vendor/ggml/src/ggml-cuda/sumrows.cuh +4 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_16.cu +6 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_32.cu +6 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_1-ncols2_8.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_1.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_2.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_16-ncols2_4.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_16.cu +6 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_32.cu +6 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_4.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_2-ncols2_8.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_1.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_32-ncols2_2.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_16.cu +6 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_2.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_4.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_4-ncols2_8.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_64-ncols2_1.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_1.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_2.cu +10 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_4.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-mma-f16-instance-ncols1_8-ncols2_8.cu +12 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq112-dv112.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq128-dv128.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq192-dv128.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq256-dv256.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq320-dv256.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq40-dv40.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq512-dv512.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq576-dv512.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq64-dv64.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq72-dv72.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq80-dv80.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-tile-instance-dkq96-dv96.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-bf16-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-f16-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_0-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q4_1-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_0-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q5_1-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-bf16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-f16.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q4_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q5_1.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/fattn-vec-instance-q8_0-q8_0.cu +7 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/generate_cu_files.py +110 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_1.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_10.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_11.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_12.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_13.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_14.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_15.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_16.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_2.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_3.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_4.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_5.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_6.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_7.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_8.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmf-instance-ncols_9.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq1_s.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_s.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xs.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq2_xxs.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_s.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq3_xxs.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_nl.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-iq4_xs.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-mxfp4.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-nvfp4.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q1_0.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q2_k.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q3_k.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_0.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_1.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q4_k.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_0.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_1.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q5_k.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q6_k.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/template-instances/mmq-instance-q8_0.cu +5 -0
- data/vendor/ggml/src/ggml-cuda/top-k.cu +95 -0
- data/vendor/ggml/src/ggml-cuda/top-k.cuh +3 -0
- data/vendor/ggml/src/ggml-cuda/topk-moe.cu +415 -0
- data/vendor/ggml/src/ggml-cuda/topk-moe.cuh +27 -0
- data/vendor/ggml/src/ggml-cuda/tri.cu +136 -0
- data/vendor/ggml/src/ggml-cuda/tri.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/tsembd.cu +47 -0
- data/vendor/ggml/src/ggml-cuda/tsembd.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/unary.cu +640 -0
- data/vendor/ggml/src/ggml-cuda/unary.cuh +114 -0
- data/vendor/ggml/src/ggml-cuda/upscale.cu +293 -0
- data/vendor/ggml/src/ggml-cuda/upscale.cuh +5 -0
- data/vendor/ggml/src/ggml-cuda/vecdotq.cuh +1317 -0
- data/vendor/ggml/src/ggml-cuda/vendors/cuda.h +28 -0
- data/vendor/ggml/src/ggml-cuda/vendors/hip.h +304 -0
- data/vendor/ggml/src/ggml-cuda/vendors/musa.h +150 -0
- data/vendor/ggml/src/ggml-cuda/wkv.cu +199 -0
- data/vendor/ggml/src/ggml-cuda/wkv.cuh +7 -0
- data/vendor/ggml/src/ggml-hexagon/CMakeLists.txt +118 -0
- data/vendor/ggml/src/ggml-hexagon/ggml-hexagon.cpp +3680 -0
- data/vendor/ggml/src/ggml-hexagon/htp/CMakeLists.txt +78 -0
- data/vendor/ggml/src/ggml-hexagon/htp/act-ops.c +782 -0
- data/vendor/ggml/src/ggml-hexagon/htp/argsort-ops.c +293 -0
- data/vendor/ggml/src/ggml-hexagon/htp/binary-ops.c +872 -0
- data/vendor/ggml/src/ggml-hexagon/htp/cmake-toolchain.cmake +157 -0
- data/vendor/ggml/src/ggml-hexagon/htp/cpy-ops.c +275 -0
- data/vendor/ggml/src/ggml-hexagon/htp/cumsum-ops.c +270 -0
- data/vendor/ggml/src/ggml-hexagon/htp/diag-ops.c +216 -0
- data/vendor/ggml/src/ggml-hexagon/htp/fill-ops.c +123 -0
- data/vendor/ggml/src/ggml-hexagon/htp/flash-attn-ops.c +727 -0
- data/vendor/ggml/src/ggml-hexagon/htp/gated-delta-net-ops.c +955 -0
- data/vendor/ggml/src/ggml-hexagon/htp/get-rows-ops.c +124 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hex-dma.c +63 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hex-dma.h +372 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hex-dump.h +86 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hex-fastdiv.h +37 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hex-utils.h +137 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-flash-attn-ops.c +1841 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-matmul-ops.c +1785 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-ops.h +71 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-profile.h +34 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-queue.c +158 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-queue.h +134 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hmx-utils.h +200 -0
- data/vendor/ggml/src/ggml-hexagon/htp/htp-ctx.h +111 -0
- data/vendor/ggml/src/ggml-hexagon/htp/htp-ops.h +181 -0
- data/vendor/ggml/src/ggml-hexagon/htp/htp_iface.idl +22 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-arith.h +443 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-base.h +308 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-copy.h +262 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-div.h +291 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-dump.h +129 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-exp.h +216 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-floor.h +100 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-inverse.h +210 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-reduce.h +296 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-repl.h +74 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-scale.h +133 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-sigmoid.h +142 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-sqrt.h +126 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-types.h +36 -0
- data/vendor/ggml/src/ggml-hexagon/htp/hvx-utils.h +19 -0
- data/vendor/ggml/src/ggml-hexagon/htp/main.c +880 -0
- data/vendor/ggml/src/ggml-hexagon/htp/matmul-ops.c +3173 -0
- data/vendor/ggml/src/ggml-hexagon/htp/repeat-ops.c +148 -0
- data/vendor/ggml/src/ggml-hexagon/htp/rope-ops.c +494 -0
- data/vendor/ggml/src/ggml-hexagon/htp/set-rows-ops.c +184 -0
- data/vendor/ggml/src/ggml-hexagon/htp/softmax-ops.c +407 -0
- data/vendor/ggml/src/ggml-hexagon/htp/solve-tri-ops.c +267 -0
- data/vendor/ggml/src/ggml-hexagon/htp/ssm-conv.c +340 -0
- data/vendor/ggml/src/ggml-hexagon/htp/sum-rows-ops.c +128 -0
- data/vendor/ggml/src/ggml-hexagon/htp/unary-ops.c +657 -0
- data/vendor/ggml/src/ggml-hexagon/htp/vtcm-utils.h +16 -0
- data/vendor/ggml/src/ggml-hexagon/htp/worker-pool.c +293 -0
- data/vendor/ggml/src/ggml-hexagon/htp/worker-pool.h +57 -0
- data/vendor/ggml/src/ggml-hexagon/htp-drv.cpp +418 -0
- data/vendor/ggml/src/ggml-hexagon/htp-drv.h +121 -0
- data/vendor/ggml/src/ggml-hexagon/libdl.h +79 -0
- data/vendor/ggml/src/ggml-hexagon/libggml-htp.inf +40 -0
- data/vendor/ggml/src/ggml-hexagon/op-desc.h +153 -0
- data/vendor/ggml/src/ggml-hip/CMakeLists.txt +157 -0
- data/vendor/ggml/src/ggml-impl.h +783 -0
- data/vendor/ggml/src/ggml-metal/CMakeLists.txt +124 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-common.cpp +457 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-common.h +52 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-context.h +41 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-context.m +739 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-device.cpp +2053 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-device.h +296 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-device.m +1829 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-impl.h +1175 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-ops.cpp +4606 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal-ops.h +97 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal.cpp +950 -0
- data/vendor/ggml/src/ggml-metal/ggml-metal.metal +10679 -0
- data/vendor/ggml/src/ggml-musa/CMakeLists.txt +124 -0
- data/vendor/ggml/src/ggml-musa/mudnn.cu +112 -0
- data/vendor/ggml/src/ggml-musa/mudnn.cuh +12 -0
- data/vendor/ggml/src/ggml-opencl/CMakeLists.txt +189 -0
- data/vendor/ggml/src/ggml-opencl/ggml-opencl.cpp +16374 -0
- data/vendor/ggml/src/ggml-opencl/kernels/add.cl +190 -0
- data/vendor/ggml/src/ggml-opencl/kernels/add_id.cl +42 -0
- data/vendor/ggml/src/ggml-opencl/kernels/argsort.cl +86 -0
- data/vendor/ggml/src/ggml-opencl/kernels/clamp.cl +20 -0
- data/vendor/ggml/src/ggml-opencl/kernels/concat.cl +51 -0
- data/vendor/ggml/src/ggml-opencl/kernels/conv2d.cl +185 -0
- data/vendor/ggml/src/ggml-opencl/kernels/conv2d_f16_f32.cl +176 -0
- data/vendor/ggml/src/ggml-opencl/kernels/cpy.cl +229 -0
- data/vendor/ggml/src/ggml-opencl/kernels/cumsum.cl +139 -0
- data/vendor/ggml/src/ggml-opencl/kernels/cvt.cl +1471 -0
- data/vendor/ggml/src/ggml-opencl/kernels/diag.cl +27 -0
- data/vendor/ggml/src/ggml-opencl/kernels/diag_mask_inf.cl +58 -0
- data/vendor/ggml/src/ggml-opencl/kernels/div.cl +138 -0
- data/vendor/ggml/src/ggml-opencl/kernels/embed_kernel.py +26 -0
- data/vendor/ggml/src/ggml-opencl/kernels/exp.cl +125 -0
- data/vendor/ggml/src/ggml-opencl/kernels/expm1.cl +113 -0
- data/vendor/ggml/src/ggml-opencl/kernels/fill.cl +17 -0
- data/vendor/ggml/src/ggml-opencl/kernels/flash_attn_f16.cl +370 -0
- data/vendor/ggml/src/ggml-opencl/kernels/flash_attn_f32.cl +371 -0
- data/vendor/ggml/src/ggml-opencl/kernels/flash_attn_f32_f16.cl +373 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gelu.cl +89 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_mxfp4_f32.cl +162 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_mxfp4_f32_ns.cl +302 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_q4_0_f32_ns.cl +252 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_q4_1_f32_ns.cl +254 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_q5_0_f32_ns.cl +256 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_moe_q5_1_f32_ns.cl +258 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_iq4_nl_f32.cl +150 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q4_0_f32.cl +139 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q4_1_f32.cl +132 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q4_k_f32.cl +172 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q5_k_f32.cl +176 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q6_k_f32.cl +140 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_noshuffle_q8_0_f32.cl +129 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemm_xmem_f16_f32_os8.cl +233 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_mxfp4_f32.cl +156 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_mxfp4_f32_ns.cl +161 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_q4_0_f32_ns.cl +116 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_q4_1_f32_ns.cl +119 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_q5_0_f32_ns.cl +119 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_moe_q5_1_f32_ns.cl +121 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_iq4_nl_f32.cl +302 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q4_0_f32.cl +274 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q4_0_f32_spec.cl +268 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q4_1_f32.cl +283 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q4_k_f32.cl +318 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q5_k_f32.cl +326 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q6_k_f32.cl +293 -0
- data/vendor/ggml/src/ggml-opencl/kernels/gemv_noshuffle_q8_0_f32.cl +195 -0
- data/vendor/ggml/src/ggml-opencl/kernels/get_rows.cl +187 -0
- data/vendor/ggml/src/ggml-opencl/kernels/glu.cl +378 -0
- data/vendor/ggml/src/ggml-opencl/kernels/group_norm.cl +121 -0
- data/vendor/ggml/src/ggml-opencl/kernels/im2col_f16.cl +57 -0
- data/vendor/ggml/src/ggml-opencl/kernels/im2col_f32.cl +57 -0
- data/vendor/ggml/src/ggml-opencl/kernels/l2_norm.cl +71 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mean.cl +140 -0
- data/vendor/ggml/src/ggml-opencl/kernels/moe_reorder_b.cl +30 -0
- data/vendor/ggml/src/ggml-opencl/kernels/moe_sort_by_expert.cl +82 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul.cl +152 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mat_f16_f32.cl +130 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_f16_f32_kq_kqv.cl +273 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_f16_f32_l4_lm.cl +146 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_f32_f32_l4_lm.cl +147 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_iq4_nl_f32_l4_lm.cl +171 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q4_0_f32_l4_lm.cl +163 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q4_1_f32_l4_lm.cl +165 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q4_k_f32_l4_lm.cl +179 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q5_k_f32_l4_lm.cl +192 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q6_k_f32_l4_lm.cl +158 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mm_q8_0_f32_l4_lm.cl +154 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_f16_f16.cl +118 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32.cl +118 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_1row.cl +94 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl +84 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_f32_f32.cl +118 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_id_mxfp4_f32.cl +189 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_id_mxfp4_f32_flat.cl +176 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_id_q4_0_f32_8x_flat.cl +283 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_id_q8_0_f32.cl +140 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_id_q8_0_f32_flat.cl +222 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_iq4_nl_f32.cl +164 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_iq4_nl_f32_flat.cl +202 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_mxfp4_f32.cl +144 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_mxfp4_f32_flat.cl +167 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32.cl +192 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_16x_flat.cl +307 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_8x_flat.cl +265 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_8x_flat.cl +272 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_v.cl +254 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_1_f32.cl +219 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_1_f32_flat.cl +229 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_k_f32.cl +180 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q4_k_f32_flat.cl +196 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q5_k_f32.cl +187 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q5_k_f32_flat.cl +203 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q6_k_f32.cl +194 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q6_k_f32_flat.cl +194 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q8_0_f32.cl +125 -0
- data/vendor/ggml/src/ggml-opencl/kernels/mul_mv_q8_0_f32_flat.cl +202 -0
- data/vendor/ggml/src/ggml-opencl/kernels/neg.cl +125 -0
- data/vendor/ggml/src/ggml-opencl/kernels/norm.cl +161 -0
- data/vendor/ggml/src/ggml-opencl/kernels/pad.cl +39 -0
- data/vendor/ggml/src/ggml-opencl/kernels/relu.cl +16 -0
- data/vendor/ggml/src/ggml-opencl/kernels/repeat.cl +38 -0
- data/vendor/ggml/src/ggml-opencl/kernels/rms_norm.cl +190 -0
- data/vendor/ggml/src/ggml-opencl/kernels/rope.cl +747 -0
- data/vendor/ggml/src/ggml-opencl/kernels/scale.cl +27 -0
- data/vendor/ggml/src/ggml-opencl/kernels/set_rows.cl +208 -0
- data/vendor/ggml/src/ggml-opencl/kernels/sigmoid.cl +29 -0
- data/vendor/ggml/src/ggml-opencl/kernels/silu.cl +30 -0
- data/vendor/ggml/src/ggml-opencl/kernels/softmax_4_f16.cl +108 -0
- data/vendor/ggml/src/ggml-opencl/kernels/softmax_4_f32.cl +108 -0
- data/vendor/ggml/src/ggml-opencl/kernels/softmax_f16.cl +107 -0
- data/vendor/ggml/src/ggml-opencl/kernels/softmax_f32.cl +107 -0
- data/vendor/ggml/src/ggml-opencl/kernels/softplus.cl +116 -0
- data/vendor/ggml/src/ggml-opencl/kernels/solve_tri.cl +51 -0
- data/vendor/ggml/src/ggml-opencl/kernels/sqr.cl +53 -0
- data/vendor/ggml/src/ggml-opencl/kernels/sqrt.cl +53 -0
- data/vendor/ggml/src/ggml-opencl/kernels/ssm_conv.cl +77 -0
- data/vendor/ggml/src/ggml-opencl/kernels/sub.cl +138 -0
- data/vendor/ggml/src/ggml-opencl/kernels/sum_rows.cl +140 -0
- data/vendor/ggml/src/ggml-opencl/kernels/tanh.cl +109 -0
- data/vendor/ggml/src/ggml-opencl/kernels/transpose.cl +143 -0
- data/vendor/ggml/src/ggml-opencl/kernels/tri.cl +32 -0
- data/vendor/ggml/src/ggml-opencl/kernels/tsembd.cl +48 -0
- data/vendor/ggml/src/ggml-opencl/kernels/upscale.cl +120 -0
- data/vendor/ggml/src/ggml-openvino/CMakeLists.txt +22 -0
- data/vendor/ggml/src/ggml-openvino/ggml-decoder.cpp +985 -0
- data/vendor/ggml/src/ggml-openvino/ggml-decoder.h +294 -0
- data/vendor/ggml/src/ggml-openvino/ggml-openvino-extra.cpp +380 -0
- data/vendor/ggml/src/ggml-openvino/ggml-openvino-extra.h +182 -0
- data/vendor/ggml/src/ggml-openvino/ggml-openvino.cpp +1132 -0
- data/vendor/ggml/src/ggml-openvino/ggml-quants.cpp +956 -0
- data/vendor/ggml/src/ggml-openvino/ggml-quants.h +153 -0
- data/vendor/ggml/src/ggml-openvino/openvino/decoder.h +74 -0
- data/vendor/ggml/src/ggml-openvino/openvino/frontend.cpp +27 -0
- data/vendor/ggml/src/ggml-openvino/openvino/frontend.h +23 -0
- data/vendor/ggml/src/ggml-openvino/openvino/input_model.cpp +17 -0
- data/vendor/ggml/src/ggml-openvino/openvino/input_model.h +29 -0
- data/vendor/ggml/src/ggml-openvino/openvino/node_context.h +112 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/cont.cpp +48 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/cpy.cpp +21 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/flash_attn_ext.cpp +90 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/get_rows.cpp +69 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/glu_geglu.cpp +61 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/glu_swiglu.cpp +62 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/mulmat.cpp +90 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/permute.cpp +102 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/reshape.cpp +83 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/rms_norm.cpp +46 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/rope.cpp +149 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/scale.cpp +41 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/set_rows.cpp +76 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/softmax.cpp +89 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/transpose.cpp +23 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/unary_gelu.cpp +25 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/unary_silu.cpp +27 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op/view.cpp +53 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op_table.cpp +47 -0
- data/vendor/ggml/src/ggml-openvino/openvino/op_table.h +40 -0
- data/vendor/ggml/src/ggml-openvino/openvino/pass/fuse_to_sdpa.cpp +60 -0
- data/vendor/ggml/src/ggml-openvino/openvino/pass/fuse_to_sdpa.h +17 -0
- data/vendor/ggml/src/ggml-openvino/openvino/pass/mark_decompression_convert_constant_folding.h +29 -0
- data/vendor/ggml/src/ggml-openvino/openvino/pass/squeeze_matmul.cpp +58 -0
- data/vendor/ggml/src/ggml-openvino/openvino/pass/squeeze_matmul.h +17 -0
- data/vendor/ggml/src/ggml-openvino/openvino/rt_info/weightless_caching_attributes.hpp +41 -0
- data/vendor/ggml/src/ggml-openvino/openvino/translate_session.cpp +317 -0
- data/vendor/ggml/src/ggml-openvino/openvino/translate_session.h +28 -0
- data/vendor/ggml/src/ggml-openvino/openvino/utils.cpp +257 -0
- data/vendor/ggml/src/ggml-openvino/openvino/utils.h +86 -0
- data/vendor/ggml/src/ggml-openvino/utils.cpp +880 -0
- data/vendor/ggml/src/ggml-openvino/utils.h +143 -0
- data/vendor/ggml/src/ggml-opt.cpp +1094 -0
- data/vendor/ggml/src/ggml-quants.c +5491 -0
- data/vendor/ggml/src/ggml-quants.h +112 -0
- data/vendor/ggml/src/ggml-rpc/CMakeLists.txt +33 -0
- data/vendor/ggml/src/ggml-rpc/ggml-rpc.cpp +1974 -0
- data/vendor/ggml/src/ggml-rpc/transport.cpp +683 -0
- data/vendor/ggml/src/ggml-rpc/transport.h +34 -0
- data/vendor/ggml/src/ggml-sycl/CMakeLists.txt +207 -0
- data/vendor/ggml/src/ggml-sycl/add-id.cpp +81 -0
- data/vendor/ggml/src/ggml-sycl/add-id.hpp +8 -0
- data/vendor/ggml/src/ggml-sycl/backend.hpp +48 -0
- data/vendor/ggml/src/ggml-sycl/binbcast.cpp +346 -0
- data/vendor/ggml/src/ggml-sycl/binbcast.hpp +39 -0
- data/vendor/ggml/src/ggml-sycl/common.cpp +155 -0
- data/vendor/ggml/src/ggml-sycl/common.hpp +1002 -0
- data/vendor/ggml/src/ggml-sycl/concat.cpp +202 -0
- data/vendor/ggml/src/ggml-sycl/concat.hpp +20 -0
- data/vendor/ggml/src/ggml-sycl/conv.cpp +101 -0
- data/vendor/ggml/src/ggml-sycl/conv.hpp +20 -0
- data/vendor/ggml/src/ggml-sycl/convert.cpp +825 -0
- data/vendor/ggml/src/ggml-sycl/convert.hpp +64 -0
- data/vendor/ggml/src/ggml-sycl/count-equal.cpp +79 -0
- data/vendor/ggml/src/ggml-sycl/count-equal.hpp +9 -0
- data/vendor/ggml/src/ggml-sycl/cpy.cpp +602 -0
- data/vendor/ggml/src/ggml-sycl/cpy.hpp +223 -0
- data/vendor/ggml/src/ggml-sycl/cumsum.cpp +148 -0
- data/vendor/ggml/src/ggml-sycl/cumsum.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/dequantize.hpp +975 -0
- data/vendor/ggml/src/ggml-sycl/diag.cpp +67 -0
- data/vendor/ggml/src/ggml-sycl/diag.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/dmmv.cpp +1579 -0
- data/vendor/ggml/src/ggml-sycl/dmmv.hpp +27 -0
- data/vendor/ggml/src/ggml-sycl/dpct/helper.hpp +3774 -0
- data/vendor/ggml/src/ggml-sycl/element_wise.cpp +1124 -0
- data/vendor/ggml/src/ggml-sycl/element_wise.hpp +94 -0
- data/vendor/ggml/src/ggml-sycl/fattn-buffers.cpp +56 -0
- data/vendor/ggml/src/ggml-sycl/fattn-buffers.hpp +63 -0
- data/vendor/ggml/src/ggml-sycl/fattn-common.hpp +1181 -0
- data/vendor/ggml/src/ggml-sycl/fattn-tile.cpp +59 -0
- data/vendor/ggml/src/ggml-sycl/fattn-tile.hpp +1246 -0
- data/vendor/ggml/src/ggml-sycl/fattn-vec.hpp +674 -0
- data/vendor/ggml/src/ggml-sycl/fattn.cpp +227 -0
- data/vendor/ggml/src/ggml-sycl/fattn.hpp +22 -0
- data/vendor/ggml/src/ggml-sycl/fill.cpp +55 -0
- data/vendor/ggml/src/ggml-sycl/fill.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/gated_delta_net.cpp +307 -0
- data/vendor/ggml/src/ggml-sycl/gated_delta_net.hpp +9 -0
- data/vendor/ggml/src/ggml-sycl/gemm.hpp +93 -0
- data/vendor/ggml/src/ggml-sycl/getrows.cpp +219 -0
- data/vendor/ggml/src/ggml-sycl/getrows.hpp +20 -0
- data/vendor/ggml/src/ggml-sycl/ggml-sycl.cpp +5520 -0
- data/vendor/ggml/src/ggml-sycl/gla.cpp +106 -0
- data/vendor/ggml/src/ggml-sycl/gla.hpp +8 -0
- data/vendor/ggml/src/ggml-sycl/im2col.cpp +400 -0
- data/vendor/ggml/src/ggml-sycl/im2col.hpp +23 -0
- data/vendor/ggml/src/ggml-sycl/mmq.cpp +3030 -0
- data/vendor/ggml/src/ggml-sycl/mmq.hpp +33 -0
- data/vendor/ggml/src/ggml-sycl/mmvq.cpp +1380 -0
- data/vendor/ggml/src/ggml-sycl/mmvq.hpp +43 -0
- data/vendor/ggml/src/ggml-sycl/norm.cpp +656 -0
- data/vendor/ggml/src/ggml-sycl/norm.hpp +28 -0
- data/vendor/ggml/src/ggml-sycl/outprod.cpp +47 -0
- data/vendor/ggml/src/ggml-sycl/outprod.hpp +10 -0
- data/vendor/ggml/src/ggml-sycl/pad.cpp +97 -0
- data/vendor/ggml/src/ggml-sycl/pad.hpp +24 -0
- data/vendor/ggml/src/ggml-sycl/pad_reflect_1d.cpp +100 -0
- data/vendor/ggml/src/ggml-sycl/pad_reflect_1d.hpp +10 -0
- data/vendor/ggml/src/ggml-sycl/presets.hpp +79 -0
- data/vendor/ggml/src/ggml-sycl/quantize.hpp +133 -0
- data/vendor/ggml/src/ggml-sycl/quants.hpp +156 -0
- data/vendor/ggml/src/ggml-sycl/repeat_back.cpp +76 -0
- data/vendor/ggml/src/ggml-sycl/repeat_back.hpp +8 -0
- data/vendor/ggml/src/ggml-sycl/roll.cpp +122 -0
- data/vendor/ggml/src/ggml-sycl/roll.hpp +20 -0
- data/vendor/ggml/src/ggml-sycl/rope.cpp +641 -0
- data/vendor/ggml/src/ggml-sycl/rope.hpp +26 -0
- data/vendor/ggml/src/ggml-sycl/set.cpp +73 -0
- data/vendor/ggml/src/ggml-sycl/set.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/set_rows.cpp +240 -0
- data/vendor/ggml/src/ggml-sycl/set_rows.hpp +8 -0
- data/vendor/ggml/src/ggml-sycl/softmax.cpp +426 -0
- data/vendor/ggml/src/ggml-sycl/softmax.hpp +24 -0
- data/vendor/ggml/src/ggml-sycl/solve_tri.cpp +172 -0
- data/vendor/ggml/src/ggml-sycl/solve_tri.hpp +8 -0
- data/vendor/ggml/src/ggml-sycl/ssm_conv.cpp +132 -0
- data/vendor/ggml/src/ggml-sycl/ssm_conv.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/ssm_scan.cpp +156 -0
- data/vendor/ggml/src/ggml-sycl/ssm_scan.hpp +5 -0
- data/vendor/ggml/src/ggml-sycl/sycl_hw.cpp +67 -0
- data/vendor/ggml/src/ggml-sycl/sycl_hw.hpp +38 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq112-dv112.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq128-dv128.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq256-dv256.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq40-dv40.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq512-dv512.cpp +6 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq576-dv512.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq64-dv64.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq72-dv72.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq80-dv80.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-tile-instance-dkq96-dv96.cpp +5 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-f16-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_0-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q4_1-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_0-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q5_1-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-f16.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q4_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q4_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q5_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q5_1.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/template-instances/fattn-vec-instance-q8_0-q8_0.cpp +8 -0
- data/vendor/ggml/src/ggml-sycl/tsembd.cpp +73 -0
- data/vendor/ggml/src/ggml-sycl/tsembd.hpp +20 -0
- data/vendor/ggml/src/ggml-sycl/type.hpp +112 -0
- data/vendor/ggml/src/ggml-sycl/upscale.cpp +410 -0
- data/vendor/ggml/src/ggml-sycl/upscale.hpp +9 -0
- data/vendor/ggml/src/ggml-sycl/vecdotq.hpp +1508 -0
- data/vendor/ggml/src/ggml-sycl/wkv.cpp +293 -0
- data/vendor/ggml/src/ggml-sycl/wkv.hpp +10 -0
- data/vendor/ggml/src/ggml-threading.cpp +12 -0
- data/vendor/ggml/src/ggml-threading.h +14 -0
- data/vendor/ggml/src/ggml-virtgpu/CMakeLists.txt +70 -0
- data/vendor/ggml/src/ggml-virtgpu/apir_cs_ggml-rpc-front.cpp +87 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/CMakeLists.txt +21 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/apir_cs_ggml-rpc-back.cpp +115 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-convert.h +13 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched-backend.cpp +102 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched-buffer-type.cpp +105 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched-buffer.cpp +179 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched-device.cpp +148 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched.cpp +51 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched.gen.h +73 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-dispatched.h +27 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend-virgl-apir.h +32 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/backend.cpp +144 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/api_remoting.h +95 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/apir_backend.gen.h +94 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/apir_backend.h +50 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/apir_cs.h +378 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/apir_cs_ggml.h +232 -0
- data/vendor/ggml/src/ggml-virtgpu/backend/shared/apir_cs_rpc.h +58 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-backend-buffer-type.cpp +81 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-backend-buffer.cpp +123 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-backend-device.cpp +160 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-backend-reg.cpp +213 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-backend.cpp +71 -0
- data/vendor/ggml/src/ggml-virtgpu/ggml-remoting.h +71 -0
- data/vendor/ggml/src/ggml-virtgpu/ggmlremoting_functions.yaml +166 -0
- data/vendor/ggml/src/ggml-virtgpu/include/apir_hw.h +9 -0
- data/vendor/ggml/src/ggml-virtgpu/regenerate_remoting.py +333 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-apir.h +15 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward-backend.cpp +58 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward-buffer-type.cpp +110 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward-buffer.cpp +173 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward-device.cpp +192 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward-impl.h +36 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-forward.gen.h +53 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-shm.cpp +99 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-shm.h +23 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-utils.cpp +179 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu-utils.h +86 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu.cpp +545 -0
- data/vendor/ggml/src/ggml-virtgpu/virtgpu.h +115 -0
- data/vendor/ggml/src/ggml-vulkan/CMakeLists.txt +220 -0
- data/vendor/ggml/src/ggml-vulkan/cmake/host-toolchain.cmake.in +15 -0
- data/vendor/ggml/src/ggml-vulkan/ggml-vulkan.cpp +17208 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt +31 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/abs.comp +21 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/acc.comp +37 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/add.comp +69 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/add1.comp +28 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/add_id.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/arange.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/argmax.comp +60 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/argsort.comp +86 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/argsort_large.comp +114 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/ceil.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/clamp.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/concat.comp +41 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/contig_copy.comp +49 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_dw.comp +105 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_mm.comp +347 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/conv_transpose_1d.comp +98 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/copy.comp +23 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/copy_from_quant.comp +51 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/copy_to_quant.comp +320 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/copy_transpose.comp +67 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/cos.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/count_equal.comp +31 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/count_experts.comp +51 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/cumsum.comp +83 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/cumsum_multipass1.comp +60 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/cumsum_multipass2.comp +66 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_f32.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs.glsl +653 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs_cm2.glsl +768 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_head.glsl +13 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_s.comp +35 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_s.comp +44 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_xs.comp +43 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_xxs.comp +49 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq3_s.comp +40 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq3_xxs.comp +51 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq4_nl.comp +32 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq4_xs.comp +34 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_mxfp4.comp +32 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_nvfp4.comp +32 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q1_0.comp +29 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q2_k.comp +34 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q3_k.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_0.comp +30 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_1.comp +32 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_k.comp +68 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_0.comp +34 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_1.comp +35 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_k.comp +70 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q6_k.comp +33 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q8_0.comp +31 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/diag.comp +28 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/diag_mask_inf.comp +34 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/div.comp +27 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/elu.comp +27 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/exp.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/bfloat16.comp +7 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/coopmat.comp +7 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/coopmat2.comp +7 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/integer_dot.comp +7 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/fill.comp +19 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn.comp +756 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_base.glsl +255 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm1.comp +626 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm2.comp +427 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_dequant.glsl +123 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_mask_opt.comp +162 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_mmq_funcs.glsl +203 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_split_k_reduce.comp +121 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/floor.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/gated_delta_net.comp +190 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/geglu.comp +13 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/geglu_erf.comp +27 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/geglu_quick.comp +11 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/gelu.comp +25 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/gelu_erf.comp +39 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/gelu_quick.comp +23 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/generic_binary_head.glsl +65 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/generic_head.glsl +11 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/generic_unary_head.glsl +83 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/get_rows.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/get_rows_quant.comp +51 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/glu_head.glsl +28 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/glu_main.glsl +39 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/group_norm.comp +66 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/hardsigmoid.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/hardswish.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp +93 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/im2col_3d.comp +124 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/l2_norm.comp +44 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/leaky_relu.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/log.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul.comp +27 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_split_k_reduce.comp +48 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec.comp +169 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_base.glsl +230 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iface.glsl +35 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq1_m.comp +132 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq1_s.comp +95 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_s.comp +90 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_xs.comp +105 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_xxs.comp +87 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq3_s.comp +90 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq3_xxs.comp +88 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_nc.comp +124 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_p021.comp +156 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q2_k.comp +128 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q3_k.comp +132 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q4_k.comp +134 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q5_k.comp +165 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q6_k.comp +130 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq.comp +143 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq_funcs.glsl +503 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +464 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_cm2.comp +624 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_funcs.glsl +600 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_id_funcs.glsl +74 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq.comp +311 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_funcs.glsl +454 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_shmem_types.glsl +93 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/multi_add.comp +194 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/neg.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/norm.comp +44 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/opt_step_adamw.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/opt_step_sgd.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/pad.comp +64 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/pool2d.comp +74 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/quantize_q8_1.comp +127 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/reglu.comp +9 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/relu.comp +21 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/repeat.comp +26 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/repeat_back.comp +37 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm.comp +150 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm_back.comp +55 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm_partials.comp +65 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/roll.comp +46 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_funcs.glsl +207 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_head.glsl +19 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_multi.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_neox.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_norm.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_params.glsl +31 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/rope_vision.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/round.comp +29 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/scale.comp +24 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sgn.comp +21 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sigmoid.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/silu.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/silu_back.comp +26 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sin.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max.comp +195 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_back.comp +54 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large1.comp +62 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large2.comp +79 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large3.comp +65 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large_common.glsl +53 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/softplus.comp +23 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/solve_tri.comp +81 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sqrt.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/square.comp +17 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/ssm_conv.comp +50 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/ssm_scan.comp +124 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/step.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sub.comp +29 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sum_rows.comp +47 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/sum_rows.glsl +25 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/swiglu.comp +9 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/swiglu_oai.comp +14 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/tanh.comp +20 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/timestep_embedding.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/topk_argsort.comp +118 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/topk_moe.comp +213 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/topk_nary_search.comp +246 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/tri.comp +42 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/trunc.comp +22 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/types.glsl +1846 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/upscale.comp +178 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/utils.glsl +25 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +1183 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/wkv6.comp +87 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/wkv7.comp +91 -0
- data/vendor/ggml/src/ggml-vulkan/vulkan-shaders/xielu.comp +35 -0
- data/vendor/ggml/src/ggml-webgpu/CMakeLists.txt +80 -0
- data/vendor/ggml/src/ggml-webgpu/ggml-webgpu-shader-lib.hpp +3231 -0
- data/vendor/ggml/src/ggml-webgpu/ggml-webgpu.cpp +4461 -0
- data/vendor/ggml/src/ggml-webgpu/pre_wgsl.hpp +778 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/add_id.wgsl +64 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/argmax.wgsl +72 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/argsort.wgsl +106 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/argsort_merge.wgsl +134 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/binary.wgsl +139 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/common_decls.tmpl +905 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/concat.wgsl +75 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/conv2d.wgsl +165 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/cpy.wgsl +81 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/cumsum.wgsl +66 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/embed_wgsl.py +89 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn.wgsl +706 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_tile.wgsl +351 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_blk.wgsl +101 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_reduce.wgsl +84 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn_vec_split.wgsl +720 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/gated_delta_net.wgsl +132 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/get_rows.wgsl +773 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/glu.wgsl +155 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/im2col.wgsl +101 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/memset.wgsl +40 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat.wgsl +747 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_decls.tmpl +1210 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id.wgsl +195 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_gather.wgsl +55 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_id_vec.wgsl +154 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_reg_tile.wgsl +149 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_subgroup_matrix.wgsl +200 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec.wgsl +133 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec_acc.tmpl +1433 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/pad.wgsl +86 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/repeat.wgsl +67 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/rms_norm_mul.wgsl +152 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/rope.wgsl +224 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/row_norm.wgsl +153 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/scale.wgsl +63 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/set.wgsl +109 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/set_rows.wgsl +109 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/soft_max.wgsl +245 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/solve_tri.wgsl +121 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/ssm_conv.wgsl +65 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/ssm_scan.wgsl +193 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/sum_rows.wgsl +55 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/unary.wgsl +210 -0
- data/vendor/ggml/src/ggml-webgpu/wgsl-shaders/upscale.wgsl +240 -0
- data/vendor/ggml/src/ggml-zdnn/CMakeLists.txt +36 -0
- data/vendor/ggml/src/ggml-zdnn/common.hpp +59 -0
- data/vendor/ggml/src/ggml-zdnn/ggml-zdnn.cpp +637 -0
- data/vendor/ggml/src/ggml-zdnn/mmf.cpp +80 -0
- data/vendor/ggml/src/ggml-zdnn/mmf.hpp +12 -0
- data/vendor/ggml/src/ggml-zdnn/utils.cpp +79 -0
- data/vendor/ggml/src/ggml-zdnn/utils.hpp +19 -0
- data/vendor/ggml/src/ggml-zendnn/CMakeLists.txt +91 -0
- data/vendor/ggml/src/ggml-zendnn/ggml-zendnn.cpp +669 -0
- data/vendor/ggml/src/ggml.c +7777 -0
- data/vendor/ggml/src/ggml.cpp +26 -0
- data/vendor/ggml/src/gguf.cpp +1556 -0
- data/vendor/ggml/tests/CMakeLists.txt +356 -0
- data/vendor/ggml/tests/test-arange.cpp +100 -0
- data/vendor/ggml/tests/test-backend-ops.cpp +9786 -0
- data/vendor/ggml/tests/test-cont.c +170 -0
- data/vendor/ggml/tests/test-conv-transpose-1d.cpp +691 -0
- data/vendor/ggml/tests/test-conv-transpose.c +248 -0
- data/vendor/ggml/tests/test-conv1d-dw-c1.cpp +243 -0
- data/vendor/ggml/tests/test-conv1d-dw-c2.cpp +243 -0
- data/vendor/ggml/tests/test-conv1d.cpp +289 -0
- data/vendor/ggml/tests/test-conv2d-dw.cpp +153 -0
- data/vendor/ggml/tests/test-conv2d.cpp +391 -0
- data/vendor/ggml/tests/test-customop.c +300 -0
- data/vendor/ggml/tests/test-dup.c +111 -0
- data/vendor/ggml/tests/test-interpolate.cpp +166 -0
- data/vendor/ggml/tests/test-opt.cpp +1003 -0
- data/vendor/ggml/tests/test-pad-reflect-1d.cpp +213 -0
- data/vendor/ggml/tests/test-pool.c +274 -0
- data/vendor/ggml/tests/test-quantize-fns.cpp +196 -0
- data/vendor/ggml/tests/test-quantize-perf.cpp +356 -0
- data/vendor/ggml/tests/test-rel-pos.c +87 -0
- data/vendor/ggml/tests/test-roll.cpp +128 -0
- data/vendor/ggml/tests/test-timestep_embedding.cpp +180 -0
- data/vendor-patches/0001-cuda-buffer_from_ptr.patch +253 -0
- data/vendor-patches/0002-cuda-buffer_from_ptr-reuse-iface.patch +117 -0
- data/vendor-patches/0003-cuda-buffer_from_ptr-copy-mode.patch +128 -0
- data/vendor-patches/0004-cuda-cpy-strided.patch +61 -0
- data/vendor-patches/0005-concat-backward.patch +36 -0
- data/vendor-patches/0006-getrows-back-large-vocab.patch +69 -0
- data/vendor-patches/0007-gpt2-backward-kernels.patch +438 -0
- data/vendor-patches/0008-mul-mat-backward-mixed-precision.patch +50 -0
- data/vendor-patches/0009-sched-unsupported-node-diagnostic.patch +26 -0
- metadata +2161 -0
|
@@ -0,0 +1,4461 @@
|
|
|
1
|
+
/*
|
|
2
|
+
WebGPU backend implementation.
|
|
3
|
+
Note: Use ClangFormat to format this file.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#include "ggml-webgpu.h"
|
|
7
|
+
|
|
8
|
+
#include "ggml-backend-impl.h"
|
|
9
|
+
#include "ggml-impl.h"
|
|
10
|
+
#include "ggml-webgpu-shader-lib.hpp"
|
|
11
|
+
#include "ggml.h"
|
|
12
|
+
|
|
13
|
+
#ifdef __EMSCRIPTEN__
|
|
14
|
+
# include <emscripten/emscripten.h>
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#include <webgpu/webgpu_cpp.h>
|
|
18
|
+
|
|
19
|
+
#include <atomic>
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <cstring>
|
|
22
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
23
|
+
# include <iomanip>
|
|
24
|
+
#endif
|
|
25
|
+
#if defined(GGML_WEBGPU_DEBUG) || defined(GGML_WEBGPU_CPU_PROFILE) || defined(GGML_WEBGPU_GPU_PROFILE)
|
|
26
|
+
# include <iostream>
|
|
27
|
+
#endif
|
|
28
|
+
#include <memory>
|
|
29
|
+
#include <mutex>
|
|
30
|
+
#include <optional>
|
|
31
|
+
#include <string>
|
|
32
|
+
#include <utility>
|
|
33
|
+
#include <vector>
|
|
34
|
+
|
|
35
|
+
#define ROUNDUP_POW2(x, pow2) (((x) + ((pow2) - 1)) & ~((pow2) - 1))
|
|
36
|
+
#define CEIL_DIV(M, N) (((M) + (N) - 1) / (N))
|
|
37
|
+
|
|
38
|
+
// Return a rectangular grid of workgroups with minimal over-provisioned workgroups.
|
|
39
|
+
// Assumes that the total number of workgroups does not exceed max_per_dim^2.
|
|
40
|
+
static inline void compute_2d_workgroups(uint32_t total_wg, uint32_t max_per_dim, uint32_t & wg_x, uint32_t & wg_y) {
|
|
41
|
+
wg_y = std::max(1u, CEIL_DIV(total_wg, max_per_dim));
|
|
42
|
+
wg_x = CEIL_DIV(total_wg, wg_y);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static inline uint32_t ggml_webgpu_u32_from_f32(float value) {
|
|
46
|
+
uint32_t bits;
|
|
47
|
+
memcpy(&bits, &value, sizeof(bits));
|
|
48
|
+
return bits;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#ifdef GGML_WEBGPU_DEBUG
|
|
52
|
+
# define WEBGPU_LOG_DEBUG(msg) std::cout << msg << std::endl
|
|
53
|
+
# define WEBGPU_DEBUG_BUF_ELEMS 512
|
|
54
|
+
#else
|
|
55
|
+
# define WEBGPU_LOG_DEBUG(msg) ((void) 0)
|
|
56
|
+
#endif // GGML_WEBGPU_DEBUG
|
|
57
|
+
|
|
58
|
+
#ifdef GGML_WEBGPU_CPU_PROFILE
|
|
59
|
+
// total timing (aggregated)
|
|
60
|
+
# define WEBGPU_CPU_PROFILE_TOTAL_START(id) auto cpu_total_start_##id = std::chrono::high_resolution_clock::now();
|
|
61
|
+
|
|
62
|
+
# define WEBGPU_CPU_PROFILE_TOTAL_END(id, ctx) \
|
|
63
|
+
auto cpu_total_end_##id = std::chrono::high_resolution_clock::now(); \
|
|
64
|
+
double cpu_total_time_##id = \
|
|
65
|
+
std::chrono::duration<double, std::milli>(cpu_total_end_##id - cpu_total_start_##id).count(); \
|
|
66
|
+
(ctx)->cpu_time_ms[#id] += cpu_total_time_##id;
|
|
67
|
+
// fine-grained timing (not included in totals)
|
|
68
|
+
# define WEBGPU_CPU_PROFILE_DETAIL_START(id) auto cpu_detail_start_##id = std::chrono::high_resolution_clock::now();
|
|
69
|
+
|
|
70
|
+
# define WEBGPU_CPU_PROFILE_DETAIL_END(id, ctx) \
|
|
71
|
+
auto cpu_detail_end_##id = std::chrono::high_resolution_clock::now(); \
|
|
72
|
+
double cpu_detail_time_##id = \
|
|
73
|
+
std::chrono::duration<double, std::milli>(cpu_detail_end_##id - cpu_detail_start_##id).count(); \
|
|
74
|
+
(ctx)->cpu_detail_ms[#id] += cpu_detail_time_##id;
|
|
75
|
+
#else
|
|
76
|
+
# define WEBGPU_CPU_PROFILE_TOTAL_START(id)
|
|
77
|
+
# define WEBGPU_CPU_PROFILE_TOTAL_END(id, ctx)
|
|
78
|
+
# define WEBGPU_CPU_PROFILE_DETAIL_START(id)
|
|
79
|
+
# define WEBGPU_CPU_PROFILE_DETAIL_END(id, ctx)
|
|
80
|
+
#endif // GGML_WEBGPU_CPU_PROFILE
|
|
81
|
+
|
|
82
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
83
|
+
# define WEBGPU_MAX_PROFILE_QUERY_COUNT 4096u
|
|
84
|
+
# define WEBGPU_TIMESTAMP_QUERY_BUF_SIZE_BYTES (WEBGPU_MAX_PROFILE_QUERY_COUNT * sizeof(uint64_t))
|
|
85
|
+
#endif
|
|
86
|
+
|
|
87
|
+
/* Constants */
|
|
88
|
+
|
|
89
|
+
#define WEBGPU_DEFAULT_COMMAND_SUBMIT_BATCH_SIZE 64u
|
|
90
|
+
#define WEBGPU_NUM_PARAM_SLOT_SAFETY_MARGIN 10u
|
|
91
|
+
#define WEBGPU_RUNTIME_WAIT_TIMEOUT_MS 30000u
|
|
92
|
+
#define WEBGPU_RUNTIME_WAIT_TIMEOUT_NS (WEBGPU_RUNTIME_WAIT_TIMEOUT_MS * 1e6)
|
|
93
|
+
#define WEBGPU_PARAMS_BUF_SIZE_BYTES 128 // enough for 32 parameters
|
|
94
|
+
#define WEBGPU_SET_ROWS_ERROR_BUF_SIZE_BYTES 4
|
|
95
|
+
#define WEBGPU_STORAGE_BUF_BINDING_MULT 4 // a storage buffer binding size must be a multiple of 4
|
|
96
|
+
|
|
97
|
+
// For operations which process a row in parallel, this seems like a reasonable
|
|
98
|
+
// default
|
|
99
|
+
#define WEBGPU_ROW_SPLIT_WG_SIZE 64
|
|
100
|
+
|
|
101
|
+
// Track https://github.com/gpuweb/gpuweb/issues/5315 for fixes to
|
|
102
|
+
// implementations so this can be removed, necessary only for get_rows right now
|
|
103
|
+
#define WEBGPU_MAX_WG_SIZE 288
|
|
104
|
+
|
|
105
|
+
/* End Constants */
|
|
106
|
+
|
|
107
|
+
// This is a "fake" base pointer, since WebGPU buffers do not have pointers to
|
|
108
|
+
// their locations.
|
|
109
|
+
static void * const webgpu_ptr_base = (void *) (uintptr_t) 0x1000; // NOLINT
|
|
110
|
+
|
|
111
|
+
static size_t ggml_webgpu_tensor_offset(const ggml_tensor * tensor) {
|
|
112
|
+
const ggml_tensor * base_tensor = tensor->view_src ? tensor->view_src : tensor;
|
|
113
|
+
return (size_t) ((uintptr_t) base_tensor->data - (uintptr_t) webgpu_ptr_base) + tensor->view_offs;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Struct definitions */
|
|
117
|
+
|
|
118
|
+
// Forward reference
|
|
119
|
+
static void ggml_webgpu_create_buffer(wgpu::Device & device,
|
|
120
|
+
wgpu::Buffer & buffer,
|
|
121
|
+
size_t size,
|
|
122
|
+
wgpu::BufferUsage usage,
|
|
123
|
+
const char * label);
|
|
124
|
+
|
|
125
|
+
// Slot-based parameter arena for compute graph encoding. Each encoded kernel
|
|
126
|
+
// gets a unique uniform-buffer slice within the current batch, and the slot
|
|
127
|
+
// cursor is reset immediately after that batch is submitted.
|
|
128
|
+
struct webgpu_param_arena {
|
|
129
|
+
wgpu::Buffer buffer;
|
|
130
|
+
size_t slot_stride = 0;
|
|
131
|
+
size_t slot_size = 0;
|
|
132
|
+
uint32_t slot_count = 0;
|
|
133
|
+
uint32_t next_slot = 0;
|
|
134
|
+
|
|
135
|
+
void init(wgpu::Device device, size_t slot_size, uint32_t slot_count, size_t alignment) {
|
|
136
|
+
this->slot_stride = ROUNDUP_POW2(slot_size, alignment);
|
|
137
|
+
this->slot_size = slot_size;
|
|
138
|
+
this->slot_count = slot_count;
|
|
139
|
+
this->next_slot = 0;
|
|
140
|
+
|
|
141
|
+
ggml_webgpu_create_buffer(device, buffer, this->slot_stride * slot_count,
|
|
142
|
+
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform, "ggml_webgpu_param_arena");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
size_t alloc_slot(size_t size) {
|
|
146
|
+
GGML_ASSERT(size <= slot_size);
|
|
147
|
+
if (next_slot >= slot_count) {
|
|
148
|
+
GGML_ABORT("ggml_webgpu: parameter arena exhausted while encoding a batch");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return slot_stride * next_slot++;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
void reset() { next_slot = 0; }
|
|
155
|
+
|
|
156
|
+
void cleanup() {
|
|
157
|
+
if (buffer) {
|
|
158
|
+
buffer.Destroy();
|
|
159
|
+
buffer = nullptr;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
~webgpu_param_arena() { this->cleanup(); }
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
struct webgpu_encoded_op {
|
|
167
|
+
uint32_t num_kernels = 0;
|
|
168
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
169
|
+
std::vector<std::string> pipeline_names;
|
|
170
|
+
#endif
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
struct webgpu_dispatch_desc {
|
|
174
|
+
webgpu_pipeline pipeline;
|
|
175
|
+
std::vector<uint32_t> params;
|
|
176
|
+
std::vector<wgpu::BindGroupEntry> bind_group_entries;
|
|
177
|
+
std::pair<uint32_t, uint32_t> workgroups = { 1, 1 };
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
struct webgpu_capabilities {
|
|
181
|
+
wgpu::Limits limits;
|
|
182
|
+
bool supports_subgroups = false;
|
|
183
|
+
bool supports_subgroup_matrix = false;
|
|
184
|
+
|
|
185
|
+
uint32_t sg_mat_m = 0;
|
|
186
|
+
uint32_t sg_mat_n = 0;
|
|
187
|
+
uint32_t sg_mat_k = 0;
|
|
188
|
+
|
|
189
|
+
uint32_t subgroup_size = 0;
|
|
190
|
+
uint32_t min_subgroup_size = 0;
|
|
191
|
+
uint32_t max_subgroup_size = 0;
|
|
192
|
+
size_t memset_bytes_per_thread;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
// Stores global webgpu members
|
|
196
|
+
struct webgpu_global_context_struct {
|
|
197
|
+
wgpu::Instance instance;
|
|
198
|
+
wgpu::Adapter adapter;
|
|
199
|
+
wgpu::Device device;
|
|
200
|
+
wgpu::Queue queue;
|
|
201
|
+
uint32_t command_submit_batch_size = WEBGPU_DEFAULT_COMMAND_SUBMIT_BATCH_SIZE;
|
|
202
|
+
uint32_t max_inflight_batches = UINT32_MAX;
|
|
203
|
+
|
|
204
|
+
webgpu_capabilities capabilities;
|
|
205
|
+
// Shared buffer to move data from device to host
|
|
206
|
+
wgpu::Buffer get_tensor_staging_buf;
|
|
207
|
+
// Global mutex for get_tensor
|
|
208
|
+
std::recursive_mutex mutex;
|
|
209
|
+
|
|
210
|
+
wgpu::Buffer memset_params_buf;
|
|
211
|
+
webgpu_pipeline memset_pipeline;
|
|
212
|
+
|
|
213
|
+
// TODO: We should rework the CPU profiling time handling to make it more useful. ref: https://github.com/ggml-org/llama.cpp/pull/22050
|
|
214
|
+
#ifdef GGML_WEBGPU_CPU_PROFILE
|
|
215
|
+
// Profiling: labeled CPU time in ms (total)
|
|
216
|
+
std::unordered_map<std::string, double> cpu_time_ms;
|
|
217
|
+
// Profiling: detailed CPU time in ms
|
|
218
|
+
std::unordered_map<std::string, double> cpu_detail_ms;
|
|
219
|
+
#endif
|
|
220
|
+
|
|
221
|
+
#ifdef GGML_WEBGPU_DEBUG
|
|
222
|
+
wgpu::Buffer debug_host_buf;
|
|
223
|
+
wgpu::Buffer debug_dev_buf;
|
|
224
|
+
#endif
|
|
225
|
+
|
|
226
|
+
~webgpu_global_context_struct() {
|
|
227
|
+
if (this->get_tensor_staging_buf) {
|
|
228
|
+
this->get_tensor_staging_buf.Destroy();
|
|
229
|
+
this->get_tensor_staging_buf = nullptr;
|
|
230
|
+
}
|
|
231
|
+
if (this->memset_params_buf) {
|
|
232
|
+
this->memset_params_buf.Destroy();
|
|
233
|
+
this->memset_params_buf = nullptr;
|
|
234
|
+
}
|
|
235
|
+
#ifdef GGML_WEBGPU_DEBUG
|
|
236
|
+
if (this->debug_host_buf) {
|
|
237
|
+
this->debug_host_buf.Destroy();
|
|
238
|
+
this->debug_host_buf = nullptr;
|
|
239
|
+
}
|
|
240
|
+
if (this->debug_dev_buf) {
|
|
241
|
+
this->debug_dev_buf.Destroy();
|
|
242
|
+
this->debug_dev_buf = nullptr;
|
|
243
|
+
}
|
|
244
|
+
#endif
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
typedef std::shared_ptr<webgpu_global_context_struct> webgpu_global_context;
|
|
249
|
+
|
|
250
|
+
// All the base objects needed to run operations on a WebGPU device
|
|
251
|
+
struct webgpu_context_struct {
|
|
252
|
+
// Points to global instances owned by ggml_backend_webgpu_reg_context
|
|
253
|
+
webgpu_global_context global_ctx;
|
|
254
|
+
|
|
255
|
+
std::unique_ptr<ggml_webgpu_shader_lib> shader_lib;
|
|
256
|
+
|
|
257
|
+
webgpu_param_arena param_arena;
|
|
258
|
+
wgpu::Buffer set_rows_dev_error_buf;
|
|
259
|
+
wgpu::Buffer set_rows_host_error_buf;
|
|
260
|
+
wgpu::CommandEncoder active_command_encoder;
|
|
261
|
+
wgpu::ComputePassEncoder active_compute_pass;
|
|
262
|
+
|
|
263
|
+
size_t memset_bytes_per_thread;
|
|
264
|
+
|
|
265
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
266
|
+
// Profiling: per-shader GPU time in ms
|
|
267
|
+
std::unordered_map<std::string, double> shader_gpu_time_ms;
|
|
268
|
+
wgpu::Buffer profile_timestamp_dev_buf;
|
|
269
|
+
wgpu::Buffer profile_timestamp_host_buf;
|
|
270
|
+
wgpu::QuerySet profile_timestamp_query_set;
|
|
271
|
+
uint32_t profile_timestamp_query_count = 0;
|
|
272
|
+
#endif
|
|
273
|
+
|
|
274
|
+
~webgpu_context_struct() {
|
|
275
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
276
|
+
if (this->profile_timestamp_host_buf) {
|
|
277
|
+
this->profile_timestamp_host_buf.Destroy();
|
|
278
|
+
this->profile_timestamp_host_buf = nullptr;
|
|
279
|
+
}
|
|
280
|
+
if (this->profile_timestamp_dev_buf) {
|
|
281
|
+
this->profile_timestamp_dev_buf.Destroy();
|
|
282
|
+
this->profile_timestamp_dev_buf = nullptr;
|
|
283
|
+
}
|
|
284
|
+
if (this->profile_timestamp_query_set) {
|
|
285
|
+
this->profile_timestamp_query_set.Destroy();
|
|
286
|
+
this->profile_timestamp_query_set = nullptr;
|
|
287
|
+
}
|
|
288
|
+
#endif
|
|
289
|
+
if (this->set_rows_host_error_buf) {
|
|
290
|
+
this->set_rows_host_error_buf.Destroy();
|
|
291
|
+
this->set_rows_host_error_buf = nullptr;
|
|
292
|
+
}
|
|
293
|
+
if (this->set_rows_dev_error_buf) {
|
|
294
|
+
this->set_rows_dev_error_buf.Destroy();
|
|
295
|
+
this->set_rows_dev_error_buf = nullptr;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
typedef std::shared_ptr<webgpu_context_struct> webgpu_context;
|
|
301
|
+
|
|
302
|
+
// Metadata required for the ggml backend registration/discovery interface
|
|
303
|
+
struct ggml_backend_webgpu_reg_context {
|
|
304
|
+
// Since the Instance is a global entrypoint into the WebGPU API, it lives here
|
|
305
|
+
webgpu_global_context webgpu_global_ctx;
|
|
306
|
+
size_t device_count;
|
|
307
|
+
const char * name;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// Per-device struct for the global logical device interface
|
|
311
|
+
struct ggml_backend_webgpu_device_context {
|
|
312
|
+
webgpu_global_context webgpu_global_ctx;
|
|
313
|
+
std::string device_name;
|
|
314
|
+
std::string device_desc;
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// Per-thread data required to actually run WebGPU operations in a backend instance
|
|
318
|
+
struct ggml_backend_webgpu_context {
|
|
319
|
+
webgpu_context webgpu_ctx;
|
|
320
|
+
std::string name;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Per-thread data related to buffers
|
|
324
|
+
struct ggml_backend_webgpu_buffer_context {
|
|
325
|
+
wgpu::Buffer buffer;
|
|
326
|
+
std::string label;
|
|
327
|
+
webgpu_global_context global_ctx;
|
|
328
|
+
|
|
329
|
+
ggml_backend_webgpu_buffer_context(wgpu::Buffer buf, std::string lbl, webgpu_global_context global_ctx_) :
|
|
330
|
+
buffer(std::move(buf)),
|
|
331
|
+
label(std::move(lbl)),
|
|
332
|
+
global_ctx(std::move(global_ctx_)) {}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
/* WebGPU object initializations */
|
|
336
|
+
|
|
337
|
+
static webgpu_pipeline ggml_webgpu_create_pipeline(wgpu::Device & device,
|
|
338
|
+
const char * shader_code,
|
|
339
|
+
const char * label,
|
|
340
|
+
const std::vector<wgpu::ConstantEntry> & constants = {}) {
|
|
341
|
+
wgpu::ShaderSourceWGSL shader_source;
|
|
342
|
+
shader_source.code = shader_code;
|
|
343
|
+
|
|
344
|
+
wgpu::ShaderModuleDescriptor shader_desc;
|
|
345
|
+
shader_desc.nextInChain = &shader_source;
|
|
346
|
+
|
|
347
|
+
wgpu::ShaderModule shader_module = device.CreateShaderModule(&shader_desc);
|
|
348
|
+
|
|
349
|
+
wgpu::ComputePipelineDescriptor pipeline_desc;
|
|
350
|
+
pipeline_desc.label = label;
|
|
351
|
+
pipeline_desc.compute.module = shader_module;
|
|
352
|
+
pipeline_desc.compute.entryPoint = "main"; // Entry point in the WGSL code
|
|
353
|
+
pipeline_desc.layout = nullptr; // nullptr means auto layout
|
|
354
|
+
if (constants.size() > 0) {
|
|
355
|
+
pipeline_desc.compute.constants = constants.data();
|
|
356
|
+
pipeline_desc.compute.constantCount = constants.size();
|
|
357
|
+
}
|
|
358
|
+
return { device.CreateComputePipeline(&pipeline_desc), label };
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
static void ggml_webgpu_create_buffer(wgpu::Device & device,
|
|
362
|
+
wgpu::Buffer & buffer,
|
|
363
|
+
size_t size,
|
|
364
|
+
wgpu::BufferUsage usage,
|
|
365
|
+
const char * label) {
|
|
366
|
+
wgpu::BufferDescriptor buffer_desc;
|
|
367
|
+
buffer_desc.size = size;
|
|
368
|
+
buffer_desc.usage = usage;
|
|
369
|
+
buffer_desc.label = label;
|
|
370
|
+
buffer_desc.mappedAtCreation = false;
|
|
371
|
+
|
|
372
|
+
// TODO: error handling
|
|
373
|
+
buffer = device.CreateBuffer(&buffer_desc);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static wgpu::Buffer ggml_webgpu_tensor_buf(const ggml_tensor * tensor) {
|
|
377
|
+
ggml_backend_webgpu_buffer_context * ctx = (ggml_backend_webgpu_buffer_context *) tensor->buffer->context;
|
|
378
|
+
return ctx->buffer;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
static size_t ggml_webgpu_tensor_misalignment(webgpu_context & ctx, const ggml_tensor * t) {
|
|
382
|
+
size_t offset = ggml_webgpu_tensor_offset(t);
|
|
383
|
+
return offset & (ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment - 1);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
static size_t ggml_webgpu_tensor_align_offset(webgpu_context & ctx, const ggml_tensor * t) {
|
|
387
|
+
size_t offset = ggml_webgpu_tensor_offset(t);
|
|
388
|
+
return offset & ~(ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment - 1);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
static size_t ggml_webgpu_tensor_binding_size(webgpu_context & ctx, ggml_tensor * t) {
|
|
392
|
+
return ROUNDUP_POW2(ggml_nbytes(t) + ggml_webgpu_tensor_misalignment(ctx, t), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
struct ggml_webgpu_merged_binding_range {
|
|
396
|
+
size_t offset;
|
|
397
|
+
size_t size;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
static ggml_webgpu_merged_binding_range ggml_webgpu_tensor_merged_binding_range(
|
|
401
|
+
webgpu_context & ctx,
|
|
402
|
+
std::initializer_list<ggml_tensor *> tensors) {
|
|
403
|
+
size_t merged_offset = SIZE_MAX;
|
|
404
|
+
size_t merged_end = 0;
|
|
405
|
+
|
|
406
|
+
for (ggml_tensor * tensor : tensors) {
|
|
407
|
+
const size_t bind_offset = ggml_webgpu_tensor_align_offset(ctx, tensor);
|
|
408
|
+
const size_t bind_end = bind_offset + ggml_webgpu_tensor_binding_size(ctx, tensor);
|
|
409
|
+
|
|
410
|
+
merged_offset = std::min(merged_offset, bind_offset);
|
|
411
|
+
merged_end = std::max(merged_end, bind_end);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return { merged_offset, merged_end - merged_offset };
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
static uint32_t ggml_webgpu_tensor_merged_element_offset(const ggml_tensor * tensor,
|
|
418
|
+
const ggml_webgpu_merged_binding_range & merged_range) {
|
|
419
|
+
return (uint32_t) ((ggml_webgpu_tensor_offset(tensor) - merged_range.offset) / ggml_type_size(tensor->type));
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
static wgpu::BindGroupEntry ggml_webgpu_make_bind_group_entry(uint32_t binding,
|
|
423
|
+
wgpu::Buffer buffer,
|
|
424
|
+
uint64_t offset,
|
|
425
|
+
uint64_t size) {
|
|
426
|
+
wgpu::BindGroupEntry entry = {};
|
|
427
|
+
entry.binding = binding;
|
|
428
|
+
entry.buffer = std::move(buffer);
|
|
429
|
+
entry.offset = offset;
|
|
430
|
+
entry.size = size;
|
|
431
|
+
return entry;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
static wgpu::BindGroupEntry ggml_webgpu_make_tensor_bind_group_entry(webgpu_context & ctx,
|
|
435
|
+
uint32_t binding,
|
|
436
|
+
ggml_tensor * tensor) {
|
|
437
|
+
return ggml_webgpu_make_bind_group_entry(binding, ggml_webgpu_tensor_buf(tensor),
|
|
438
|
+
ggml_webgpu_tensor_align_offset(ctx, tensor),
|
|
439
|
+
ggml_webgpu_tensor_binding_size(ctx, tensor));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** End WebGPU object initializations */
|
|
443
|
+
|
|
444
|
+
/** WebGPU Actions */
|
|
445
|
+
|
|
446
|
+
template <typename T>
|
|
447
|
+
static void ggml_backend_webgpu_check_wait_status(wgpu::WaitStatus wait_status,
|
|
448
|
+
T callback_status,
|
|
449
|
+
T success_status,
|
|
450
|
+
const char * wait_name,
|
|
451
|
+
const char * failure_name,
|
|
452
|
+
const char * callback_message) {
|
|
453
|
+
if (wait_status == wgpu::WaitStatus::TimedOut) {
|
|
454
|
+
GGML_ABORT("ggml_webgpu: %s timed out after %u ms\n", wait_name, WEBGPU_RUNTIME_WAIT_TIMEOUT_MS);
|
|
455
|
+
}
|
|
456
|
+
if (wait_status == wgpu::WaitStatus::Error) {
|
|
457
|
+
GGML_ABORT("ggml_webgpu: %s failed\n", wait_name);
|
|
458
|
+
}
|
|
459
|
+
if (callback_status != success_status) {
|
|
460
|
+
GGML_ABORT("ggml_webgpu: %s failed with status %d: %s\n", failure_name, static_cast<int>(callback_status),
|
|
461
|
+
callback_message);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// TODO: these next two functions may want tuning across different platforms and workloads,
|
|
466
|
+
static uint32_t ggml_backend_webgpu_get_max_inflight_batches() {
|
|
467
|
+
return UINT32_MAX;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
static uint32_t ggml_backend_webgpu_get_command_submit_batch_size() {
|
|
471
|
+
return WEBGPU_DEFAULT_COMMAND_SUBMIT_BATCH_SIZE;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
static void ggml_backend_webgpu_wait_queue(webgpu_global_context & ctx) {
|
|
475
|
+
wgpu::QueueWorkDoneStatus callback_status = wgpu::QueueWorkDoneStatus::Error;
|
|
476
|
+
std::string callback_message;
|
|
477
|
+
|
|
478
|
+
const wgpu::WaitStatus wait_status = ctx->instance.WaitAny(
|
|
479
|
+
ctx->queue.OnSubmittedWorkDone(
|
|
480
|
+
wgpu::CallbackMode::AllowSpontaneous,
|
|
481
|
+
[&callback_status, &callback_message](wgpu::QueueWorkDoneStatus status, wgpu::StringView message) {
|
|
482
|
+
callback_status = status;
|
|
483
|
+
callback_message = std::string(message);
|
|
484
|
+
}),
|
|
485
|
+
WEBGPU_RUNTIME_WAIT_TIMEOUT_NS);
|
|
486
|
+
|
|
487
|
+
ggml_backend_webgpu_check_wait_status(wait_status, callback_status, wgpu::QueueWorkDoneStatus::Success,
|
|
488
|
+
"Queue wait", "Queue work", callback_message.c_str());
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
static void ggml_backend_webgpu_map_buffer(webgpu_global_context & ctx,
|
|
492
|
+
wgpu::Buffer & buffer,
|
|
493
|
+
wgpu::MapMode mode,
|
|
494
|
+
size_t offset,
|
|
495
|
+
size_t size) {
|
|
496
|
+
wgpu::MapAsyncStatus callback_status = wgpu::MapAsyncStatus::Error;
|
|
497
|
+
std::string callback_message;
|
|
498
|
+
|
|
499
|
+
const wgpu::WaitStatus wait_status = ctx->instance.WaitAny(
|
|
500
|
+
buffer.MapAsync(mode, offset, size, wgpu::CallbackMode::AllowSpontaneous,
|
|
501
|
+
[&callback_status, &callback_message](wgpu::MapAsyncStatus status, wgpu::StringView message) {
|
|
502
|
+
callback_status = status;
|
|
503
|
+
callback_message = std::string(message);
|
|
504
|
+
}),
|
|
505
|
+
WEBGPU_RUNTIME_WAIT_TIMEOUT_NS);
|
|
506
|
+
|
|
507
|
+
ggml_backend_webgpu_check_wait_status(wait_status, callback_status, wgpu::MapAsyncStatus::Success,
|
|
508
|
+
"Buffer map wait", "Buffer map", callback_message.c_str());
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
static void ggml_backend_webgpu_submit_commands(webgpu_context & ctx,
|
|
512
|
+
const wgpu::CommandBuffer commands,
|
|
513
|
+
uint32_t & num_inflight_batches) {
|
|
514
|
+
if (num_inflight_batches >= ctx->global_ctx->max_inflight_batches) {
|
|
515
|
+
ggml_backend_webgpu_wait_queue(ctx->global_ctx);
|
|
516
|
+
num_inflight_batches = 0;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
ctx->global_ctx->queue.Submit(1, &commands);
|
|
520
|
+
num_inflight_batches++;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
#ifdef GGML_WEBGPU_DEBUG
|
|
524
|
+
// This function adds debugging information to shaders, as WebGPU does not support printing directly.
|
|
525
|
+
// To use, add a bind group entry to the setup for the shader you are debugging, add the buffer and
|
|
526
|
+
// debug statements in the shader, and then call this function after encoding the commands and submitting them.
|
|
527
|
+
static void ggml_backend_webgpu_debug(webgpu_global_context & ctx) {
|
|
528
|
+
wgpu::CommandEncoder encoder = ctx->device.CreateCommandEncoder();
|
|
529
|
+
encoder.CopyBufferToBuffer(ctx->debug_dev_buf, 0, ctx->debug_host_buf, 0, ctx->debug_host_buf.GetSize());
|
|
530
|
+
wgpu::CommandBuffer commands = encoder.Finish();
|
|
531
|
+
ctx->queue.Submit(1, &commands);
|
|
532
|
+
ggml_backend_webgpu_map_buffer(ctx, ctx->debug_host_buf, wgpu::MapMode::Read, 0, ctx->debug_host_buf.GetSize());
|
|
533
|
+
const float * debug_data = (const float *) ctx->debug_host_buf.GetConstMappedRange();
|
|
534
|
+
std::cout << "debug[0]: " << debug_data[0] << "\n";
|
|
535
|
+
ctx->debug_host_buf.Unmap();
|
|
536
|
+
}
|
|
537
|
+
#endif
|
|
538
|
+
|
|
539
|
+
static webgpu_encoded_op ggml_backend_webgpu_build_multi(webgpu_context & ctx,
|
|
540
|
+
const std::vector<webgpu_dispatch_desc> & dispatches) {
|
|
541
|
+
webgpu_encoded_op result = {};
|
|
542
|
+
std::vector<wgpu::BindGroup> bind_groups;
|
|
543
|
+
std::vector<size_t> param_offsets;
|
|
544
|
+
result.num_kernels = dispatches.size();
|
|
545
|
+
|
|
546
|
+
for (size_t i = 0; i < dispatches.size(); i++) {
|
|
547
|
+
const webgpu_dispatch_desc & dispatch = dispatches[i];
|
|
548
|
+
const size_t param_size = dispatch.params.size() * sizeof(uint32_t);
|
|
549
|
+
const size_t param_offset = ctx->param_arena.alloc_slot(param_size);
|
|
550
|
+
|
|
551
|
+
std::vector<wgpu::BindGroupEntry> entries = dispatch.bind_group_entries;
|
|
552
|
+
uint32_t params_binding_num = entries.size();
|
|
553
|
+
entries.push_back(ggml_webgpu_make_bind_group_entry(params_binding_num, ctx->param_arena.buffer, param_offset,
|
|
554
|
+
ctx->param_arena.slot_size));
|
|
555
|
+
|
|
556
|
+
wgpu::BindGroupDescriptor bind_group_desc;
|
|
557
|
+
bind_group_desc.layout = dispatch.pipeline.pipeline.GetBindGroupLayout(0);
|
|
558
|
+
bind_group_desc.entryCount = entries.size();
|
|
559
|
+
bind_group_desc.entries = entries.data();
|
|
560
|
+
bind_group_desc.label = dispatch.pipeline.name.c_str();
|
|
561
|
+
bind_groups.push_back(ctx->global_ctx->device.CreateBindGroup(&bind_group_desc));
|
|
562
|
+
param_offsets.push_back(param_offset);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
for (size_t i = 0; i < param_offsets.size(); i++) {
|
|
566
|
+
ctx->global_ctx->queue.WriteBuffer(ctx->param_arena.buffer, param_offsets[i], dispatches[i].params.data(),
|
|
567
|
+
dispatches[i].params.size() * sizeof(uint32_t));
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
571
|
+
for (size_t i = 0; i < dispatches.size(); i++) {
|
|
572
|
+
GGML_ASSERT(ctx->profile_timestamp_query_count + 2 <= WEBGPU_MAX_PROFILE_QUERY_COUNT);
|
|
573
|
+
const uint32_t query_begin = ctx->profile_timestamp_query_count++;
|
|
574
|
+
const uint32_t query_end = ctx->profile_timestamp_query_count++;
|
|
575
|
+
|
|
576
|
+
wgpu::PassTimestampWrites ts_writes = {};
|
|
577
|
+
ts_writes.querySet = ctx->profile_timestamp_query_set;
|
|
578
|
+
ts_writes.beginningOfPassWriteIndex = query_begin;
|
|
579
|
+
ts_writes.endOfPassWriteIndex = query_end;
|
|
580
|
+
wgpu::ComputePassDescriptor pass_desc = {};
|
|
581
|
+
pass_desc.timestampWrites = &ts_writes;
|
|
582
|
+
|
|
583
|
+
wgpu::ComputePassEncoder pass = ctx->active_command_encoder.BeginComputePass(&pass_desc);
|
|
584
|
+
|
|
585
|
+
pass.SetPipeline(dispatches[i].pipeline.pipeline);
|
|
586
|
+
pass.SetBindGroup(0, bind_groups[i]);
|
|
587
|
+
pass.DispatchWorkgroups(dispatches[i].workgroups.first, dispatches[i].workgroups.second, 1);
|
|
588
|
+
pass.End();
|
|
589
|
+
result.pipeline_names.push_back(dispatches[i].pipeline.name);
|
|
590
|
+
}
|
|
591
|
+
#else
|
|
592
|
+
for (size_t i = 0; i < dispatches.size(); i++) {
|
|
593
|
+
ctx->active_compute_pass.SetPipeline(dispatches[i].pipeline.pipeline);
|
|
594
|
+
ctx->active_compute_pass.SetBindGroup(0, bind_groups[i]);
|
|
595
|
+
ctx->active_compute_pass.DispatchWorkgroups(dispatches[i].workgroups.first, dispatches[i].workgroups.second, 1);
|
|
596
|
+
}
|
|
597
|
+
#endif
|
|
598
|
+
|
|
599
|
+
return result;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
static webgpu_encoded_op ggml_backend_webgpu_build(webgpu_context & ctx,
|
|
603
|
+
webgpu_pipeline & pipeline,
|
|
604
|
+
std::vector<uint32_t> params,
|
|
605
|
+
std::vector<wgpu::BindGroupEntry> bind_group_entries,
|
|
606
|
+
uint32_t wg_x,
|
|
607
|
+
uint32_t wg_y = 1) {
|
|
608
|
+
return ggml_backend_webgpu_build_multi(
|
|
609
|
+
ctx, {
|
|
610
|
+
{ pipeline, std::move(params), std::move(bind_group_entries), { wg_x, wg_y } },
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
static void ggml_backend_webgpu_buffer_memset(webgpu_global_context & ctx,
|
|
615
|
+
wgpu::Buffer & buf,
|
|
616
|
+
uint32_t value,
|
|
617
|
+
size_t offset,
|
|
618
|
+
size_t size) {
|
|
619
|
+
std::vector<uint32_t> params = { (uint32_t) offset, (uint32_t) size, value };
|
|
620
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_bind_group_entry(0, buf, 0, buf.GetSize()) };
|
|
621
|
+
size_t bytes_per_wg = WEBGPU_MAX_WG_SIZE * ctx->capabilities.memset_bytes_per_thread;
|
|
622
|
+
uint32_t wg_x = CEIL_DIV(size + 3, bytes_per_wg);
|
|
623
|
+
|
|
624
|
+
ctx->queue.WriteBuffer(ctx->memset_params_buf, 0, params.data(), params.size() * sizeof(uint32_t));
|
|
625
|
+
|
|
626
|
+
wgpu::BindGroupEntry params_entry = {};
|
|
627
|
+
params_entry.binding = 1;
|
|
628
|
+
params_entry.buffer = ctx->memset_params_buf;
|
|
629
|
+
params_entry.offset = 0;
|
|
630
|
+
params_entry.size = WEBGPU_PARAMS_BUF_SIZE_BYTES;
|
|
631
|
+
entries.push_back(params_entry);
|
|
632
|
+
|
|
633
|
+
wgpu::BindGroupDescriptor bind_group_desc;
|
|
634
|
+
bind_group_desc.layout = ctx->memset_pipeline.pipeline.GetBindGroupLayout(0);
|
|
635
|
+
bind_group_desc.entryCount = entries.size();
|
|
636
|
+
bind_group_desc.entries = entries.data();
|
|
637
|
+
bind_group_desc.label = ctx->memset_pipeline.name.c_str();
|
|
638
|
+
wgpu::BindGroup bind_group = ctx->device.CreateBindGroup(&bind_group_desc);
|
|
639
|
+
|
|
640
|
+
wgpu::CommandEncoder encoder = ctx->device.CreateCommandEncoder();
|
|
641
|
+
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
|
642
|
+
pass.SetPipeline(ctx->memset_pipeline.pipeline);
|
|
643
|
+
pass.SetBindGroup(0, bind_group);
|
|
644
|
+
pass.DispatchWorkgroups(wg_x, 1, 1);
|
|
645
|
+
pass.End();
|
|
646
|
+
|
|
647
|
+
wgpu::CommandBuffer command = encoder.Finish();
|
|
648
|
+
std::vector<wgpu::CommandBuffer> commands = { command };
|
|
649
|
+
ctx->queue.Submit(commands.size(), commands.data());
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/** End WebGPU Actions */
|
|
653
|
+
|
|
654
|
+
/** GGML Backend Interface */
|
|
655
|
+
|
|
656
|
+
static const char * ggml_backend_webgpu_name(ggml_backend_t backend) {
|
|
657
|
+
ggml_backend_webgpu_context * ctx = (ggml_backend_webgpu_context *) backend->context;
|
|
658
|
+
return ctx->name.c_str();
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
static void ggml_backend_webgpu_free(ggml_backend_t backend) {
|
|
662
|
+
ggml_backend_webgpu_context * ctx = (ggml_backend_webgpu_context *) backend->context;
|
|
663
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_free(" << ctx->name << ")");
|
|
664
|
+
|
|
665
|
+
#ifdef GGML_WEBGPU_CPU_PROFILE
|
|
666
|
+
std::cout << "\n[ggml_webgpu cpu profiling summary]\n";
|
|
667
|
+
double total_cpu = 0.0;
|
|
668
|
+
for (const auto & kv : ctx->webgpu_ctx->global_ctx->cpu_time_ms) {
|
|
669
|
+
total_cpu += kv.second;
|
|
670
|
+
}
|
|
671
|
+
std::cout << "ggml_webgpu: total cpu time: " << total_cpu << " ms\n";
|
|
672
|
+
std::cout << "ggml_webgpu: cpu breakdown:\n";
|
|
673
|
+
for (const auto & kv : ctx->webgpu_ctx->global_ctx->cpu_time_ms) {
|
|
674
|
+
double pct = (total_cpu > 0.0) ? (kv.second / total_cpu * 100.0) : 0.0;
|
|
675
|
+
std::cout << "ggml_webgpu: " << kv.first << ": " << kv.second << " ms (" << pct << "%)\n";
|
|
676
|
+
}
|
|
677
|
+
if (ctx->webgpu_ctx->global_ctx->cpu_detail_ms.size() > 0) {
|
|
678
|
+
std::cout << "ggml_webgpu: cpu detailed breakdown:\n";
|
|
679
|
+
}
|
|
680
|
+
for (const auto & kv : ctx->webgpu_ctx->global_ctx->cpu_detail_ms) {
|
|
681
|
+
double pct = (total_cpu > 0.0) ? (kv.second / total_cpu * 100.0) : 0.0;
|
|
682
|
+
std::cout << "ggml_webgpu: " << kv.first << ": " << kv.second << " ms (" << pct << "%)\n";
|
|
683
|
+
}
|
|
684
|
+
#endif
|
|
685
|
+
|
|
686
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
687
|
+
std::cout << "\n[ggml_webgpu gpu profiling summary]\n";
|
|
688
|
+
double total_gpu = 0.0;
|
|
689
|
+
for (const auto & kv : ctx->webgpu_ctx->shader_gpu_time_ms) {
|
|
690
|
+
total_gpu += kv.second;
|
|
691
|
+
}
|
|
692
|
+
std::cout << "ggml_webgpu: total gpu time (all shaders): " << total_gpu << " ms\n";
|
|
693
|
+
std::cout << "\nggml_webgpu: gpu breakdown:\n";
|
|
694
|
+
for (const auto & kv : ctx->webgpu_ctx->shader_gpu_time_ms) {
|
|
695
|
+
double pct = (total_gpu > 0.0) ? (kv.second / total_gpu * 100.0) : 0.0;
|
|
696
|
+
std::cout << "ggml_webgpu: " << kv.first << ": " << kv.second << " ms (" << std::fixed << std::setprecision(2)
|
|
697
|
+
<< pct << "%)\n";
|
|
698
|
+
}
|
|
699
|
+
#endif
|
|
700
|
+
|
|
701
|
+
#if defined(GGML_WEBGPU_CPU_PROFILE) && defined(GGML_WEBGPU_GPU_PROFILE)
|
|
702
|
+
std::cout << "ggml_webgpu: gpu/cpu ratio: " << (total_cpu > 0.0 ? total_gpu / total_cpu : 0.0) << "\n";
|
|
703
|
+
#endif
|
|
704
|
+
|
|
705
|
+
delete ctx;
|
|
706
|
+
delete backend;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
static webgpu_encoded_op ggml_webgpu_cpy(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
710
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
711
|
+
shader_lib_ctx.src0 = src;
|
|
712
|
+
shader_lib_ctx.dst = dst;
|
|
713
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
714
|
+
|
|
715
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_cpy_pipeline(shader_lib_ctx);
|
|
716
|
+
|
|
717
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
718
|
+
|
|
719
|
+
uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
720
|
+
|
|
721
|
+
std::vector<uint32_t> params = {
|
|
722
|
+
ne, (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
723
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
724
|
+
// Convert byte-strides to element-strides
|
|
725
|
+
(uint32_t) (src->nb[0] / ggml_type_size(src->type)), (uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
726
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)), (uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
727
|
+
(uint32_t) (dst->nb[0] / ggml_type_size(dst->type)), (uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
728
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)), (uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
729
|
+
// Logical shapes
|
|
730
|
+
(uint32_t) src->ne[0], (uint32_t) src->ne[1], (uint32_t) src->ne[2], (uint32_t) dst->ne[0],
|
|
731
|
+
(uint32_t) dst->ne[1], (uint32_t) dst->ne[2]
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
735
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
736
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst),
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
740
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
static webgpu_encoded_op ggml_webgpu_set(webgpu_context & ctx,
|
|
744
|
+
ggml_tensor * src0,
|
|
745
|
+
ggml_tensor * src1,
|
|
746
|
+
ggml_tensor * dst) {
|
|
747
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
748
|
+
shader_lib_ctx.src0 = src0;
|
|
749
|
+
shader_lib_ctx.src1 = src1;
|
|
750
|
+
shader_lib_ctx.dst = dst;
|
|
751
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
752
|
+
|
|
753
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_set_pipeline(shader_lib_ctx);
|
|
754
|
+
|
|
755
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
756
|
+
const bool inplace = decisions->inplace;
|
|
757
|
+
|
|
758
|
+
const uint32_t ne = inplace ? (uint32_t) ggml_nelements(src1) : (uint32_t) ggml_nelements(dst);
|
|
759
|
+
const uint32_t dst_type_size = (uint32_t) ggml_type_size(dst->type);
|
|
760
|
+
|
|
761
|
+
std::vector<uint32_t> params = {
|
|
762
|
+
ne,
|
|
763
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
764
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
765
|
+
(uint32_t) (((const int32_t *) dst->op_params)[3] / dst_type_size),
|
|
766
|
+
|
|
767
|
+
(uint32_t) (src1->nb[0] / ggml_type_size(src1->type)),
|
|
768
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
769
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
770
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
771
|
+
|
|
772
|
+
1u,
|
|
773
|
+
(uint32_t) (((const int32_t *) dst->op_params)[0] / dst_type_size),
|
|
774
|
+
(uint32_t) (((const int32_t *) dst->op_params)[1] / dst_type_size),
|
|
775
|
+
(uint32_t) (((const int32_t *) dst->op_params)[2] / dst_type_size),
|
|
776
|
+
|
|
777
|
+
(uint32_t) src1->ne[0],
|
|
778
|
+
(uint32_t) src1->ne[1],
|
|
779
|
+
(uint32_t) src1->ne[2],
|
|
780
|
+
(uint32_t) src1->ne[3],
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
std::vector<wgpu::BindGroupEntry> entries;
|
|
784
|
+
uint32_t binding_index = 0;
|
|
785
|
+
if (!inplace) {
|
|
786
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0));
|
|
787
|
+
binding_index++;
|
|
788
|
+
}
|
|
789
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_index, src1));
|
|
790
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_index + 1, dst));
|
|
791
|
+
|
|
792
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
793
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
static webgpu_encoded_op ggml_webgpu_pad(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
797
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
798
|
+
shader_lib_ctx.src0 = src;
|
|
799
|
+
shader_lib_ctx.dst = dst;
|
|
800
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
801
|
+
|
|
802
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_pad_pipeline(shader_lib_ctx);
|
|
803
|
+
|
|
804
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
805
|
+
|
|
806
|
+
const uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
807
|
+
|
|
808
|
+
std::vector<uint32_t> params = {
|
|
809
|
+
ne,
|
|
810
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
811
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
812
|
+
// Strides (in elements)
|
|
813
|
+
(uint32_t) (src->nb[0] / ggml_type_size(src->type)),
|
|
814
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
815
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
816
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
817
|
+
// Shapes
|
|
818
|
+
(uint32_t) src->ne[0],
|
|
819
|
+
(uint32_t) src->ne[1],
|
|
820
|
+
(uint32_t) src->ne[2],
|
|
821
|
+
(uint32_t) src->ne[3],
|
|
822
|
+
(uint32_t) dst->ne[0],
|
|
823
|
+
(uint32_t) dst->ne[1],
|
|
824
|
+
(uint32_t) dst->ne[2],
|
|
825
|
+
(uint32_t) dst->ne[3],
|
|
826
|
+
// Pad sizes
|
|
827
|
+
(uint32_t) ggml_get_op_params_i32(dst, 0),
|
|
828
|
+
(uint32_t) ggml_get_op_params_i32(dst, 1),
|
|
829
|
+
(uint32_t) ggml_get_op_params_i32(dst, 2),
|
|
830
|
+
(uint32_t) ggml_get_op_params_i32(dst, 3),
|
|
831
|
+
(uint32_t) ggml_get_op_params_i32(dst, 4),
|
|
832
|
+
(uint32_t) ggml_get_op_params_i32(dst, 5),
|
|
833
|
+
(uint32_t) ggml_get_op_params_i32(dst, 6),
|
|
834
|
+
(uint32_t) ggml_get_op_params_i32(dst, 7),
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
838
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
839
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst),
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
843
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
static webgpu_encoded_op ggml_webgpu_solve_tri(webgpu_context & ctx,
|
|
847
|
+
ggml_tensor * src0,
|
|
848
|
+
ggml_tensor * src1,
|
|
849
|
+
ggml_tensor * dst) {
|
|
850
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
851
|
+
shader_lib_ctx.src0 = src0;
|
|
852
|
+
shader_lib_ctx.src1 = src1;
|
|
853
|
+
shader_lib_ctx.dst = dst;
|
|
854
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
855
|
+
shader_lib_ctx.wg_mem_limit_bytes = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
856
|
+
|
|
857
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_solve_tri_pipeline(shader_lib_ctx);
|
|
858
|
+
|
|
859
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
860
|
+
|
|
861
|
+
std::vector<uint32_t> params = {
|
|
862
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
863
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
864
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
865
|
+
|
|
866
|
+
(uint32_t) (src0->nb[0] / ggml_type_size(src0->type)),
|
|
867
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
868
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
869
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
870
|
+
|
|
871
|
+
(uint32_t) (src1->nb[0] / ggml_type_size(src1->type)),
|
|
872
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
873
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
874
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
875
|
+
|
|
876
|
+
(uint32_t) (dst->nb[0] / ggml_type_size(dst->type)),
|
|
877
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
878
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
879
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
880
|
+
|
|
881
|
+
(uint32_t) src1->ne[0],
|
|
882
|
+
(uint32_t) dst->ne[2],
|
|
883
|
+
(uint32_t) dst->ne[3],
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
887
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
888
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
889
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
const uint32_t wg_x = CEIL_DIV((uint32_t) src1->ne[0], decisions->wg_size);
|
|
893
|
+
const uint32_t wg_y = (uint32_t) (dst->ne[2] * dst->ne[3]);
|
|
894
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
static webgpu_encoded_op ggml_webgpu_conv_2d(webgpu_context & ctx,
|
|
898
|
+
ggml_tensor * src0,
|
|
899
|
+
ggml_tensor * src1,
|
|
900
|
+
ggml_tensor * dst) {
|
|
901
|
+
const int32_t s0 = ggml_get_op_params_i32(dst, 0);
|
|
902
|
+
const int32_t s1 = ggml_get_op_params_i32(dst, 1);
|
|
903
|
+
const int32_t p0 = ggml_get_op_params_i32(dst, 2);
|
|
904
|
+
const int32_t p1 = ggml_get_op_params_i32(dst, 3);
|
|
905
|
+
const int32_t d0 = ggml_get_op_params_i32(dst, 4);
|
|
906
|
+
const int32_t d1 = ggml_get_op_params_i32(dst, 5);
|
|
907
|
+
|
|
908
|
+
std::vector<uint32_t> params = {
|
|
909
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
910
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
911
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
912
|
+
|
|
913
|
+
(uint32_t) (src0->nb[0] / ggml_type_size(src0->type)),
|
|
914
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
915
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
916
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
917
|
+
|
|
918
|
+
(uint32_t) (src1->nb[0] / ggml_type_size(src1->type)),
|
|
919
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
920
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
921
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
922
|
+
|
|
923
|
+
(uint32_t) (dst->nb[0] / ggml_type_size(dst->type)),
|
|
924
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
925
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
926
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
927
|
+
|
|
928
|
+
(uint32_t) src0->ne[0],
|
|
929
|
+
(uint32_t) src0->ne[1],
|
|
930
|
+
(uint32_t) src0->ne[2],
|
|
931
|
+
|
|
932
|
+
(uint32_t) src1->ne[0],
|
|
933
|
+
(uint32_t) src1->ne[1],
|
|
934
|
+
|
|
935
|
+
(uint32_t) dst->ne[0],
|
|
936
|
+
(uint32_t) dst->ne[1],
|
|
937
|
+
(uint32_t) dst->ne[2],
|
|
938
|
+
(uint32_t) dst->ne[3],
|
|
939
|
+
|
|
940
|
+
(uint32_t) s0,
|
|
941
|
+
(uint32_t) s1,
|
|
942
|
+
(uint32_t) p0,
|
|
943
|
+
(uint32_t) p1,
|
|
944
|
+
(uint32_t) d0,
|
|
945
|
+
(uint32_t) d1,
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
949
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
950
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
951
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
955
|
+
shader_lib_ctx.src0 = src0;
|
|
956
|
+
shader_lib_ctx.src1 = src1;
|
|
957
|
+
shader_lib_ctx.dst = dst;
|
|
958
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
959
|
+
|
|
960
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_conv2d_pipeline(shader_lib_ctx);
|
|
961
|
+
|
|
962
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
963
|
+
|
|
964
|
+
uint32_t total_wg = CEIL_DIV((uint32_t) ggml_nelements(dst), decisions->wg_size);
|
|
965
|
+
uint32_t wg_x = std::min(ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension, total_wg);
|
|
966
|
+
uint32_t wg_y = CEIL_DIV(total_wg, wg_x);
|
|
967
|
+
|
|
968
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
static webgpu_encoded_op ggml_webgpu_im2col(webgpu_context & ctx,
|
|
972
|
+
ggml_tensor * src0,
|
|
973
|
+
ggml_tensor * src1,
|
|
974
|
+
ggml_tensor * dst) {
|
|
975
|
+
const int32_t s0 = ggml_get_op_params_i32(dst, 0);
|
|
976
|
+
const int32_t s1 = ggml_get_op_params_i32(dst, 1);
|
|
977
|
+
const int32_t p0 = ggml_get_op_params_i32(dst, 2);
|
|
978
|
+
const int32_t p1 = ggml_get_op_params_i32(dst, 3);
|
|
979
|
+
const int32_t d0 = ggml_get_op_params_i32(dst, 4);
|
|
980
|
+
const int32_t d1 = ggml_get_op_params_i32(dst, 5);
|
|
981
|
+
const bool is_2D = ggml_get_op_params_i32(dst, 6) == 1;
|
|
982
|
+
|
|
983
|
+
const uint32_t KW = src0->ne[0];
|
|
984
|
+
const uint32_t KH = is_2D ? src0->ne[1] : 1;
|
|
985
|
+
const uint32_t IC = is_2D ? src0->ne[2] : src0->ne[1];
|
|
986
|
+
|
|
987
|
+
const uint32_t IW = src1->ne[0];
|
|
988
|
+
const uint32_t IH = is_2D ? src1->ne[1] : 1;
|
|
989
|
+
const uint32_t N = is_2D ? src1->ne[3] : src1->ne[2];
|
|
990
|
+
|
|
991
|
+
const uint32_t OW = dst->ne[1];
|
|
992
|
+
const uint32_t OH = is_2D ? dst->ne[2] : 1;
|
|
993
|
+
|
|
994
|
+
const uint32_t si0 = (uint32_t) (src1->nb[0] / ggml_type_size(src1->type));
|
|
995
|
+
const uint32_t si1 = is_2D ? (uint32_t) (src1->nb[1] / ggml_type_size(src1->type)) : 0;
|
|
996
|
+
const uint32_t si2 = is_2D ? (uint32_t) (src1->nb[2] / ggml_type_size(src1->type)) :
|
|
997
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type));
|
|
998
|
+
const uint32_t si3 = is_2D ? (uint32_t) (src1->nb[3] / ggml_type_size(src1->type)) :
|
|
999
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type));
|
|
1000
|
+
|
|
1001
|
+
const uint32_t so0 = (uint32_t) (dst->nb[0] / ggml_type_size(dst->type));
|
|
1002
|
+
const uint32_t so1 = (uint32_t) (dst->nb[1] / ggml_type_size(dst->type));
|
|
1003
|
+
const uint32_t so2 = is_2D ? (uint32_t) (dst->nb[2] / ggml_type_size(dst->type)) : 0;
|
|
1004
|
+
const uint32_t so3 = is_2D ? (uint32_t) (dst->nb[3] / ggml_type_size(dst->type)) :
|
|
1005
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type));
|
|
1006
|
+
|
|
1007
|
+
std::vector<uint32_t> params = {
|
|
1008
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
1009
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1010
|
+
|
|
1011
|
+
si0,
|
|
1012
|
+
si1,
|
|
1013
|
+
si2,
|
|
1014
|
+
si3,
|
|
1015
|
+
so0,
|
|
1016
|
+
so1,
|
|
1017
|
+
so2,
|
|
1018
|
+
so3,
|
|
1019
|
+
|
|
1020
|
+
KW,
|
|
1021
|
+
KH,
|
|
1022
|
+
IC,
|
|
1023
|
+
|
|
1024
|
+
IW,
|
|
1025
|
+
IH,
|
|
1026
|
+
N,
|
|
1027
|
+
|
|
1028
|
+
OW,
|
|
1029
|
+
OH,
|
|
1030
|
+
|
|
1031
|
+
(uint32_t) s0,
|
|
1032
|
+
(uint32_t) s1,
|
|
1033
|
+
(uint32_t) p0,
|
|
1034
|
+
(uint32_t) p1,
|
|
1035
|
+
(uint32_t) d0,
|
|
1036
|
+
(uint32_t) d1,
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1040
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src1),
|
|
1041
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst),
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1045
|
+
shader_lib_ctx.src0 = src0;
|
|
1046
|
+
shader_lib_ctx.src1 = src1;
|
|
1047
|
+
shader_lib_ctx.dst = dst;
|
|
1048
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1049
|
+
|
|
1050
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_im2col_pipeline(shader_lib_ctx);
|
|
1051
|
+
|
|
1052
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
1053
|
+
|
|
1054
|
+
uint32_t total_wg = CEIL_DIV((uint32_t) ggml_nelements(dst), decisions->wg_size);
|
|
1055
|
+
uint32_t wg_x = std::min(ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension, total_wg);
|
|
1056
|
+
uint32_t wg_y = CEIL_DIV(total_wg, wg_x);
|
|
1057
|
+
|
|
1058
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
static webgpu_encoded_op ggml_webgpu_ssm_conv(webgpu_context & ctx,
|
|
1062
|
+
ggml_tensor * src0,
|
|
1063
|
+
ggml_tensor * src1,
|
|
1064
|
+
ggml_tensor * dst) {
|
|
1065
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1066
|
+
shader_lib_ctx.src0 = src0;
|
|
1067
|
+
shader_lib_ctx.src1 = src1;
|
|
1068
|
+
shader_lib_ctx.dst = dst;
|
|
1069
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1070
|
+
|
|
1071
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_ssm_conv_pipeline(shader_lib_ctx);
|
|
1072
|
+
auto * decisions = static_cast<ggml_webgpu_ssm_conv_shader_decisions *>(pipeline.context.get());
|
|
1073
|
+
|
|
1074
|
+
const uint32_t token_tiles = CEIL_DIV((uint32_t) dst->ne[1], decisions->tokens_per_wg);
|
|
1075
|
+
|
|
1076
|
+
std::vector<uint32_t> params = {
|
|
1077
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
1078
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
1079
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1080
|
+
|
|
1081
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1082
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1083
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
1084
|
+
|
|
1085
|
+
(uint32_t) (dst->nb[0] / ggml_type_size(dst->type)),
|
|
1086
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
1087
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
1088
|
+
|
|
1089
|
+
(uint32_t) src1->ne[0],
|
|
1090
|
+
(uint32_t) src0->ne[1],
|
|
1091
|
+
(uint32_t) dst->ne[1],
|
|
1092
|
+
(uint32_t) dst->ne[2],
|
|
1093
|
+
token_tiles,
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1097
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
1098
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
1099
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
const uint32_t wg_x = CEIL_DIV((uint32_t) src0->ne[1], decisions->block_size);
|
|
1103
|
+
const uint32_t wg_y = token_tiles * (uint32_t) dst->ne[2];
|
|
1104
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
static webgpu_encoded_op ggml_webgpu_ssm_scan(webgpu_context & ctx,
|
|
1108
|
+
ggml_tensor * src0,
|
|
1109
|
+
ggml_tensor * src1,
|
|
1110
|
+
ggml_tensor * src2,
|
|
1111
|
+
ggml_tensor * src3,
|
|
1112
|
+
ggml_tensor * src4,
|
|
1113
|
+
ggml_tensor * src5,
|
|
1114
|
+
ggml_tensor * src6,
|
|
1115
|
+
ggml_tensor * dst) {
|
|
1116
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1117
|
+
shader_lib_ctx.src0 = src0;
|
|
1118
|
+
shader_lib_ctx.src1 = src1;
|
|
1119
|
+
shader_lib_ctx.src4 = src4;
|
|
1120
|
+
shader_lib_ctx.src5 = src5;
|
|
1121
|
+
shader_lib_ctx.dst = dst;
|
|
1122
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1123
|
+
shader_lib_ctx.supports_subgroups = ctx->global_ctx->capabilities.supports_subgroups;
|
|
1124
|
+
|
|
1125
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_ssm_scan_pipeline(shader_lib_ctx);
|
|
1126
|
+
auto * decisions = static_cast<ggml_webgpu_ssm_scan_shader_decisions *>(pipeline.context.get());
|
|
1127
|
+
const bool xbc_overlap = decisions->xbc_overlap;
|
|
1128
|
+
|
|
1129
|
+
uint32_t offset_x = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type));
|
|
1130
|
+
uint32_t offset_B = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src4) / ggml_type_size(src4->type));
|
|
1131
|
+
uint32_t offset_C = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src5) / ggml_type_size(src5->type));
|
|
1132
|
+
size_t xbc_bind_offset = 0;
|
|
1133
|
+
size_t xbc_bind_size = 0;
|
|
1134
|
+
if (xbc_overlap) {
|
|
1135
|
+
const ggml_webgpu_merged_binding_range merged_range =
|
|
1136
|
+
ggml_webgpu_tensor_merged_binding_range(ctx, { src1, src4, src5 });
|
|
1137
|
+
xbc_bind_offset = merged_range.offset;
|
|
1138
|
+
xbc_bind_size = merged_range.size;
|
|
1139
|
+
offset_x = ggml_webgpu_tensor_merged_element_offset(src1, merged_range);
|
|
1140
|
+
offset_B = ggml_webgpu_tensor_merged_element_offset(src4, merged_range);
|
|
1141
|
+
offset_C = ggml_webgpu_tensor_merged_element_offset(src5, merged_range);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
std::vector<uint32_t> params = {
|
|
1145
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
1146
|
+
offset_x,
|
|
1147
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)),
|
|
1148
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src3) / ggml_type_size(src3->type)),
|
|
1149
|
+
offset_B,
|
|
1150
|
+
offset_C,
|
|
1151
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src6) / ggml_type_size(src6->type)),
|
|
1152
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1153
|
+
|
|
1154
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1155
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1156
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
1157
|
+
|
|
1158
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
1159
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
1160
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
1161
|
+
|
|
1162
|
+
(uint32_t) (src2->nb[1] / ggml_type_size(src2->type)),
|
|
1163
|
+
(uint32_t) (src2->nb[2] / ggml_type_size(src2->type)),
|
|
1164
|
+
|
|
1165
|
+
(uint32_t) src3->ne[0],
|
|
1166
|
+
(uint32_t) (src3->nb[1] / ggml_type_size(src3->type)),
|
|
1167
|
+
|
|
1168
|
+
(uint32_t) (src4->nb[1] / ggml_type_size(src4->type)),
|
|
1169
|
+
(uint32_t) (src4->nb[2] / ggml_type_size(src4->type)),
|
|
1170
|
+
(uint32_t) (src4->nb[3] / ggml_type_size(src4->type)),
|
|
1171
|
+
|
|
1172
|
+
(uint32_t) (src5->nb[1] / ggml_type_size(src5->type)),
|
|
1173
|
+
(uint32_t) (src5->nb[2] / ggml_type_size(src5->type)),
|
|
1174
|
+
(uint32_t) (src5->nb[3] / ggml_type_size(src5->type)),
|
|
1175
|
+
|
|
1176
|
+
(uint32_t) src0->ne[0],
|
|
1177
|
+
(uint32_t) src0->ne[1],
|
|
1178
|
+
(uint32_t) src0->ne[2],
|
|
1179
|
+
(uint32_t) src4->ne[1],
|
|
1180
|
+
(uint32_t) src1->ne[2],
|
|
1181
|
+
(uint32_t) src1->ne[3],
|
|
1182
|
+
(uint32_t) ggml_nelements(src1),
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1186
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
1187
|
+
};
|
|
1188
|
+
if (xbc_overlap) {
|
|
1189
|
+
entries.push_back(
|
|
1190
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(src1), xbc_bind_offset, xbc_bind_size));
|
|
1191
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, src2));
|
|
1192
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 3, src3));
|
|
1193
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 4, src6));
|
|
1194
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 5, dst));
|
|
1195
|
+
} else {
|
|
1196
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1));
|
|
1197
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, src2));
|
|
1198
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 3, src3));
|
|
1199
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 4, src4));
|
|
1200
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 5, src5));
|
|
1201
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 6, src6));
|
|
1202
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 7, dst));
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
const uint32_t total_wg = (uint32_t) (src0->ne[1] * src0->ne[2] * src1->ne[3]);
|
|
1206
|
+
const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
1207
|
+
uint32_t wg_x;
|
|
1208
|
+
uint32_t wg_y;
|
|
1209
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1210
|
+
|
|
1211
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
static webgpu_encoded_op ggml_webgpu_gated_delta_net(webgpu_context & ctx,
|
|
1215
|
+
ggml_tensor * src0,
|
|
1216
|
+
ggml_tensor * src1,
|
|
1217
|
+
ggml_tensor * src2,
|
|
1218
|
+
ggml_tensor * src3,
|
|
1219
|
+
ggml_tensor * src4,
|
|
1220
|
+
ggml_tensor * src5,
|
|
1221
|
+
ggml_tensor * dst) {
|
|
1222
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1223
|
+
shader_lib_ctx.src0 = src0;
|
|
1224
|
+
shader_lib_ctx.src1 = src1;
|
|
1225
|
+
shader_lib_ctx.src2 = src2;
|
|
1226
|
+
shader_lib_ctx.src3 = src3;
|
|
1227
|
+
shader_lib_ctx.src4 = src4;
|
|
1228
|
+
shader_lib_ctx.dst = dst;
|
|
1229
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1230
|
+
|
|
1231
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_gated_delta_net_pipeline(shader_lib_ctx);
|
|
1232
|
+
|
|
1233
|
+
const uint32_t s_v = (uint32_t) src2->ne[0];
|
|
1234
|
+
const uint32_t h = (uint32_t) src2->ne[1];
|
|
1235
|
+
const uint32_t n_tokens = (uint32_t) src2->ne[2];
|
|
1236
|
+
const uint32_t n_seqs = (uint32_t) src2->ne[3];
|
|
1237
|
+
const float scale = 1.0f / sqrtf((float) s_v);
|
|
1238
|
+
uint32_t scale_u32;
|
|
1239
|
+
memcpy(&scale_u32, &scale, sizeof(scale_u32));
|
|
1240
|
+
|
|
1241
|
+
std::vector<uint32_t> params = {
|
|
1242
|
+
h,
|
|
1243
|
+
n_tokens,
|
|
1244
|
+
n_seqs,
|
|
1245
|
+
s_v * h * n_tokens * n_seqs,
|
|
1246
|
+
|
|
1247
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1248
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1249
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
1250
|
+
|
|
1251
|
+
(uint32_t) (src2->nb[1] / ggml_type_size(src2->type)),
|
|
1252
|
+
(uint32_t) (src2->nb[2] / ggml_type_size(src2->type)),
|
|
1253
|
+
(uint32_t) (src2->nb[3] / ggml_type_size(src2->type)),
|
|
1254
|
+
|
|
1255
|
+
(uint32_t) (src4->nb[1] / ggml_type_size(src4->type)),
|
|
1256
|
+
(uint32_t) (src4->nb[2] / ggml_type_size(src4->type)),
|
|
1257
|
+
(uint32_t) (src4->nb[3] / ggml_type_size(src4->type)),
|
|
1258
|
+
|
|
1259
|
+
(uint32_t) src0->ne[1],
|
|
1260
|
+
(uint32_t) (src2->ne[3] / src0->ne[3]),
|
|
1261
|
+
scale_u32,
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1265
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0), ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
1266
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, src2), ggml_webgpu_make_tensor_bind_group_entry(ctx, 3, src3),
|
|
1267
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 4, src4), ggml_webgpu_make_tensor_bind_group_entry(ctx, 5, src5),
|
|
1268
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 6, dst),
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, h, n_seqs);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
static std::optional<webgpu_encoded_op> ggml_webgpu_set_rows(webgpu_context & ctx,
|
|
1275
|
+
ggml_tensor * src,
|
|
1276
|
+
ggml_tensor * idx,
|
|
1277
|
+
ggml_tensor * dst) {
|
|
1278
|
+
// For set rows specifically, we need to check if src and idx are empty
|
|
1279
|
+
// tensors.
|
|
1280
|
+
if (ggml_is_empty(src) || ggml_is_empty(idx)) {
|
|
1281
|
+
return std::nullopt;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1285
|
+
shader_lib_ctx.src0 = src;
|
|
1286
|
+
shader_lib_ctx.src1 = idx;
|
|
1287
|
+
shader_lib_ctx.dst = dst;
|
|
1288
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1289
|
+
|
|
1290
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_set_rows_pipeline(shader_lib_ctx);
|
|
1291
|
+
|
|
1292
|
+
auto * decisions = static_cast<ggml_webgpu_set_rows_shader_decisions *>(pipeline.context.get());
|
|
1293
|
+
|
|
1294
|
+
std::vector<uint32_t> params = {
|
|
1295
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
1296
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, idx) / ggml_type_size(idx->type)),
|
|
1297
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1298
|
+
// Convert byte-strides to element-strides
|
|
1299
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)), (uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
1300
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)), (uint32_t) (idx->nb[0] / ggml_type_size(idx->type)),
|
|
1301
|
+
(uint32_t) (idx->nb[1] / ggml_type_size(idx->type)), (uint32_t) (idx->nb[2] / ggml_type_size(idx->type)),
|
|
1302
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)), (uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
1303
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
1304
|
+
// Shape of src
|
|
1305
|
+
(uint32_t) src->ne[0], (uint32_t) src->ne[1], (uint32_t) src->ne[2], (uint32_t) src->ne[3],
|
|
1306
|
+
// Shape of idx
|
|
1307
|
+
(uint32_t) (idx->ne[1]), (uint32_t) (idx->ne[2])
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1311
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
1312
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, idx),
|
|
1313
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
if (decisions->i64_idx) {
|
|
1317
|
+
entries.push_back(ggml_webgpu_make_bind_group_entry(3, ctx->set_rows_dev_error_buf, 0,
|
|
1318
|
+
ctx->set_rows_dev_error_buf.GetSize()));
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
uint32_t threads;
|
|
1322
|
+
if (decisions->vec4) {
|
|
1323
|
+
threads = (src->ne[1] * src->ne[2] * src->ne[3]) * (src->ne[0] / 4);
|
|
1324
|
+
} else {
|
|
1325
|
+
threads = src->ne[0] * src->ne[1] * src->ne[2] * src->ne[3];
|
|
1326
|
+
}
|
|
1327
|
+
uint32_t wg_x = CEIL_DIV(threads, decisions->wg_size);
|
|
1328
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, 1);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// Workgroup size is a common constant
|
|
1332
|
+
static std::vector<wgpu::ConstantEntry> ggml_webgpu_wg_size_entry(uint32_t wg_size) {
|
|
1333
|
+
std::vector<wgpu::ConstantEntry> constants(1);
|
|
1334
|
+
constants[0].key = "wg_size";
|
|
1335
|
+
constants[0].value = wg_size;
|
|
1336
|
+
return constants;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
static webgpu_encoded_op ggml_webgpu_get_rows(webgpu_context & ctx,
|
|
1340
|
+
ggml_tensor * src,
|
|
1341
|
+
ggml_tensor * idx,
|
|
1342
|
+
ggml_tensor * dst) {
|
|
1343
|
+
const bool float_parallel = src->type == GGML_TYPE_F32 || src->type == GGML_TYPE_F16 || src->type == GGML_TYPE_I32;
|
|
1344
|
+
|
|
1345
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1346
|
+
shader_lib_ctx.src0 = src;
|
|
1347
|
+
shader_lib_ctx.src1 = nullptr;
|
|
1348
|
+
shader_lib_ctx.dst = dst;
|
|
1349
|
+
shader_lib_ctx.max_wg_size = WEBGPU_MAX_WG_SIZE;
|
|
1350
|
+
|
|
1351
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_get_rows_pipeline(shader_lib_ctx);
|
|
1352
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
1353
|
+
|
|
1354
|
+
std::vector<uint32_t> params = { (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
1355
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, idx) / ggml_type_size(idx->type)),
|
|
1356
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1357
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
1358
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
1359
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
1360
|
+
(uint32_t) (idx->nb[0] / ggml_type_size(idx->type)),
|
|
1361
|
+
(uint32_t) (idx->nb[1] / ggml_type_size(idx->type)),
|
|
1362
|
+
(uint32_t) (idx->nb[2] / ggml_type_size(idx->type)),
|
|
1363
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
1364
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
1365
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
1366
|
+
(uint32_t) dst->ne[0],
|
|
1367
|
+
(uint32_t) dst->ne[1],
|
|
1368
|
+
(uint32_t) dst->ne[2],
|
|
1369
|
+
(uint32_t) dst->ne[3],
|
|
1370
|
+
(uint32_t) (idx->ne[1]),
|
|
1371
|
+
(uint32_t) (idx->ne[2]) };
|
|
1372
|
+
|
|
1373
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
1374
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, idx),
|
|
1375
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst) };
|
|
1376
|
+
|
|
1377
|
+
uint32_t blocks_per_row = (uint32_t) (dst->ne[0] / (src->type == GGML_TYPE_F32 && dst->ne[0] % 4 == 0 ? 4 : 1));
|
|
1378
|
+
uint32_t total_rows = (uint32_t) (dst->ne[1] * dst->ne[2] * dst->ne[3]);
|
|
1379
|
+
uint32_t total_threads = float_parallel ? blocks_per_row * total_rows : total_rows;
|
|
1380
|
+
uint32_t wg_x = CEIL_DIV(total_threads, decisions->wg_size);
|
|
1381
|
+
|
|
1382
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
static webgpu_encoded_op ggml_webgpu_mul_mat(webgpu_context & ctx,
|
|
1386
|
+
ggml_tensor * src0,
|
|
1387
|
+
ggml_tensor * src1,
|
|
1388
|
+
ggml_tensor * dst) {
|
|
1389
|
+
// Determine if this is a mat-vec operation
|
|
1390
|
+
bool is_vec = (dst->ne[1] == 1);
|
|
1391
|
+
|
|
1392
|
+
// Determine if we should use fast path
|
|
1393
|
+
bool use_fast = false;
|
|
1394
|
+
switch (src1->type) {
|
|
1395
|
+
case GGML_TYPE_F16:
|
|
1396
|
+
use_fast = (src0->type == GGML_TYPE_F16);
|
|
1397
|
+
break;
|
|
1398
|
+
case GGML_TYPE_F32:
|
|
1399
|
+
// TODO: implement better mat-mat for k-quants, mat-vec for all k-quants except q6_K
|
|
1400
|
+
switch (src0->type) {
|
|
1401
|
+
case GGML_TYPE_F32:
|
|
1402
|
+
case GGML_TYPE_F16:
|
|
1403
|
+
case GGML_TYPE_Q4_0:
|
|
1404
|
+
case GGML_TYPE_Q4_1:
|
|
1405
|
+
case GGML_TYPE_Q5_0:
|
|
1406
|
+
case GGML_TYPE_Q5_1:
|
|
1407
|
+
case GGML_TYPE_Q8_0:
|
|
1408
|
+
case GGML_TYPE_Q6_K:
|
|
1409
|
+
case GGML_TYPE_Q4_K:
|
|
1410
|
+
case GGML_TYPE_Q5_K:
|
|
1411
|
+
case GGML_TYPE_Q3_K:
|
|
1412
|
+
case GGML_TYPE_Q2_K:
|
|
1413
|
+
case GGML_TYPE_Q1_0:
|
|
1414
|
+
case GGML_TYPE_IQ1_S:
|
|
1415
|
+
case GGML_TYPE_IQ1_M:
|
|
1416
|
+
case GGML_TYPE_IQ2_XXS:
|
|
1417
|
+
case GGML_TYPE_IQ2_XS:
|
|
1418
|
+
case GGML_TYPE_IQ2_S:
|
|
1419
|
+
case GGML_TYPE_IQ3_XXS:
|
|
1420
|
+
case GGML_TYPE_IQ3_S:
|
|
1421
|
+
case GGML_TYPE_IQ4_NL:
|
|
1422
|
+
case GGML_TYPE_IQ4_XS:
|
|
1423
|
+
case GGML_TYPE_MXFP4:
|
|
1424
|
+
use_fast = true;
|
|
1425
|
+
break;
|
|
1426
|
+
default:
|
|
1427
|
+
break;
|
|
1428
|
+
}
|
|
1429
|
+
break;
|
|
1430
|
+
default:
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1435
|
+
|
|
1436
|
+
shader_lib_ctx.src0 = src0;
|
|
1437
|
+
shader_lib_ctx.src1 = src1;
|
|
1438
|
+
shader_lib_ctx.dst = dst;
|
|
1439
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1440
|
+
shader_lib_ctx.supports_subgroups = ctx->global_ctx->capabilities.supports_subgroups;
|
|
1441
|
+
shader_lib_ctx.supports_subgroup_matrix = ctx->global_ctx->capabilities.supports_subgroup_matrix;
|
|
1442
|
+
shader_lib_ctx.sg_mat_m = ctx->global_ctx->capabilities.sg_mat_m;
|
|
1443
|
+
shader_lib_ctx.sg_mat_n = ctx->global_ctx->capabilities.sg_mat_n;
|
|
1444
|
+
shader_lib_ctx.sg_mat_k = ctx->global_ctx->capabilities.sg_mat_k;
|
|
1445
|
+
shader_lib_ctx.min_subgroup_size = ctx->global_ctx->capabilities.min_subgroup_size;
|
|
1446
|
+
shader_lib_ctx.max_subgroup_size = ctx->global_ctx->capabilities.max_subgroup_size;
|
|
1447
|
+
|
|
1448
|
+
// Get or create pipeline
|
|
1449
|
+
webgpu_pipeline pipeline;
|
|
1450
|
+
|
|
1451
|
+
if (use_fast && is_vec) {
|
|
1452
|
+
pipeline = ctx->shader_lib->get_mul_mat_vec_pipeline(shader_lib_ctx);
|
|
1453
|
+
} else if (use_fast) {
|
|
1454
|
+
pipeline = ctx->shader_lib->get_mul_mat_fast_pipeline(shader_lib_ctx);
|
|
1455
|
+
} else {
|
|
1456
|
+
pipeline = ctx->shader_lib->get_mul_mat_legacy_pipeline(shader_lib_ctx);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
// Build params
|
|
1460
|
+
std::vector<uint32_t> params = {
|
|
1461
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
1462
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
1463
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1464
|
+
(uint32_t) dst->ne[0],
|
|
1465
|
+
(uint32_t) dst->ne[1],
|
|
1466
|
+
(uint32_t) src0->ne[0],
|
|
1467
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1468
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
1469
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1470
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
1471
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
1472
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
1473
|
+
(uint32_t) src0->ne[2],
|
|
1474
|
+
(uint32_t) src0->ne[3],
|
|
1475
|
+
(uint32_t) (src1->ne[2] / src0->ne[2]),
|
|
1476
|
+
(uint32_t) (src1->ne[3] / src0->ne[3])
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
// Build bind group entries
|
|
1480
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1481
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
1482
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
1483
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
// Calculate workgroup dimensions
|
|
1487
|
+
uint32_t wg_x = 1;
|
|
1488
|
+
uint32_t wg_y = 1;
|
|
1489
|
+
const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
1490
|
+
|
|
1491
|
+
if (use_fast && is_vec) {
|
|
1492
|
+
auto * decisions = static_cast<ggml_webgpu_mul_mat_vec_shader_decisions *>(pipeline.context.get());
|
|
1493
|
+
|
|
1494
|
+
uint32_t batches = dst->ne[2] * dst->ne[3];
|
|
1495
|
+
uint32_t output_groups = CEIL_DIV(dst->ne[0], decisions->outputs_per_wg);
|
|
1496
|
+
uint32_t total_wg = output_groups * batches;
|
|
1497
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1498
|
+
} else if (use_fast) {
|
|
1499
|
+
auto * decisions = static_cast<ggml_webgpu_mul_mat_shader_decisions *>(pipeline.context.get());
|
|
1500
|
+
|
|
1501
|
+
// Fast-path tiled/subgroup calculations
|
|
1502
|
+
uint32_t wg_m;
|
|
1503
|
+
uint32_t wg_n;
|
|
1504
|
+
if (decisions->use_subgroup_matrix) {
|
|
1505
|
+
uint32_t wg_m_sg_tile =
|
|
1506
|
+
decisions->subgroup_m * decisions->subgroup_matrix_m * ctx->global_ctx->capabilities.sg_mat_m;
|
|
1507
|
+
wg_m = CEIL_DIV(dst->ne[0], wg_m_sg_tile);
|
|
1508
|
+
uint32_t wg_n_sg_tile =
|
|
1509
|
+
decisions->subgroup_n * decisions->subgroup_matrix_n * ctx->global_ctx->capabilities.sg_mat_n;
|
|
1510
|
+
wg_n = CEIL_DIV(dst->ne[1], wg_n_sg_tile);
|
|
1511
|
+
} else {
|
|
1512
|
+
uint32_t tile_m_s = decisions->tile_m * decisions->wg_size_m;
|
|
1513
|
+
uint32_t tile_n_s = decisions->tile_n * decisions->wg_size_n;
|
|
1514
|
+
wg_m = CEIL_DIV(dst->ne[0], tile_m_s);
|
|
1515
|
+
wg_n = CEIL_DIV(dst->ne[1], tile_n_s);
|
|
1516
|
+
}
|
|
1517
|
+
uint32_t total_wg = wg_m * wg_n * dst->ne[2] * dst->ne[3];
|
|
1518
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1519
|
+
|
|
1520
|
+
} else { // legacy
|
|
1521
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
1522
|
+
uint32_t wg_size = decisions->wg_size;
|
|
1523
|
+
uint32_t total_wg = CEIL_DIV(dst->ne[0] * dst->ne[1] * dst->ne[2] * dst->ne[3], wg_size);
|
|
1524
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
static webgpu_encoded_op ggml_webgpu_mul_mat_id_vec(webgpu_context & ctx,
|
|
1531
|
+
ggml_tensor * src0,
|
|
1532
|
+
ggml_tensor * src1,
|
|
1533
|
+
ggml_tensor * src2,
|
|
1534
|
+
ggml_tensor * dst) {
|
|
1535
|
+
const uint32_t param_n_expert = (uint32_t) src0->ne[2];
|
|
1536
|
+
const uint32_t param_n_expert_used = (uint32_t) dst->ne[1];
|
|
1537
|
+
|
|
1538
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1539
|
+
shader_lib_ctx.src0 = src0;
|
|
1540
|
+
shader_lib_ctx.src1 = src1;
|
|
1541
|
+
shader_lib_ctx.src2 = src2;
|
|
1542
|
+
shader_lib_ctx.dst = dst;
|
|
1543
|
+
shader_lib_ctx.supports_subgroups = ctx->global_ctx->capabilities.supports_subgroups;
|
|
1544
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1545
|
+
|
|
1546
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_mul_mat_id_vec_pipeline(shader_lib_ctx);
|
|
1547
|
+
|
|
1548
|
+
std::vector<uint32_t> params = {
|
|
1549
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
1550
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
1551
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)),
|
|
1552
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1553
|
+
(uint32_t) src0->ne[0],
|
|
1554
|
+
(uint32_t) src0->ne[1],
|
|
1555
|
+
param_n_expert,
|
|
1556
|
+
param_n_expert_used,
|
|
1557
|
+
(uint32_t) src1->ne[1],
|
|
1558
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1559
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
1560
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1561
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1564
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1565
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(src0), ggml_webgpu_tensor_align_offset(ctx, src0),
|
|
1566
|
+
ggml_webgpu_tensor_binding_size(ctx, src0)),
|
|
1567
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(src1), ggml_webgpu_tensor_align_offset(ctx, src1),
|
|
1568
|
+
ggml_webgpu_tensor_binding_size(ctx, src1)),
|
|
1569
|
+
ggml_webgpu_make_bind_group_entry(2, ggml_webgpu_tensor_buf(src2), ggml_webgpu_tensor_align_offset(ctx, src2),
|
|
1570
|
+
ggml_webgpu_tensor_binding_size(ctx, src2)),
|
|
1571
|
+
ggml_webgpu_make_bind_group_entry(3, ggml_webgpu_tensor_buf(dst), ggml_webgpu_tensor_align_offset(ctx, dst),
|
|
1572
|
+
ggml_webgpu_tensor_binding_size(ctx, dst)),
|
|
1573
|
+
};
|
|
1574
|
+
|
|
1575
|
+
uint32_t wg_x = 1;
|
|
1576
|
+
uint32_t wg_y = 1;
|
|
1577
|
+
|
|
1578
|
+
auto * decisions = static_cast<ggml_webgpu_mul_mat_vec_shader_decisions *>(pipeline.context.get());
|
|
1579
|
+
|
|
1580
|
+
const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
1581
|
+
uint32_t output_groups = CEIL_DIV(dst->ne[0], decisions->outputs_per_wg);
|
|
1582
|
+
uint32_t total_wg = output_groups * param_n_expert_used;
|
|
1583
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1584
|
+
|
|
1585
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
static webgpu_encoded_op ggml_webgpu_mul_mat_id(webgpu_context & ctx,
|
|
1589
|
+
ggml_tensor * src0,
|
|
1590
|
+
ggml_tensor * src1,
|
|
1591
|
+
ggml_tensor * src2,
|
|
1592
|
+
ggml_tensor * dst) {
|
|
1593
|
+
// we can use mat-vec fast path
|
|
1594
|
+
if (dst->ne[2] == 1) {
|
|
1595
|
+
return ggml_webgpu_mul_mat_id_vec(ctx, src0, src1, src2, dst);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1599
|
+
shader_lib_ctx.src0 = src0;
|
|
1600
|
+
shader_lib_ctx.src1 = src1;
|
|
1601
|
+
shader_lib_ctx.src2 = src2;
|
|
1602
|
+
shader_lib_ctx.dst = dst;
|
|
1603
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1604
|
+
|
|
1605
|
+
// Get or create pipeline
|
|
1606
|
+
webgpu_pipeline gather_pipeline;
|
|
1607
|
+
webgpu_pipeline main_pipeline;
|
|
1608
|
+
|
|
1609
|
+
std::vector<webgpu_dispatch_desc> dispatches;
|
|
1610
|
+
|
|
1611
|
+
gather_pipeline = ctx->shader_lib->get_mul_mat_id_gather_pipeline(shader_lib_ctx);
|
|
1612
|
+
main_pipeline = ctx->shader_lib->get_mul_mat_id_pipeline(shader_lib_ctx);
|
|
1613
|
+
|
|
1614
|
+
const uint32_t param_n_expert = (uint32_t) src0->ne[2];
|
|
1615
|
+
const uint32_t param_n_expert_used = (uint32_t) dst->ne[1];
|
|
1616
|
+
const uint32_t param_n_tokens = (uint32_t) dst->ne[2];
|
|
1617
|
+
|
|
1618
|
+
// params for mul_mat_id_gather.wgsl
|
|
1619
|
+
std::vector<uint32_t> gather_params = {
|
|
1620
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)),
|
|
1621
|
+
param_n_expert,
|
|
1622
|
+
param_n_expert_used,
|
|
1623
|
+
param_n_tokens,
|
|
1624
|
+
(uint32_t) (src2->nb[1] / ggml_type_size(src2->type)),
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
const size_t dst_offset = ggml_webgpu_tensor_offset(dst);
|
|
1628
|
+
const size_t gathered_buf_nbytes = src0->ne[2] * src1->ne[2] * sizeof(uint32_t);
|
|
1629
|
+
|
|
1630
|
+
const size_t gathered_expert_used_align_offset = ROUNDUP_POW2(
|
|
1631
|
+
dst_offset + ggml_nbytes(dst), ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
1632
|
+
const size_t gathered_tokens_align_offset =
|
|
1633
|
+
ROUNDUP_POW2(gathered_expert_used_align_offset + gathered_buf_nbytes,
|
|
1634
|
+
ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
1635
|
+
const size_t gathered_count_ids_align_offset =
|
|
1636
|
+
ROUNDUP_POW2(gathered_tokens_align_offset + gathered_buf_nbytes,
|
|
1637
|
+
ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
1638
|
+
|
|
1639
|
+
const size_t gathered_binding_size = ROUNDUP_POW2(gathered_buf_nbytes, WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
1640
|
+
const size_t gathered_count_ids_binding_size =
|
|
1641
|
+
ROUNDUP_POW2(src0->ne[2] * sizeof(uint32_t), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
1642
|
+
|
|
1643
|
+
// bind group entries for mul_mat_id_gather.wgsl
|
|
1644
|
+
std::vector<wgpu::BindGroupEntry> gather_entries = {
|
|
1645
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(src2), ggml_webgpu_tensor_align_offset(ctx, src2),
|
|
1646
|
+
ggml_webgpu_tensor_binding_size(ctx, src2)),
|
|
1647
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(dst), gathered_expert_used_align_offset,
|
|
1648
|
+
gathered_binding_size),
|
|
1649
|
+
ggml_webgpu_make_bind_group_entry(2, ggml_webgpu_tensor_buf(dst), gathered_tokens_align_offset,
|
|
1650
|
+
gathered_binding_size),
|
|
1651
|
+
ggml_webgpu_make_bind_group_entry(3, ggml_webgpu_tensor_buf(dst), gathered_count_ids_align_offset,
|
|
1652
|
+
gathered_count_ids_binding_size),
|
|
1653
|
+
};
|
|
1654
|
+
|
|
1655
|
+
const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
1656
|
+
|
|
1657
|
+
const uint32_t gather_total_wg = param_n_expert;
|
|
1658
|
+
const uint32_t gather_wg_x = std::min(gather_total_wg, max_wg_per_dim);
|
|
1659
|
+
const uint32_t gather_wg_y = CEIL_DIV(gather_total_wg, gather_wg_x);
|
|
1660
|
+
|
|
1661
|
+
dispatches.push_back({
|
|
1662
|
+
gather_pipeline, std::move(gather_params), std::move(gather_entries), { gather_wg_x, gather_wg_y }
|
|
1663
|
+
});
|
|
1664
|
+
|
|
1665
|
+
// params for mul_mat_id.wgsl
|
|
1666
|
+
std::vector<uint32_t> main_params = {
|
|
1667
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
1668
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
1669
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1670
|
+
(uint32_t) src0->ne[0],
|
|
1671
|
+
(uint32_t) src0->ne[1],
|
|
1672
|
+
param_n_expert,
|
|
1673
|
+
param_n_expert_used,
|
|
1674
|
+
param_n_tokens,
|
|
1675
|
+
(uint32_t) src1->ne[1],
|
|
1676
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
1677
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
1678
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
1679
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
// bind group entries for mul_mat_id.wgsl
|
|
1683
|
+
std::vector<wgpu::BindGroupEntry> main_entries = {
|
|
1684
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(src0), ggml_webgpu_tensor_align_offset(ctx, src0),
|
|
1685
|
+
ggml_webgpu_tensor_binding_size(ctx, src0)),
|
|
1686
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(src1), ggml_webgpu_tensor_align_offset(ctx, src1),
|
|
1687
|
+
ggml_webgpu_tensor_binding_size(ctx, src1)),
|
|
1688
|
+
ggml_webgpu_make_bind_group_entry(2, ggml_webgpu_tensor_buf(dst), ggml_webgpu_tensor_align_offset(ctx, dst),
|
|
1689
|
+
ggml_webgpu_tensor_binding_size(ctx, dst)),
|
|
1690
|
+
ggml_webgpu_make_bind_group_entry(3, ggml_webgpu_tensor_buf(dst), gathered_expert_used_align_offset,
|
|
1691
|
+
gathered_binding_size),
|
|
1692
|
+
ggml_webgpu_make_bind_group_entry(4, ggml_webgpu_tensor_buf(dst), gathered_tokens_align_offset,
|
|
1693
|
+
gathered_binding_size),
|
|
1694
|
+
ggml_webgpu_make_bind_group_entry(5, ggml_webgpu_tensor_buf(dst), gathered_count_ids_align_offset,
|
|
1695
|
+
gathered_count_ids_binding_size),
|
|
1696
|
+
};
|
|
1697
|
+
|
|
1698
|
+
// Calculate workgroup dimensions
|
|
1699
|
+
uint32_t wg_x = 1;
|
|
1700
|
+
uint32_t wg_y = 1;
|
|
1701
|
+
|
|
1702
|
+
auto * main_decisions = static_cast<ggml_webgpu_mul_mat_shader_decisions *>(main_pipeline.context.get());
|
|
1703
|
+
|
|
1704
|
+
uint32_t wg_m;
|
|
1705
|
+
|
|
1706
|
+
uint32_t tile_m_s = main_decisions->tile_m * main_decisions->wg_size_m;
|
|
1707
|
+
uint32_t tile_n_s = main_decisions->tile_n * main_decisions->wg_size_n;
|
|
1708
|
+
wg_m = CEIL_DIV(dst->ne[0], tile_m_s);
|
|
1709
|
+
uint32_t total_gathered = dst->ne[1] * dst->ne[2];
|
|
1710
|
+
uint32_t max_active_experts = std::min((uint32_t) src0->ne[2], total_gathered);
|
|
1711
|
+
uint32_t max_wg_n = CEIL_DIV(total_gathered, tile_n_s) + max_active_experts;
|
|
1712
|
+
uint32_t total_wg = wg_m * max_wg_n;
|
|
1713
|
+
|
|
1714
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
1715
|
+
|
|
1716
|
+
dispatches.push_back({
|
|
1717
|
+
main_pipeline, std::move(main_params), std::move(main_entries), { wg_x, wg_y }
|
|
1718
|
+
});
|
|
1719
|
+
|
|
1720
|
+
return ggml_backend_webgpu_build_multi(ctx, dispatches);
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
static webgpu_encoded_op ggml_webgpu_flash_attn(webgpu_context & ctx,
|
|
1724
|
+
ggml_tensor * Q,
|
|
1725
|
+
ggml_tensor * K,
|
|
1726
|
+
ggml_tensor * V,
|
|
1727
|
+
ggml_tensor * mask,
|
|
1728
|
+
ggml_tensor * sinks,
|
|
1729
|
+
ggml_tensor * dst) {
|
|
1730
|
+
float scale = ggml_get_op_params_f32(dst, 0);
|
|
1731
|
+
float max_bias = ggml_get_op_params_f32(dst, 1);
|
|
1732
|
+
float logit_softcap = ggml_get_op_params_f32(dst, 2);
|
|
1733
|
+
if (logit_softcap != 0.0f) {
|
|
1734
|
+
scale /= logit_softcap;
|
|
1735
|
+
}
|
|
1736
|
+
float n_head_log2 = float(1u << (uint32_t) floor(log2(Q->ne[2])));
|
|
1737
|
+
float m0 = powf(2.0f, -(max_bias) / n_head_log2);
|
|
1738
|
+
float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
|
|
1739
|
+
|
|
1740
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
1741
|
+
shader_lib_ctx.src0 = Q;
|
|
1742
|
+
shader_lib_ctx.src1 = K;
|
|
1743
|
+
shader_lib_ctx.src2 = V;
|
|
1744
|
+
shader_lib_ctx.src3 = mask;
|
|
1745
|
+
shader_lib_ctx.src4 = sinks;
|
|
1746
|
+
shader_lib_ctx.dst = dst;
|
|
1747
|
+
shader_lib_ctx.supports_subgroups = ctx->global_ctx->capabilities.supports_subgroups;
|
|
1748
|
+
shader_lib_ctx.supports_subgroup_matrix = ctx->global_ctx->capabilities.supports_subgroup_matrix;
|
|
1749
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
1750
|
+
shader_lib_ctx.wg_mem_limit_bytes = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
1751
|
+
shader_lib_ctx.sg_mat_m = ctx->global_ctx->capabilities.sg_mat_m;
|
|
1752
|
+
shader_lib_ctx.sg_mat_n = ctx->global_ctx->capabilities.sg_mat_n;
|
|
1753
|
+
shader_lib_ctx.sg_mat_k = ctx->global_ctx->capabilities.sg_mat_k;
|
|
1754
|
+
shader_lib_ctx.min_subgroup_size = ctx->global_ctx->capabilities.min_subgroup_size;
|
|
1755
|
+
shader_lib_ctx.max_subgroup_size = ctx->global_ctx->capabilities.max_subgroup_size;
|
|
1756
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_flash_attn_pipeline(
|
|
1757
|
+
shader_lib_ctx, ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
1758
|
+
auto * decisions = static_cast<ggml_webgpu_flash_attn_decisions *>(pipeline.context.get());
|
|
1759
|
+
const int has_mask = (mask != nullptr);
|
|
1760
|
+
const int has_sinks = (sinks != nullptr);
|
|
1761
|
+
const bool kv_overlap = decisions->kv_overlap;
|
|
1762
|
+
|
|
1763
|
+
uint32_t offset_k = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, K) / ggml_type_size(K->type));
|
|
1764
|
+
uint32_t offset_v = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, V) / ggml_type_size(V->type));
|
|
1765
|
+
size_t kv_bind_offset = 0;
|
|
1766
|
+
size_t kv_bind_size = 0;
|
|
1767
|
+
if (kv_overlap) {
|
|
1768
|
+
const ggml_webgpu_merged_binding_range merged_range = ggml_webgpu_tensor_merged_binding_range(ctx, { K, V });
|
|
1769
|
+
kv_bind_offset = merged_range.offset;
|
|
1770
|
+
kv_bind_size = merged_range.size;
|
|
1771
|
+
offset_k = ggml_webgpu_tensor_merged_element_offset(K, merged_range);
|
|
1772
|
+
offset_v = ggml_webgpu_tensor_merged_element_offset(V, merged_range);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
std::vector<uint32_t> params = {
|
|
1776
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, Q) / ggml_type_size(Q->type)),
|
|
1777
|
+
offset_k,
|
|
1778
|
+
offset_v,
|
|
1779
|
+
has_mask ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, mask) / ggml_type_size(mask->type)) : 0,
|
|
1780
|
+
has_sinks ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, sinks) / ggml_type_size(sinks->type)) : 0,
|
|
1781
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
1782
|
+
(uint32_t) Q->ne[2], // number of heads
|
|
1783
|
+
(uint32_t) Q->ne[1], // sequence length (Q)
|
|
1784
|
+
(uint32_t) K->ne[1], // sequence length (K/V)
|
|
1785
|
+
(uint32_t) (Q->nb[1] / ggml_type_size(Q->type)), // stride (elements/blocks) of Q in dimension 1
|
|
1786
|
+
(uint32_t) (Q->nb[2] / ggml_type_size(Q->type)), // stride (elements/blocks) of Q in dimension 2
|
|
1787
|
+
(uint32_t) (Q->nb[3] / ggml_type_size(Q->type)), // stride (elements/blocks) of Q in dimension 3
|
|
1788
|
+
(uint32_t) (K->nb[1] / ggml_type_size(K->type)), // stride (elements/blocks) of K in dimension 1
|
|
1789
|
+
(uint32_t) (K->nb[2] / ggml_type_size(K->type)), // stride (elements/blocks) of K in dimension 2
|
|
1790
|
+
(uint32_t) (K->nb[3] / ggml_type_size(K->type)), // stride (elements/blocks) of K in dimension 3
|
|
1791
|
+
(uint32_t) (V->nb[1] / ggml_type_size(V->type)), // stride (elements/blocks) of V in dimension 1
|
|
1792
|
+
(uint32_t) (V->nb[2] / ggml_type_size(V->type)), // stride (elements/blocks) of V in dimension 2
|
|
1793
|
+
(uint32_t) (V->nb[3] / ggml_type_size(V->type)), // stride (elements/blocks) of V in dimension 3
|
|
1794
|
+
has_mask ? (uint32_t) (mask->nb[3] / ggml_type_size(mask->type)) : 0, // stride of mask dim 3
|
|
1795
|
+
(uint32_t) (Q->ne[2] / K->ne[2]), // repeat factor for K/V in dim 2 (MHA/MQA/GQA)
|
|
1796
|
+
ggml_webgpu_u32_from_f32(scale), // scale (possibly adjusted for logit softcap)
|
|
1797
|
+
ggml_webgpu_u32_from_f32(max_bias),
|
|
1798
|
+
ggml_webgpu_u32_from_f32(logit_softcap),
|
|
1799
|
+
ggml_webgpu_u32_from_f32(n_head_log2),
|
|
1800
|
+
ggml_webgpu_u32_from_f32(m0),
|
|
1801
|
+
ggml_webgpu_u32_from_f32(m1)
|
|
1802
|
+
|
|
1803
|
+
};
|
|
1804
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
1805
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, Q),
|
|
1806
|
+
};
|
|
1807
|
+
if (kv_overlap) {
|
|
1808
|
+
entries.push_back(
|
|
1809
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(K), kv_bind_offset, kv_bind_size));
|
|
1810
|
+
} else {
|
|
1811
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, K));
|
|
1812
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, V));
|
|
1813
|
+
}
|
|
1814
|
+
uint32_t binding_index = kv_overlap ? 2u : 3u;
|
|
1815
|
+
if (has_mask) {
|
|
1816
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_index++, mask));
|
|
1817
|
+
}
|
|
1818
|
+
if (has_sinks) {
|
|
1819
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_index++, sinks));
|
|
1820
|
+
}
|
|
1821
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_index++, dst));
|
|
1822
|
+
|
|
1823
|
+
if (decisions->path != GGML_WEBGPU_FLASH_ATTN_PATH_VEC) {
|
|
1824
|
+
uint32_t wg_per_head = CEIL_DIV(Q->ne[1], decisions->q_tile);
|
|
1825
|
+
uint32_t wg_x = wg_per_head * Q->ne[2] * Q->ne[3]; // wg per head * number of heads * number of batches
|
|
1826
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
wgpu::Buffer blk_buf = {};
|
|
1830
|
+
uint64_t blk_size_bytes = 0;
|
|
1831
|
+
uint32_t blk_nblk0 = 0;
|
|
1832
|
+
uint32_t blk_nblk1 = 0;
|
|
1833
|
+
uint32_t blk_batch_count = 0;
|
|
1834
|
+
|
|
1835
|
+
const uint32_t vec_nwg_cap = ctx->global_ctx->capabilities.min_subgroup_size;
|
|
1836
|
+
uint32_t nwg = 1u;
|
|
1837
|
+
const uint64_t kv_span = (uint64_t) std::max(1u, decisions->kv_tile);
|
|
1838
|
+
while ((2u * nwg * kv_span) < (uint64_t) K->ne[1] && nwg < vec_nwg_cap) {
|
|
1839
|
+
nwg <<= 1;
|
|
1840
|
+
}
|
|
1841
|
+
nwg = std::min(nwg, vec_nwg_cap);
|
|
1842
|
+
const uint64_t nrows = (uint64_t) Q->ne[1] * Q->ne[2] * Q->ne[3];
|
|
1843
|
+
const bool use_vec_reduce = nwg > 1u;
|
|
1844
|
+
GGML_ASSERT(nrows <= UINT32_MAX);
|
|
1845
|
+
|
|
1846
|
+
uint64_t tmp_stats_base = 0;
|
|
1847
|
+
uint64_t tmp_size_bytes = 0;
|
|
1848
|
+
wgpu::Buffer tmp_buf = {};
|
|
1849
|
+
uint64_t tmp_bind_offset = 0;
|
|
1850
|
+
uint64_t tmp_bind_size = 0;
|
|
1851
|
+
const size_t align_bytes = ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment;
|
|
1852
|
+
const size_t dst_offset = ggml_webgpu_tensor_offset(dst);
|
|
1853
|
+
size_t scratch_offset = ROUNDUP_POW2(dst_offset + ggml_nbytes(dst), align_bytes);
|
|
1854
|
+
|
|
1855
|
+
if (use_vec_reduce) {
|
|
1856
|
+
const uint64_t tmp_data_elems = nrows * (uint64_t) V->ne[0] * nwg;
|
|
1857
|
+
const uint64_t tmp_stats_elems = nrows * 2u * nwg;
|
|
1858
|
+
tmp_stats_base = tmp_data_elems;
|
|
1859
|
+
tmp_size_bytes =
|
|
1860
|
+
ROUNDUP_POW2((tmp_data_elems + tmp_stats_elems) * sizeof(float), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
1861
|
+
GGML_ASSERT(tmp_stats_base <= UINT32_MAX);
|
|
1862
|
+
tmp_buf = ggml_webgpu_tensor_buf(dst);
|
|
1863
|
+
tmp_bind_offset = scratch_offset;
|
|
1864
|
+
tmp_bind_size = tmp_size_bytes;
|
|
1865
|
+
scratch_offset = ROUNDUP_POW2(scratch_offset + tmp_size_bytes, align_bytes);
|
|
1866
|
+
} else {
|
|
1867
|
+
// nwg==1 writes final dst directly in vec-split; bind tmp to a tiny non-overlapping scratch region.
|
|
1868
|
+
tmp_size_bytes = WEBGPU_STORAGE_BUF_BINDING_MULT;
|
|
1869
|
+
tmp_buf = ggml_webgpu_tensor_buf(dst);
|
|
1870
|
+
tmp_bind_offset = scratch_offset;
|
|
1871
|
+
tmp_bind_size = tmp_size_bytes;
|
|
1872
|
+
scratch_offset = ROUNDUP_POW2(scratch_offset + tmp_size_bytes, align_bytes);
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
webgpu_pipeline blk_pipeline;
|
|
1876
|
+
std::vector<uint32_t> blk_params;
|
|
1877
|
+
std::vector<wgpu::BindGroupEntry> blk_entries;
|
|
1878
|
+
if (has_mask) {
|
|
1879
|
+
blk_nblk0 = CEIL_DIV((uint32_t) K->ne[1], decisions->kv_tile);
|
|
1880
|
+
blk_nblk1 = (uint32_t) Q->ne[1];
|
|
1881
|
+
blk_buf = ggml_webgpu_tensor_buf(dst);
|
|
1882
|
+
const uint32_t stride_mask3 = (uint32_t) (mask->nb[3] / ggml_type_size(mask->type));
|
|
1883
|
+
blk_batch_count = stride_mask3 > 0 ? (uint32_t) Q->ne[3] : 1u;
|
|
1884
|
+
const uint64_t blk_elems = (uint64_t) blk_nblk0 * blk_nblk1 * blk_batch_count;
|
|
1885
|
+
blk_size_bytes = ROUNDUP_POW2(blk_elems * sizeof(uint32_t), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
1886
|
+
const ggml_webgpu_shader_lib_context blk_shader_ctx = shader_lib_ctx;
|
|
1887
|
+
blk_pipeline = ctx->shader_lib->get_flash_attn_blk_pipeline(blk_shader_ctx, decisions->kv_tile);
|
|
1888
|
+
|
|
1889
|
+
blk_params = {
|
|
1890
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, mask) / ggml_type_size(mask->type)), // offset_mask
|
|
1891
|
+
(uint32_t) Q->ne[1], // seq_len_q
|
|
1892
|
+
(uint32_t) K->ne[1], // seq_len_kv
|
|
1893
|
+
stride_mask3, // stride_mask3
|
|
1894
|
+
blk_nblk0, // nblk0
|
|
1895
|
+
blk_nblk1, // nblk1
|
|
1896
|
+
};
|
|
1897
|
+
blk_entries = {
|
|
1898
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(mask),
|
|
1899
|
+
ggml_webgpu_tensor_align_offset(ctx, mask),
|
|
1900
|
+
ggml_webgpu_tensor_binding_size(ctx, mask)),
|
|
1901
|
+
ggml_webgpu_make_bind_group_entry(1, blk_buf, scratch_offset, blk_size_bytes),
|
|
1902
|
+
};
|
|
1903
|
+
scratch_offset = ROUNDUP_POW2(scratch_offset + blk_size_bytes, align_bytes);
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
std::vector<uint32_t> split_params = params;
|
|
1907
|
+
if (has_mask) {
|
|
1908
|
+
split_params.push_back(0u); // blk_base
|
|
1909
|
+
split_params.push_back(blk_nblk0); // blk_nblk0
|
|
1910
|
+
split_params.push_back(blk_nblk1); // blk_nblk1
|
|
1911
|
+
}
|
|
1912
|
+
split_params.push_back(0u); // tmp_data_base
|
|
1913
|
+
split_params.push_back((uint32_t) tmp_stats_base); // tmp_stats_base
|
|
1914
|
+
split_params.push_back(nwg); // nwg
|
|
1915
|
+
|
|
1916
|
+
std::vector<wgpu::BindGroupEntry> split_entries = {
|
|
1917
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(Q), ggml_webgpu_tensor_align_offset(ctx, Q),
|
|
1918
|
+
ggml_webgpu_tensor_binding_size(ctx, Q)),
|
|
1919
|
+
};
|
|
1920
|
+
if (kv_overlap) {
|
|
1921
|
+
split_entries.push_back(
|
|
1922
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(K), kv_bind_offset, kv_bind_size));
|
|
1923
|
+
} else {
|
|
1924
|
+
split_entries.push_back(ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(K),
|
|
1925
|
+
ggml_webgpu_tensor_align_offset(ctx, K),
|
|
1926
|
+
ggml_webgpu_tensor_binding_size(ctx, K)));
|
|
1927
|
+
split_entries.push_back(ggml_webgpu_make_bind_group_entry(2, ggml_webgpu_tensor_buf(V),
|
|
1928
|
+
ggml_webgpu_tensor_align_offset(ctx, V),
|
|
1929
|
+
ggml_webgpu_tensor_binding_size(ctx, V)));
|
|
1930
|
+
}
|
|
1931
|
+
uint32_t split_binding_index = kv_overlap ? 2u : 3u;
|
|
1932
|
+
if (has_mask) {
|
|
1933
|
+
split_entries.push_back(ggml_webgpu_make_bind_group_entry(split_binding_index++, ggml_webgpu_tensor_buf(mask),
|
|
1934
|
+
ggml_webgpu_tensor_align_offset(ctx, mask),
|
|
1935
|
+
ggml_webgpu_tensor_binding_size(ctx, mask)));
|
|
1936
|
+
}
|
|
1937
|
+
if (has_sinks) {
|
|
1938
|
+
split_entries.push_back(ggml_webgpu_make_bind_group_entry(split_binding_index++, ggml_webgpu_tensor_buf(sinks),
|
|
1939
|
+
ggml_webgpu_tensor_align_offset(ctx, sinks),
|
|
1940
|
+
ggml_webgpu_tensor_binding_size(ctx, sinks)));
|
|
1941
|
+
}
|
|
1942
|
+
if (has_mask) {
|
|
1943
|
+
split_entries.push_back(
|
|
1944
|
+
ggml_webgpu_make_bind_group_entry(split_binding_index++, blk_buf, blk_entries[1].offset, blk_size_bytes));
|
|
1945
|
+
}
|
|
1946
|
+
split_entries.push_back(
|
|
1947
|
+
ggml_webgpu_make_bind_group_entry(split_binding_index++, tmp_buf, tmp_bind_offset, tmp_bind_size));
|
|
1948
|
+
split_entries.push_back(ggml_webgpu_make_bind_group_entry(split_binding_index++, ggml_webgpu_tensor_buf(dst),
|
|
1949
|
+
ggml_webgpu_tensor_align_offset(ctx, dst),
|
|
1950
|
+
ggml_webgpu_tensor_binding_size(ctx, dst)));
|
|
1951
|
+
|
|
1952
|
+
webgpu_pipeline reduce_pipeline;
|
|
1953
|
+
std::vector<uint32_t> reduce_params;
|
|
1954
|
+
std::vector<wgpu::BindGroupEntry> reduce_entries;
|
|
1955
|
+
if (use_vec_reduce) {
|
|
1956
|
+
const uint32_t reduce_sg_size = ctx->global_ctx->capabilities.max_subgroup_size;
|
|
1957
|
+
const uint32_t reduce_wg_size =
|
|
1958
|
+
std::max(reduce_sg_size, (uint32_t) std::min<uint64_t>(
|
|
1959
|
+
(uint64_t) nwg * reduce_sg_size,
|
|
1960
|
+
ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup));
|
|
1961
|
+
ggml_webgpu_shader_lib_context reduce_shader_ctx = shader_lib_ctx;
|
|
1962
|
+
reduce_shader_ctx.max_wg_size = reduce_wg_size;
|
|
1963
|
+
reduce_pipeline = ctx->shader_lib->get_flash_attn_vec_reduce_pipeline(reduce_shader_ctx);
|
|
1964
|
+
|
|
1965
|
+
reduce_params = {
|
|
1966
|
+
(uint32_t) nrows, // nrows
|
|
1967
|
+
(uint32_t) Q->ne[1], // seq_len_q
|
|
1968
|
+
(uint32_t) Q->ne[2], // n_heads
|
|
1969
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)), // offset_dst
|
|
1970
|
+
nwg, // nwg
|
|
1971
|
+
0u, // tmp_data_base
|
|
1972
|
+
(uint32_t) tmp_stats_base, // tmp_stats_base
|
|
1973
|
+
};
|
|
1974
|
+
|
|
1975
|
+
reduce_entries = {
|
|
1976
|
+
ggml_webgpu_make_bind_group_entry(0, tmp_buf, tmp_bind_offset, tmp_size_bytes),
|
|
1977
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(dst), ggml_webgpu_tensor_align_offset(ctx, dst),
|
|
1978
|
+
ggml_webgpu_tensor_binding_size(ctx, dst)),
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
uint32_t wg_x = Q->ne[1] * Q->ne[2] * Q->ne[3];
|
|
1983
|
+
const uint64_t split_wg_total = (uint64_t) wg_x * nwg;
|
|
1984
|
+
GGML_ASSERT(split_wg_total <= UINT32_MAX);
|
|
1985
|
+
|
|
1986
|
+
std::vector<webgpu_dispatch_desc> dispatches;
|
|
1987
|
+
|
|
1988
|
+
if (has_mask) {
|
|
1989
|
+
dispatches.push_back({
|
|
1990
|
+
blk_pipeline, std::move(blk_params), std::move(blk_entries), { blk_nblk0, blk_nblk1 * blk_batch_count }
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
dispatches.push_back({
|
|
1994
|
+
pipeline, std::move(split_params), std::move(split_entries), { (uint32_t) split_wg_total, 1u }
|
|
1995
|
+
});
|
|
1996
|
+
if (use_vec_reduce) {
|
|
1997
|
+
dispatches.push_back({
|
|
1998
|
+
reduce_pipeline, std::move(reduce_params), std::move(reduce_entries), { (uint32_t) nrows, 1u }
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
return ggml_backend_webgpu_build_multi(ctx, dispatches);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
static webgpu_encoded_op ggml_webgpu_unary_op(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2006
|
+
bool is_unary = dst->op == GGML_OP_UNARY;
|
|
2007
|
+
|
|
2008
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2009
|
+
shader_lib_ctx.src0 = src;
|
|
2010
|
+
shader_lib_ctx.src1 = nullptr;
|
|
2011
|
+
shader_lib_ctx.dst = dst;
|
|
2012
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2013
|
+
|
|
2014
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_unary_pipeline(shader_lib_ctx);
|
|
2015
|
+
|
|
2016
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2017
|
+
const bool inplace = decisions->inplace;
|
|
2018
|
+
|
|
2019
|
+
uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
2020
|
+
|
|
2021
|
+
std::vector<uint32_t> params = { ne,
|
|
2022
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2023
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2024
|
+
(uint32_t) (src->nb[0] / ggml_type_size(src->type)),
|
|
2025
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
2026
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
2027
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
2028
|
+
(uint32_t) src->ne[0],
|
|
2029
|
+
(uint32_t) src->ne[1],
|
|
2030
|
+
(uint32_t) src->ne[2] };
|
|
2031
|
+
|
|
2032
|
+
ggml_tensor * effective_src = src;
|
|
2033
|
+
if (is_unary) {
|
|
2034
|
+
ggml_unary_op unary_op = ggml_get_unary_op(dst);
|
|
2035
|
+
switch (unary_op) {
|
|
2036
|
+
case GGML_UNARY_OP_XIELU:
|
|
2037
|
+
{
|
|
2038
|
+
// Get float parameters and reinterpret their bit patterns as uint32_t
|
|
2039
|
+
// for passing through the params buffer
|
|
2040
|
+
float alpha_n = ggml_get_op_params_f32(dst, 1);
|
|
2041
|
+
float alpha_p = ggml_get_op_params_f32(dst, 2);
|
|
2042
|
+
float beta = ggml_get_op_params_f32(dst, 3);
|
|
2043
|
+
float eps = ggml_get_op_params_f32(dst, 4);
|
|
2044
|
+
params.push_back(ggml_webgpu_u32_from_f32(alpha_n));
|
|
2045
|
+
params.push_back(ggml_webgpu_u32_from_f32(alpha_p));
|
|
2046
|
+
params.push_back(ggml_webgpu_u32_from_f32(beta));
|
|
2047
|
+
params.push_back(ggml_webgpu_u32_from_f32(eps));
|
|
2048
|
+
break;
|
|
2049
|
+
}
|
|
2050
|
+
default:
|
|
2051
|
+
break;
|
|
2052
|
+
}
|
|
2053
|
+
} else if (dst->op == GGML_OP_CLAMP) {
|
|
2054
|
+
float clamp_min = ggml_get_op_params_f32(dst, 0);
|
|
2055
|
+
float clamp_max = ggml_get_op_params_f32(dst, 1);
|
|
2056
|
+
params.push_back(ggml_webgpu_u32_from_f32(clamp_min));
|
|
2057
|
+
params.push_back(ggml_webgpu_u32_from_f32(clamp_max));
|
|
2058
|
+
} else if (dst->op == GGML_OP_FILL) {
|
|
2059
|
+
float fill_val = ggml_get_op_params_f32(dst, 0);
|
|
2060
|
+
params.push_back(ggml_webgpu_u32_from_f32(fill_val));
|
|
2061
|
+
effective_src = dst; // fill simply fills dst
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
2065
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, effective_src),
|
|
2066
|
+
};
|
|
2067
|
+
if (!inplace) {
|
|
2068
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst));
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
2072
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
static webgpu_encoded_op ggml_webgpu_binary_op(webgpu_context & ctx,
|
|
2076
|
+
ggml_tensor * src0,
|
|
2077
|
+
ggml_tensor * src1,
|
|
2078
|
+
ggml_tensor * dst) {
|
|
2079
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2080
|
+
shader_lib_ctx.src0 = src0;
|
|
2081
|
+
shader_lib_ctx.src1 = src1;
|
|
2082
|
+
shader_lib_ctx.dst = dst;
|
|
2083
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2084
|
+
|
|
2085
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_binary_pipeline(shader_lib_ctx);
|
|
2086
|
+
auto * decisions = static_cast<ggml_webgpu_binary_shader_decisions *>(pipeline.context.get());
|
|
2087
|
+
|
|
2088
|
+
uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
2089
|
+
|
|
2090
|
+
size_t src0_webgpu_tensor_align_offset = ggml_webgpu_tensor_align_offset(ctx, src0);
|
|
2091
|
+
size_t src1_webgpu_tensor_align_offset = ggml_webgpu_tensor_align_offset(ctx, src1);
|
|
2092
|
+
|
|
2093
|
+
uint32_t offset_src0 = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type));
|
|
2094
|
+
uint32_t offset_src1 = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type));
|
|
2095
|
+
size_t merged_offset = 0;
|
|
2096
|
+
size_t merged_size = 0;
|
|
2097
|
+
if (decisions->src_overlap) {
|
|
2098
|
+
const ggml_webgpu_merged_binding_range merged_range =
|
|
2099
|
+
ggml_webgpu_tensor_merged_binding_range(ctx, { src0, src1 });
|
|
2100
|
+
merged_offset = merged_range.offset;
|
|
2101
|
+
merged_size = merged_range.size;
|
|
2102
|
+
offset_src0 = ggml_webgpu_tensor_merged_element_offset(src0, merged_range);
|
|
2103
|
+
offset_src1 = ggml_webgpu_tensor_merged_element_offset(src1, merged_range);
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
std::vector<uint32_t> params = {
|
|
2107
|
+
ne,
|
|
2108
|
+
offset_src0,
|
|
2109
|
+
offset_src1,
|
|
2110
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2111
|
+
(uint32_t) (src0->nb[0] / ggml_type_size(src0->type)),
|
|
2112
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2113
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2114
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2115
|
+
(uint32_t) (src1->nb[0] / ggml_type_size(src1->type)),
|
|
2116
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
2117
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
2118
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
2119
|
+
(uint32_t) src0->ne[0],
|
|
2120
|
+
(uint32_t) src0->ne[1],
|
|
2121
|
+
(uint32_t) src0->ne[2],
|
|
2122
|
+
(uint32_t) src1->ne[0],
|
|
2123
|
+
(uint32_t) src1->ne[1],
|
|
2124
|
+
(uint32_t) src1->ne[2],
|
|
2125
|
+
(uint32_t) src1->ne[3],
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
std::vector<wgpu::BindGroupEntry> entries;
|
|
2129
|
+
|
|
2130
|
+
if (decisions->src_overlap) {
|
|
2131
|
+
entries.push_back(
|
|
2132
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(src0), merged_offset, merged_size));
|
|
2133
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst));
|
|
2134
|
+
} else {
|
|
2135
|
+
entries.push_back(ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(src0),
|
|
2136
|
+
src0_webgpu_tensor_align_offset,
|
|
2137
|
+
ggml_webgpu_tensor_binding_size(ctx, src0)));
|
|
2138
|
+
entries.push_back(ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(src1),
|
|
2139
|
+
src1_webgpu_tensor_align_offset,
|
|
2140
|
+
ggml_webgpu_tensor_binding_size(ctx, src1)));
|
|
2141
|
+
if (!decisions->inplace && !decisions->overlap) {
|
|
2142
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst));
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
2147
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
static webgpu_encoded_op ggml_webgpu_add_id(webgpu_context & ctx,
|
|
2151
|
+
ggml_tensor * src0,
|
|
2152
|
+
ggml_tensor * src1,
|
|
2153
|
+
ggml_tensor * src2,
|
|
2154
|
+
ggml_tensor * dst) {
|
|
2155
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2156
|
+
shader_lib_ctx.src0 = src0;
|
|
2157
|
+
shader_lib_ctx.src1 = src1;
|
|
2158
|
+
shader_lib_ctx.src2 = src2;
|
|
2159
|
+
shader_lib_ctx.dst = dst;
|
|
2160
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2161
|
+
|
|
2162
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_add_id_pipeline(shader_lib_ctx);
|
|
2163
|
+
|
|
2164
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2165
|
+
|
|
2166
|
+
std::vector<uint32_t> params = {
|
|
2167
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
2168
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
2169
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)),
|
|
2170
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2171
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2172
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2173
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
2174
|
+
(uint32_t) (src2->nb[0] / ggml_type_size(src2->type)),
|
|
2175
|
+
(uint32_t) (src2->nb[1] / ggml_type_size(src2->type)),
|
|
2176
|
+
(uint32_t) dst->ne[0],
|
|
2177
|
+
(uint32_t) dst->ne[1],
|
|
2178
|
+
(uint32_t) dst->ne[2],
|
|
2179
|
+
};
|
|
2180
|
+
|
|
2181
|
+
std::vector<wgpu::BindGroupEntry> entries;
|
|
2182
|
+
|
|
2183
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0));
|
|
2184
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1));
|
|
2185
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, src2));
|
|
2186
|
+
|
|
2187
|
+
if (!decisions->inplace) {
|
|
2188
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 3, dst));
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
uint32_t wg_x = 1;
|
|
2192
|
+
uint32_t wg_y = 1;
|
|
2193
|
+
uint32_t total_wg = ggml_nrows(dst);
|
|
2194
|
+
const uint32_t max_wg_per_dim = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
2195
|
+
compute_2d_workgroups(total_wg, max_wg_per_dim, wg_x, wg_y);
|
|
2196
|
+
|
|
2197
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
static webgpu_encoded_op ggml_webgpu_concat(webgpu_context & ctx,
|
|
2201
|
+
ggml_tensor * src0,
|
|
2202
|
+
ggml_tensor * src1,
|
|
2203
|
+
ggml_tensor * dst) {
|
|
2204
|
+
uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
2205
|
+
uint32_t dim = (uint32_t) dst->op_params[0];
|
|
2206
|
+
|
|
2207
|
+
std::vector<uint32_t> params = {
|
|
2208
|
+
ne,
|
|
2209
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
2210
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
2211
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2212
|
+
(uint32_t) (src0->nb[0] / ggml_type_size(src0->type)),
|
|
2213
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2214
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2215
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2216
|
+
(uint32_t) (src1->nb[0] / ggml_type_size(src1->type)),
|
|
2217
|
+
(uint32_t) (src1->nb[1] / ggml_type_size(src1->type)),
|
|
2218
|
+
(uint32_t) (src1->nb[2] / ggml_type_size(src1->type)),
|
|
2219
|
+
(uint32_t) (src1->nb[3] / ggml_type_size(src1->type)),
|
|
2220
|
+
(uint32_t) dst->ne[0],
|
|
2221
|
+
(uint32_t) dst->ne[1],
|
|
2222
|
+
(uint32_t) dst->ne[2],
|
|
2223
|
+
(uint32_t) dst->ne[3],
|
|
2224
|
+
dim,
|
|
2225
|
+
(uint32_t) src0->ne[dim]
|
|
2226
|
+
};
|
|
2227
|
+
|
|
2228
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
2229
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
2230
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1),
|
|
2231
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst),
|
|
2232
|
+
};
|
|
2233
|
+
|
|
2234
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2235
|
+
shader_lib_ctx.src0 = src0;
|
|
2236
|
+
shader_lib_ctx.src1 = src1;
|
|
2237
|
+
shader_lib_ctx.dst = dst;
|
|
2238
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2239
|
+
|
|
2240
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_concat_pipeline(shader_lib_ctx);
|
|
2241
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2242
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
2243
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
static webgpu_encoded_op ggml_webgpu_repeat(webgpu_context & ctx, ggml_tensor * src0, ggml_tensor * dst) {
|
|
2247
|
+
uint32_t ne = (uint32_t) ggml_nelements(dst);
|
|
2248
|
+
|
|
2249
|
+
std::vector<uint32_t> params = { ne,
|
|
2250
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) /
|
|
2251
|
+
ggml_type_size(src0->type)),
|
|
2252
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2253
|
+
(uint32_t) (src0->nb[0] / ggml_type_size(src0->type)),
|
|
2254
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2255
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2256
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2257
|
+
(uint32_t) (src0->ne[0]),
|
|
2258
|
+
(uint32_t) (src0->ne[1]),
|
|
2259
|
+
(uint32_t) (src0->ne[2]),
|
|
2260
|
+
(uint32_t) (src0->ne[3]),
|
|
2261
|
+
(uint32_t) (dst->ne[0]),
|
|
2262
|
+
(uint32_t) (dst->ne[1]),
|
|
2263
|
+
(uint32_t) (dst->ne[2]) };
|
|
2264
|
+
|
|
2265
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
2266
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
2267
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst),
|
|
2268
|
+
};
|
|
2269
|
+
|
|
2270
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2271
|
+
shader_lib_ctx.src0 = src0;
|
|
2272
|
+
shader_lib_ctx.dst = dst;
|
|
2273
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2274
|
+
|
|
2275
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_repeat_pipeline(shader_lib_ctx);
|
|
2276
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2277
|
+
uint32_t wg_x = CEIL_DIV(ne, decisions->wg_size);
|
|
2278
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
static std::optional<webgpu_encoded_op> ggml_webgpu_rms_norm_mul(webgpu_context & ctx,
|
|
2282
|
+
ggml_tensor * rn_src,
|
|
2283
|
+
ggml_tensor * rn_dst,
|
|
2284
|
+
ggml_tensor * mul_src0,
|
|
2285
|
+
ggml_tensor * mul_src1,
|
|
2286
|
+
ggml_tensor * dst) {
|
|
2287
|
+
ggml_tensor * mul_src;
|
|
2288
|
+
|
|
2289
|
+
if (ggml_webgpu_tensor_equal(rn_dst, mul_src0)) {
|
|
2290
|
+
mul_src = mul_src1;
|
|
2291
|
+
} else if (ggml_webgpu_tensor_equal(rn_dst, mul_src1)) {
|
|
2292
|
+
mul_src = mul_src0;
|
|
2293
|
+
} else {
|
|
2294
|
+
GGML_ABORT("rms_norm must be equal to the one of mul_src0 and mul_src1");
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
uint32_t offset_rn_src = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, rn_src) / ggml_type_size(rn_src->type));
|
|
2298
|
+
uint32_t offset_mul_src =
|
|
2299
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, mul_src) / ggml_type_size(mul_src->type));
|
|
2300
|
+
size_t merged_offset = 0;
|
|
2301
|
+
size_t merged_size = 0;
|
|
2302
|
+
|
|
2303
|
+
std::vector<uint32_t> params = {
|
|
2304
|
+
offset_rn_src,
|
|
2305
|
+
offset_mul_src,
|
|
2306
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2307
|
+
(uint32_t) (rn_src->nb[1] / ggml_type_size(rn_src->type)),
|
|
2308
|
+
(uint32_t) (rn_src->nb[2] / ggml_type_size(rn_src->type)),
|
|
2309
|
+
(uint32_t) (rn_src->nb[3] / ggml_type_size(rn_src->type)),
|
|
2310
|
+
(uint32_t) (mul_src->nb[1] / ggml_type_size(mul_src->type)),
|
|
2311
|
+
(uint32_t) (mul_src->nb[2] / ggml_type_size(mul_src->type)),
|
|
2312
|
+
(uint32_t) (mul_src->nb[3] / ggml_type_size(mul_src->type)),
|
|
2313
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2314
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2315
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2316
|
+
(uint32_t) mul_src->ne[0],
|
|
2317
|
+
(uint32_t) mul_src->ne[1],
|
|
2318
|
+
(uint32_t) mul_src->ne[2],
|
|
2319
|
+
(uint32_t) mul_src->ne[3],
|
|
2320
|
+
(uint32_t) dst->ne[0],
|
|
2321
|
+
(uint32_t) dst->ne[1],
|
|
2322
|
+
(uint32_t) dst->ne[2],
|
|
2323
|
+
(uint32_t) dst->ne[3],
|
|
2324
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(rn_dst, 0)) // epsilon, treated as f32 in the shader
|
|
2325
|
+
};
|
|
2326
|
+
|
|
2327
|
+
std::vector<wgpu::BindGroupEntry> entries;
|
|
2328
|
+
|
|
2329
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2330
|
+
shader_lib_ctx.src0 = rn_src;
|
|
2331
|
+
shader_lib_ctx.src1 = mul_src;
|
|
2332
|
+
shader_lib_ctx.dst = dst;
|
|
2333
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2334
|
+
|
|
2335
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_rms_norm_mul_pipeline(shader_lib_ctx);
|
|
2336
|
+
auto * decisions = static_cast<ggml_webgpu_rms_norm_mul_shader_decisions *>(pipeline.context.get());
|
|
2337
|
+
|
|
2338
|
+
if (decisions->src_overlap) {
|
|
2339
|
+
const ggml_webgpu_merged_binding_range merged_range =
|
|
2340
|
+
ggml_webgpu_tensor_merged_binding_range(ctx, { rn_src, mul_src });
|
|
2341
|
+
merged_offset = merged_range.offset;
|
|
2342
|
+
merged_size = merged_range.size;
|
|
2343
|
+
offset_rn_src = ggml_webgpu_tensor_merged_element_offset(rn_src, merged_range);
|
|
2344
|
+
offset_mul_src = ggml_webgpu_tensor_merged_element_offset(mul_src, merged_range);
|
|
2345
|
+
params[0] = offset_rn_src;
|
|
2346
|
+
params[1] = offset_mul_src;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
if (decisions->inplace || decisions->overlap) {
|
|
2350
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, rn_src));
|
|
2351
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, mul_src));
|
|
2352
|
+
} else if (decisions->src_overlap) {
|
|
2353
|
+
entries.push_back(
|
|
2354
|
+
ggml_webgpu_make_bind_group_entry(0, ggml_webgpu_tensor_buf(rn_src), merged_offset, merged_size));
|
|
2355
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst));
|
|
2356
|
+
} else {
|
|
2357
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, rn_src));
|
|
2358
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, mul_src));
|
|
2359
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, dst));
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, ggml_nrows(dst));
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
static webgpu_encoded_op ggml_webgpu_row_norm(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2366
|
+
std::vector<uint32_t> params = {
|
|
2367
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2368
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2369
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
2370
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
2371
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
2372
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2373
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2374
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2375
|
+
(uint32_t) src->ne[0],
|
|
2376
|
+
(uint32_t) src->ne[1],
|
|
2377
|
+
(uint32_t) src->ne[2],
|
|
2378
|
+
(uint32_t) src->ne[3],
|
|
2379
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 0)) // epsilon, treated as f32 in the shader
|
|
2380
|
+
};
|
|
2381
|
+
|
|
2382
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2383
|
+
shader_lib_ctx.src0 = src;
|
|
2384
|
+
shader_lib_ctx.dst = dst;
|
|
2385
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2386
|
+
|
|
2387
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_row_norm_pipeline(shader_lib_ctx);
|
|
2388
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2389
|
+
|
|
2390
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src) };
|
|
2391
|
+
if (!decisions->inplace) {
|
|
2392
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst));
|
|
2393
|
+
}
|
|
2394
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, ggml_nrows(src));
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
static webgpu_encoded_op ggml_webgpu_rope(webgpu_context & ctx,
|
|
2398
|
+
ggml_tensor * src0,
|
|
2399
|
+
ggml_tensor * src1,
|
|
2400
|
+
ggml_tensor * src2,
|
|
2401
|
+
ggml_tensor * dst) {
|
|
2402
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2403
|
+
shader_lib_ctx.src0 = src0;
|
|
2404
|
+
shader_lib_ctx.src1 = src1;
|
|
2405
|
+
shader_lib_ctx.src2 = src2;
|
|
2406
|
+
shader_lib_ctx.dst = dst;
|
|
2407
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2408
|
+
|
|
2409
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_rope_pipeline(shader_lib_ctx);
|
|
2410
|
+
|
|
2411
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2412
|
+
|
|
2413
|
+
const bool inplace = decisions->inplace;
|
|
2414
|
+
const int has_freq_factor = (src2 != nullptr);
|
|
2415
|
+
|
|
2416
|
+
const int n_dims = ((int32_t *) dst->op_params)[1];
|
|
2417
|
+
const int mode = ((int32_t *) dst->op_params)[2];
|
|
2418
|
+
const int n_ctx_orig = ((int32_t *) dst->op_params)[4];
|
|
2419
|
+
|
|
2420
|
+
float freq_base;
|
|
2421
|
+
float freq_scale;
|
|
2422
|
+
float ext_factor;
|
|
2423
|
+
float attn_factor;
|
|
2424
|
+
float beta_fast;
|
|
2425
|
+
float beta_slow;
|
|
2426
|
+
memcpy(&freq_base, (int32_t *) dst->op_params + 5, sizeof(float));
|
|
2427
|
+
memcpy(&freq_scale, (int32_t *) dst->op_params + 6, sizeof(float));
|
|
2428
|
+
memcpy(&ext_factor, (int32_t *) dst->op_params + 7, sizeof(float));
|
|
2429
|
+
memcpy(&attn_factor, (int32_t *) dst->op_params + 8, sizeof(float));
|
|
2430
|
+
memcpy(&beta_fast, (int32_t *) dst->op_params + 9, sizeof(float));
|
|
2431
|
+
memcpy(&beta_slow, (int32_t *) dst->op_params + 10, sizeof(float));
|
|
2432
|
+
|
|
2433
|
+
int sections[4];
|
|
2434
|
+
memcpy(sections, (int32_t *) dst->op_params + 11, 4 * sizeof(int));
|
|
2435
|
+
|
|
2436
|
+
float theta_scale = powf(freq_base, -2.0f / n_dims);
|
|
2437
|
+
|
|
2438
|
+
float corr_dims[2];
|
|
2439
|
+
ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, corr_dims);
|
|
2440
|
+
|
|
2441
|
+
std::vector<uint32_t> params = {
|
|
2442
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
2443
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)),
|
|
2444
|
+
src2 != nullptr ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)) : 0,
|
|
2445
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2446
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2447
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2448
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2449
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2450
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2451
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2452
|
+
(uint32_t) ggml_nelements(src0) / 2,
|
|
2453
|
+
(uint32_t) src0->ne[0],
|
|
2454
|
+
(uint32_t) src0->ne[1],
|
|
2455
|
+
(uint32_t) src0->ne[2],
|
|
2456
|
+
(uint32_t) n_dims,
|
|
2457
|
+
(uint32_t) mode,
|
|
2458
|
+
ggml_webgpu_u32_from_f32(theta_scale),
|
|
2459
|
+
ggml_webgpu_u32_from_f32(attn_factor),
|
|
2460
|
+
ggml_webgpu_u32_from_f32(freq_scale),
|
|
2461
|
+
ggml_webgpu_u32_from_f32(ext_factor),
|
|
2462
|
+
ggml_webgpu_u32_from_f32(corr_dims[0]),
|
|
2463
|
+
ggml_webgpu_u32_from_f32(corr_dims[1]),
|
|
2464
|
+
(uint32_t) sections[0],
|
|
2465
|
+
(uint32_t) sections[1],
|
|
2466
|
+
(uint32_t) sections[2],
|
|
2467
|
+
(uint32_t) sections[3]
|
|
2468
|
+
};
|
|
2469
|
+
|
|
2470
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
2471
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1) };
|
|
2472
|
+
uint32_t dst_binding = 2;
|
|
2473
|
+
if (has_freq_factor) {
|
|
2474
|
+
dst_binding = 3;
|
|
2475
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 2, src2));
|
|
2476
|
+
}
|
|
2477
|
+
if (!inplace) {
|
|
2478
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, dst_binding, dst));
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
uint32_t wg_x = CEIL_DIV(ggml_nelements(dst), decisions->wg_size);
|
|
2482
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2485
|
+
static webgpu_encoded_op ggml_webgpu_glu(webgpu_context & ctx,
|
|
2486
|
+
ggml_tensor * src0,
|
|
2487
|
+
ggml_tensor * src1,
|
|
2488
|
+
ggml_tensor * dst) {
|
|
2489
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2490
|
+
shader_lib_ctx.src0 = src0;
|
|
2491
|
+
shader_lib_ctx.src1 = src1;
|
|
2492
|
+
shader_lib_ctx.dst = dst;
|
|
2493
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2494
|
+
|
|
2495
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_glu_pipeline(shader_lib_ctx);
|
|
2496
|
+
|
|
2497
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2498
|
+
|
|
2499
|
+
const int split = (src1 != nullptr);
|
|
2500
|
+
|
|
2501
|
+
std::vector<uint32_t> params = {
|
|
2502
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
2503
|
+
src1 != nullptr ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)) : 0,
|
|
2504
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2505
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2506
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2507
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2508
|
+
src1 != nullptr ? (uint32_t) (src1->nb[1] / ggml_type_size(src1->type)) :
|
|
2509
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2510
|
+
src1 != nullptr ? (uint32_t) (src1->nb[2] / ggml_type_size(src1->type)) :
|
|
2511
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2512
|
+
src1 != nullptr ? (uint32_t) (src1->nb[3] / ggml_type_size(src1->type)) :
|
|
2513
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2514
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2515
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2516
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2517
|
+
(uint32_t) ggml_nelements(dst),
|
|
2518
|
+
(uint32_t) dst->ne[0],
|
|
2519
|
+
(uint32_t) dst->ne[1],
|
|
2520
|
+
(uint32_t) dst->ne[2],
|
|
2521
|
+
(uint32_t) ((int32_t *) dst->op_params)[1], // swapped
|
|
2522
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 2)), // alpha, for swiglu_oai
|
|
2523
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 3)), // limit, for swiglu_oai
|
|
2524
|
+
};
|
|
2525
|
+
|
|
2526
|
+
std::vector<wgpu::BindGroupEntry> entries = {
|
|
2527
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src0),
|
|
2528
|
+
};
|
|
2529
|
+
uint32_t dst_binding = 1;
|
|
2530
|
+
if (split) {
|
|
2531
|
+
dst_binding = 2;
|
|
2532
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, src1));
|
|
2533
|
+
}
|
|
2534
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, dst_binding, dst));
|
|
2535
|
+
|
|
2536
|
+
uint32_t wg_x = CEIL_DIV(ggml_nelements(dst), decisions->wg_size);
|
|
2537
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
static webgpu_encoded_op ggml_webgpu_scale(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2541
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2542
|
+
shader_lib_ctx.src0 = src;
|
|
2543
|
+
shader_lib_ctx.src1 = nullptr;
|
|
2544
|
+
shader_lib_ctx.dst = dst;
|
|
2545
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2546
|
+
|
|
2547
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_scale_pipeline(shader_lib_ctx);
|
|
2548
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2549
|
+
|
|
2550
|
+
// params unchanged
|
|
2551
|
+
std::vector<uint32_t> params = {
|
|
2552
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2553
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2554
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
2555
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
2556
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
2557
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2558
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2559
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2560
|
+
(uint32_t) ggml_nelements(dst),
|
|
2561
|
+
(uint32_t) src->ne[0],
|
|
2562
|
+
(uint32_t) src->ne[1],
|
|
2563
|
+
(uint32_t) src->ne[2],
|
|
2564
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 0)), // scale
|
|
2565
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 1)) // bias
|
|
2566
|
+
};
|
|
2567
|
+
|
|
2568
|
+
// bindgroups unchanged
|
|
2569
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src) };
|
|
2570
|
+
|
|
2571
|
+
if (!decisions->inplace) {
|
|
2572
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst));
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
uint32_t wg_x = CEIL_DIV(ggml_nelements(dst), decisions->wg_size);
|
|
2576
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
static webgpu_encoded_op ggml_webgpu_soft_max(webgpu_context & ctx,
|
|
2580
|
+
ggml_tensor * src0,
|
|
2581
|
+
ggml_tensor * src1,
|
|
2582
|
+
ggml_tensor * src2,
|
|
2583
|
+
ggml_tensor * dst) {
|
|
2584
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2585
|
+
shader_lib_ctx.src0 = src0;
|
|
2586
|
+
shader_lib_ctx.src1 = src1;
|
|
2587
|
+
shader_lib_ctx.src2 = src2;
|
|
2588
|
+
shader_lib_ctx.dst = dst;
|
|
2589
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2590
|
+
|
|
2591
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_soft_max_pipeline(shader_lib_ctx);
|
|
2592
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2593
|
+
|
|
2594
|
+
const bool inplace = decisions->inplace;
|
|
2595
|
+
const int has_mask = (src1 != nullptr);
|
|
2596
|
+
const int has_sink = (src2 != nullptr);
|
|
2597
|
+
float max_bias = ggml_get_op_params_f32(dst, 1);
|
|
2598
|
+
float n_head_log2 = float(1u << (uint32_t) floor(log2(src0->ne[2])));
|
|
2599
|
+
float m0 = powf(2.0f, -(max_bias) / n_head_log2);
|
|
2600
|
+
float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
|
|
2601
|
+
|
|
2602
|
+
std::vector<uint32_t> params = {
|
|
2603
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src0) / ggml_type_size(src0->type)),
|
|
2604
|
+
has_mask ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src1) / ggml_type_size(src1->type)) : 0,
|
|
2605
|
+
has_sink ? (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src2) / ggml_type_size(src2->type)) : 0,
|
|
2606
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2607
|
+
(uint32_t) (src0->nb[1] / ggml_type_size(src0->type)),
|
|
2608
|
+
(uint32_t) (src0->nb[2] / ggml_type_size(src0->type)),
|
|
2609
|
+
(uint32_t) (src0->nb[3] / ggml_type_size(src0->type)),
|
|
2610
|
+
has_mask ? (uint32_t) (src1->nb[1] / ggml_type_size(src1->type)) : 0,
|
|
2611
|
+
has_mask ? (uint32_t) (src1->nb[2] / ggml_type_size(src1->type)) : 0,
|
|
2612
|
+
has_mask ? (uint32_t) (src1->nb[3] / ggml_type_size(src1->type)) : 0,
|
|
2613
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2614
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2615
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2616
|
+
(uint32_t) ggml_nelements(dst),
|
|
2617
|
+
(uint32_t) src0->ne[0],
|
|
2618
|
+
(uint32_t) src0->ne[1],
|
|
2619
|
+
(uint32_t) src0->ne[2],
|
|
2620
|
+
has_mask ? (uint32_t) src1->ne[2] : 0,
|
|
2621
|
+
has_mask ? (uint32_t) src1->ne[3] : 0,
|
|
2622
|
+
ggml_webgpu_u32_from_f32(ggml_get_op_params_f32(dst, 0)), // scale
|
|
2623
|
+
ggml_webgpu_u32_from_f32(max_bias),
|
|
2624
|
+
ggml_webgpu_u32_from_f32(n_head_log2),
|
|
2625
|
+
ggml_webgpu_u32_from_f32(m0),
|
|
2626
|
+
ggml_webgpu_u32_from_f32(m1)
|
|
2627
|
+
};
|
|
2628
|
+
|
|
2629
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_bind_group_entry(
|
|
2630
|
+
0, ggml_webgpu_tensor_buf(src0), ggml_webgpu_tensor_align_offset(ctx, src0),
|
|
2631
|
+
ggml_webgpu_tensor_binding_size(ctx, src0)) };
|
|
2632
|
+
uint32_t binding_num = 1;
|
|
2633
|
+
if (has_mask) {
|
|
2634
|
+
entries.push_back(ggml_webgpu_make_bind_group_entry(binding_num, ggml_webgpu_tensor_buf(src1),
|
|
2635
|
+
ggml_webgpu_tensor_align_offset(ctx, src1),
|
|
2636
|
+
ggml_webgpu_tensor_binding_size(ctx, src1)));
|
|
2637
|
+
binding_num++;
|
|
2638
|
+
}
|
|
2639
|
+
if (has_sink) {
|
|
2640
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_num, src2));
|
|
2641
|
+
binding_num++;
|
|
2642
|
+
}
|
|
2643
|
+
if (!inplace) {
|
|
2644
|
+
entries.push_back(ggml_webgpu_make_tensor_bind_group_entry(ctx, binding_num, dst));
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, ggml_nrows(dst));
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
static webgpu_encoded_op ggml_webgpu_argmax(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2651
|
+
std::vector<uint32_t> params = { (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2652
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2653
|
+
(uint32_t) src->ne[0] };
|
|
2654
|
+
|
|
2655
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2656
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst) };
|
|
2657
|
+
|
|
2658
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2659
|
+
shader_lib_ctx.src0 = src;
|
|
2660
|
+
shader_lib_ctx.dst = dst;
|
|
2661
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2662
|
+
|
|
2663
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_argmax_pipeline(shader_lib_ctx);
|
|
2664
|
+
uint32_t wg_x = ggml_nelements(dst);
|
|
2665
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
static webgpu_encoded_op ggml_webgpu_argsort(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2669
|
+
bool is_top_k = dst->op == GGML_OP_TOP_K;
|
|
2670
|
+
|
|
2671
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2672
|
+
shader_lib_ctx.src0 = src;
|
|
2673
|
+
shader_lib_ctx.src1 = nullptr;
|
|
2674
|
+
shader_lib_ctx.dst = dst;
|
|
2675
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2676
|
+
shader_lib_ctx.wg_mem_limit_bytes = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
2677
|
+
|
|
2678
|
+
webgpu_pipeline argsort_pipeline = ctx->shader_lib->get_argsort_pipeline(shader_lib_ctx);
|
|
2679
|
+
auto * argsort_decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(argsort_pipeline.context.get());
|
|
2680
|
+
|
|
2681
|
+
webgpu_pipeline argsort_merge_pipeline = ctx->shader_lib->get_argsort_merge_pipeline(shader_lib_ctx);
|
|
2682
|
+
|
|
2683
|
+
const uint32_t src_ne0 = (uint32_t) src->ne[0];
|
|
2684
|
+
const uint32_t nrows = (uint32_t) ggml_nrows(src);
|
|
2685
|
+
const uint32_t npr = CEIL_DIV(src_ne0, argsort_decisions->wg_size);
|
|
2686
|
+
const uint32_t block_size =
|
|
2687
|
+
is_top_k ? std::min(argsort_decisions->wg_size, (uint32_t) dst->ne[0]) : argsort_decisions->wg_size;
|
|
2688
|
+
uint32_t out_ne0 = src_ne0;
|
|
2689
|
+
if (is_top_k) {
|
|
2690
|
+
if (npr > 1) {
|
|
2691
|
+
const uint32_t last_tile = src_ne0 - (npr - 1) * argsort_decisions->wg_size;
|
|
2692
|
+
out_ne0 = (npr - 1) * block_size + std::min(last_tile, block_size);
|
|
2693
|
+
} else {
|
|
2694
|
+
out_ne0 = block_size;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
uint32_t merge_len = block_size;
|
|
2699
|
+
uint32_t merge_passes = 0;
|
|
2700
|
+
while (merge_len < out_ne0) {
|
|
2701
|
+
merge_len <<= 1;
|
|
2702
|
+
merge_passes++;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
const bool start_in_tmp = (merge_passes % 2) == 1;
|
|
2706
|
+
|
|
2707
|
+
const size_t dst_offset = ggml_webgpu_tensor_offset(dst);
|
|
2708
|
+
const size_t idx_nbytes = out_ne0 * ggml_nrows(dst) * sizeof(int32_t);
|
|
2709
|
+
const size_t tmp_offset =
|
|
2710
|
+
ROUNDUP_POW2(dst_offset + idx_nbytes, ctx->global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
2711
|
+
const size_t tmp_binding_size = ROUNDUP_POW2(idx_nbytes, WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
2712
|
+
const size_t dst_binding_size =
|
|
2713
|
+
ROUNDUP_POW2(idx_nbytes + ggml_webgpu_tensor_misalignment(ctx, dst), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
2714
|
+
|
|
2715
|
+
const uint32_t offset_src = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type));
|
|
2716
|
+
const uint32_t offset_dst = (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type));
|
|
2717
|
+
const uint32_t offset_tmp = 0;
|
|
2718
|
+
const uint32_t stride_src1 = (uint32_t) (src->nb[1] / ggml_type_size(src->type));
|
|
2719
|
+
const uint32_t stride_src2 = (uint32_t) (src->nb[2] / ggml_type_size(src->type));
|
|
2720
|
+
const uint32_t stride_src3 = (uint32_t) (src->nb[3] / ggml_type_size(src->type));
|
|
2721
|
+
const uint32_t stride_idx1 = out_ne0;
|
|
2722
|
+
const uint32_t stride_idx2 = out_ne0 * (uint32_t) dst->ne[1];
|
|
2723
|
+
const uint32_t stride_idx3 = stride_idx2 * (uint32_t) dst->ne[2];
|
|
2724
|
+
|
|
2725
|
+
std::vector<webgpu_dispatch_desc> dispatches;
|
|
2726
|
+
|
|
2727
|
+
const uint32_t init_offset = start_in_tmp ? offset_tmp : offset_dst;
|
|
2728
|
+
const size_t init_align_offset = start_in_tmp ? tmp_offset : ggml_webgpu_tensor_align_offset(ctx, dst);
|
|
2729
|
+
const size_t init_binding_size = start_in_tmp ? tmp_binding_size : dst_binding_size;
|
|
2730
|
+
|
|
2731
|
+
std::vector<uint32_t> init_params = {
|
|
2732
|
+
offset_src, init_offset, stride_src1, stride_src2, stride_src3, stride_idx1,
|
|
2733
|
+
stride_idx2, stride_idx3, src_ne0, (uint32_t) src->ne[1], (uint32_t) src->ne[2], out_ne0,
|
|
2734
|
+
block_size, npr, nrows
|
|
2735
|
+
};
|
|
2736
|
+
|
|
2737
|
+
const uint32_t total_wg_init = npr * nrows;
|
|
2738
|
+
const uint32_t max_wg = ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
2739
|
+
const uint32_t wg_x_init = std::min(total_wg_init, max_wg);
|
|
2740
|
+
const uint32_t wg_y_init = CEIL_DIV(total_wg_init, wg_x_init);
|
|
2741
|
+
std::vector<wgpu::BindGroupEntry> init_entries = {
|
|
2742
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2743
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(dst), init_align_offset, init_binding_size)
|
|
2744
|
+
};
|
|
2745
|
+
|
|
2746
|
+
dispatches.push_back({
|
|
2747
|
+
argsort_pipeline, std::move(init_params), std::move(init_entries), { wg_x_init, wg_y_init }
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
if (merge_passes == 0) {
|
|
2751
|
+
return ggml_backend_webgpu_build_multi(ctx, dispatches);
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
bool in_is_tmp = start_in_tmp;
|
|
2755
|
+
uint32_t len = block_size;
|
|
2756
|
+
while (len < out_ne0) {
|
|
2757
|
+
const uint32_t nm = CEIL_DIV(out_ne0, 2 * len);
|
|
2758
|
+
|
|
2759
|
+
const bool out_is_tmp = !in_is_tmp;
|
|
2760
|
+
const uint32_t offset_in = in_is_tmp ? offset_tmp : offset_dst;
|
|
2761
|
+
const uint32_t offset_out = out_is_tmp ? offset_tmp : offset_dst;
|
|
2762
|
+
const size_t align_in = in_is_tmp ? tmp_offset : ggml_webgpu_tensor_align_offset(ctx, dst);
|
|
2763
|
+
const size_t align_out = out_is_tmp ? tmp_offset : ggml_webgpu_tensor_align_offset(ctx, dst);
|
|
2764
|
+
const size_t size_in = in_is_tmp ? tmp_binding_size : dst_binding_size;
|
|
2765
|
+
const size_t size_out = out_is_tmp ? tmp_binding_size : dst_binding_size;
|
|
2766
|
+
const uint32_t top_k_out = (is_top_k && nm == 1) ? (uint32_t) dst->ne[0] : out_ne0;
|
|
2767
|
+
const uint32_t stride_out1 = top_k_out;
|
|
2768
|
+
const uint32_t stride_out2 = top_k_out * (uint32_t) dst->ne[1];
|
|
2769
|
+
const uint32_t stride_out3 = stride_out2 * (uint32_t) dst->ne[2];
|
|
2770
|
+
|
|
2771
|
+
std::vector<uint32_t> merge_params = { offset_src,
|
|
2772
|
+
offset_in,
|
|
2773
|
+
offset_out,
|
|
2774
|
+
stride_src1,
|
|
2775
|
+
stride_src2,
|
|
2776
|
+
stride_src3,
|
|
2777
|
+
stride_idx1,
|
|
2778
|
+
stride_idx2,
|
|
2779
|
+
stride_idx3,
|
|
2780
|
+
stride_out1,
|
|
2781
|
+
stride_out2,
|
|
2782
|
+
stride_out3,
|
|
2783
|
+
out_ne0,
|
|
2784
|
+
(uint32_t) src->ne[1],
|
|
2785
|
+
(uint32_t) src->ne[2],
|
|
2786
|
+
top_k_out,
|
|
2787
|
+
len,
|
|
2788
|
+
nm,
|
|
2789
|
+
nrows };
|
|
2790
|
+
|
|
2791
|
+
std::vector<wgpu::BindGroupEntry> merge_entries = {
|
|
2792
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2793
|
+
ggml_webgpu_make_bind_group_entry(1, ggml_webgpu_tensor_buf(dst), align_in, size_in),
|
|
2794
|
+
ggml_webgpu_make_bind_group_entry(2, ggml_webgpu_tensor_buf(dst), align_out, size_out)
|
|
2795
|
+
};
|
|
2796
|
+
|
|
2797
|
+
const uint32_t total_wg_merge = nm * nrows;
|
|
2798
|
+
const uint32_t wg_x_merge = std::min(total_wg_merge, max_wg);
|
|
2799
|
+
const uint32_t wg_y_merge = CEIL_DIV(total_wg_merge, wg_x_merge);
|
|
2800
|
+
dispatches.push_back({
|
|
2801
|
+
argsort_merge_pipeline, std::move(merge_params), std::move(merge_entries), { wg_x_merge, wg_y_merge }
|
|
2802
|
+
});
|
|
2803
|
+
|
|
2804
|
+
len <<= 1;
|
|
2805
|
+
in_is_tmp = !in_is_tmp;
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
return ggml_backend_webgpu_build_multi(ctx, dispatches);
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
static webgpu_encoded_op ggml_webgpu_cumsum(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2812
|
+
std::vector<uint32_t> params = { (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2813
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2814
|
+
(uint32_t) src->ne[0] };
|
|
2815
|
+
|
|
2816
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2817
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst) };
|
|
2818
|
+
|
|
2819
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2820
|
+
shader_lib_ctx.src0 = src;
|
|
2821
|
+
shader_lib_ctx.src1 = nullptr;
|
|
2822
|
+
shader_lib_ctx.dst = dst;
|
|
2823
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2824
|
+
|
|
2825
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_cumsum_pipeline(shader_lib_ctx);
|
|
2826
|
+
uint32_t wg_x = ggml_nrows(dst);
|
|
2827
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
static webgpu_encoded_op ggml_webgpu_sum_rows(webgpu_context & ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2831
|
+
bool total_sum = dst->op == GGML_OP_SUM;
|
|
2832
|
+
std::vector<uint32_t> params = { (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2833
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2834
|
+
total_sum ? 0 : (uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
2835
|
+
total_sum ? 0 : (uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
2836
|
+
total_sum ? 0 : (uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
2837
|
+
total_sum ? static_cast<uint32_t>(ggml_nelements(src)) : (uint32_t) src->ne[0],
|
|
2838
|
+
total_sum ? 1 : (uint32_t) src->ne[1],
|
|
2839
|
+
total_sum ? 1 : (uint32_t) src->ne[2] };
|
|
2840
|
+
|
|
2841
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2842
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst) };
|
|
2843
|
+
|
|
2844
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2845
|
+
shader_lib_ctx.src0 = src;
|
|
2846
|
+
shader_lib_ctx.dst = dst;
|
|
2847
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2848
|
+
|
|
2849
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_sum_rows_pipeline(shader_lib_ctx);
|
|
2850
|
+
|
|
2851
|
+
uint32_t wg_x = total_sum ? 1 : ggml_nrows(dst);
|
|
2852
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x);
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
static bool ggml_webgpu_can_fuse_rms_norm_mul(const struct ggml_cgraph * cgraph, int node_idx) {
|
|
2856
|
+
if (!ggml_can_fuse(cgraph, node_idx, { GGML_OP_RMS_NORM, GGML_OP_MUL })) {
|
|
2857
|
+
return false;
|
|
2858
|
+
}
|
|
2859
|
+
|
|
2860
|
+
// additional constraints specific to this fusion
|
|
2861
|
+
const ggml_tensor * rms_norm = cgraph->nodes[node_idx];
|
|
2862
|
+
const ggml_tensor * mul = cgraph->nodes[node_idx + 1];
|
|
2863
|
+
|
|
2864
|
+
GGML_ASSERT(rms_norm->src[0]->type == GGML_TYPE_F32);
|
|
2865
|
+
GGML_ASSERT(rms_norm->type == GGML_TYPE_F32);
|
|
2866
|
+
// rms_norm only supports f32
|
|
2867
|
+
if (mul->src[0]->type != GGML_TYPE_F32 || mul->src[1]->type != GGML_TYPE_F32 || mul->type != GGML_TYPE_F32) {
|
|
2868
|
+
return false;
|
|
2869
|
+
}
|
|
2870
|
+
// if rms_norm is the B operand, then we don't handle broadcast
|
|
2871
|
+
if (rms_norm == mul->src[1] && !ggml_are_same_shape(mul->src[0], rms_norm)) {
|
|
2872
|
+
return false;
|
|
2873
|
+
}
|
|
2874
|
+
// rms_norm shader assumes contiguous rows
|
|
2875
|
+
if (!ggml_is_contiguous_rows(mul->src[0]) || !ggml_is_contiguous_rows(mul->src[1])) {
|
|
2876
|
+
return false;
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
return true;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
static webgpu_encoded_op ggml_webgpu_upscale(webgpu_context ctx, ggml_tensor * src, ggml_tensor * dst) {
|
|
2883
|
+
const uint32_t mode_flags = (uint32_t) ggml_get_op_params_i32(dst, 0);
|
|
2884
|
+
std::vector<uint32_t> params = { (uint32_t) (ggml_webgpu_tensor_misalignment(ctx, src) / ggml_type_size(src->type)),
|
|
2885
|
+
(uint32_t) (ggml_webgpu_tensor_misalignment(ctx, dst) / ggml_type_size(dst->type)),
|
|
2886
|
+
|
|
2887
|
+
(uint32_t) (src->nb[0] / ggml_type_size(src->type)),
|
|
2888
|
+
(uint32_t) (src->nb[1] / ggml_type_size(src->type)),
|
|
2889
|
+
(uint32_t) (src->nb[2] / ggml_type_size(src->type)),
|
|
2890
|
+
(uint32_t) (src->nb[3] / ggml_type_size(src->type)),
|
|
2891
|
+
|
|
2892
|
+
(uint32_t) (dst->nb[0] / ggml_type_size(dst->type)),
|
|
2893
|
+
(uint32_t) (dst->nb[1] / ggml_type_size(dst->type)),
|
|
2894
|
+
(uint32_t) (dst->nb[2] / ggml_type_size(dst->type)),
|
|
2895
|
+
(uint32_t) (dst->nb[3] / ggml_type_size(dst->type)),
|
|
2896
|
+
|
|
2897
|
+
(uint32_t) src->ne[0],
|
|
2898
|
+
(uint32_t) src->ne[1],
|
|
2899
|
+
(uint32_t) src->ne[2],
|
|
2900
|
+
(uint32_t) src->ne[3],
|
|
2901
|
+
|
|
2902
|
+
(uint32_t) dst->ne[0],
|
|
2903
|
+
(uint32_t) dst->ne[1],
|
|
2904
|
+
(uint32_t) dst->ne[2],
|
|
2905
|
+
(uint32_t) dst->ne[3],
|
|
2906
|
+
|
|
2907
|
+
mode_flags };
|
|
2908
|
+
|
|
2909
|
+
std::vector<wgpu::BindGroupEntry> entries = { ggml_webgpu_make_tensor_bind_group_entry(ctx, 0, src),
|
|
2910
|
+
ggml_webgpu_make_tensor_bind_group_entry(ctx, 1, dst) };
|
|
2911
|
+
|
|
2912
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
2913
|
+
shader_lib_ctx.src0 = src;
|
|
2914
|
+
shader_lib_ctx.dst = dst;
|
|
2915
|
+
shader_lib_ctx.max_wg_size = ctx->global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
2916
|
+
|
|
2917
|
+
webgpu_pipeline pipeline = ctx->shader_lib->get_upscale_pipeline(shader_lib_ctx);
|
|
2918
|
+
auto * decisions = static_cast<ggml_webgpu_generic_shader_decisions *>(pipeline.context.get());
|
|
2919
|
+
uint32_t total_wg = CEIL_DIV((uint32_t) ggml_nelements(dst), decisions->wg_size);
|
|
2920
|
+
uint32_t wg_x = std::min(ctx->global_ctx->capabilities.limits.maxComputeWorkgroupsPerDimension, total_wg);
|
|
2921
|
+
uint32_t wg_y = CEIL_DIV(total_wg, wg_x);
|
|
2922
|
+
return ggml_backend_webgpu_build(ctx, pipeline, params, entries, wg_x, wg_y);
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
// Returns the encoded command, or std::nullopt if the operation is a no-op
|
|
2926
|
+
static std::optional<webgpu_encoded_op> ggml_webgpu_encode(webgpu_context ctx,
|
|
2927
|
+
ggml_cgraph * cgraph,
|
|
2928
|
+
int node_idx,
|
|
2929
|
+
int & num_encoded_ops) {
|
|
2930
|
+
ggml_tensor ** nodes = cgraph->nodes;
|
|
2931
|
+
ggml_tensor * node = nodes[node_idx];
|
|
2932
|
+
|
|
2933
|
+
if (ggml_is_empty(node)) {
|
|
2934
|
+
return std::nullopt;
|
|
2935
|
+
}
|
|
2936
|
+
if ((node->flags & GGML_TENSOR_FLAG_COMPUTE) == 0) {
|
|
2937
|
+
return std::nullopt;
|
|
2938
|
+
}
|
|
2939
|
+
WEBGPU_LOG_DEBUG("ggml_webgpu_encode(" << node << ", " << ggml_op_name(node->op) << ")");
|
|
2940
|
+
|
|
2941
|
+
ggml_tensor * src0 = node->src[0];
|
|
2942
|
+
ggml_tensor * src1 = node->src[1];
|
|
2943
|
+
ggml_tensor * src2 = node->src[2];
|
|
2944
|
+
|
|
2945
|
+
switch (node->op) {
|
|
2946
|
+
// no-ops
|
|
2947
|
+
case GGML_OP_NONE:
|
|
2948
|
+
case GGML_OP_VIEW:
|
|
2949
|
+
case GGML_OP_PERMUTE:
|
|
2950
|
+
case GGML_OP_TRANSPOSE:
|
|
2951
|
+
case GGML_OP_RESHAPE:
|
|
2952
|
+
return std::nullopt;
|
|
2953
|
+
case GGML_OP_CPY:
|
|
2954
|
+
case GGML_OP_CONT:
|
|
2955
|
+
return ggml_webgpu_cpy(ctx, src0, node);
|
|
2956
|
+
case GGML_OP_SET:
|
|
2957
|
+
return ggml_webgpu_set(ctx, src0, src1, node);
|
|
2958
|
+
case GGML_OP_SET_ROWS:
|
|
2959
|
+
return ggml_webgpu_set_rows(ctx, src0, src1, node);
|
|
2960
|
+
case GGML_OP_GET_ROWS:
|
|
2961
|
+
return ggml_webgpu_get_rows(ctx, src0, src1, node);
|
|
2962
|
+
case GGML_OP_MUL_MAT:
|
|
2963
|
+
return ggml_webgpu_mul_mat(ctx, src0, src1, node);
|
|
2964
|
+
case GGML_OP_MUL_MAT_ID:
|
|
2965
|
+
return ggml_webgpu_mul_mat_id(ctx, src0, src1, src2, node);
|
|
2966
|
+
case GGML_OP_FLASH_ATTN_EXT:
|
|
2967
|
+
return ggml_webgpu_flash_attn(ctx, src0, src1, src2, node->src[3], node->src[4], node);
|
|
2968
|
+
case GGML_OP_ADD:
|
|
2969
|
+
case GGML_OP_SUB:
|
|
2970
|
+
case GGML_OP_MUL:
|
|
2971
|
+
case GGML_OP_DIV:
|
|
2972
|
+
return ggml_webgpu_binary_op(ctx, src0, src1, node);
|
|
2973
|
+
case GGML_OP_ADD_ID:
|
|
2974
|
+
return ggml_webgpu_add_id(ctx, src0, src1, src2, node);
|
|
2975
|
+
case GGML_OP_CONCAT:
|
|
2976
|
+
return ggml_webgpu_concat(ctx, src0, src1, node);
|
|
2977
|
+
case GGML_OP_REPEAT:
|
|
2978
|
+
return ggml_webgpu_repeat(ctx, src0, node);
|
|
2979
|
+
case GGML_OP_RMS_NORM:
|
|
2980
|
+
if (ggml_webgpu_can_fuse_rms_norm_mul(cgraph, node_idx)) {
|
|
2981
|
+
num_encoded_ops = 2;
|
|
2982
|
+
ggml_tensor * mul_node = nodes[node_idx + 1];
|
|
2983
|
+
return ggml_webgpu_rms_norm_mul(ctx, src0, node, mul_node->src[0], mul_node->src[1], mul_node);
|
|
2984
|
+
} else {
|
|
2985
|
+
return ggml_webgpu_row_norm(ctx, src0, node);
|
|
2986
|
+
}
|
|
2987
|
+
case GGML_OP_NORM:
|
|
2988
|
+
case GGML_OP_L2_NORM:
|
|
2989
|
+
return ggml_webgpu_row_norm(ctx, src0, node);
|
|
2990
|
+
case GGML_OP_ROPE:
|
|
2991
|
+
return ggml_webgpu_rope(ctx, src0, src1, src2, node);
|
|
2992
|
+
case GGML_OP_GLU:
|
|
2993
|
+
return ggml_webgpu_glu(ctx, src0, src1, node);
|
|
2994
|
+
case GGML_OP_SCALE:
|
|
2995
|
+
return ggml_webgpu_scale(ctx, src0, node);
|
|
2996
|
+
case GGML_OP_SOFT_MAX:
|
|
2997
|
+
return ggml_webgpu_soft_max(ctx, src0, src1, src2, node);
|
|
2998
|
+
case GGML_OP_UNARY:
|
|
2999
|
+
case GGML_OP_CLAMP:
|
|
3000
|
+
case GGML_OP_FILL:
|
|
3001
|
+
case GGML_OP_LOG:
|
|
3002
|
+
case GGML_OP_SQR:
|
|
3003
|
+
case GGML_OP_SQRT:
|
|
3004
|
+
case GGML_OP_SIN:
|
|
3005
|
+
case GGML_OP_COS:
|
|
3006
|
+
case GGML_OP_DIAG:
|
|
3007
|
+
case GGML_OP_TRI:
|
|
3008
|
+
return ggml_webgpu_unary_op(ctx, src0, node);
|
|
3009
|
+
case GGML_OP_SOLVE_TRI:
|
|
3010
|
+
return ggml_webgpu_solve_tri(ctx, src0, src1, node);
|
|
3011
|
+
case GGML_OP_SSM_CONV:
|
|
3012
|
+
return ggml_webgpu_ssm_conv(ctx, src0, src1, node);
|
|
3013
|
+
case GGML_OP_SSM_SCAN:
|
|
3014
|
+
return ggml_webgpu_ssm_scan(ctx, src0, src1, src2, node->src[3], node->src[4], node->src[5], node->src[6],
|
|
3015
|
+
node);
|
|
3016
|
+
case GGML_OP_GATED_DELTA_NET:
|
|
3017
|
+
return ggml_webgpu_gated_delta_net(ctx, src0, src1, src2, node->src[3], node->src[4], node->src[5], node);
|
|
3018
|
+
case GGML_OP_PAD:
|
|
3019
|
+
return ggml_webgpu_pad(ctx, src0, node);
|
|
3020
|
+
case GGML_OP_ARGMAX:
|
|
3021
|
+
return ggml_webgpu_argmax(ctx, src0, node);
|
|
3022
|
+
case GGML_OP_ARGSORT:
|
|
3023
|
+
case GGML_OP_TOP_K:
|
|
3024
|
+
// we reuse the same argsort implementation for top_k
|
|
3025
|
+
return ggml_webgpu_argsort(ctx, src0, node);
|
|
3026
|
+
case GGML_OP_CUMSUM:
|
|
3027
|
+
return ggml_webgpu_cumsum(ctx, src0, node);
|
|
3028
|
+
case GGML_OP_SUM:
|
|
3029
|
+
case GGML_OP_SUM_ROWS:
|
|
3030
|
+
return ggml_webgpu_sum_rows(ctx, src0, node);
|
|
3031
|
+
case GGML_OP_CONV_2D:
|
|
3032
|
+
return ggml_webgpu_conv_2d(ctx, src0, src1, node);
|
|
3033
|
+
case GGML_OP_IM2COL:
|
|
3034
|
+
return ggml_webgpu_im2col(ctx, src0, src1, node);
|
|
3035
|
+
case GGML_OP_UPSCALE:
|
|
3036
|
+
return ggml_webgpu_upscale(ctx, src0, node);
|
|
3037
|
+
default:
|
|
3038
|
+
return std::nullopt;
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
|
|
3042
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3043
|
+
static void ggml_backend_webgpu_collect_profile_results(webgpu_context & ctx,
|
|
3044
|
+
const std::vector<std::string> & pipeline_names,
|
|
3045
|
+
uint32_t & num_inflight_batches) {
|
|
3046
|
+
if (pipeline_names.empty()) {
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
wgpu::CommandEncoder encoder = ctx->global_ctx->device.CreateCommandEncoder();
|
|
3051
|
+
encoder.ResolveQuerySet(ctx->profile_timestamp_query_set, 0, ctx->profile_timestamp_query_count,
|
|
3052
|
+
ctx->profile_timestamp_dev_buf, 0);
|
|
3053
|
+
encoder.CopyBufferToBuffer(ctx->profile_timestamp_dev_buf, 0, ctx->profile_timestamp_host_buf, 0,
|
|
3054
|
+
ctx->profile_timestamp_query_count * sizeof(uint64_t));
|
|
3055
|
+
|
|
3056
|
+
wgpu::CommandBuffer profile_commands = encoder.Finish();
|
|
3057
|
+
ggml_backend_webgpu_submit_commands(ctx, profile_commands, num_inflight_batches);
|
|
3058
|
+
|
|
3059
|
+
const size_t mapped_size = ctx->profile_timestamp_query_count * sizeof(uint64_t);
|
|
3060
|
+
GGML_ASSERT(ctx->profile_timestamp_query_count == 2 * pipeline_names.size());
|
|
3061
|
+
|
|
3062
|
+
ggml_backend_webgpu_map_buffer(ctx->global_ctx, ctx->profile_timestamp_host_buf, wgpu::MapMode::Read, 0,
|
|
3063
|
+
mapped_size);
|
|
3064
|
+
const uint64_t * ts_data = (const uint64_t *) ctx->profile_timestamp_host_buf.GetConstMappedRange(0, mapped_size);
|
|
3065
|
+
|
|
3066
|
+
for (size_t i = 0; i < pipeline_names.size(); ++i) {
|
|
3067
|
+
// WebGPU timestamps are in ns; convert to ms.
|
|
3068
|
+
const double elapsed_ms = double(ts_data[2 * i + 1] - ts_data[2 * i]) * 1e-6;
|
|
3069
|
+
ctx->shader_gpu_time_ms[pipeline_names[i]] += elapsed_ms;
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
ctx->profile_timestamp_host_buf.Unmap();
|
|
3073
|
+
}
|
|
3074
|
+
#endif
|
|
3075
|
+
|
|
3076
|
+
// Don't bother checking set_rows index overflow for now, since practically the WebGPU doesn't need to support
|
|
3077
|
+
// models that would require it right now.
|
|
3078
|
+
static void ggml_backend_webgpu_check_set_rows(webgpu_context & ctx, uint32_t & num_inflight_batches) {
|
|
3079
|
+
#ifdef GGML_WEBGPU_CHECK_SET_ROWS
|
|
3080
|
+
wgpu::CommandEncoder encoder = ctx->global_ctx->device.CreateCommandEncoder();
|
|
3081
|
+
encoder.CopyBufferToBuffer(ctx->set_rows_dev_error_buf, 0, ctx->set_rows_host_error_buf, 0,
|
|
3082
|
+
ctx->set_rows_host_error_buf.GetSize());
|
|
3083
|
+
wgpu::CommandBuffer commands = encoder.Finish();
|
|
3084
|
+
ggml_backend_webgpu_submit_commands(ctx, commands, num_inflight_batches);
|
|
3085
|
+
ggml_backend_webgpu_map_buffer(ctx->global_ctx, ctx->set_rows_host_error_buf, wgpu::MapMode::Read, 0,
|
|
3086
|
+
ctx->set_rows_host_error_buf.GetSize());
|
|
3087
|
+
const uint32_t * error_data = (const uint32_t *) ctx->set_rows_host_error_buf.GetConstMappedRange();
|
|
3088
|
+
if (*error_data) {
|
|
3089
|
+
GGML_ABORT("ggml_webgpu: SET_ROWS index > 2^32, unsupported.");
|
|
3090
|
+
}
|
|
3091
|
+
ctx->set_rows_host_error_buf.Unmap();
|
|
3092
|
+
#else
|
|
3093
|
+
GGML_UNUSED(ctx);
|
|
3094
|
+
GGML_UNUSED(num_inflight_batches);
|
|
3095
|
+
#endif
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
static ggml_status ggml_backend_webgpu_graph_compute(ggml_backend_t backend, struct ggml_cgraph * cgraph) {
|
|
3099
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_graph_compute(" << cgraph->n_nodes << " nodes)");
|
|
3100
|
+
|
|
3101
|
+
ggml_backend_webgpu_context * backend_ctx = (ggml_backend_webgpu_context *) backend->context;
|
|
3102
|
+
webgpu_context ctx = backend_ctx->webgpu_ctx;
|
|
3103
|
+
|
|
3104
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(graph_compute);
|
|
3105
|
+
|
|
3106
|
+
std::vector<webgpu_encoded_op> commands;
|
|
3107
|
+
|
|
3108
|
+
uint32_t num_batched_kernels = 0;
|
|
3109
|
+
uint32_t num_inflight_batches = 0;
|
|
3110
|
+
bool contains_set_rows = false;
|
|
3111
|
+
bool batch_compute_passes = true;
|
|
3112
|
+
int num_encoded_ops = 1;
|
|
3113
|
+
int node_idx = 0;
|
|
3114
|
+
|
|
3115
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3116
|
+
ctx->profile_timestamp_query_count = 0;
|
|
3117
|
+
batch_compute_passes = false;
|
|
3118
|
+
std::vector<std::string> profile_pipeline_names;
|
|
3119
|
+
#endif
|
|
3120
|
+
|
|
3121
|
+
ctx->active_command_encoder = ctx->global_ctx->device.CreateCommandEncoder();
|
|
3122
|
+
if (batch_compute_passes) {
|
|
3123
|
+
ctx->active_compute_pass = ctx->active_command_encoder.BeginComputePass();
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
while (node_idx < cgraph->n_nodes) {
|
|
3127
|
+
if (cgraph->nodes[node_idx]->op == GGML_OP_SET_ROWS) {
|
|
3128
|
+
contains_set_rows = true;
|
|
3129
|
+
}
|
|
3130
|
+
if (auto cmd = ggml_webgpu_encode(ctx, cgraph, node_idx, num_encoded_ops)) {
|
|
3131
|
+
commands.push_back(*cmd);
|
|
3132
|
+
num_batched_kernels += cmd.value().num_kernels;
|
|
3133
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3134
|
+
profile_pipeline_names.insert(profile_pipeline_names.end(), cmd->pipeline_names.begin(),
|
|
3135
|
+
cmd->pipeline_names.end());
|
|
3136
|
+
#endif
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
if (num_batched_kernels >= ctx->global_ctx->command_submit_batch_size) {
|
|
3140
|
+
if (ctx->active_compute_pass) {
|
|
3141
|
+
ctx->active_compute_pass.End();
|
|
3142
|
+
}
|
|
3143
|
+
num_batched_kernels = 0;
|
|
3144
|
+
wgpu::CommandBuffer batch_commands = ctx->active_command_encoder.Finish();
|
|
3145
|
+
ggml_backend_webgpu_submit_commands(ctx, batch_commands, num_inflight_batches);
|
|
3146
|
+
|
|
3147
|
+
// reset state for next batch
|
|
3148
|
+
ctx->active_command_encoder = ctx->global_ctx->device.CreateCommandEncoder();
|
|
3149
|
+
if (batch_compute_passes) {
|
|
3150
|
+
ctx->active_compute_pass = ctx->active_command_encoder.BeginComputePass();
|
|
3151
|
+
}
|
|
3152
|
+
ctx->param_arena.reset();
|
|
3153
|
+
commands.clear();
|
|
3154
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3155
|
+
// flush before the next batch can overflow the QuerySet
|
|
3156
|
+
if (ctx->profile_timestamp_query_count + 2 * ctx->global_ctx->command_submit_batch_size >=
|
|
3157
|
+
WEBGPU_MAX_PROFILE_QUERY_COUNT) {
|
|
3158
|
+
ggml_backend_webgpu_collect_profile_results(ctx, profile_pipeline_names, num_inflight_batches);
|
|
3159
|
+
// reset profile timestamp state
|
|
3160
|
+
ctx->profile_timestamp_query_count = 0;
|
|
3161
|
+
profile_pipeline_names.clear();
|
|
3162
|
+
}
|
|
3163
|
+
#endif
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3166
|
+
node_idx += num_encoded_ops;
|
|
3167
|
+
num_encoded_ops = 1;
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
if (ctx->active_compute_pass) {
|
|
3171
|
+
ctx->active_compute_pass.End();
|
|
3172
|
+
ctx->active_compute_pass = nullptr;
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
if (num_batched_kernels > 0) {
|
|
3176
|
+
wgpu::CommandBuffer batch_commands = ctx->active_command_encoder.Finish();
|
|
3177
|
+
ggml_backend_webgpu_submit_commands(ctx, batch_commands, num_inflight_batches);
|
|
3178
|
+
ctx->param_arena.reset();
|
|
3179
|
+
commands.clear();
|
|
3180
|
+
}
|
|
3181
|
+
ctx->active_command_encoder = nullptr;
|
|
3182
|
+
|
|
3183
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3184
|
+
ggml_backend_webgpu_collect_profile_results(ctx, profile_pipeline_names, num_inflight_batches);
|
|
3185
|
+
#endif
|
|
3186
|
+
|
|
3187
|
+
if (contains_set_rows) {
|
|
3188
|
+
ggml_backend_webgpu_check_set_rows(ctx, num_inflight_batches);
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(graph_compute, ctx->global_ctx);
|
|
3192
|
+
return GGML_STATUS_SUCCESS;
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
struct ggml_backend_webgpu_event_context {
|
|
3196
|
+
webgpu_global_context global_ctx;
|
|
3197
|
+
wgpu::Future future;
|
|
3198
|
+
bool recorded = false;
|
|
3199
|
+
};
|
|
3200
|
+
|
|
3201
|
+
static ggml_backend_event_t ggml_backend_webgpu_device_event_new(ggml_backend_dev_t device) {
|
|
3202
|
+
ggml_backend_webgpu_device_context * dev_ctx = (ggml_backend_webgpu_device_context *) device->context;
|
|
3203
|
+
|
|
3204
|
+
auto * event_ctx = new ggml_backend_webgpu_event_context();
|
|
3205
|
+
event_ctx->global_ctx = dev_ctx->webgpu_global_ctx;
|
|
3206
|
+
|
|
3207
|
+
auto * event = new ggml_backend_event;
|
|
3208
|
+
event->device = device;
|
|
3209
|
+
event->context = event_ctx;
|
|
3210
|
+
return event;
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
static void ggml_backend_webgpu_device_event_free(ggml_backend_dev_t dev, ggml_backend_event_t event) {
|
|
3214
|
+
GGML_UNUSED(dev);
|
|
3215
|
+
delete static_cast<ggml_backend_webgpu_event_context *>(event->context);
|
|
3216
|
+
delete event;
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3219
|
+
static void ggml_backend_webgpu_device_event_synchronize(ggml_backend_dev_t dev, ggml_backend_event_t event) {
|
|
3220
|
+
GGML_UNUSED(dev);
|
|
3221
|
+
ggml_backend_webgpu_event_context * event_ctx = (ggml_backend_webgpu_event_context *) event->context;
|
|
3222
|
+
if (!event_ctx->recorded) {
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
wgpu::WaitStatus status =
|
|
3226
|
+
event_ctx->global_ctx->instance.WaitAny(event_ctx->future, WEBGPU_RUNTIME_WAIT_TIMEOUT_NS);
|
|
3227
|
+
if (status == wgpu::WaitStatus::TimedOut) {
|
|
3228
|
+
GGML_ABORT("ggml_webgpu: event_synchronize timed out after %u ms\n", WEBGPU_RUNTIME_WAIT_TIMEOUT_MS);
|
|
3229
|
+
}
|
|
3230
|
+
event_ctx->recorded = false;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
static void ggml_backend_webgpu_event_record(ggml_backend_t backend, ggml_backend_event_t event) {
|
|
3234
|
+
ggml_backend_webgpu_context * backend_ctx = (ggml_backend_webgpu_context *) backend->context;
|
|
3235
|
+
ggml_backend_webgpu_event_context * event_ctx = (ggml_backend_webgpu_event_context *) event->context;
|
|
3236
|
+
|
|
3237
|
+
event_ctx->future = backend_ctx->webgpu_ctx->global_ctx->queue.OnSubmittedWorkDone(
|
|
3238
|
+
wgpu::CallbackMode::AllowSpontaneous, [](wgpu::QueueWorkDoneStatus, wgpu::StringView) {});
|
|
3239
|
+
event_ctx->recorded = true;
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
static void ggml_backend_webgpu_event_wait(ggml_backend_t backend, ggml_backend_event_t event) {
|
|
3243
|
+
GGML_UNUSED(backend);
|
|
3244
|
+
ggml_backend_webgpu_device_event_synchronize(nullptr, event);
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3247
|
+
static void ggml_backend_webgpu_set_tensor_async(ggml_backend_t backend,
|
|
3248
|
+
ggml_tensor * tensor,
|
|
3249
|
+
const void * data,
|
|
3250
|
+
size_t offset,
|
|
3251
|
+
size_t size) {
|
|
3252
|
+
GGML_UNUSED(backend);
|
|
3253
|
+
auto * buf_ctx = (ggml_backend_webgpu_buffer_context *) tensor->buffer->context;
|
|
3254
|
+
size_t total_offset = ggml_webgpu_tensor_offset(tensor) + offset;
|
|
3255
|
+
|
|
3256
|
+
// Write aligned portion
|
|
3257
|
+
buf_ctx->global_ctx->queue.WriteBuffer(buf_ctx->buffer, total_offset, data, (size / 4) * 4);
|
|
3258
|
+
|
|
3259
|
+
if (size % 4 != 0) {
|
|
3260
|
+
// If size is not a multiple of 4, we need to memset the remaining bytes
|
|
3261
|
+
size_t remaining_size = size % 4;
|
|
3262
|
+
|
|
3263
|
+
// pack the remaining bytes into a uint32_t
|
|
3264
|
+
uint32_t val32 = 0;
|
|
3265
|
+
|
|
3266
|
+
for (size_t i = 0; i < remaining_size; i++) {
|
|
3267
|
+
((uint8_t *) &val32)[i] = ((const uint8_t *) data)[size - remaining_size + i];
|
|
3268
|
+
}
|
|
3269
|
+
// memset the remaining bytes
|
|
3270
|
+
ggml_backend_webgpu_buffer_memset(buf_ctx->global_ctx, buf_ctx->buffer, val32,
|
|
3271
|
+
total_offset + (size - remaining_size), remaining_size);
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
static void ggml_backend_webgpu_synchronize(ggml_backend_t backend) {
|
|
3276
|
+
ggml_backend_webgpu_context * backend_ctx = (ggml_backend_webgpu_context *) backend->context;
|
|
3277
|
+
ggml_backend_webgpu_wait_queue(backend_ctx->webgpu_ctx->global_ctx);
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
static ggml_backend_i ggml_backend_webgpu_i = {
|
|
3281
|
+
/* .get_name = */ ggml_backend_webgpu_name,
|
|
3282
|
+
/* .free = */ ggml_backend_webgpu_free,
|
|
3283
|
+
/* .set_tensor_async = */ ggml_backend_webgpu_set_tensor_async,
|
|
3284
|
+
/* .get_tensor_async = */ NULL,
|
|
3285
|
+
/* .set_tensor_2d_async = */ NULL,
|
|
3286
|
+
/* .get_tensor_2d_async = */ NULL,
|
|
3287
|
+
/* .cpy_tensor_async = */ NULL,
|
|
3288
|
+
/* .synchronize = */ ggml_backend_webgpu_synchronize,
|
|
3289
|
+
/* .graph_plan_create = */ NULL,
|
|
3290
|
+
/* .graph_plan_free = */ NULL,
|
|
3291
|
+
/* .graph_plan_update = */ NULL,
|
|
3292
|
+
/* .graph_plan_compute = */ NULL,
|
|
3293
|
+
/* .graph_compute = */ ggml_backend_webgpu_graph_compute,
|
|
3294
|
+
/* .event_record = */ ggml_backend_webgpu_event_record,
|
|
3295
|
+
/* .event_wait = */ ggml_backend_webgpu_event_wait,
|
|
3296
|
+
/* .graph_optimize = */ NULL,
|
|
3297
|
+
};
|
|
3298
|
+
|
|
3299
|
+
/* End GGML Backend Interface */
|
|
3300
|
+
|
|
3301
|
+
/* GGML Backend Buffer Interface */
|
|
3302
|
+
|
|
3303
|
+
static void ggml_backend_webgpu_buffer_free_buffer(ggml_backend_buffer_t buffer) {
|
|
3304
|
+
ggml_backend_webgpu_buffer_context * ctx = static_cast<ggml_backend_webgpu_buffer_context *>(buffer->context);
|
|
3305
|
+
if (ctx != nullptr && ctx->buffer != nullptr) {
|
|
3306
|
+
ctx->buffer.Destroy();
|
|
3307
|
+
delete ctx;
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
|
|
3311
|
+
// Returns the "fake" base pointer.
|
|
3312
|
+
static void * ggml_backend_webgpu_buffer_get_base(ggml_backend_buffer_t buffer) {
|
|
3313
|
+
GGML_UNUSED(buffer);
|
|
3314
|
+
return webgpu_ptr_base;
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3317
|
+
static void ggml_backend_webgpu_buffer_memset_tensor(ggml_backend_buffer_t buffer,
|
|
3318
|
+
ggml_tensor * tensor,
|
|
3319
|
+
uint8_t value,
|
|
3320
|
+
size_t offset,
|
|
3321
|
+
size_t size) {
|
|
3322
|
+
if (size == 0) {
|
|
3323
|
+
WEBGPU_LOG_DEBUG(
|
|
3324
|
+
"ggml_backend_webgpu_buffer_memset_tensor: size is zero, "
|
|
3325
|
+
"nothing to do.");
|
|
3326
|
+
return;
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(memset_tensor);
|
|
3330
|
+
|
|
3331
|
+
ggml_backend_webgpu_buffer_context * buf_ctx = (ggml_backend_webgpu_buffer_context *) buffer->context;
|
|
3332
|
+
|
|
3333
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_buffer_memset_tensor(" << buf_ctx->label << ", " << tensor << ", " << value
|
|
3334
|
+
<< ", " << offset << ", " << size << ")");
|
|
3335
|
+
|
|
3336
|
+
size_t total_offset = ggml_webgpu_tensor_offset(tensor) + offset;
|
|
3337
|
+
|
|
3338
|
+
// This is a trick to set all bytes of a u32 to the same 1 byte value.
|
|
3339
|
+
uint32_t val32 = (uint32_t) value * 0x01010101;
|
|
3340
|
+
ggml_backend_webgpu_buffer_memset(buf_ctx->global_ctx, buf_ctx->buffer, val32, total_offset, size);
|
|
3341
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(memset_tensor, buf_ctx->global_ctx);
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
static void ggml_backend_webgpu_buffer_set_tensor(ggml_backend_buffer_t buffer,
|
|
3345
|
+
ggml_tensor * tensor,
|
|
3346
|
+
const void * data,
|
|
3347
|
+
size_t offset,
|
|
3348
|
+
size_t size) {
|
|
3349
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(set_tensor);
|
|
3350
|
+
ggml_backend_webgpu_buffer_context * buf_ctx = (ggml_backend_webgpu_buffer_context *) buffer->context;
|
|
3351
|
+
|
|
3352
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_buffer_set_tensor(" << buf_ctx->label << ", " << tensor << ", " << data
|
|
3353
|
+
<< ", " << offset << ", " << size << ")");
|
|
3354
|
+
|
|
3355
|
+
size_t total_offset = ggml_webgpu_tensor_offset(tensor) + offset;
|
|
3356
|
+
|
|
3357
|
+
buf_ctx->global_ctx->queue.WriteBuffer(buf_ctx->buffer, total_offset, data, (size / 4) * 4);
|
|
3358
|
+
|
|
3359
|
+
if (size % 4 != 0) {
|
|
3360
|
+
// If size is not a multiple of 4, we need to memset the remaining bytes
|
|
3361
|
+
size_t remaining_size = size % 4;
|
|
3362
|
+
|
|
3363
|
+
// pack the remaining bytes into a uint32_t
|
|
3364
|
+
uint32_t val32 = 0;
|
|
3365
|
+
|
|
3366
|
+
for (size_t i = 0; i < remaining_size; i++) {
|
|
3367
|
+
((uint8_t *) &val32)[i] = ((const uint8_t *) data)[size - remaining_size + i];
|
|
3368
|
+
}
|
|
3369
|
+
// memset the remaining bytes
|
|
3370
|
+
ggml_backend_webgpu_buffer_memset(buf_ctx->global_ctx, buf_ctx->buffer, val32,
|
|
3371
|
+
total_offset + (size - remaining_size), remaining_size);
|
|
3372
|
+
}
|
|
3373
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(set_tensor, buf_ctx->global_ctx);
|
|
3374
|
+
}
|
|
3375
|
+
|
|
3376
|
+
static void ggml_backend_webgpu_buffer_get_tensor(ggml_backend_buffer_t buffer,
|
|
3377
|
+
const ggml_tensor * tensor,
|
|
3378
|
+
void * data,
|
|
3379
|
+
size_t offset,
|
|
3380
|
+
size_t size) {
|
|
3381
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(get_tensor);
|
|
3382
|
+
ggml_backend_webgpu_buffer_context * buf_ctx = (ggml_backend_webgpu_buffer_context *) buffer->context;
|
|
3383
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_buffer_get_tensor(" << buf_ctx->label << ", " << tensor << ", " << data
|
|
3384
|
+
<< ", " << offset << ", " << size << ")");
|
|
3385
|
+
wgpu::Device device = buf_ctx->global_ctx->device;
|
|
3386
|
+
|
|
3387
|
+
size_t total_offset = ggml_webgpu_tensor_offset(tensor) + offset;
|
|
3388
|
+
|
|
3389
|
+
size_t final_size = size;
|
|
3390
|
+
if (size % 4 != 0) {
|
|
3391
|
+
// If size is not a multiple of 4, we need to round it up to the next
|
|
3392
|
+
// multiple of 4
|
|
3393
|
+
final_size = size + (4 - (size % 4));
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
std::lock_guard<std::recursive_mutex> lock(buf_ctx->global_ctx->mutex);
|
|
3397
|
+
|
|
3398
|
+
if (buf_ctx->global_ctx->get_tensor_staging_buf == nullptr ||
|
|
3399
|
+
buf_ctx->global_ctx->get_tensor_staging_buf.GetSize() < final_size) {
|
|
3400
|
+
// Create a new staging buffer if it doesn't exist or is too small
|
|
3401
|
+
if (buf_ctx->global_ctx->get_tensor_staging_buf) {
|
|
3402
|
+
buf_ctx->global_ctx->get_tensor_staging_buf.Destroy();
|
|
3403
|
+
}
|
|
3404
|
+
ggml_webgpu_create_buffer(device, buf_ctx->global_ctx->get_tensor_staging_buf, final_size,
|
|
3405
|
+
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead, "get_tensor_staging_buf");
|
|
3406
|
+
}
|
|
3407
|
+
|
|
3408
|
+
// Copy the data from the buffer to the staging buffer
|
|
3409
|
+
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
3410
|
+
encoder.CopyBufferToBuffer(buf_ctx->buffer, total_offset, buf_ctx->global_ctx->get_tensor_staging_buf, 0,
|
|
3411
|
+
final_size);
|
|
3412
|
+
wgpu::CommandBuffer commands = encoder.Finish();
|
|
3413
|
+
|
|
3414
|
+
// Submit the command buffer to the queue
|
|
3415
|
+
buf_ctx->global_ctx->queue.Submit(1, &commands);
|
|
3416
|
+
|
|
3417
|
+
// Map the staging buffer to read the data
|
|
3418
|
+
ggml_backend_webgpu_map_buffer(buf_ctx->global_ctx, buf_ctx->global_ctx->get_tensor_staging_buf,
|
|
3419
|
+
wgpu::MapMode::Read, 0, final_size);
|
|
3420
|
+
// Must specify size here since the staging buffer might be larger than the tensor size
|
|
3421
|
+
const void * mapped_range = buf_ctx->global_ctx->get_tensor_staging_buf.GetConstMappedRange(0, final_size);
|
|
3422
|
+
|
|
3423
|
+
// Copy the data from the mapped range to the output buffer
|
|
3424
|
+
std::memcpy(data, mapped_range, size);
|
|
3425
|
+
buf_ctx->global_ctx->get_tensor_staging_buf.Unmap();
|
|
3426
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(get_tensor, buf_ctx->global_ctx);
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
static void ggml_backend_webgpu_buffer_clear(ggml_backend_buffer_t buffer, uint8_t value) {
|
|
3430
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_buffer_clear(" << buffer << ", " << (uint32_t) value << ")");
|
|
3431
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(clear);
|
|
3432
|
+
ggml_backend_webgpu_buffer_context * buf_ctx = (ggml_backend_webgpu_buffer_context *) buffer->context;
|
|
3433
|
+
ggml_backend_webgpu_buffer_memset(buf_ctx->global_ctx, buf_ctx->buffer, value, 0, buffer->size);
|
|
3434
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(clear, buf_ctx->global_ctx);
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3437
|
+
static ggml_backend_buffer_i ggml_backend_webgpu_buffer_interface = {
|
|
3438
|
+
/* .free_buffer = */ ggml_backend_webgpu_buffer_free_buffer,
|
|
3439
|
+
/* .get_base = */ ggml_backend_webgpu_buffer_get_base,
|
|
3440
|
+
/* .init_tensor = */ NULL, // TODO: optional, needed?
|
|
3441
|
+
/* .memset_tensor = */ ggml_backend_webgpu_buffer_memset_tensor,
|
|
3442
|
+
/* .set_tensor = */ ggml_backend_webgpu_buffer_set_tensor,
|
|
3443
|
+
/* .get_tensor = */ ggml_backend_webgpu_buffer_get_tensor,
|
|
3444
|
+
/* .set_tensor_2d = */ NULL,
|
|
3445
|
+
/* .get_tensor_2d = */ NULL,
|
|
3446
|
+
/* .cpy_tensor = */ NULL, // TODO: optional, implement this
|
|
3447
|
+
/* .clear = */ ggml_backend_webgpu_buffer_clear,
|
|
3448
|
+
/* .reset = */ NULL, // TODO: optional, think it coordinates with
|
|
3449
|
+
// .init_tensor
|
|
3450
|
+
};
|
|
3451
|
+
|
|
3452
|
+
/* End GGML Backend Buffer Interface */
|
|
3453
|
+
|
|
3454
|
+
/* GGML Backend Buffer Type Interface */
|
|
3455
|
+
|
|
3456
|
+
static const char * ggml_backend_webgpu_buffer_type_get_name(ggml_backend_buffer_type_t buft) {
|
|
3457
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(buft->device->context);
|
|
3458
|
+
return ctx->device_name.c_str();
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
static ggml_backend_buffer_t ggml_backend_webgpu_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft,
|
|
3462
|
+
size_t size) {
|
|
3463
|
+
static std::atomic<int> buffer_count;
|
|
3464
|
+
int buffer_id = buffer_count++;
|
|
3465
|
+
std::string buf_name = "tensor_buf" + std::to_string(buffer_id);
|
|
3466
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_buffer_type_alloc_buffer_" << buffer_id << ": " << size << " bytes");
|
|
3467
|
+
|
|
3468
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(buft->device->context);
|
|
3469
|
+
wgpu::Buffer buf;
|
|
3470
|
+
ggml_webgpu_create_buffer(ctx->webgpu_global_ctx->device, buf, ROUNDUP_POW2(size, WEBGPU_STORAGE_BUF_BINDING_MULT),
|
|
3471
|
+
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst,
|
|
3472
|
+
buf_name.c_str());
|
|
3473
|
+
|
|
3474
|
+
ggml_backend_webgpu_buffer_context * buf_ctx =
|
|
3475
|
+
new ggml_backend_webgpu_buffer_context(buf, buf_name, ctx->webgpu_global_ctx);
|
|
3476
|
+
|
|
3477
|
+
return ggml_backend_buffer_init(buft, ggml_backend_webgpu_buffer_interface, buf_ctx, size);
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
static size_t ggml_backend_webgpu_buffer_type_get_alignment(ggml_backend_buffer_type_t buft) {
|
|
3481
|
+
ggml_backend_webgpu_device_context * dev_ctx =
|
|
3482
|
+
static_cast<ggml_backend_webgpu_device_context *>(buft->device->context);
|
|
3483
|
+
return dev_ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment;
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
// maxBufferSize might be larger, but you can't bind more than
|
|
3487
|
+
// maxStorageBufferBindingSize to a single binding.
|
|
3488
|
+
static size_t ggml_backend_webgpu_buffer_type_get_max_size(ggml_backend_buffer_type_t buft) {
|
|
3489
|
+
ggml_backend_webgpu_device_context * dev_ctx =
|
|
3490
|
+
static_cast<ggml_backend_webgpu_device_context *>(buft->device->context);
|
|
3491
|
+
return dev_ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize;
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3494
|
+
static size_t ggml_backend_webgpu_buffer_type_get_alloc_size(ggml_backend_buffer_type_t buft,
|
|
3495
|
+
const ggml_tensor * tensor) {
|
|
3496
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(buft->device->context);
|
|
3497
|
+
size_t res = ggml_nbytes(tensor);
|
|
3498
|
+
switch (tensor->op) {
|
|
3499
|
+
case GGML_OP_ARGSORT:
|
|
3500
|
+
res = ROUNDUP_POW2(res * 2 + ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment,
|
|
3501
|
+
WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3502
|
+
break;
|
|
3503
|
+
case GGML_OP_TOP_K:
|
|
3504
|
+
{
|
|
3505
|
+
const ggml_tensor * src0 = tensor->src[0];
|
|
3506
|
+
if (src0) {
|
|
3507
|
+
const size_t full = sizeof(int32_t) * ggml_nelements(src0);
|
|
3508
|
+
res = ROUNDUP_POW2(
|
|
3509
|
+
full * 2 + ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment,
|
|
3510
|
+
WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
break;
|
|
3514
|
+
case GGML_OP_FLASH_ATTN_EXT:
|
|
3515
|
+
{
|
|
3516
|
+
const ggml_tensor * Q = tensor->src[0];
|
|
3517
|
+
const ggml_tensor * K = tensor->src[1];
|
|
3518
|
+
const ggml_tensor * V = tensor->src[2];
|
|
3519
|
+
const ggml_tensor * mask = tensor->src[3];
|
|
3520
|
+
const ggml_tensor * sinks = tensor->src[4];
|
|
3521
|
+
if (Q && K && V) {
|
|
3522
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
3523
|
+
shader_lib_ctx.src0 = const_cast<ggml_tensor *>(Q);
|
|
3524
|
+
shader_lib_ctx.src1 = const_cast<ggml_tensor *>(K);
|
|
3525
|
+
shader_lib_ctx.src2 = const_cast<ggml_tensor *>(V);
|
|
3526
|
+
shader_lib_ctx.src3 = const_cast<ggml_tensor *>(mask);
|
|
3527
|
+
shader_lib_ctx.src4 = const_cast<ggml_tensor *>(sinks);
|
|
3528
|
+
shader_lib_ctx.dst = const_cast<ggml_tensor *>(tensor);
|
|
3529
|
+
shader_lib_ctx.max_wg_size =
|
|
3530
|
+
ctx->webgpu_global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
3531
|
+
shader_lib_ctx.wg_mem_limit_bytes =
|
|
3532
|
+
ctx->webgpu_global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
3533
|
+
shader_lib_ctx.supports_subgroups = ctx->webgpu_global_ctx->capabilities.supports_subgroups;
|
|
3534
|
+
shader_lib_ctx.supports_subgroup_matrix =
|
|
3535
|
+
ctx->webgpu_global_ctx->capabilities.supports_subgroup_matrix;
|
|
3536
|
+
shader_lib_ctx.sg_mat_m = ctx->webgpu_global_ctx->capabilities.sg_mat_m;
|
|
3537
|
+
shader_lib_ctx.sg_mat_n = ctx->webgpu_global_ctx->capabilities.sg_mat_n;
|
|
3538
|
+
shader_lib_ctx.sg_mat_k = ctx->webgpu_global_ctx->capabilities.sg_mat_k;
|
|
3539
|
+
shader_lib_ctx.min_subgroup_size = ctx->webgpu_global_ctx->capabilities.min_subgroup_size;
|
|
3540
|
+
shader_lib_ctx.max_subgroup_size = ctx->webgpu_global_ctx->capabilities.max_subgroup_size;
|
|
3541
|
+
|
|
3542
|
+
const ggml_webgpu_flash_attn_decisions decisions = ggml_webgpu_flash_attn_get_decisions(
|
|
3543
|
+
shader_lib_ctx, ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
3544
|
+
|
|
3545
|
+
if (decisions.path == GGML_WEBGPU_FLASH_ATTN_PATH_VEC) {
|
|
3546
|
+
const uint32_t kv_tile = decisions.kv_tile;
|
|
3547
|
+
|
|
3548
|
+
const uint32_t vec_nwg_cap = ctx->webgpu_global_ctx->capabilities.min_subgroup_size;
|
|
3549
|
+
uint32_t nwg = 1u;
|
|
3550
|
+
const uint64_t kv_span = (uint64_t) std::max(1u, kv_tile);
|
|
3551
|
+
while ((2u * nwg * kv_span) < (uint64_t) K->ne[1] && nwg < vec_nwg_cap) {
|
|
3552
|
+
nwg <<= 1;
|
|
3553
|
+
}
|
|
3554
|
+
nwg = std::min(nwg, vec_nwg_cap);
|
|
3555
|
+
|
|
3556
|
+
const size_t align =
|
|
3557
|
+
ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment;
|
|
3558
|
+
const uint64_t nrows = (uint64_t) Q->ne[1] * Q->ne[2] * Q->ne[3];
|
|
3559
|
+
if (nwg > 1u) {
|
|
3560
|
+
const uint64_t tmp_data_elems = nrows * (uint64_t) V->ne[0] * nwg;
|
|
3561
|
+
const uint64_t tmp_stats_elems = nrows * 2u * nwg;
|
|
3562
|
+
const size_t tmp_size_bytes = ROUNDUP_POW2(
|
|
3563
|
+
(tmp_data_elems + tmp_stats_elems) * sizeof(float), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3564
|
+
res += tmp_size_bytes + align;
|
|
3565
|
+
} else {
|
|
3566
|
+
res += WEBGPU_STORAGE_BUF_BINDING_MULT + align;
|
|
3567
|
+
}
|
|
3568
|
+
if (mask != nullptr) {
|
|
3569
|
+
const uint32_t blk_nblk0 = CEIL_DIV((uint32_t) K->ne[1], kv_tile);
|
|
3570
|
+
const uint32_t blk_nblk1 = CEIL_DIV((uint32_t) Q->ne[1], 1u);
|
|
3571
|
+
const uint32_t stride_mask3 = (uint32_t) (mask->nb[3] / ggml_type_size(mask->type));
|
|
3572
|
+
const uint32_t blk_batch_count = stride_mask3 > 0 ? (uint32_t) Q->ne[3] : 1u;
|
|
3573
|
+
const uint64_t blk_elems = (uint64_t) blk_nblk0 * blk_nblk1 * blk_batch_count;
|
|
3574
|
+
const size_t blk_size_bytes =
|
|
3575
|
+
ROUNDUP_POW2(blk_elems * sizeof(uint32_t), WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3576
|
+
res += blk_size_bytes + align;
|
|
3577
|
+
}
|
|
3578
|
+
res = ROUNDUP_POW2(res, WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
break;
|
|
3583
|
+
case GGML_OP_MUL_MAT_ID:
|
|
3584
|
+
{
|
|
3585
|
+
const ggml_tensor * src0 = tensor->src[0];
|
|
3586
|
+
const ggml_tensor * src1 = tensor->src[1];
|
|
3587
|
+
if (src0 && src1) {
|
|
3588
|
+
const size_t gathered_size = sizeof(uint32_t) * tensor->src[0]->ne[2] * tensor->src[1]->ne[2];
|
|
3589
|
+
const size_t gathered_count_ids_size = sizeof(uint32_t) * tensor->src[0]->ne[2];
|
|
3590
|
+
res = ROUNDUP_POW2(
|
|
3591
|
+
res + gathered_size * 2 + gathered_count_ids_size +
|
|
3592
|
+
ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment * 3,
|
|
3593
|
+
WEBGPU_STORAGE_BUF_BINDING_MULT);
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
break;
|
|
3597
|
+
default:
|
|
3598
|
+
break;
|
|
3599
|
+
}
|
|
3600
|
+
return res;
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3603
|
+
/* End GGML Backend Buffer Type Interface */
|
|
3604
|
+
|
|
3605
|
+
/* GGML Backend Device Interface */
|
|
3606
|
+
|
|
3607
|
+
static const char * ggml_backend_webgpu_device_get_name(ggml_backend_dev_t dev) {
|
|
3608
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(dev->context);
|
|
3609
|
+
return ctx->device_name.c_str();
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3612
|
+
static const char * ggml_backend_webgpu_device_get_description(ggml_backend_dev_t dev) {
|
|
3613
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(dev->context);
|
|
3614
|
+
return ctx->device_desc.c_str();
|
|
3615
|
+
}
|
|
3616
|
+
|
|
3617
|
+
static void ggml_backend_webgpu_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) {
|
|
3618
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(dev->context);
|
|
3619
|
+
// TODO: for now, return maxBufferSize as both free and total memory
|
|
3620
|
+
// Track https://github.com/gpuweb/gpuweb/issues/5505 for updates.
|
|
3621
|
+
uint64_t max_buffer_size = ctx->webgpu_global_ctx->capabilities.limits.maxBufferSize;
|
|
3622
|
+
// If we're on a 32-bit system, clamp to UINTPTR_MAX
|
|
3623
|
+
#if UINTPTR_MAX < UINT64_MAX
|
|
3624
|
+
uint64_t max_ptr_size = static_cast<uint64_t>(UINTPTR_MAX);
|
|
3625
|
+
if (max_buffer_size > max_ptr_size) {
|
|
3626
|
+
max_buffer_size = max_ptr_size;
|
|
3627
|
+
}
|
|
3628
|
+
#endif
|
|
3629
|
+
*free = static_cast<size_t>(max_buffer_size);
|
|
3630
|
+
*total = static_cast<size_t>(max_buffer_size);
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
static enum ggml_backend_dev_type ggml_backend_webgpu_device_get_type(ggml_backend_dev_t dev) {
|
|
3634
|
+
GGML_UNUSED(dev);
|
|
3635
|
+
return GGML_BACKEND_DEVICE_TYPE_GPU;
|
|
3636
|
+
}
|
|
3637
|
+
|
|
3638
|
+
static void ggml_backend_webgpu_device_get_props(ggml_backend_dev_t dev, struct ggml_backend_dev_props * props) {
|
|
3639
|
+
props->name = ggml_backend_webgpu_device_get_name(dev);
|
|
3640
|
+
props->description = ggml_backend_webgpu_device_get_description(dev);
|
|
3641
|
+
props->type = ggml_backend_webgpu_device_get_type(dev);
|
|
3642
|
+
ggml_backend_webgpu_device_get_memory(dev, &props->memory_free, &props->memory_total);
|
|
3643
|
+
props->caps = {
|
|
3644
|
+
/* .async = */ false,
|
|
3645
|
+
/* .host_buffer = */ false,
|
|
3646
|
+
/* .buffer_from_host_ptr = */ false,
|
|
3647
|
+
/* .events = */ false,
|
|
3648
|
+
};
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
static ggml_guid_t ggml_backend_webgpu_guid(void) {
|
|
3652
|
+
static ggml_guid guid = { 0x67, 0xc7, 0xa4, 0xb1, 0x78, 0x74, 0x4f, 0x51,
|
|
3653
|
+
0x9d, 0x65, 0x44, 0x6d, 0xe4, 0x1b, 0x82, 0x9a };
|
|
3654
|
+
return &guid;
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
static void ggml_webgpu_init_memset_pipeline(webgpu_global_context & ctx) {
|
|
3658
|
+
// we use the maximum workgroup size for the memset pipeline
|
|
3659
|
+
size_t max_threads = WEBGPU_MAX_WG_SIZE * ctx->capabilities.limits.maxComputeWorkgroupsPerDimension;
|
|
3660
|
+
// Size the bytes_per_thread so that the largest buffer size can be handled
|
|
3661
|
+
ctx->capabilities.memset_bytes_per_thread =
|
|
3662
|
+
CEIL_DIV(ctx->capabilities.limits.maxStorageBufferBindingSize, max_threads);
|
|
3663
|
+
std::vector<wgpu::ConstantEntry> constants(2);
|
|
3664
|
+
constants[0].key = "wg_size";
|
|
3665
|
+
constants[0].value = WEBGPU_MAX_WG_SIZE;
|
|
3666
|
+
constants[1].key = "bytes_per_thread";
|
|
3667
|
+
constants[1].value = ctx->capabilities.memset_bytes_per_thread;
|
|
3668
|
+
ctx->memset_pipeline = ggml_webgpu_create_pipeline(ctx->device, wgsl_memset, "memset", constants);
|
|
3669
|
+
}
|
|
3670
|
+
|
|
3671
|
+
static bool create_webgpu_device(ggml_backend_webgpu_reg_context * ctx) {
|
|
3672
|
+
wgpu::RequestAdapterOptions options = {};
|
|
3673
|
+
|
|
3674
|
+
#ifndef __EMSCRIPTEN__
|
|
3675
|
+
// TODO: track need for these toggles: https://issues.chromium.org/issues/42251215
|
|
3676
|
+
const char * const adapterEnabledToggles[] = { "vulkan_enable_f16_on_nvidia", "use_vulkan_memory_model" };
|
|
3677
|
+
wgpu::DawnTogglesDescriptor adapterTogglesDesc;
|
|
3678
|
+
adapterTogglesDesc.enabledToggles = adapterEnabledToggles;
|
|
3679
|
+
adapterTogglesDesc.enabledToggleCount = 2;
|
|
3680
|
+
options.nextInChain = &adapterTogglesDesc;
|
|
3681
|
+
#endif
|
|
3682
|
+
|
|
3683
|
+
ctx->webgpu_global_ctx->instance.WaitAny(
|
|
3684
|
+
ctx->webgpu_global_ctx->instance.RequestAdapter(
|
|
3685
|
+
&options, wgpu::CallbackMode::AllowSpontaneous,
|
|
3686
|
+
[&ctx](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, const char * message) {
|
|
3687
|
+
if (status != wgpu::RequestAdapterStatus::Success) {
|
|
3688
|
+
GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
|
|
3689
|
+
return;
|
|
3690
|
+
}
|
|
3691
|
+
ctx->webgpu_global_ctx->adapter = std::move(adapter);
|
|
3692
|
+
}),
|
|
3693
|
+
UINT64_MAX);
|
|
3694
|
+
GGML_ASSERT(ctx->webgpu_global_ctx->adapter != nullptr);
|
|
3695
|
+
|
|
3696
|
+
ctx->webgpu_global_ctx->adapter.GetLimits(&ctx->webgpu_global_ctx->capabilities.limits);
|
|
3697
|
+
|
|
3698
|
+
wgpu::AdapterInfo info{};
|
|
3699
|
+
#ifndef __EMSCRIPTEN__
|
|
3700
|
+
wgpu::AdapterPropertiesSubgroupMatrixConfigs subgroup_matrix_configs{};
|
|
3701
|
+
if (ctx->webgpu_global_ctx->adapter.HasFeature(wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix)) {
|
|
3702
|
+
info.nextInChain = &subgroup_matrix_configs;
|
|
3703
|
+
}
|
|
3704
|
+
#endif
|
|
3705
|
+
ctx->webgpu_global_ctx->adapter.GetInfo(&info);
|
|
3706
|
+
ctx->webgpu_global_ctx->command_submit_batch_size = ggml_backend_webgpu_get_command_submit_batch_size();
|
|
3707
|
+
ctx->webgpu_global_ctx->max_inflight_batches = ggml_backend_webgpu_get_max_inflight_batches();
|
|
3708
|
+
wgpu::SupportedFeatures features;
|
|
3709
|
+
ctx->webgpu_global_ctx->adapter.GetFeatures(&features);
|
|
3710
|
+
// we require f16 support
|
|
3711
|
+
GGML_ASSERT(ctx->webgpu_global_ctx->adapter.HasFeature(wgpu::FeatureName::ShaderF16));
|
|
3712
|
+
ctx->webgpu_global_ctx->capabilities.supports_subgroups =
|
|
3713
|
+
ctx->webgpu_global_ctx->adapter.HasFeature(wgpu::FeatureName::Subgroups);
|
|
3714
|
+
|
|
3715
|
+
bool valid_subgroup_matrix_config = false;
|
|
3716
|
+
#ifndef __EMSCRIPTEN__
|
|
3717
|
+
// Accept f16 subgroup matrix configurations (square or non-square).
|
|
3718
|
+
// NVIDIA GPUs typically report square configs (e.g. 16x16x16),
|
|
3719
|
+
// while Intel Xe2 GPUs report non-square configs (e.g. 8x16x16).
|
|
3720
|
+
// The shaders are already parameterized to handle any M/N/K dimensions.
|
|
3721
|
+
if (ctx->webgpu_global_ctx->adapter.HasFeature(wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix)) {
|
|
3722
|
+
for (size_t i = 0; i < subgroup_matrix_configs.configCount; i++) {
|
|
3723
|
+
const wgpu::SubgroupMatrixConfig config = subgroup_matrix_configs.configs[i];
|
|
3724
|
+
if (config.componentType == wgpu::SubgroupMatrixComponentType::F16 &&
|
|
3725
|
+
config.resultComponentType == wgpu::SubgroupMatrixComponentType::F16) {
|
|
3726
|
+
ctx->webgpu_global_ctx->capabilities.sg_mat_m = config.M;
|
|
3727
|
+
ctx->webgpu_global_ctx->capabilities.sg_mat_n = config.N;
|
|
3728
|
+
ctx->webgpu_global_ctx->capabilities.sg_mat_k = config.K;
|
|
3729
|
+
valid_subgroup_matrix_config = true;
|
|
3730
|
+
break;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
#endif
|
|
3735
|
+
ctx->webgpu_global_ctx->capabilities.supports_subgroup_matrix = valid_subgroup_matrix_config;
|
|
3736
|
+
|
|
3737
|
+
// Runtime subgroup size can be any supported size in this range. Shaders
|
|
3738
|
+
// that allocate per-lane register arrays must size them for the minimum.
|
|
3739
|
+
ctx->webgpu_global_ctx->capabilities.min_subgroup_size = info.subgroupMinSize;
|
|
3740
|
+
ctx->webgpu_global_ctx->capabilities.max_subgroup_size = info.subgroupMaxSize;
|
|
3741
|
+
// Initialize device
|
|
3742
|
+
std::vector<wgpu::FeatureName> required_features = { wgpu::FeatureName::ShaderF16 };
|
|
3743
|
+
|
|
3744
|
+
#ifndef __EMSCRIPTEN__
|
|
3745
|
+
required_features.push_back(wgpu::FeatureName::ImplicitDeviceSynchronization);
|
|
3746
|
+
if (ctx->webgpu_global_ctx->capabilities.supports_subgroup_matrix) {
|
|
3747
|
+
required_features.push_back(wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix);
|
|
3748
|
+
}
|
|
3749
|
+
#endif
|
|
3750
|
+
|
|
3751
|
+
if (ctx->webgpu_global_ctx->capabilities.supports_subgroups) {
|
|
3752
|
+
required_features.push_back(wgpu::FeatureName::Subgroups);
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3756
|
+
required_features.push_back(wgpu::FeatureName::TimestampQuery);
|
|
3757
|
+
#endif
|
|
3758
|
+
|
|
3759
|
+
wgpu::DeviceDescriptor dev_desc;
|
|
3760
|
+
dev_desc.requiredLimits = &ctx->webgpu_global_ctx->capabilities.limits;
|
|
3761
|
+
dev_desc.requiredFeatures = required_features.data();
|
|
3762
|
+
dev_desc.requiredFeatureCount = required_features.size();
|
|
3763
|
+
dev_desc.SetDeviceLostCallback(
|
|
3764
|
+
wgpu::CallbackMode::AllowSpontaneous,
|
|
3765
|
+
[](const wgpu::Device & device, wgpu::DeviceLostReason reason, wgpu::StringView message) {
|
|
3766
|
+
if (reason == wgpu::DeviceLostReason::Destroyed) {
|
|
3767
|
+
return;
|
|
3768
|
+
}
|
|
3769
|
+
GGML_UNUSED(device);
|
|
3770
|
+
GGML_LOG_ERROR("ggml_webgpu: Device lost! Reason: %d, Message: %s\n", static_cast<int>(reason),
|
|
3771
|
+
std::string(message).c_str());
|
|
3772
|
+
});
|
|
3773
|
+
dev_desc.SetUncapturedErrorCallback(
|
|
3774
|
+
[](const wgpu::Device & device, wgpu::ErrorType reason, wgpu::StringView message) {
|
|
3775
|
+
GGML_UNUSED(device);
|
|
3776
|
+
GGML_ABORT("ggml_webgpu: Device error! Reason: %d, Message: %s\n", static_cast<int>(reason),
|
|
3777
|
+
std::string(message).c_str());
|
|
3778
|
+
});
|
|
3779
|
+
|
|
3780
|
+
#ifndef __EMSCRIPTEN__
|
|
3781
|
+
// Enable Dawn-specific toggles to increase native performance
|
|
3782
|
+
// TODO: Maybe WebGPU needs a "fast" mode where you can request compilers skip adding checks like these,
|
|
3783
|
+
// only for native performance?
|
|
3784
|
+
const char * const deviceEnabledToggles[] = { "disable_robustness", "disable_workgroup_init",
|
|
3785
|
+
"disable_polyfills_on_integer_div_and_mod" };
|
|
3786
|
+
const char * const deviceDisabledToggles[] = { "timestamp_quantization" };
|
|
3787
|
+
wgpu::DawnTogglesDescriptor deviceTogglesDesc;
|
|
3788
|
+
deviceTogglesDesc.enabledToggles = deviceEnabledToggles;
|
|
3789
|
+
deviceTogglesDesc.enabledToggleCount = 3;
|
|
3790
|
+
deviceTogglesDesc.disabledToggles = deviceDisabledToggles;
|
|
3791
|
+
deviceTogglesDesc.disabledToggleCount = 1;
|
|
3792
|
+
|
|
3793
|
+
dev_desc.nextInChain = &deviceTogglesDesc;
|
|
3794
|
+
#endif
|
|
3795
|
+
|
|
3796
|
+
ctx->webgpu_global_ctx->instance.WaitAny(
|
|
3797
|
+
ctx->webgpu_global_ctx->adapter.RequestDevice(
|
|
3798
|
+
&dev_desc, wgpu::CallbackMode::AllowSpontaneous,
|
|
3799
|
+
[ctx](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
|
|
3800
|
+
if (status != wgpu::RequestDeviceStatus::Success) {
|
|
3801
|
+
GGML_LOG_ERROR("ggml_webgpu: Failed to get a device: %s\n", std::string(message).c_str());
|
|
3802
|
+
return;
|
|
3803
|
+
}
|
|
3804
|
+
ctx->webgpu_global_ctx->device = std::move(device);
|
|
3805
|
+
}),
|
|
3806
|
+
UINT64_MAX);
|
|
3807
|
+
GGML_ASSERT(ctx->webgpu_global_ctx->device != nullptr);
|
|
3808
|
+
|
|
3809
|
+
ggml_webgpu_init_memset_pipeline(ctx->webgpu_global_ctx);
|
|
3810
|
+
ggml_webgpu_create_buffer(ctx->webgpu_global_ctx->device, ctx->webgpu_global_ctx->memset_params_buf,
|
|
3811
|
+
WEBGPU_PARAMS_BUF_SIZE_BYTES, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform,
|
|
3812
|
+
"memset_params_buf");
|
|
3813
|
+
ctx->webgpu_global_ctx->queue = ctx->webgpu_global_ctx->device.GetQueue();
|
|
3814
|
+
|
|
3815
|
+
GGML_LOG_INFO(
|
|
3816
|
+
"ggml_webgpu: adapter_info: vendor_id: %u | vendor: %s | architecture: %s | device_id: %u | name: %s | "
|
|
3817
|
+
"device_desc: %s\n",
|
|
3818
|
+
info.vendorID, std::string(info.vendor).c_str(), std::string(info.architecture).c_str(), info.deviceID,
|
|
3819
|
+
std::string(info.device).c_str(), std::string(info.description).c_str());
|
|
3820
|
+
return true;
|
|
3821
|
+
}
|
|
3822
|
+
|
|
3823
|
+
static webgpu_context initialize_webgpu_context(ggml_backend_dev_t dev) {
|
|
3824
|
+
ggml_backend_webgpu_device_context * dev_ctx = (ggml_backend_webgpu_device_context *) dev->context;
|
|
3825
|
+
webgpu_context webgpu_ctx = std::make_shared<webgpu_context_struct>();
|
|
3826
|
+
webgpu_ctx->global_ctx = dev_ctx->webgpu_global_ctx;
|
|
3827
|
+
webgpu_ctx->shader_lib = std::make_unique<ggml_webgpu_shader_lib>(dev_ctx->webgpu_global_ctx->device);
|
|
3828
|
+
webgpu_ctx->param_arena.init(
|
|
3829
|
+
webgpu_ctx->global_ctx->device, WEBGPU_PARAMS_BUF_SIZE_BYTES,
|
|
3830
|
+
webgpu_ctx->global_ctx->command_submit_batch_size + WEBGPU_NUM_PARAM_SLOT_SAFETY_MARGIN,
|
|
3831
|
+
webgpu_ctx->global_ctx->capabilities.limits.minUniformBufferOffsetAlignment);
|
|
3832
|
+
ggml_webgpu_create_buffer(webgpu_ctx->global_ctx->device, webgpu_ctx->set_rows_dev_error_buf,
|
|
3833
|
+
WEBGPU_SET_ROWS_ERROR_BUF_SIZE_BYTES,
|
|
3834
|
+
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc, "set_rows_dev_error_buf");
|
|
3835
|
+
ggml_webgpu_create_buffer(webgpu_ctx->global_ctx->device, webgpu_ctx->set_rows_host_error_buf,
|
|
3836
|
+
WEBGPU_SET_ROWS_ERROR_BUF_SIZE_BYTES,
|
|
3837
|
+
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead, "set_rows_host_error_buf");
|
|
3838
|
+
|
|
3839
|
+
#ifdef GGML_WEBGPU_GPU_PROFILE
|
|
3840
|
+
ggml_webgpu_create_buffer(
|
|
3841
|
+
webgpu_ctx->global_ctx->device, webgpu_ctx->profile_timestamp_dev_buf, WEBGPU_TIMESTAMP_QUERY_BUF_SIZE_BYTES,
|
|
3842
|
+
wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopySrc, "profile_timestamp_dev_buf");
|
|
3843
|
+
ggml_webgpu_create_buffer(webgpu_ctx->global_ctx->device, webgpu_ctx->profile_timestamp_host_buf,
|
|
3844
|
+
WEBGPU_TIMESTAMP_QUERY_BUF_SIZE_BYTES,
|
|
3845
|
+
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead, "profile_timestamp_host_buf");
|
|
3846
|
+
wgpu::QuerySetDescriptor query_set_desc = {};
|
|
3847
|
+
query_set_desc.type = wgpu::QueryType::Timestamp;
|
|
3848
|
+
query_set_desc.count = WEBGPU_MAX_PROFILE_QUERY_COUNT;
|
|
3849
|
+
webgpu_ctx->profile_timestamp_query_set = webgpu_ctx->global_ctx->device.CreateQuerySet(&query_set_desc);
|
|
3850
|
+
#endif
|
|
3851
|
+
|
|
3852
|
+
#ifdef GGML_WEBGPU_DEBUG
|
|
3853
|
+
// Initialize debug buffers
|
|
3854
|
+
ggml_webgpu_create_buffer(webgpu_ctx->global_ctx->device, webgpu_ctx->global_ctx->debug_host_buf,
|
|
3855
|
+
WEBGPU_DEBUG_BUF_ELEMS * sizeof(uint32_t),
|
|
3856
|
+
wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead, "debug_host_buf");
|
|
3857
|
+
ggml_webgpu_create_buffer(webgpu_ctx->global_ctx->device, webgpu_ctx->global_ctx->debug_dev_buf,
|
|
3858
|
+
WEBGPU_DEBUG_BUF_ELEMS * sizeof(uint32_t),
|
|
3859
|
+
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc, "debug_dev_buf");
|
|
3860
|
+
#endif
|
|
3861
|
+
return webgpu_ctx;
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
static ggml_backend_t ggml_backend_webgpu_backend_init(ggml_backend_dev_t dev, const char * params) {
|
|
3865
|
+
GGML_UNUSED(params);
|
|
3866
|
+
|
|
3867
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_backend_init()");
|
|
3868
|
+
|
|
3869
|
+
ggml_backend_webgpu_device_context * dev_ctx = static_cast<ggml_backend_webgpu_device_context *>(dev->context);
|
|
3870
|
+
|
|
3871
|
+
auto * backend_ctx = new ggml_backend_webgpu_context();
|
|
3872
|
+
backend_ctx->name = GGML_WEBGPU_NAME + std::string(": ") + dev_ctx->device_name;
|
|
3873
|
+
backend_ctx->webgpu_ctx = initialize_webgpu_context(dev);
|
|
3874
|
+
|
|
3875
|
+
// See GGML Backend Interface section
|
|
3876
|
+
auto * backend = new ggml_backend();
|
|
3877
|
+
*backend = {
|
|
3878
|
+
/* .guid = */ ggml_backend_webgpu_guid(),
|
|
3879
|
+
/* .interface = */ ggml_backend_webgpu_i,
|
|
3880
|
+
/* .device = */ dev,
|
|
3881
|
+
/* .context = */ backend_ctx,
|
|
3882
|
+
};
|
|
3883
|
+
return backend;
|
|
3884
|
+
}
|
|
3885
|
+
|
|
3886
|
+
static ggml_backend_buffer_type_t ggml_backend_webgpu_device_get_buffer_type(ggml_backend_dev_t dev) {
|
|
3887
|
+
// See GGML Backend Buffer Type Interface section
|
|
3888
|
+
|
|
3889
|
+
static struct ggml_backend_buffer_type ggml_backend_webgpu_buffer_type = {
|
|
3890
|
+
/* .iface = */ {
|
|
3891
|
+
/* .get_name = */ ggml_backend_webgpu_buffer_type_get_name,
|
|
3892
|
+
/* .alloc_buffer = */ ggml_backend_webgpu_buffer_type_alloc_buffer,
|
|
3893
|
+
/* .get_alignment = */ ggml_backend_webgpu_buffer_type_get_alignment,
|
|
3894
|
+
/* .get_max_size = */ ggml_backend_webgpu_buffer_type_get_max_size,
|
|
3895
|
+
/* .get_alloc_size = */ ggml_backend_webgpu_buffer_type_get_alloc_size,
|
|
3896
|
+
/* .is_host = */ NULL, // defaults to false
|
|
3897
|
+
},
|
|
3898
|
+
/* .device = */
|
|
3899
|
+
dev,
|
|
3900
|
+
/* .context = */ NULL
|
|
3901
|
+
};
|
|
3902
|
+
|
|
3903
|
+
return &ggml_backend_webgpu_buffer_type;
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3906
|
+
static bool ggml_backend_webgpu_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) {
|
|
3907
|
+
GGML_UNUSED(dev);
|
|
3908
|
+
return buft->iface.get_name == ggml_backend_webgpu_buffer_type_get_name;
|
|
3909
|
+
}
|
|
3910
|
+
|
|
3911
|
+
static bool ggml_webgpu_supported_qtype(ggml_type type) {
|
|
3912
|
+
switch (type) {
|
|
3913
|
+
case GGML_TYPE_Q1_0:
|
|
3914
|
+
case GGML_TYPE_Q4_0:
|
|
3915
|
+
case GGML_TYPE_Q4_1:
|
|
3916
|
+
case GGML_TYPE_Q5_0:
|
|
3917
|
+
case GGML_TYPE_Q5_1:
|
|
3918
|
+
case GGML_TYPE_Q8_0:
|
|
3919
|
+
case GGML_TYPE_Q2_K:
|
|
3920
|
+
case GGML_TYPE_Q3_K:
|
|
3921
|
+
case GGML_TYPE_Q4_K:
|
|
3922
|
+
case GGML_TYPE_Q5_K:
|
|
3923
|
+
case GGML_TYPE_Q6_K:
|
|
3924
|
+
case GGML_TYPE_IQ2_XXS:
|
|
3925
|
+
case GGML_TYPE_IQ2_XS:
|
|
3926
|
+
case GGML_TYPE_IQ2_S:
|
|
3927
|
+
case GGML_TYPE_IQ3_XXS:
|
|
3928
|
+
case GGML_TYPE_IQ3_S:
|
|
3929
|
+
case GGML_TYPE_IQ1_S:
|
|
3930
|
+
case GGML_TYPE_IQ1_M:
|
|
3931
|
+
case GGML_TYPE_IQ4_NL:
|
|
3932
|
+
case GGML_TYPE_IQ4_XS:
|
|
3933
|
+
case GGML_TYPE_MXFP4:
|
|
3934
|
+
return true;
|
|
3935
|
+
default:
|
|
3936
|
+
return false;
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
static bool ggml_backend_webgpu_device_supports_op(ggml_backend_dev_t dev, const ggml_tensor * op) {
|
|
3941
|
+
ggml_backend_webgpu_device_context * ctx = static_cast<ggml_backend_webgpu_device_context *>(dev->context);
|
|
3942
|
+
|
|
3943
|
+
ggml_tensor * src0 = op->src[0];
|
|
3944
|
+
ggml_tensor * src1 = op->src[1];
|
|
3945
|
+
ggml_tensor * src2 = op->src[2];
|
|
3946
|
+
|
|
3947
|
+
// on smaller devices (or CI), tensors may be larger than the max storage buffer size
|
|
3948
|
+
if (ggml_nbytes(op) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize ||
|
|
3949
|
+
(src0 != nullptr &&
|
|
3950
|
+
ggml_nbytes(src0) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize) ||
|
|
3951
|
+
(src1 != nullptr &&
|
|
3952
|
+
ggml_nbytes(src1) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize)) {
|
|
3953
|
+
return false;
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3956
|
+
bool supports_op = false;
|
|
3957
|
+
switch (op->op) {
|
|
3958
|
+
case GGML_OP_NONE:
|
|
3959
|
+
case GGML_OP_VIEW:
|
|
3960
|
+
case GGML_OP_PERMUTE:
|
|
3961
|
+
case GGML_OP_TRANSPOSE:
|
|
3962
|
+
case GGML_OP_RESHAPE:
|
|
3963
|
+
supports_op = true;
|
|
3964
|
+
break;
|
|
3965
|
+
case GGML_OP_ADD:
|
|
3966
|
+
case GGML_OP_SUB:
|
|
3967
|
+
case GGML_OP_MUL:
|
|
3968
|
+
case GGML_OP_DIV:
|
|
3969
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type) &&
|
|
3970
|
+
(src1->type == op->type);
|
|
3971
|
+
break;
|
|
3972
|
+
case GGML_OP_ADD_ID:
|
|
3973
|
+
supports_op = src0->type == GGML_TYPE_F32;
|
|
3974
|
+
break;
|
|
3975
|
+
case GGML_OP_CONCAT:
|
|
3976
|
+
supports_op = (src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_I32);
|
|
3977
|
+
break;
|
|
3978
|
+
case GGML_OP_REPEAT:
|
|
3979
|
+
supports_op = (src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_I32 || src0->type == GGML_TYPE_I16);
|
|
3980
|
+
break;
|
|
3981
|
+
case GGML_OP_CPY:
|
|
3982
|
+
case GGML_OP_CONT:
|
|
3983
|
+
supports_op = ((op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) &&
|
|
3984
|
+
(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16)) ||
|
|
3985
|
+
(op->type == GGML_TYPE_I32 && src0->type == GGML_TYPE_F32);
|
|
3986
|
+
break;
|
|
3987
|
+
case GGML_OP_SET:
|
|
3988
|
+
supports_op = src0->type == src1->type && src0->type == op->type &&
|
|
3989
|
+
(op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_I32);
|
|
3990
|
+
break;
|
|
3991
|
+
case GGML_OP_SET_ROWS:
|
|
3992
|
+
supports_op = ((op->type == GGML_TYPE_F16 || op->type == GGML_TYPE_F32) && src0->type == GGML_TYPE_F32 &&
|
|
3993
|
+
(src1->type == GGML_TYPE_I64 || src1->type == GGML_TYPE_I32));
|
|
3994
|
+
break;
|
|
3995
|
+
case GGML_OP_GET_ROWS:
|
|
3996
|
+
if (src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16 || ggml_webgpu_supported_qtype(src0->type)) {
|
|
3997
|
+
supports_op = (op->type == GGML_TYPE_F32);
|
|
3998
|
+
} else if (src0->type == GGML_TYPE_I32) {
|
|
3999
|
+
supports_op = op->type == GGML_TYPE_I32;
|
|
4000
|
+
}
|
|
4001
|
+
break;
|
|
4002
|
+
case GGML_OP_MUL_MAT:
|
|
4003
|
+
{
|
|
4004
|
+
switch (src1->type) {
|
|
4005
|
+
case GGML_TYPE_F16:
|
|
4006
|
+
supports_op |= (src0->type == GGML_TYPE_F16);
|
|
4007
|
+
break;
|
|
4008
|
+
case GGML_TYPE_F32:
|
|
4009
|
+
switch (src0->type) {
|
|
4010
|
+
case GGML_TYPE_F32:
|
|
4011
|
+
case GGML_TYPE_F16:
|
|
4012
|
+
case GGML_TYPE_Q1_0:
|
|
4013
|
+
case GGML_TYPE_Q4_0:
|
|
4014
|
+
case GGML_TYPE_Q4_1:
|
|
4015
|
+
case GGML_TYPE_Q5_0:
|
|
4016
|
+
case GGML_TYPE_Q5_1:
|
|
4017
|
+
case GGML_TYPE_Q8_0:
|
|
4018
|
+
case GGML_TYPE_Q2_K:
|
|
4019
|
+
case GGML_TYPE_Q3_K:
|
|
4020
|
+
case GGML_TYPE_Q4_K:
|
|
4021
|
+
case GGML_TYPE_Q5_K:
|
|
4022
|
+
case GGML_TYPE_Q6_K:
|
|
4023
|
+
case GGML_TYPE_IQ2_XXS:
|
|
4024
|
+
case GGML_TYPE_IQ2_XS:
|
|
4025
|
+
case GGML_TYPE_IQ2_S:
|
|
4026
|
+
case GGML_TYPE_IQ3_XXS:
|
|
4027
|
+
case GGML_TYPE_IQ3_S:
|
|
4028
|
+
case GGML_TYPE_IQ1_S:
|
|
4029
|
+
case GGML_TYPE_IQ1_M:
|
|
4030
|
+
case GGML_TYPE_IQ4_NL:
|
|
4031
|
+
case GGML_TYPE_IQ4_XS:
|
|
4032
|
+
case GGML_TYPE_MXFP4:
|
|
4033
|
+
supports_op = true;
|
|
4034
|
+
break;
|
|
4035
|
+
default:
|
|
4036
|
+
break;
|
|
4037
|
+
}
|
|
4038
|
+
default:
|
|
4039
|
+
break;
|
|
4040
|
+
}
|
|
4041
|
+
break;
|
|
4042
|
+
}
|
|
4043
|
+
case GGML_OP_MUL_MAT_ID:
|
|
4044
|
+
switch (src1->type) {
|
|
4045
|
+
case GGML_TYPE_F16:
|
|
4046
|
+
supports_op |= (src0->type == GGML_TYPE_F16);
|
|
4047
|
+
break;
|
|
4048
|
+
case GGML_TYPE_F32:
|
|
4049
|
+
switch (src0->type) {
|
|
4050
|
+
case GGML_TYPE_F32:
|
|
4051
|
+
case GGML_TYPE_F16:
|
|
4052
|
+
case GGML_TYPE_Q1_0:
|
|
4053
|
+
case GGML_TYPE_Q4_0:
|
|
4054
|
+
case GGML_TYPE_Q4_1:
|
|
4055
|
+
case GGML_TYPE_Q5_0:
|
|
4056
|
+
case GGML_TYPE_Q5_1:
|
|
4057
|
+
case GGML_TYPE_Q8_0:
|
|
4058
|
+
case GGML_TYPE_Q2_K:
|
|
4059
|
+
case GGML_TYPE_Q3_K:
|
|
4060
|
+
case GGML_TYPE_Q4_K:
|
|
4061
|
+
case GGML_TYPE_Q5_K:
|
|
4062
|
+
case GGML_TYPE_Q6_K:
|
|
4063
|
+
case GGML_TYPE_IQ1_S:
|
|
4064
|
+
case GGML_TYPE_IQ1_M:
|
|
4065
|
+
case GGML_TYPE_IQ2_XXS:
|
|
4066
|
+
case GGML_TYPE_IQ2_XS:
|
|
4067
|
+
case GGML_TYPE_IQ2_S:
|
|
4068
|
+
case GGML_TYPE_IQ3_XXS:
|
|
4069
|
+
case GGML_TYPE_IQ3_S:
|
|
4070
|
+
case GGML_TYPE_IQ4_NL:
|
|
4071
|
+
case GGML_TYPE_IQ4_XS:
|
|
4072
|
+
case GGML_TYPE_MXFP4:
|
|
4073
|
+
supports_op = true;
|
|
4074
|
+
break;
|
|
4075
|
+
default:
|
|
4076
|
+
break;
|
|
4077
|
+
}
|
|
4078
|
+
break;
|
|
4079
|
+
default:
|
|
4080
|
+
break;
|
|
4081
|
+
}
|
|
4082
|
+
break;
|
|
4083
|
+
case GGML_OP_FLASH_ATTN_EXT:
|
|
4084
|
+
{
|
|
4085
|
+
supports_op = src0->type == GGML_TYPE_F32 &&
|
|
4086
|
+
(src1->type == GGML_TYPE_F32 || src1->type == GGML_TYPE_F16 ||
|
|
4087
|
+
src1->type == GGML_TYPE_Q4_0 || src1->type == GGML_TYPE_Q8_0) &&
|
|
4088
|
+
src2->type == src1->type && op->type == GGML_TYPE_F32;
|
|
4089
|
+
if (!supports_op) {
|
|
4090
|
+
break;
|
|
4091
|
+
}
|
|
4092
|
+
ggml_webgpu_shader_lib_context shader_lib_ctx = {};
|
|
4093
|
+
shader_lib_ctx.src0 = src0;
|
|
4094
|
+
shader_lib_ctx.src1 = src1;
|
|
4095
|
+
shader_lib_ctx.src2 = src2;
|
|
4096
|
+
shader_lib_ctx.src3 = op->src[3];
|
|
4097
|
+
shader_lib_ctx.src4 = op->src[4];
|
|
4098
|
+
shader_lib_ctx.dst = const_cast<ggml_tensor *>(op);
|
|
4099
|
+
shader_lib_ctx.supports_subgroups = ctx->webgpu_global_ctx->capabilities.supports_subgroups;
|
|
4100
|
+
shader_lib_ctx.supports_subgroup_matrix = ctx->webgpu_global_ctx->capabilities.supports_subgroup_matrix;
|
|
4101
|
+
shader_lib_ctx.max_wg_size =
|
|
4102
|
+
ctx->webgpu_global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
4103
|
+
shader_lib_ctx.wg_mem_limit_bytes =
|
|
4104
|
+
ctx->webgpu_global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
4105
|
+
shader_lib_ctx.sg_mat_m = ctx->webgpu_global_ctx->capabilities.sg_mat_m;
|
|
4106
|
+
shader_lib_ctx.sg_mat_n = ctx->webgpu_global_ctx->capabilities.sg_mat_n;
|
|
4107
|
+
shader_lib_ctx.sg_mat_k = ctx->webgpu_global_ctx->capabilities.sg_mat_k;
|
|
4108
|
+
shader_lib_ctx.min_subgroup_size = ctx->webgpu_global_ctx->capabilities.min_subgroup_size;
|
|
4109
|
+
shader_lib_ctx.max_subgroup_size = ctx->webgpu_global_ctx->capabilities.max_subgroup_size;
|
|
4110
|
+
|
|
4111
|
+
const ggml_webgpu_flash_attn_decisions decisions = ggml_webgpu_flash_attn_get_decisions(
|
|
4112
|
+
shader_lib_ctx, ctx->webgpu_global_ctx->capabilities.limits.minStorageBufferOffsetAlignment);
|
|
4113
|
+
const size_t limit_bytes = ctx->webgpu_global_ctx->capabilities.limits.maxComputeWorkgroupStorageSize;
|
|
4114
|
+
const bool has_mask = op->src[3] != nullptr;
|
|
4115
|
+
if (decisions.path == GGML_WEBGPU_FLASH_ATTN_PATH_NONE) {
|
|
4116
|
+
supports_op = false;
|
|
4117
|
+
break;
|
|
4118
|
+
}
|
|
4119
|
+
if (decisions.path == GGML_WEBGPU_FLASH_ATTN_PATH_VEC) {
|
|
4120
|
+
const size_t min_bytes = ggml_webgpu_flash_attn_wg_mem_bytes(
|
|
4121
|
+
decisions.q_tile, decisions.kv_tile, (uint32_t) src0->ne[0], (uint32_t) src2->ne[0], has_mask,
|
|
4122
|
+
decisions.kv_direct, decisions.path);
|
|
4123
|
+
if (min_bytes > limit_bytes) {
|
|
4124
|
+
supports_op = false;
|
|
4125
|
+
}
|
|
4126
|
+
break;
|
|
4127
|
+
}
|
|
4128
|
+
|
|
4129
|
+
if (decisions.path == GGML_WEBGPU_FLASH_ATTN_PATH_TILE) {
|
|
4130
|
+
const size_t min_bytes = ggml_webgpu_flash_attn_wg_mem_bytes(
|
|
4131
|
+
decisions.q_tile, decisions.kv_tile, (uint32_t) src0->ne[0], (uint32_t) src2->ne[0], has_mask,
|
|
4132
|
+
decisions.kv_direct, decisions.path);
|
|
4133
|
+
if (min_bytes > limit_bytes) {
|
|
4134
|
+
supports_op = false;
|
|
4135
|
+
}
|
|
4136
|
+
break;
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4139
|
+
if (!ctx->webgpu_global_ctx->capabilities.supports_subgroup_matrix) {
|
|
4140
|
+
supports_op = false;
|
|
4141
|
+
break;
|
|
4142
|
+
}
|
|
4143
|
+
const size_t min_bytes = ggml_webgpu_flash_attn_wg_mem_bytes(
|
|
4144
|
+
decisions.q_tile, decisions.kv_tile, (uint32_t) src0->ne[0], (uint32_t) src2->ne[0], has_mask,
|
|
4145
|
+
decisions.kv_direct, decisions.path);
|
|
4146
|
+
if (min_bytes > limit_bytes) {
|
|
4147
|
+
supports_op = false;
|
|
4148
|
+
}
|
|
4149
|
+
break;
|
|
4150
|
+
}
|
|
4151
|
+
case GGML_OP_RMS_NORM:
|
|
4152
|
+
case GGML_OP_NORM:
|
|
4153
|
+
case GGML_OP_L2_NORM:
|
|
4154
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
|
|
4155
|
+
break;
|
|
4156
|
+
case GGML_OP_ROPE:
|
|
4157
|
+
supports_op = op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16;
|
|
4158
|
+
break;
|
|
4159
|
+
case GGML_OP_GLU:
|
|
4160
|
+
switch (ggml_get_glu_op(op)) {
|
|
4161
|
+
case GGML_GLU_OP_REGLU:
|
|
4162
|
+
case GGML_GLU_OP_GEGLU:
|
|
4163
|
+
case GGML_GLU_OP_SWIGLU:
|
|
4164
|
+
case GGML_GLU_OP_GEGLU_ERF:
|
|
4165
|
+
case GGML_GLU_OP_GEGLU_QUICK:
|
|
4166
|
+
supports_op = op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16;
|
|
4167
|
+
break;
|
|
4168
|
+
case GGML_GLU_OP_SWIGLU_OAI:
|
|
4169
|
+
supports_op = op->type == GGML_TYPE_F32;
|
|
4170
|
+
break;
|
|
4171
|
+
default:
|
|
4172
|
+
break;
|
|
4173
|
+
}
|
|
4174
|
+
break;
|
|
4175
|
+
case GGML_OP_SCALE:
|
|
4176
|
+
supports_op = op->type == GGML_TYPE_F32;
|
|
4177
|
+
break;
|
|
4178
|
+
case GGML_OP_SOFT_MAX:
|
|
4179
|
+
supports_op = op->type == GGML_TYPE_F32;
|
|
4180
|
+
break;
|
|
4181
|
+
case GGML_OP_UNARY:
|
|
4182
|
+
{
|
|
4183
|
+
const ggml_unary_op UNARY_OP = ggml_get_unary_op(op);
|
|
4184
|
+
|
|
4185
|
+
switch (UNARY_OP) {
|
|
4186
|
+
case GGML_UNARY_OP_ABS:
|
|
4187
|
+
case GGML_UNARY_OP_SGN:
|
|
4188
|
+
case GGML_UNARY_OP_NEG:
|
|
4189
|
+
case GGML_UNARY_OP_STEP:
|
|
4190
|
+
case GGML_UNARY_OP_TANH:
|
|
4191
|
+
case GGML_UNARY_OP_ELU:
|
|
4192
|
+
case GGML_UNARY_OP_RELU:
|
|
4193
|
+
case GGML_UNARY_OP_SIGMOID:
|
|
4194
|
+
case GGML_UNARY_OP_GELU:
|
|
4195
|
+
case GGML_UNARY_OP_GELU_QUICK:
|
|
4196
|
+
case GGML_UNARY_OP_SILU:
|
|
4197
|
+
case GGML_UNARY_OP_HARDSWISH:
|
|
4198
|
+
case GGML_UNARY_OP_HARDSIGMOID:
|
|
4199
|
+
case GGML_UNARY_OP_EXP:
|
|
4200
|
+
case GGML_UNARY_OP_GELU_ERF:
|
|
4201
|
+
case GGML_UNARY_OP_SOFTPLUS:
|
|
4202
|
+
case GGML_UNARY_OP_EXPM1:
|
|
4203
|
+
case GGML_UNARY_OP_FLOOR:
|
|
4204
|
+
case GGML_UNARY_OP_CEIL:
|
|
4205
|
+
case GGML_UNARY_OP_ROUND:
|
|
4206
|
+
case GGML_UNARY_OP_TRUNC:
|
|
4207
|
+
case GGML_UNARY_OP_XIELU:
|
|
4208
|
+
supports_op =
|
|
4209
|
+
(op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4210
|
+
break;
|
|
4211
|
+
default:
|
|
4212
|
+
break;
|
|
4213
|
+
}
|
|
4214
|
+
}
|
|
4215
|
+
break;
|
|
4216
|
+
case GGML_OP_TRI:
|
|
4217
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
|
|
4218
|
+
break;
|
|
4219
|
+
case GGML_OP_DIAG:
|
|
4220
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
|
|
4221
|
+
break;
|
|
4222
|
+
case GGML_OP_SOLVE_TRI:
|
|
4223
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32;
|
|
4224
|
+
break;
|
|
4225
|
+
case GGML_OP_CONV_2D:
|
|
4226
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) &&
|
|
4227
|
+
(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16) &&
|
|
4228
|
+
(src1->type == GGML_TYPE_F32 || src1->type == GGML_TYPE_F16);
|
|
4229
|
+
break;
|
|
4230
|
+
case GGML_OP_IM2COL:
|
|
4231
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) &&
|
|
4232
|
+
(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16);
|
|
4233
|
+
break;
|
|
4234
|
+
case GGML_OP_SSM_CONV:
|
|
4235
|
+
supports_op = op->type == GGML_TYPE_F32;
|
|
4236
|
+
break;
|
|
4237
|
+
case GGML_OP_SSM_SCAN:
|
|
4238
|
+
supports_op = op->type == GGML_TYPE_F32 &&
|
|
4239
|
+
src0->ne[0] <= ctx->webgpu_global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
4240
|
+
break;
|
|
4241
|
+
case GGML_OP_GATED_DELTA_NET:
|
|
4242
|
+
{
|
|
4243
|
+
const uint32_t s_v = (uint32_t) src2->ne[0];
|
|
4244
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32 &&
|
|
4245
|
+
src2->type == GGML_TYPE_F32 && op->src[3]->type == GGML_TYPE_F32 &&
|
|
4246
|
+
op->src[4]->type == GGML_TYPE_F32 && op->src[5]->type == GGML_TYPE_F32 &&
|
|
4247
|
+
s_v <= ctx->webgpu_global_ctx->capabilities.limits.maxComputeInvocationsPerWorkgroup;
|
|
4248
|
+
}
|
|
4249
|
+
break;
|
|
4250
|
+
case GGML_OP_CLAMP:
|
|
4251
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4252
|
+
break;
|
|
4253
|
+
case GGML_OP_FILL:
|
|
4254
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
|
|
4255
|
+
break;
|
|
4256
|
+
case GGML_OP_LOG:
|
|
4257
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4258
|
+
break;
|
|
4259
|
+
case GGML_OP_SQR:
|
|
4260
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4261
|
+
break;
|
|
4262
|
+
case GGML_OP_SQRT:
|
|
4263
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4264
|
+
break;
|
|
4265
|
+
case GGML_OP_SIN:
|
|
4266
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4267
|
+
break;
|
|
4268
|
+
case GGML_OP_COS:
|
|
4269
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) && (src0->type == op->type);
|
|
4270
|
+
break;
|
|
4271
|
+
case GGML_OP_PAD:
|
|
4272
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == GGML_TYPE_F32;
|
|
4273
|
+
break;
|
|
4274
|
+
case GGML_OP_ARGMAX:
|
|
4275
|
+
supports_op = op->type == GGML_TYPE_I32 && src0->type == GGML_TYPE_F32;
|
|
4276
|
+
break;
|
|
4277
|
+
case GGML_OP_ARGSORT:
|
|
4278
|
+
supports_op = op->type == GGML_TYPE_I32 && src0->type == GGML_TYPE_F32 && ggml_is_contiguous_rows(src0);
|
|
4279
|
+
break;
|
|
4280
|
+
case GGML_OP_TOP_K:
|
|
4281
|
+
supports_op = op->type == GGML_TYPE_I32 && src0->type == GGML_TYPE_F32 && ggml_is_contiguous_rows(src0);
|
|
4282
|
+
break;
|
|
4283
|
+
case GGML_OP_CUMSUM:
|
|
4284
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == op->type;
|
|
4285
|
+
break;
|
|
4286
|
+
case GGML_OP_SUM:
|
|
4287
|
+
case GGML_OP_SUM_ROWS:
|
|
4288
|
+
supports_op = op->type == GGML_TYPE_F32 && src0->type == op->type && ggml_is_contiguous_rows(src0);
|
|
4289
|
+
break;
|
|
4290
|
+
case GGML_OP_UPSCALE:
|
|
4291
|
+
supports_op = (op->type == GGML_TYPE_F32 || op->type == GGML_TYPE_F16) &&
|
|
4292
|
+
(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16);
|
|
4293
|
+
break;
|
|
4294
|
+
default:
|
|
4295
|
+
break;
|
|
4296
|
+
}
|
|
4297
|
+
if (ggml_nbytes(op) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize ||
|
|
4298
|
+
(src0 != nullptr &&
|
|
4299
|
+
ggml_nbytes(src0) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize) ||
|
|
4300
|
+
(src1 != nullptr &&
|
|
4301
|
+
ggml_nbytes(src1) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize) ||
|
|
4302
|
+
(src2 != nullptr &&
|
|
4303
|
+
ggml_nbytes(src2) > ctx->webgpu_global_ctx->capabilities.limits.maxStorageBufferBindingSize)) {
|
|
4304
|
+
supports_op = false;
|
|
4305
|
+
WEBGPU_LOG_DEBUG("ggml_webgpu op not supported due to size: ");
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
if (!supports_op) {
|
|
4309
|
+
WEBGPU_LOG_DEBUG("ggml_webgpu op not supported: "
|
|
4310
|
+
<< ggml_op_name(op->op) << " with types dst: " << ggml_type_name(op->type)
|
|
4311
|
+
<< ", src0: " << (op->src[0] ? ggml_type_name(op->src[0]->type) : "null")
|
|
4312
|
+
<< ", src1: " << (op->src[1] ? ggml_type_name(op->src[1]->type) : "null"));
|
|
4313
|
+
} else {
|
|
4314
|
+
WEBGPU_LOG_DEBUG("ggml_webgpu op supported: "
|
|
4315
|
+
<< ggml_op_name(op->op) << " with types dst: " << ggml_type_name(op->type)
|
|
4316
|
+
<< ", src0: " << (op->src[0] ? ggml_type_name(op->src[0]->type) : "null")
|
|
4317
|
+
<< ", src1: " << (op->src[1] ? ggml_type_name(op->src[1]->type) : "null"));
|
|
4318
|
+
}
|
|
4319
|
+
return supports_op;
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
static struct ggml_backend_device_i ggml_backend_webgpu_device_i = {
|
|
4323
|
+
/* .get_name = */ ggml_backend_webgpu_device_get_name,
|
|
4324
|
+
/* .get_description = */ ggml_backend_webgpu_device_get_description,
|
|
4325
|
+
/* .get_memory = */ ggml_backend_webgpu_device_get_memory,
|
|
4326
|
+
/* .get_type = */ ggml_backend_webgpu_device_get_type,
|
|
4327
|
+
/* .get_props = */ ggml_backend_webgpu_device_get_props,
|
|
4328
|
+
/* .init_backend = */ ggml_backend_webgpu_backend_init,
|
|
4329
|
+
/* .get_buffer_type = */ ggml_backend_webgpu_device_get_buffer_type,
|
|
4330
|
+
/* .get_host_buffer_type = */ NULL,
|
|
4331
|
+
/* .buffer_from_host_ptr = */ NULL,
|
|
4332
|
+
/* .supports_op = */ ggml_backend_webgpu_device_supports_op,
|
|
4333
|
+
/* .supports_buft = */ ggml_backend_webgpu_device_supports_buft,
|
|
4334
|
+
/* .offload_op = */ NULL,
|
|
4335
|
+
/* .event_new = */ ggml_backend_webgpu_device_event_new,
|
|
4336
|
+
/* .event_free = */ ggml_backend_webgpu_device_event_free,
|
|
4337
|
+
/* .event_synchronize = */ ggml_backend_webgpu_device_event_synchronize,
|
|
4338
|
+
};
|
|
4339
|
+
|
|
4340
|
+
/* End GGML Backend Device Interface */
|
|
4341
|
+
|
|
4342
|
+
/* GGML Backend Registration Interface */
|
|
4343
|
+
|
|
4344
|
+
static const char * ggml_backend_webgpu_reg_get_name(ggml_backend_reg_t reg) {
|
|
4345
|
+
ggml_backend_webgpu_reg_context * ctx = static_cast<ggml_backend_webgpu_reg_context *>(reg->context);
|
|
4346
|
+
return ctx->name;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
static size_t ggml_backend_webgpu_reg_get_device_count(ggml_backend_reg_t reg) {
|
|
4350
|
+
ggml_backend_webgpu_reg_context * ctx = static_cast<ggml_backend_webgpu_reg_context *>(reg->context);
|
|
4351
|
+
return ctx->device_count;
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
// Only one device is supported for now
|
|
4355
|
+
static ggml_backend_dev_t ggml_backend_webgpu_reg_get_device(ggml_backend_reg_t reg, size_t index) {
|
|
4356
|
+
GGML_ASSERT(index == 0);
|
|
4357
|
+
WEBGPU_LOG_DEBUG("ggml_backend_reg_get_device()");
|
|
4358
|
+
|
|
4359
|
+
WEBGPU_CPU_PROFILE_TOTAL_START(reg_get_device);
|
|
4360
|
+
|
|
4361
|
+
ggml_backend_webgpu_reg_context * reg_ctx = static_cast<ggml_backend_webgpu_reg_context *>(reg->context);
|
|
4362
|
+
|
|
4363
|
+
create_webgpu_device(reg_ctx);
|
|
4364
|
+
|
|
4365
|
+
static ggml_backend_webgpu_device_context device_ctx;
|
|
4366
|
+
device_ctx.device_name = GGML_WEBGPU_NAME;
|
|
4367
|
+
device_ctx.device_desc = GGML_WEBGPU_NAME;
|
|
4368
|
+
device_ctx.webgpu_global_ctx = reg_ctx->webgpu_global_ctx;
|
|
4369
|
+
// See GGML Backend Device Interface section
|
|
4370
|
+
static ggml_backend_device device = {
|
|
4371
|
+
/* .iface = */ ggml_backend_webgpu_device_i,
|
|
4372
|
+
/* .reg = */ reg,
|
|
4373
|
+
/* .context = */ &device_ctx,
|
|
4374
|
+
};
|
|
4375
|
+
|
|
4376
|
+
WEBGPU_CPU_PROFILE_TOTAL_END(reg_get_device, reg_ctx->webgpu_global_ctx);
|
|
4377
|
+
return &device;
|
|
4378
|
+
}
|
|
4379
|
+
|
|
4380
|
+
static const struct ggml_backend_reg_i ggml_backend_webgpu_reg_i = {
|
|
4381
|
+
/* .get_name = */ ggml_backend_webgpu_reg_get_name,
|
|
4382
|
+
/* .get_device_count = */ ggml_backend_webgpu_reg_get_device_count,
|
|
4383
|
+
/* .get_device = */ ggml_backend_webgpu_reg_get_device,
|
|
4384
|
+
/* .get_proc_address = */ NULL,
|
|
4385
|
+
};
|
|
4386
|
+
|
|
4387
|
+
/* End GGML Backend Registration Interface */
|
|
4388
|
+
|
|
4389
|
+
ggml_backend_reg_t ggml_backend_webgpu_reg() {
|
|
4390
|
+
WEBGPU_LOG_DEBUG("ggml_backend_webgpu_reg()");
|
|
4391
|
+
|
|
4392
|
+
// Intentionally leak the global registry context to avoid crashing inside
|
|
4393
|
+
// Dawn/Vulkan static teardown during process exit.
|
|
4394
|
+
static ggml_backend_webgpu_reg_context * ctx = new ggml_backend_webgpu_reg_context();
|
|
4395
|
+
|
|
4396
|
+
static ggml_backend_reg reg = {
|
|
4397
|
+
/* .api_version = */ GGML_BACKEND_API_VERSION,
|
|
4398
|
+
/* .iface = */ ggml_backend_webgpu_reg_i,
|
|
4399
|
+
/* .context = */ ctx,
|
|
4400
|
+
};
|
|
4401
|
+
|
|
4402
|
+
ctx->name = GGML_WEBGPU_NAME;
|
|
4403
|
+
ctx->device_count = 0;
|
|
4404
|
+
|
|
4405
|
+
// Keep one Dawn/WebGPU instance alive for the lifetime of the static backend
|
|
4406
|
+
// registry. Recreating it on repeated registry lookups can invalidate
|
|
4407
|
+
// adapter/device references that are still held by the backend/device layer.
|
|
4408
|
+
if (ctx->webgpu_global_ctx != nullptr && ctx->webgpu_global_ctx->instance != nullptr) {
|
|
4409
|
+
return ®
|
|
4410
|
+
}
|
|
4411
|
+
|
|
4412
|
+
wgpu::InstanceDescriptor instance_descriptor{};
|
|
4413
|
+
std::vector<wgpu::InstanceFeatureName> instance_features = { wgpu::InstanceFeatureName::TimedWaitAny };
|
|
4414
|
+
instance_descriptor.requiredFeatures = instance_features.data();
|
|
4415
|
+
instance_descriptor.requiredFeatureCount = instance_features.size();
|
|
4416
|
+
|
|
4417
|
+
#ifndef __EMSCRIPTEN__
|
|
4418
|
+
const char * const instanceEnabledToggles[] = { "allow_unsafe_apis" };
|
|
4419
|
+
wgpu::DawnTogglesDescriptor instanceTogglesDesc;
|
|
4420
|
+
instanceTogglesDesc.enabledToggles = instanceEnabledToggles;
|
|
4421
|
+
instanceTogglesDesc.enabledToggleCount = 1;
|
|
4422
|
+
instance_descriptor.nextInChain = &instanceTogglesDesc;
|
|
4423
|
+
#endif
|
|
4424
|
+
|
|
4425
|
+
wgpu::Instance inst = wgpu::CreateInstance(&instance_descriptor);
|
|
4426
|
+
ctx->webgpu_global_ctx = webgpu_global_context(new webgpu_global_context_struct());
|
|
4427
|
+
ctx->webgpu_global_ctx->instance = std::move(inst);
|
|
4428
|
+
|
|
4429
|
+
// Probe for adapter support
|
|
4430
|
+
wgpu::Adapter adapter;
|
|
4431
|
+
if (ctx->webgpu_global_ctx->instance != nullptr) {
|
|
4432
|
+
wgpu::RequestAdapterOptions options = {};
|
|
4433
|
+
|
|
4434
|
+
// probe for adapter support
|
|
4435
|
+
ctx->webgpu_global_ctx->instance.WaitAny(
|
|
4436
|
+
ctx->webgpu_global_ctx->instance.RequestAdapter(
|
|
4437
|
+
&options, wgpu::CallbackMode::AllowSpontaneous,
|
|
4438
|
+
[&adapter](wgpu::RequestAdapterStatus status, wgpu::Adapter _adapter, const char * message) {
|
|
4439
|
+
if (status != wgpu::RequestAdapterStatus::Success) {
|
|
4440
|
+
GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
|
|
4441
|
+
return;
|
|
4442
|
+
}
|
|
4443
|
+
adapter = std::move(_adapter);
|
|
4444
|
+
}),
|
|
4445
|
+
UINT64_MAX);
|
|
4446
|
+
}
|
|
4447
|
+
|
|
4448
|
+
if (adapter != nullptr) {
|
|
4449
|
+
ctx->device_count = 1;
|
|
4450
|
+
}
|
|
4451
|
+
|
|
4452
|
+
return ®
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
ggml_backend_t ggml_backend_webgpu_init(void) {
|
|
4456
|
+
ggml_backend_dev_t dev = ggml_backend_reg_dev_get(ggml_backend_webgpu_reg(), 0);
|
|
4457
|
+
|
|
4458
|
+
return ggml_backend_webgpu_backend_init(dev, nullptr);
|
|
4459
|
+
}
|
|
4460
|
+
|
|
4461
|
+
GGML_BACKEND_DL_IMPL(ggml_backend_webgpu_reg)
|