diff --git a/.devops/nix/package-gguf-py.nix b/.devops/nix/package-gguf-py.nix
deleted file mode 100644
index cca2f36a5..000000000
--- a/.devops/nix/package-gguf-py.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- lib,
- llamaVersion,
- numpy,
- tqdm,
- sentencepiece,
- pyyaml,
- poetry-core,
- buildPythonPackage,
- pytestCheckHook,
-}:
-
-buildPythonPackage {
- pname = "gguf";
- version = llamaVersion;
- pyproject = true;
- nativeBuildInputs = [ poetry-core ];
- propagatedBuildInputs = [
- numpy
- tqdm
- sentencepiece
- pyyaml
- ];
- src = lib.cleanSource ../../gguf-py;
- pythonImportsCheck = [
- "numpy"
- "gguf"
- ];
- nativeCheckInputs = [ pytestCheckHook ];
- doCheck = true;
- meta = with lib; {
- description = "Python package for writing binary files in the GGUF format";
- license = licenses.mit;
- maintainers = [ maintainers.ditsuke ];
- };
-}
diff --git a/.devops/nix/python-scripts.nix b/.devops/nix/python-scripts.nix
deleted file mode 100644
index 56ea18278..000000000
--- a/.devops/nix/python-scripts.nix
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- lib,
- stdenv,
- buildPythonPackage,
- poetry-core,
- mkShell,
- python3Packages,
- gguf-py,
-}@inputs:
-
-let
- llama-python-deps = with python3Packages; [
- numpy
- sentencepiece
- transformers
- protobuf
- torchWithoutCuda
- gguf-py
- tqdm
-
- # for scripts/compare-llama-bench.py
- gitpython
- tabulate
-
- # for examples/pydantic-models-to-grammar-examples.py
- docstring-parser
- pydantic
-
- ];
-
- llama-python-test-deps = with python3Packages; [
- # Server bench
- matplotlib
-
- # server tests
- openai
- pytest
- prometheus-client
- ];
-in
-
-buildPythonPackage ({
- pname = "llama-scripts";
- version = "0.0.0";
- pyproject = true;
-
- # NOTE: The files filtered out here are not visible in the build sandbox, neither
- # do they affect the output hash. They can be modified without triggering a rebuild.
- src = lib.cleanSourceWith {
- filter =
- name: type:
- let
- any = builtins.any (x: x);
- baseName = builtins.baseNameOf name;
- in
- any [
- (lib.hasSuffix ".py" name)
- (baseName == "README.md")
- (baseName == "pyproject.toml")
- ];
- src = lib.cleanSource ../../.;
- };
- nativeBuildInputs = [ poetry-core ];
- nativeCheckInputs = llama-python-test-deps;
- dependencies = llama-python-deps;
-})
diff --git a/.github/actions/windows-setup-curl/action.yml b/.github/actions/windows-setup-curl/action.yml
deleted file mode 100644
index 5d76da3d7..000000000
--- a/.github/actions/windows-setup-curl/action.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: 'Windows - Setup CURL'
-description: 'Composite action, to be reused in other workflow'
-inputs:
- curl_version:
- description: 'CURL version'
- required: false
- default: '8.6.0_6'
-outputs:
- curl_path:
- description: "Path to the downloaded libcurl"
- value: ${{ steps.get_libcurl.outputs.curl_path }}
-
-runs:
- using: "composite"
- steps:
- - name: libCURL
- id: get_libcurl
- shell: powershell
- env:
- CURL_VERSION: ${{ inputs.curl_version }}
- run: |
- curl.exe -o $env:RUNNER_TEMP/curl.zip -L "https://curl.se/windows/dl-${env:CURL_VERSION}/curl-${env:CURL_VERSION}-win64-mingw.zip"
- mkdir $env:RUNNER_TEMP/libcurl
- tar.exe -xvf $env:RUNNER_TEMP/curl.zip --strip-components=1 -C $env:RUNNER_TEMP/libcurl
- echo "curl_path=$env:RUNNER_TEMP/libcurl" >> $env:GITHUB_OUTPUT
diff --git a/docs/backend/OPENCL.md b/docs/backend/OPENCL.md
deleted file mode 100644
index 07146f710..000000000
--- a/docs/backend/OPENCL.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# llama.cpp for OpenCL
-
-- [Background](#background)
-- [OS](#os)
-- [Hardware](#hardware)
-- [DataType Supports](#datatype-supports)
-- [Model Preparation](#model-preparation)
-- [CMake Options](#cmake-options)
-- [Android](#android)
-- [Windows 11 Arm64](#windows-11-arm64)
-- [Known Issue](#known-issues)
-- [TODO](#todo)
-
-## Background
-
-OpenCL (Open Computing Language) is an open, royalty-free standard for cross-platform, parallel programming of diverse accelerators found in supercomputers, cloud servers, personal computers, mobile devices and embedded platforms. OpenCL specifies a programming language (based on C99) for programming these devices and application programming interfaces (APIs) to control the platform and execute programs on the compute devices. Similar to CUDA, OpenCL has been widely used to program GPUs and is supported by most GPU vendors.
-
-### Llama.cpp + OpenCL
-
-The llama.cpp OpenCL backend is designed to enable llama.cpp on **Qualcomm Adreno GPU** firstly via OpenCL. Thanks to the portabilty of OpenCL, the OpenCL backend can also run on certain Intel GPUs although the performance is not optimal.
-
-## OS
-
-| OS | Status | Verified |
-|---------|---------|------------------------------------------------|
-| Android | Support | Snapdragon 8 Gen 3, Snapdragon 8 Elite |
-| Windows | Support | Windows 11 Arm64 with Snapdragon X Elite |
-| Linux | Support | Ubuntu 22.04 WSL2 with Intel 12700H |
-
-## Hardware
-
-### Adreno GPU
-
-**Verified devices**
-
-| Adreno GPU | Status |
-|:------------------------------------:|:-------:|
-| Adreno 750 (Snapdragon 8 Gen 3) | Support |
-| Adreno 830 (Snapdragon 8 Elite) | Support |
-| Adreno X85 (Snapdragon X Elite) | Support |
-
-## DataType Supports
-
-| DataType | Status |
-|:----------------------:|:--------------------------:|
-| Q4_0 | Support |
-| Q6_K | Support, but not optimized |
-
-## Model Preparation
-
-You can refer to the general [*Prepare and Quantize*](README.md#prepare-and-quantize) guide for model prepration.
-
-Currently we support `Q4_0` quantization and have optimize for it. To achieve best performance on Adreno GPU, add `--pure` to `llama-quantize`. For example,
-
-```sh
-./llama-quantize --pure ggml-model-qwen2.5-3b-f16.gguf ggml-model-qwen-3b-Q4_0.gguf Q4_0
-```
-
-Since `Q6_K` is also supported, `Q4_0` quantization without `--pure` will also work. However, the performance will be worse compared to pure `Q4_0` quantization.
-
-## CMake Options
-
-The OpenCL backend has the following CMake options that control the behavior of the backend.
-
-| CMake options | Default value | Description |
-|:---------------------------------:|:--------------:|:------------------------------------------|
-| `GGML_OPENCL_EMBED_KERNELS` | `ON` | Embed OpenCL kernels into the executable. |
-| `GGML_OPENCL_USE_ADRENO_KERNELS` | `ON` | Use kernels optimized for Adreno. |
-
-## Android
-
-Ubuntu 22.04 is used for targeting Android. Make sure the following tools are accessible from command line,
-
-* Git
-* CMake 3.29
-* Ninja
-* Python3
-
-### I. Setup Environment
-
-1. **Install NDK**
-
-```sh
-cd ~
-wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip && \
-unzip commandlinetools-linux-8512546_latest.zip && \
-mkdir -p ~/android-sdk/cmdline-tools && \
-mv cmdline-tools latest && \
-mv latest ~/android-sdk/cmdline-tools/ && \
-rm -rf commandlinetools-linux-8512546_latest.zip
-
-yes | ~/android-sdk/cmdline-tools/latest/bin/sdkmanager "ndk;26.3.11579264"
-```
-
-2. **Install OpenCL Headers and Library**
-
-```sh
-mkdir -p ~/dev/llm
-cd ~/dev/llm
-
-git clone https://github.com/KhronosGroup/OpenCL-Headers && \
-cd OpenCL-Headers && \
-cp -r CL ~/android-sdk/ndk/26.3.11579264/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include
-
-cd ~/dev/llm
-
-git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader && \
-cd OpenCL-ICD-Loader && \
-mkdir build_ndk26 && cd build_ndk26 && \
-cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_TOOLCHAIN_FILE=$HOME/android-sdk/ndk/26.3.11579264/build/cmake/android.toolchain.cmake \
- -DOPENCL_ICD_LOADER_HEADERS_DIR=$HOME/android-sdk/ndk/26.3.11579264/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include \
- -DANDROID_ABI=arm64-v8a \
- -DANDROID_PLATFORM=24 \
- -DANDROID_STL=c++_shared && \
-ninja && \
-cp libOpenCL.so ~/android-sdk/ndk/26.3.11579264/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android
-```
-
-### II. Build llama.cpp
-
-```sh
-cd ~/dev/llm
-
-git clone https://github.com/ggml-org/llama.cpp && \
-cd llama.cpp && \
-mkdir build-android && cd build-android
-
-cmake .. -G Ninja \
- -DCMAKE_TOOLCHAIN_FILE=$HOME/android-sdk/ndk/26.3.11579264/build/cmake/android.toolchain.cmake \
- -DANDROID_ABI=arm64-v8a \
- -DANDROID_PLATFORM=android-28 \
- -DBUILD_SHARED_LIBS=OFF \
- -DGGML_OPENCL=ON
-
-ninja
-```
-
-## Windows 11 Arm64
-
-A Snapdragon X Elite device with Windows 11 Arm64 is used. Make sure the following tools are accessible from command line,
-
-* Git
-* CMake 3.29
-* Clang 19
-* Ninja
-* Visual Studio 2022
-* Powershell 7
-
-Visual Studio provides necessary headers and libraries although it is not directly used for building.
-Alternatively, Visual Studio Build Tools can be installed instead of the full Visual Studio.
-
-Powershell 7 is used for the following commands.
-If an older version of Powershell is used, these commands may not work as they are.
-
-### I. Setup Environment
-
-1. **Install OpenCL Headers and Library**
-
-```powershell
-mkdir -p ~/dev/llm
-
-cd ~/dev/llm
-git clone https://github.com/KhronosGroup/OpenCL-Headers && cd OpenCL-Headers
-mkdir build && cd build
-cmake .. -G Ninja `
- -DBUILD_TESTING=OFF `
- -DOPENCL_HEADERS_BUILD_TESTING=OFF `
- -DOPENCL_HEADERS_BUILD_CXX_TESTS=OFF `
- -DCMAKE_INSTALL_PREFIX="$HOME/dev/llm/opencl"
-cmake --build . --target install
-
-cd ~/dev/llm
-git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader && cd OpenCL-ICD-Loader
-mkdir build && cd build
-cmake .. -G Ninja `
- -DCMAKE_BUILD_TYPE=Release `
- -DCMAKE_PREFIX_PATH="$HOME/dev/llm/opencl" `
- -DCMAKE_INSTALL_PREFIX="$HOME/dev/llm/opencl"
-cmake --build . --target install
-```
-
-### II. Build llama.cpp
-
-```powershell
-
-mkdir -p ~/dev/llm
-cd ~/dev/llm
-
-git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
-mkdir build && cd build
-
-cmake .. -G Ninja `
- -DCMAKE_TOOLCHAIN_FILE="$HOME/dev/llm/llama.cpp/cmake/arm64-windows-llvm.cmake" `
- -DCMAKE_BUILD_TYPE=Release `
- -DCMAKE_PREFIX_PATH="$HOME/dev/llm/opencl" `
- -DBUILD_SHARED_LIBS=OFF `
- -DGGML_OPENCL=ON
-ninja
-```
-
-## Known Issues
-
-- Currently OpenCL backend does not work on Adreno 6xx GPUs.
-
-## TODO
-
-- Optimization for Q6_K
-- Support and optimization for Q4_K
diff --git a/docs/function-calling.md b/docs/function-calling.md
deleted file mode 100644
index c3873c3fa..000000000
--- a/docs/function-calling.md
+++ /dev/null
@@ -1,394 +0,0 @@
-# Function Calling
-
-[chat.h](../common/chat.h) (https://github.com/ggml-org/llama.cpp/pull/9639) adds support for [OpenAI-style function calling](https://platform.openai.com/docs/guides/function-calling) and is used in:
-- `llama-server` when started w/ `--jinja` flag
-- `llama-cli` (WIP: https://github.com/ggml-org/llama.cpp/pull/11556)
-
-## Universal support w/ Native & Generic handlers
-
-Function calling is supported for all models (see https://github.com/ggml-org/llama.cpp/pull/9639):
-
-- Native tool call formats supported:
- - Llama 3.1 / 3.3 (including builtin tools support - tool names for `wolfram_alpha`, `web_search` / `brave_search`, `code_interpreter`), Llama 3.2
- - Functionary v3.1 / v3.2
- - Hermes 2/3, Qwen 2.5
- - Qwen 2.5 Coder (WIP: https://github.com/ggml-org/llama.cpp/pull/12034)
- - Mistral Nemo
- - Firefunction v2
- - Command R7B
- - DeepSeek R1 (WIP / seems reluctant to call any tools?)
-
-- Generic tool call is supported when the template isn't recognized by native format handlers (you'll see `Chat format: Generic` in the logs).
- - Use `--chat-template-file` to override the template when appropriate (see examples below)
- - Generic support may consume more tokens and be less efficient than a model's native format.
-
-
-Show some common templates and which format handler they use
-
-| Template | Format |
-|----------|--------|
-| Almawave-Velvet-14B.jinja | Hermes 2 Pro |
-| AtlaAI-Selene-1-Mini-Llama-3.1-8B.jinja | Llama 3.x |
-| CohereForAI-aya-expanse-8b.jinja | Generic |
-| CohereForAI-c4ai-command-r-plus-default.jinja | Generic |
-| CohereForAI-c4ai-command-r-plus-rag.jinja | Generic |
-| CohereForAI-c4ai-command-r-plus-tool_use.jinja | Generic |
-| CohereForAI-c4ai-command-r7b-12-2024-default.jinja | Command R7B (extract reasoning) |
-| CohereForAI-c4ai-command-r7b-12-2024-rag.jinja | Command R7B (extract reasoning) |
-| CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja | Command R7B (extract reasoning) |
-| CohereForAI-c4ai-command-r7b-12-2024.jinja | Generic |
-| DavieLion-Llama-3.2-1B-SPIN-iter3.jinja | Generic |
-| Delta-Vector-Rei-12B.jinja | Mistral Nemo |
-| EpistemeAI-Mistral-Nemo-Instruct-12B-Philosophy-Math.jinja | Mistral Nemo |
-| FlofloB-83k_continued_pretraining_Qwen2.5-0.5B-Instruct_Unsloth_merged_16bit.jinja | Hermes 2 Pro |
-| FlofloB-test_continued_pretraining_Phi-3-mini-4k-instruct_Unsloth_merged_16bit.jinja | Generic |
-| HelpingAI-HAI-SER.jinja | Generic |
-| HuggingFaceTB-SmolLM2-1.7B-Instruct.jinja | Generic |
-| HuggingFaceTB-SmolLM2-135M-Instruct.jinja | Generic |
-| HuggingFaceTB-SmolLM2-360M-Instruct.jinja | Generic |
-| INSAIT-Institute-BgGPT-Gemma-2-27B-IT-v1.0.jinja | Generic |
-| Ihor-Text2Graph-R1-Qwen2.5-0.5b.jinja | Hermes 2 Pro |
-| Infinigence-Megrez-3B-Instruct.jinja | Generic |
-| Josephgflowers-TinyLlama_v1.1_math_code-world-test-1.jinja | Generic |
-| LGAI-EXAONE-EXAONE-3.5-2.4B-Instruct.jinja | Generic |
-| LGAI-EXAONE-EXAONE-3.5-7.8B-Instruct.jinja | Generic |
-| LatitudeGames-Wayfarer-12B.jinja | Generic |
-| Magpie-Align-Llama-3-8B-Magpie-Align-v0.1.jinja | Generic |
-| Magpie-Align-Llama-3.1-8B-Magpie-Align-v0.1.jinja | Generic |
-| MaziyarPanahi-calme-3.2-instruct-78b.jinja | Generic |
-| MiniMaxAI-MiniMax-Text-01.jinja | Generic |
-| MiniMaxAI-MiniMax-VL-01.jinja | Generic |
-| NaniDAO-deepseek-r1-qwen-2.5-32B-ablated.jinja | DeepSeek R1 (extract reasoning) |
-| NexaAIDev-Octopus-v2.jinja | Generic |
-| NousResearch-Hermes-2-Pro-Llama-3-8B-default.jinja | Generic |
-| NousResearch-Hermes-2-Pro-Llama-3-8B-tool_use.jinja | Hermes 2 Pro |
-| NousResearch-Hermes-2-Pro-Mistral-7B-default.jinja | Generic |
-| NousResearch-Hermes-2-Pro-Mistral-7B-tool_use.jinja | Hermes 2 Pro |
-| NousResearch-Hermes-3-Llama-3.1-70B-default.jinja | Generic |
-| NousResearch-Hermes-3-Llama-3.1-70B-tool_use.jinja | Hermes 2 Pro |
-| NovaSky-AI-Sky-T1-32B-Flash.jinja | Hermes 2 Pro |
-| NovaSky-AI-Sky-T1-32B-Preview.jinja | Hermes 2 Pro |
-| OnlyCheeini-greesychat-turbo.jinja | Generic |
-| Orenguteng-Llama-3.1-8B-Lexi-Uncensored-V2.jinja | Llama 3.x |
-| OrionStarAI-Orion-14B-Chat.jinja | Generic |
-| PowerInfer-SmallThinker-3B-Preview.jinja | Generic |
-| PrimeIntellect-INTELLECT-1-Instruct.jinja | Generic |
-| Qwen-QVQ-72B-Preview.jinja | Generic |
-| Qwen-QwQ-32B-Preview.jinja | Hermes 2 Pro |
-| Qwen-Qwen1.5-7B-Chat.jinja | Generic |
-| Qwen-Qwen2-7B-Instruct.jinja | Generic |
-| Qwen-Qwen2-VL-72B-Instruct.jinja | Generic |
-| Qwen-Qwen2-VL-7B-Instruct.jinja | Generic |
-| Qwen-Qwen2.5-0.5B.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-1.5B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-14B-Instruct-1M.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-14B.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-32B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-32B.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-3B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-72B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-7B-Instruct-1M.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-7B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-7B.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-Coder-32B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-Coder-7B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-Math-1.5B.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-Math-7B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-VL-3B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-VL-72B-Instruct.jinja | Hermes 2 Pro |
-| Qwen-Qwen2.5-VL-7B-Instruct.jinja | Hermes 2 Pro |
-| RWKV-Red-Team-ARWKV-7B-Preview-0.1.jinja | Hermes 2 Pro |
-| SakanaAI-TinySwallow-1.5B-Instruct.jinja | Hermes 2 Pro |
-| SakanaAI-TinySwallow-1.5B.jinja | Hermes 2 Pro |
-| Sao10K-70B-L3.3-Cirrus-x1.jinja | Llama 3.x |
-| SentientAGI-Dobby-Mini-Leashed-Llama-3.1-8B.jinja | Llama 3.x |
-| SentientAGI-Dobby-Mini-Unhinged-Llama-3.1-8B.jinja | Llama 3.x |
-| Steelskull-L3.3-Damascus-R1.jinja | Llama 3.x |
-| Steelskull-L3.3-MS-Nevoria-70b.jinja | Llama 3.x |
-| Steelskull-L3.3-Nevoria-R1-70b.jinja | Llama 3.x |
-| THUDM-glm-4-9b-chat.jinja | Generic |
-| THUDM-glm-edge-1.5b-chat.jinja | Generic |
-| Tarek07-Progenitor-V1.1-LLaMa-70B.jinja | Llama 3.x |
-| TheBloke-FusionNet_34Bx2_MoE-AWQ.jinja | Generic |
-| TinyLlama-TinyLlama-1.1B-Chat-v1.0.jinja | Generic |
-| UCLA-AGI-Mistral7B-PairRM-SPPO-Iter3.jinja | Generic |
-| ValiantLabs-Llama3.1-8B-Enigma.jinja | Llama 3.x |
-| abacusai-Fewshot-Metamath-OrcaVicuna-Mistral.jinja | Generic |
-| ai21labs-AI21-Jamba-1.5-Large.jinja | Generic |
-| allenai-Llama-3.1-Tulu-3-405B-SFT.jinja | Generic |
-| allenai-Llama-3.1-Tulu-3-405B.jinja | Generic |
-| allenai-Llama-3.1-Tulu-3-8B.jinja | Generic |
-| arcee-ai-Virtuoso-Lite.jinja | Hermes 2 Pro |
-| arcee-ai-Virtuoso-Medium-v2.jinja | Hermes 2 Pro |
-| arcee-ai-Virtuoso-Small-v2.jinja | Hermes 2 Pro |
-| avemio-GRAG-NEMO-12B-ORPO-HESSIAN-AI.jinja | Generic |
-| bespokelabs-Bespoke-Stratos-7B.jinja | Hermes 2 Pro |
-| bfuzzy1-acheron-m1a-llama.jinja | Generic |
-| bofenghuang-vigogne-2-70b-chat.jinja | Generic |
-| bytedance-research-UI-TARS-72B-DPO.jinja | Generic |
-| bytedance-research-UI-TARS-7B-DPO.jinja | Generic |
-| bytedance-research-UI-TARS-7B-SFT.jinja | Generic |
-| carsenk-phi3.5_mini_exp_825_uncensored.jinja | Generic |
-| cyberagent-DeepSeek-R1-Distill-Qwen-14B-Japanese.jinja | DeepSeek R1 (extract reasoning) |
-| cyberagent-DeepSeek-R1-Distill-Qwen-32B-Japanese.jinja | DeepSeek R1 (extract reasoning) |
-| databricks-dbrx-instruct.jinja | Generic |
-| deepseek-ai-DeepSeek-Coder-V2-Instruct.jinja | Generic |
-| deepseek-ai-DeepSeek-Coder-V2-Lite-Base.jinja | Generic |
-| deepseek-ai-DeepSeek-Coder-V2-Lite-Instruct.jinja | Generic |
-| deepseek-ai-DeepSeek-R1-Distill-Llama-70B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Distill-Llama-8B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Distill-Qwen-1.5B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Distill-Qwen-14B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Distill-Qwen-32B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Distill-Qwen-7B.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1-Zero.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-R1.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-V2-Lite.jinja | Generic |
-| deepseek-ai-DeepSeek-V2.5.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-DeepSeek-V3.jinja | DeepSeek R1 (extract reasoning) |
-| deepseek-ai-deepseek-coder-33b-instruct.jinja | Generic |
-| deepseek-ai-deepseek-coder-6.7b-instruct.jinja | Generic |
-| deepseek-ai-deepseek-coder-7b-instruct-v1.5.jinja | Generic |
-| deepseek-ai-deepseek-llm-67b-chat.jinja | Generic |
-| deepseek-ai-deepseek-llm-7b-chat.jinja | Generic |
-| dicta-il-dictalm2.0-instruct.jinja | Generic |
-| ehristoforu-Falcon3-8B-Franken-Basestruct.jinja | Hermes 2 Pro |
-| fireworks-ai-llama-3-firefunction-v2.jinja | FireFunction v2 |
-| godlikehhd-alpaca_data_sampled_ifd_new_5200.jinja | Hermes 2 Pro |
-| godlikehhd-alpaca_data_score_max_0.7_2600.jinja | Hermes 2 Pro |
-| google-gemma-2-27b-it.jinja | Generic |
-| google-gemma-2-2b-it.jinja | Generic |
-| google-gemma-2-2b-jpn-it.jinja | Generic |
-| google-gemma-7b-it.jinja | Generic |
-| huihui-ai-DeepSeek-R1-Distill-Llama-70B-abliterated.jinja | DeepSeek R1 (extract reasoning) |
-| huihui-ai-DeepSeek-R1-Distill-Llama-8B-abliterated.jinja | DeepSeek R1 (extract reasoning) |
-| huihui-ai-DeepSeek-R1-Distill-Qwen-14B-abliterated-v2.jinja | DeepSeek R1 (extract reasoning) |
-| huihui-ai-DeepSeek-R1-Distill-Qwen-32B-abliterated.jinja | DeepSeek R1 (extract reasoning) |
-| huihui-ai-DeepSeek-R1-Distill-Qwen-7B-abliterated-v2.jinja | DeepSeek R1 (extract reasoning) |
-| huihui-ai-Qwen2.5-14B-Instruct-1M-abliterated.jinja | Hermes 2 Pro |
-| ibm-granite-granite-3.1-8b-instruct.jinja | Generic |
-| indischepartij-MiniCPM-3B-OpenHermes-2.5-v2.jinja | Generic |
-| inflatebot-MN-12B-Mag-Mell-R1.jinja | Generic |
-| jinaai-ReaderLM-v2.jinja | Generic |
-| kms7530-chemeng_qwen-math-7b_24_1_100_1_nonmath.jinja | Hermes 2 Pro |
-| knifeayumu-Cydonia-v1.3-Magnum-v4-22B.jinja | Mistral Nemo |
-| langgptai-qwen1.5-7b-chat-sa-v0.1.jinja | Generic |
-| lightblue-DeepSeek-R1-Distill-Qwen-7B-Japanese.jinja | DeepSeek R1 (extract reasoning) |
-| mattshumer-Reflection-Llama-3.1-70B.jinja | Generic |
-| meetkai-functionary-medium-v3.1.jinja | Functionary v3.1 Llama 3.1 |
-| meetkai-functionary-medium-v3.2.jinja | Functionary v3.2 |
-| meta-llama-Llama-2-7b-chat-hf.jinja | Generic |
-| meta-llama-Llama-3.1-8B-Instruct.jinja | Llama 3.x |
-| meta-llama-Llama-3.2-11B-Vision-Instruct.jinja | Llama 3.x |
-| meta-llama-Llama-3.2-1B-Instruct.jinja | Llama 3.x |
-| meta-llama-Llama-3.2-3B-Instruct.jinja | Llama 3.x |
-| meta-llama-Llama-3.3-70B-Instruct.jinja | Llama 3.x |
-| meta-llama-Meta-Llama-3-8B-Instruct.jinja | Generic |
-| meta-llama-Meta-Llama-3.1-8B-Instruct.jinja | Llama 3.x |
-| microsoft-Phi-3-medium-4k-instruct.jinja | Generic |
-| microsoft-Phi-3-mini-4k-instruct.jinja | Generic |
-| microsoft-Phi-3-small-8k-instruct.jinja | Generic |
-| microsoft-Phi-3.5-mini-instruct.jinja | Generic |
-| microsoft-Phi-3.5-vision-instruct.jinja | Generic |
-| microsoft-phi-4.jinja | Generic |
-| migtissera-Tess-3-Mistral-Nemo-12B.jinja | Generic |
-| ministral-Ministral-3b-instruct.jinja | Generic |
-| mistralai-Codestral-22B-v0.1.jinja | Generic |
-| mistralai-Mistral-7B-Instruct-v0.1.jinja | Generic |
-| mistralai-Mistral-7B-Instruct-v0.2.jinja | Generic |
-| mistralai-Mistral-7B-Instruct-v0.3.jinja | Mistral Nemo |
-| mistralai-Mistral-Large-Instruct-2407.jinja | Mistral Nemo |
-| mistralai-Mistral-Large-Instruct-2411.jinja | Generic |
-| mistralai-Mistral-Nemo-Instruct-2407.jinja | Mistral Nemo |
-| mistralai-Mistral-Small-24B-Instruct-2501.jinja | Generic |
-| mistralai-Mixtral-8x7B-Instruct-v0.1.jinja | Generic |
-| mkurman-Qwen2.5-14B-DeepSeek-R1-1M.jinja | Hermes 2 Pro |
-| mlabonne-AlphaMonarch-7B.jinja | Generic |
-| mlx-community-Josiefied-Qwen2.5-0.5B-Instruct-abliterated-v1-float32.jinja | Hermes 2 Pro |
-| mlx-community-Qwen2.5-VL-7B-Instruct-8bit.jinja | Hermes 2 Pro |
-| mobiuslabsgmbh-DeepSeek-R1-ReDistill-Qwen-1.5B-v1.1.jinja | DeepSeek R1 (extract reasoning) |
-| netcat420-MFANNv0.20.jinja | Generic |
-| netcat420-MFANNv0.24.jinja | Generic |
-| netease-youdao-Confucius-o1-14B.jinja | Hermes 2 Pro |
-| nvidia-AceMath-7B-RM.jinja | Hermes 2 Pro |
-| nvidia-Eagle2-1B.jinja | Hermes 2 Pro |
-| nvidia-Eagle2-9B.jinja | Hermes 2 Pro |
-| nvidia-Llama-3.1-Nemotron-70B-Instruct-HF.jinja | Llama 3.x |
-| onnx-community-DeepSeek-R1-Distill-Qwen-1.5B-ONNX.jinja | DeepSeek R1 (extract reasoning) |
-| open-thoughts-OpenThinker-7B.jinja | Hermes 2 Pro |
-| openchat-openchat-3.5-0106.jinja | Generic |
-| pankajmathur-orca_mini_v6_8b.jinja | Generic |
-| princeton-nlp-Mistral-7B-Base-SFT-RDPO.jinja | Generic |
-| princeton-nlp-Mistral-7B-Instruct-DPO.jinja | Generic |
-| princeton-nlp-Mistral-7B-Instruct-RDPO.jinja | Generic |
-| prithivMLmods-Bellatrix-Tiny-1.5B-R1.jinja | Hermes 2 Pro |
-| prithivMLmods-Bellatrix-Tiny-1B-R1.jinja | Llama 3.x |
-| prithivMLmods-Bellatrix-Tiny-1B-v3.jinja | Generic |
-| prithivMLmods-Bellatrix-Tiny-3B-R1.jinja | Llama 3.x |
-| prithivMLmods-Blaze-14B-xElite.jinja | Generic |
-| prithivMLmods-Calcium-Opus-14B-Elite2-R1.jinja | Hermes 2 Pro |
-| prithivMLmods-Calme-Ties-78B.jinja | Generic |
-| prithivMLmods-Calme-Ties2-78B.jinja | Generic |
-| prithivMLmods-Calme-Ties3-78B.jinja | Generic |
-| prithivMLmods-ChemQwen2-vL.jinja | Generic |
-| prithivMLmods-GWQ2b.jinja | Generic |
-| prithivMLmods-LatexMind-2B-Codec.jinja | Generic |
-| prithivMLmods-Llama-3.2-6B-AlgoCode.jinja | Llama 3.x |
-| prithivMLmods-Megatron-Opus-14B-Exp.jinja | Hermes 2 Pro |
-| prithivMLmods-Megatron-Opus-14B-Stock.jinja | Hermes 2 Pro |
-| prithivMLmods-Megatron-Opus-7B-Exp.jinja | Hermes 2 Pro |
-| prithivMLmods-Omni-Reasoner-Merged.jinja | Hermes 2 Pro |
-| prithivMLmods-Omni-Reasoner4-Merged.jinja | Hermes 2 Pro |
-| prithivMLmods-Primal-Opus-14B-Optimus-v1.jinja | Hermes 2 Pro |
-| prithivMLmods-QwQ-Math-IO-500M.jinja | Hermes 2 Pro |
-| prithivMLmods-Qwen-7B-Distill-Reasoner.jinja | DeepSeek R1 (extract reasoning) |
-| prithivMLmods-Qwen2.5-1.5B-DeepSeek-R1-Instruct.jinja | Hermes 2 Pro |
-| prithivMLmods-Qwen2.5-14B-DeepSeek-R1-1M.jinja | Hermes 2 Pro |
-| prithivMLmods-Qwen2.5-32B-DeepSeek-R1-Instruct.jinja | Hermes 2 Pro |
-| prithivMLmods-Qwen2.5-7B-DeepSeek-R1-1M.jinja | Hermes 2 Pro |
-| prithivMLmods-Triangulum-v2-10B.jinja | Hermes 2 Pro |
-| qingy2024-Falcon3-2x10B-MoE-Instruct.jinja | Hermes 2 Pro |
-| rubenroy-Zurich-14B-GCv2-5m.jinja | Hermes 2 Pro |
-| rubenroy-Zurich-7B-GCv2-5m.jinja | Hermes 2 Pro |
-| silma-ai-SILMA-Kashif-2B-Instruct-v1.0.jinja | Generic |
-| simplescaling-s1-32B.jinja | Hermes 2 Pro |
-| sometimesanotion-Lamarck-14B-v0.7.jinja | Hermes 2 Pro |
-| sonthenguyen-zephyr-sft-bnb-4bit-DPO-mtbr-180steps.jinja | Generic |
-| sthenno-tempesthenno-icy-0130.jinja | Generic |
-| sumink-qwft.jinja | Hermes 2 Pro |
-| teknium-OpenHermes-2.5-Mistral-7B.jinja | Generic |
-| thirdeyeai-elevate360m.jinja | Generic |
-| tiiuae-Falcon3-10B-Instruct.jinja | Hermes 2 Pro |
-| unsloth-DeepSeek-R1-Distill-Llama-8B-unsloth-bnb-4bit.jinja | DeepSeek R1 (extract reasoning) |
-| unsloth-DeepSeek-R1-Distill-Llama-8B.jinja | DeepSeek R1 (extract reasoning) |
-| unsloth-DeepSeek-R1.jinja | DeepSeek R1 (extract reasoning) |
-| unsloth-Mistral-Small-24B-Instruct-2501-unsloth-bnb-4bit.jinja | Generic |
-| upstage-solar-pro-preview-instruct.jinja | Generic |
-| whyhow-ai-PatientSeek.jinja | Generic |
-| xwen-team-Xwen-72B-Chat.jinja | Hermes 2 Pro |
-| xwen-team-Xwen-7B-Chat.jinja | Hermes 2 Pro |
-
-This table can be generated with:
-
-```bash
-./build/bin/test-chat ../minja/build/tests/*.jinja 2>/dev/null
-```
-
-
-
-# Usage - need tool-aware Jinja template
-
-First, start a server with any model, but make sure it has a tools-enabled template: you can verify this by inspecting the `chat_template` or `chat_template_tool_use` properties in `http://localhost:8080/props`).
-
-Here are some models known to work (w/ chat template override when needed):
-
-```shell
-# Native support:
-
-llama-server --jinja -fa -hf bartowski/Qwen2.5-7B-Instruct-GGUF:Q4_K_M
-llama-server --jinja -fa -hf bartowski/Mistral-Nemo-Instruct-2407-GGUF:Q6_K_L
-llama-server --jinja -fa -hf bartowski/Llama-3.3-70B-Instruct-GGUF:Q4_K_M
-
-# Native support for DeepSeek R1 works best w/ our template override (official template is buggy, although we do work around it)
-
-llama-server --jinja -fa -hf bartowski/DeepSeek-R1-Distill-Qwen-7B-GGUF:Q6_K_L \
- --chat-template-file models/templates/llama-cpp-deepseek-r1.jinja
-
-llama-server --jinja -fa -hf bartowski/DeepSeek-R1-Distill-Qwen-32B-GGUF:Q4_K_M \
- --chat-template-file models/templates/llama-cpp-deepseek-r1.jinja
-
-# Native support requires the right template for these GGUFs:
-
-llama-server --jinja -fa -hf bartowski/functionary-small-v3.2-GGUF:Q4_K_M
- --chat-template-file models/templates/meetkai-functionary-medium-v3.2.jinja
-
-llama-server --jinja -fa -hf bartowski/Hermes-2-Pro-Llama-3-8B-GGUF:Q4_K_M \
- --chat-template-file models/templates/NousResearch-Hermes-2-Pro-Llama-3-8B-tool_use.jinja
-
-llama-server --jinja -fa -hf bartowski/Hermes-3-Llama-3.1-8B-GGUF:Q4_K_M \
- --chat-template-file models/templates/NousResearch-Hermes-3-Llama-3.1-8B-tool_use.jinja
-
-llama-server --jinja -fa -hf bartowski/firefunction-v2-GGUF -hff firefunction-v2-IQ1_M.gguf \
- --chat-template-file models/templates/fireworks-ai-llama-3-firefunction-v2.jinja
-
-llama-server --jinja -fa -hf bartowski/c4ai-command-r7b-12-2024-GGUF:Q6_K_L \
- --chat-template-file models/templates/CohereForAI-c4ai-command-r7b-12-2024-tool_use.jinja
-
-# Generic format support
-llama-server --jinja -fa -hf bartowski/phi-4-GGUF:Q4_0
-llama-server --jinja -fa -hf bartowski/gemma-2-2b-it-GGUF:Q8_0
-llama-server --jinja -fa -hf bartowski/c4ai-command-r-v01-GGUF:Q2_K
-```
-
-To get the official template from original HuggingFace repos, you can use [scripts/get_chat_template.py](../scripts/get_chat_template.py) (see examples invocations in [models/templates/README.md](../models/templates/README.md))
-
-> [!TIP]
-> If there is no official `tool_use` Jinja template, you may want to set `--chat-template chatml` to use a default that works with many models (YMMV!), or write your own (e.g. we provide a custom [llama-cpp-deepseek-r1.jinja](../models/templates/llama-cpp-deepseek-r1.jinja) for DeepSeek R1 distills)
-
-Test in CLI (or with any library / software that can use OpenAI-compatible API backends):
-
-```bash
-curl http://localhost:8080/v1/chat/completions -d '{
-"model": "gpt-3.5-turbo",
-"tools": [
- {
- "type":"function",
- "function":{
- "name":"python",
- "description":"Runs code in an ipython interpreter and returns the result of the execution after 60 seconds.",
- "parameters":{
- "type":"object",
- "properties":{
- "code":{
- "type":"string",
- "description":"The code to run in the ipython interpreter."
- }
- },
- "required":["code"]
- }
- }
- }
-],
-"messages": [
- {
- "role": "user",
- "content": "Print a hello world message with python."
- }
-]
-}'
-```
-
-
-Show output
-
-```json
-{
-"choices": [
- {
- "finish_reason": "tool",
- "index": 0,
- "message": {
- "content": null,
- "tool_calls": [
- {
- "name": "python",
- "arguments": "{\"code\":\" \\nprint(\\\"Hello, World!\\\")\"}"
- }
- ],
- "role": "assistant"
- }
- }
-],
-"created": 1727287211,
-"model": "gpt-3.5-turbo",
-"object": "chat.completion",
-"usage": {
- "completion_tokens": 16,
- "prompt_tokens": 44,
- "total_tokens": 60
-},
-"id": "chatcmpl-Htbgh9feMmGM0LEH2hmQvwsCxq3c6Ni8"
-}
-```
-
-
diff --git a/ggml/cmake/GitVars.cmake b/ggml/cmake/GitVars.cmake
deleted file mode 100644
index 1a4c24ebf..000000000
--- a/ggml/cmake/GitVars.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-find_package(Git)
-
-# the commit's SHA1
-execute_process(COMMAND
- "${GIT_EXECUTABLE}" describe --match=NeVeRmAtCh --always --abbrev=8
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- OUTPUT_VARIABLE GIT_SHA1
- ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-# the date of the commit
-execute_process(COMMAND
- "${GIT_EXECUTABLE}" log -1 --format=%ad --date=local
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- OUTPUT_VARIABLE GIT_DATE
- ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-# the subject of the commit
-execute_process(COMMAND
- "${GIT_EXECUTABLE}" log -1 --format=%s
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
- OUTPUT_VARIABLE GIT_COMMIT_SUBJECT
- ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
diff --git a/ggml/cmake/common.cmake b/ggml/cmake/common.cmake
deleted file mode 100644
index 1976d0ae9..000000000
--- a/ggml/cmake/common.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-function(ggml_get_flags CCID CCVER)
- set(C_FLAGS "")
- set(CXX_FLAGS "")
-
- if (CCID MATCHES "Clang")
- set(C_FLAGS -Wunreachable-code-break -Wunreachable-code-return)
- set(CXX_FLAGS -Wunreachable-code-break -Wunreachable-code-return -Wmissing-prototypes -Wextra-semi)
-
- if (
- (CCID STREQUAL "Clang" AND CCVER VERSION_GREATER_EQUAL 3.8.0) OR
- (CCID STREQUAL "AppleClang" AND CCVER VERSION_GREATER_EQUAL 7.3.0)
- )
- list(APPEND C_FLAGS -Wdouble-promotion)
- endif()
- elseif (CCID STREQUAL "GNU")
- set(C_FLAGS -Wdouble-promotion)
- set(CXX_FLAGS -Wno-array-bounds)
-
- if (CCVER VERSION_GREATER_EQUAL 8.1.0)
- list(APPEND CXX_FLAGS -Wextra-semi)
- endif()
- endif()
-
- set(GF_C_FLAGS ${C_FLAGS} PARENT_SCOPE)
- set(GF_CXX_FLAGS ${CXX_FLAGS} PARENT_SCOPE)
-endfunction()
diff --git a/ggml/src/ggml-opencl/CMakeLists.txt b/ggml/src/ggml-opencl/CMakeLists.txt
deleted file mode 100644
index 352deb321..000000000
--- a/ggml/src/ggml-opencl/CMakeLists.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-find_package(OpenCL REQUIRED)
-find_package(Python3 REQUIRED)
-
-set(TARGET_NAME ggml-opencl)
-
-ggml_add_backend_library(${TARGET_NAME}
- ggml-opencl.cpp
- ../../include/ggml-opencl.h)
-target_link_libraries(${TARGET_NAME} PRIVATE ${OpenCL_LIBRARIES})
-target_include_directories(${TARGET_NAME} PRIVATE ${OpenCL_INCLUDE_DIRS})
-
-if (GGML_OPENCL_PROFILING)
- message(STATUS "OpenCL profiling enabled (increases CPU overhead)")
- add_compile_definitions(GGML_OPENCL_PROFILING)
-endif ()
-
-add_compile_definitions(GGML_OPENCL_SOA_Q)
-add_compile_definitions(GGML_OPENCL_TARGET_VERSION=${GGML_OPENCL_TARGET_VERSION})
-
-if (GGML_OPENCL_USE_ADRENO_KERNELS)
- message(STATUS "OpenCL will use matmul kernels optimized for Adreno")
- add_compile_definitions(GGML_OPENCL_USE_ADRENO_KERNELS)
-endif ()
-
-if (GGML_OPENCL_EMBED_KERNELS)
- add_compile_definitions(GGML_OPENCL_EMBED_KERNELS)
-
- set(EMBED_KERNEL_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/kernels/embed_kernel.py")
- file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/autogenerated")
-
- target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/autogenerated")
-endif ()
-
-function(ggml_opencl_add_kernel KNAME)
- set(KERN_HDR ${CMAKE_CURRENT_BINARY_DIR}/autogenerated/${KNAME}.cl.h)
- set(KERN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/kernels/${KNAME}.cl)
-
- if (GGML_OPENCL_EMBED_KERNELS)
- message(STATUS "opencl: embedding kernel ${KNAME}")
-
- # Python must be accessible from command line
- add_custom_command(
- OUTPUT ${KERN_HDR}
- COMMAND ${Python3_EXECUTABLE} ${EMBED_KERNEL_SCRIPT} ${KERN_SRC} ${KERN_HDR}
- DEPENDS ${KERN_SRC} ${EMBED_KERNEL_SCRIPT}
- COMMENT "Generate ${KERN_HDR}"
- )
-
- target_sources(${TARGET_NAME} PRIVATE ${KERN_HDR})
- else ()
- message(STATUS "opencl: adding kernel ${KNAME}")
- configure_file(${KERN_SRC} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KNAME}.cl COPYONLY)
- endif ()
-endfunction()
-
-set(GGML_OPENCL_KERNELS
- add
- clamp
- cpy
- cvt
- diag_mask_inf
- gelu
- gemv_noshuffle_general
- gemv_noshuffle
- get_rows
- im2col_f32
- im2col_f16
- mul_mat_Ab_Bi_8x4
- mul_mv_f16_f16
- mul_mv_f16_f32_1row
- mul_mv_f16_f32_l4
- mul_mv_f16_f32
- mul_mv_f32_f32
- mul_mv_q4_0_f32
- mul_mv_q4_0_f32_v
- mul_mv_q4_0_f32_8x_flat
- mul_mv_q4_0_f32_1d_8x_flat
- mul_mv_q4_0_f32_1d_16x_flat
- mul_mv_q6_k
- mul
- norm
- relu
- rms_norm
- rope
- scale
- silu
- softmax_4_f32
- softmax_4_f16
- softmax_f32
- softmax_f16
- transpose
-)
-
-foreach (K ${GGML_OPENCL_KERNELS})
- ggml_opencl_add_kernel(${K})
-endforeach()
diff --git a/ggml/src/ggml-opencl/ggml-opencl.cpp b/ggml/src/ggml-opencl/ggml-opencl.cpp
deleted file mode 100644
index 05a2f4e63..000000000
--- a/ggml/src/ggml-opencl/ggml-opencl.cpp
+++ /dev/null
@@ -1,4966 +0,0 @@
-#define CL_TARGET_OPENCL_VERSION GGML_OPENCL_TARGET_VERSION
-#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
-
-// suppress warnings in CL headers for GCC and Clang
-#pragma GCC diagnostic ignored "-Woverlength-strings"
-#ifdef __clang__
-#pragma GCC diagnostic ignored "-Wgnu-anonymous-struct"
-#endif
-
-#include "ggml-opencl.h"
-#include "ggml-backend.h"
-#include "ggml-impl.h"
-#include "ggml-backend-impl.h"
-#include "ggml.h"
-
-#include
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#undef MIN
-#undef MAX
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define UNUSED(x) (void)(x)
-
-#define CL_CHECK(err) \
- do { \
- cl_int err_ = (err); \
- if (err_ != CL_SUCCESS) { \
- GGML_LOG_ERROR("ggml_opencl: %s error %d at %s:%d\n", \
- #err, err_, __FILE__, __LINE__); \
- GGML_ASSERT(0); \
- } \
- } while (0)
-
-//------------------------------------------------------------------------------
-// OpenCL
-//------------------------------------------------------------------------------
-
-bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor);
-
-enum GPU_FAMILY {
- ADRENO,
- INTEL,
- UNKNOWN,
-};
-
-enum ADRENO_GPU_GEN {
- ADRENO_UNKNOWN,
- A7X,
- A8X,
- X1E,
-};
-
-enum ADRENO_CL_COMPILER_TYPE {
- E031,
- DX,
-};
-
-struct ggml_cl_version {
- cl_uint major = 0;
- cl_uint minor = 0;
-};
-
-struct ggml_cl_compiler_version {
- ADRENO_CL_COMPILER_TYPE type;
- int major = -1;
- int minor = -1;
- int patch = -1;
-
- bool same(ADRENO_CL_COMPILER_TYPE t, int x, int y, int z) const {
- return major == x && minor == y && patch == z && type == t;
- }
- bool newer_than(ADRENO_CL_COMPILER_TYPE t, int x, int y, int z) const {
- return major*10000 + minor*100 + patch > x*10000 + y*100 + z && type == t;
- }
- bool newer_than_or_same(ADRENO_CL_COMPILER_TYPE t, int x, int y, int z) const {
- return same(t, x, y, z) || newer_than(t, x, y, z);
- }
-};
-
-// Parses a version string of form "XX.YY ". On an error returns ggml_cl_version with all zeroes.
-static ggml_cl_version parse_cl_version(std::string_view str) {
- size_t major_str_begin = 0;
- size_t major_str_end = str.find(".", major_str_begin);
- if (major_str_end == std::string::npos) {
- return {};
- }
-
- size_t minor_str_begin = major_str_end + 1;
- size_t minor_str_end = str.find(" ", minor_str_begin);
- if (minor_str_end == std::string::npos) {
- return {};
- }
-
- cl_uint version_major;
- if (std::from_chars(str.data() + major_str_begin, str.data() + major_str_end, version_major).ec != std::errc{}) {
- return {};
- }
-
- cl_uint version_minor;
- if (std::from_chars(str.data() + minor_str_begin, str.data() + minor_str_end, version_minor).ec != std::errc{}) {
- return {};
- }
- return { version_major, version_minor };
-}
-
-// Returns OpenCL platform's version. On an error returns ggml_cl_version with all zeroes.
-static ggml_cl_version get_opencl_platform_version(cl_platform_id platform) {
- size_t param_size;
- CL_CHECK(clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, nullptr, ¶m_size));
- std::unique_ptr param_storage(new char[param_size]);
- CL_CHECK(clGetPlatformInfo(platform, CL_PLATFORM_VERSION, param_size, param_storage.get(), nullptr));
-
- auto param_value = std::string_view(param_storage.get(), param_size);
- const std::string version_prefix = "OpenCL "; // Suffix: "XX.YY "
- if (param_value.find(version_prefix) != 0) {
- return {};
- }
- param_value.remove_prefix(version_prefix.length());
- return parse_cl_version(param_value);
-}
-
-// Return a version to use in OpenCL C compilation. On an error returns ggml_cl_version with all zeroes.
-static ggml_cl_version get_opencl_c_version(ggml_cl_version platform_version, cl_device_id device) {
- size_t param_size;
-
-#if CL_TARGET_OPENCL_VERSION >= 300
- if (platform_version.major >= 3) {
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS, 0, nullptr, ¶m_size));
- if (!param_size) {
- return {};
- }
-
- std::unique_ptr versions(new cl_name_version[param_size]);
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS, param_size, versions.get(), nullptr));
- unsigned versions_count = param_size / sizeof(cl_name_version);
-
- cl_version version_max = 0;
- for (unsigned i = 0; i < versions_count; i++) {
- version_max = std::max(versions[i].version, version_max);
- }
-
- return { CL_VERSION_MAJOR(version_max), CL_VERSION_MINOR(version_max) };
- }
-#else
- GGML_UNUSED(platform_version);
-#endif // CL_TARGET_OPENCL_VERSION >= 300
-
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, 0, nullptr, ¶m_size));
- if (!param_size) {
- return {};
- }
-
- std::unique_ptr param_storage(new char[param_size]);
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, param_size, param_storage.get(), nullptr));
- auto param_value = std::string_view(param_storage.get(), param_size);
-
- const std::string version_prefix = "OpenCL C "; // Suffix: "XX.YY "
- if (param_value.find(version_prefix) != 0) {
- return {};
- }
- param_value.remove_prefix(version_prefix.length());
-
- return parse_cl_version(param_value);
-}
-
-static ADRENO_GPU_GEN get_adreno_gpu_gen(const char *device_name) {
- if (strstr(device_name, "730") ||
- strstr(device_name, "740") ||
- strstr(device_name, "750")) {
- return ADRENO_GPU_GEN::A7X;
- }
-
- if (strstr(device_name, "830")) {
- return ADRENO_GPU_GEN::A8X;
- }
-
- if (strstr(device_name, "X1")) {
- return ADRENO_GPU_GEN::X1E;
- }
-
- return ADRENO_GPU_GEN::ADRENO_UNKNOWN;
-}
-
-static ggml_cl_compiler_version get_adreno_cl_compiler_version(const char *driver_version) {
- std::string driver_ver_str(driver_version);
- ADRENO_CL_COMPILER_TYPE type = ADRENO_CL_COMPILER_TYPE::E031;
- size_t compiler_ver_pos = driver_ver_str.find("E031");
- size_t compiler_ver_len = 13;
- size_t compiler_major_offset = 5;
- size_t compiler_minor_offset = 8;
- size_t compiler_patch_offset = 11;
-
- if (compiler_ver_pos == std::string::npos) {
- compiler_ver_pos = driver_ver_str.find("DX");
- if (compiler_ver_pos == std::string::npos) {
- return {};
- }
- type = ADRENO_CL_COMPILER_TYPE::DX;
- compiler_ver_len = 11;
- compiler_major_offset = 3;
- }
-
- std::string compiler_ver_str = driver_ver_str.substr(compiler_ver_pos, compiler_ver_len);
- int major = std::atoi(compiler_ver_str.substr(compiler_major_offset, 2).c_str());
- int minor = std::atoi(compiler_ver_str.substr(compiler_minor_offset, 2).c_str());
- int patch = std::atoi(compiler_ver_str.substr(compiler_patch_offset, 2).c_str());
- return { type, major, minor, patch };
-}
-
-// backend device context
-struct ggml_backend_opencl_device_context {
- cl_platform_id platform;
- std::string platform_name;
-
- cl_device_id device;
- std::string device_name;
-};
-
-// backend context
-struct ggml_backend_opencl_context {
- cl_device_id device;
- std::string device_name;
-
- std::string driver_version;
-
- GPU_FAMILY gpu_family;
- ADRENO_GPU_GEN adreno_gen;
-
- cl_int alignment;
- size_t max_alloc_size;
- bool fp16_support;
- bool has_vector_subgroup_broadcast;
- ggml_cl_compiler_version adreno_cl_compiler_version;
-
- int adreno_wave_size;
-
- cl_context context;
- cl_command_queue queue;
-
- cl_program program_add;
- cl_program program_clamp;
- cl_program program_cpy;
- cl_program program_cvt;
- cl_program program_diag_mask_inf;
- cl_program program_gelu;
- cl_program program_gemv_noshuffle_general;
- cl_program program_gemv_noshuffle;
- cl_program program_get_rows;
- cl_program program_im2col_f16;
- cl_program program_im2col_f32;
- cl_program program_mul_mat_Ab_Bi_8x4;
- cl_program program_mul_mv_q4_0_f32;
- cl_program program_mul_mv_q4_0_f32_v;
- cl_program program_mul_mv_q4_0_f32_8x_flat;
- cl_program program_mul_mv_q4_0_f32_1d_8x_flat;
- cl_program program_mul_mv_q4_0_f32_1d_16x_flat;
- cl_program program_mul_mv_q6_K;
- cl_program program_mul_mv_f16_f16;
- cl_program program_mul_mv_f16_f32_1row;
- cl_program program_mul_mv_f16_f32_l4;
- cl_program program_mul_mv_f16_f32;
- cl_program program_mul_mv_f32_f32;
- cl_program program_mul;
- cl_program program_norm;
- cl_program program_relu;
- cl_program program_rms_norm;
- cl_program program_rope;
- cl_program program_scale;
- cl_program program_silu;
- cl_program program_softmax_f32;
- cl_program program_softmax_f16;
- cl_program program_softmax_4_f32;
- cl_program program_softmax_4_f16;
-
- cl_kernel kernel_add, kernel_add_row;
- cl_kernel kernel_mul, kernel_mul_row;
- cl_kernel kernel_scale;
- cl_kernel kernel_silu, kernel_silu_4;
- cl_kernel kernel_gelu, kernel_gelu_4;
- cl_kernel kernel_gelu_quick, kernel_gelu_quick_4;
- cl_kernel kernel_relu;
- cl_kernel kernel_clamp;
- cl_kernel kernel_norm;
- cl_kernel kernel_rms_norm;
- cl_kernel kernel_diag_mask_inf, kernel_diag_mask_inf_8;
- cl_kernel kernel_soft_max, kernel_soft_max_4;
- cl_kernel kernel_soft_max_f16, kernel_soft_max_4_f16;
- cl_kernel kernel_get_rows_f32, kernel_get_rows_f16, kernel_get_rows_q4_0;
- cl_kernel kernel_rope_norm_f32, kernel_rope_norm_f16, kernel_rope_neox_f32, kernel_rope_neox_f16;
- cl_kernel kernel_rope_multi_f32, kernel_rope_multi_f16, kernel_rope_vision_f32, kernel_rope_vision_f16;
- cl_kernel kernel_cpy_f16_f16, kernel_cpy_f16_f32, kernel_cpy_f32_f16, kernel_cpy_f32_f32;
- cl_kernel kernel_mul_mat_f32_f32;
- cl_kernel kernel_mul_mat_f16_f16;
- cl_kernel kernel_mul_mat_f16_f32_1row;
- cl_kernel kernel_mul_mat_f16_f32;
- cl_kernel kernel_mul_mat_f16_f32_l4;
- cl_kernel kernel_mul_mat_q4_0_f32, kernel_mul_mat_q4_0_f32_v;
- cl_kernel kernel_convert_block_q4_0, kernel_restore_block_q4_0;
- cl_kernel kernel_mul_mat_q4_0_f32_8x_flat;
- cl_kernel kernel_convert_block_q4_0_noshuffle;
- cl_kernel kernel_mul_mat_q4_0_f32_1d_8x_flat, kernel_mul_mat_q4_0_f32_1d_16x_flat;
- cl_kernel kernel_mul_mv_q6_K_f32;
- cl_kernel kernel_im2col_f32, kernel_im2col_f16;
-
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- // Transpose kernels
- cl_program program_transpose;
-
- cl_kernel kernel_transpose_32;
- cl_kernel kernel_transpose_32_16;
- cl_kernel kernel_transpose_16;
-
- cl_mem A_s_d_max; // max scale buffer size for transpose
- cl_mem A_q_d_max; // max weight buffer size for transpose
- cl_mem B_d_max; // max activation buffer size for transpose
-
- // Gemm and Gemv related programs, kernels, etc
- cl_program program_CL_gemm;
- cl_program program_CL_gemv_general;
- cl_program program_CL_gemv_4096_1_11008;
- cl_program program_CL_gemv_4096_1_4096;
- cl_program program_CL_gemv_11008_1_4096;
- cl_program program_CL_gemv_32000_1_4096;
- cl_kernel CL_mul_mat_Ab_Bi_8x4;
- cl_kernel CL_mul_mat_vec_q4_0_f32_1d_4x_flat_general;
- cl_kernel CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_11008;
- cl_kernel CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_4096;
- cl_kernel CL_mul_mat_vec_q4_0_f32_1d_4x_flat_11008_1_4096;
- cl_kernel CL_mul_mat_vec_q4_0_f32_1d_4x_flat_32000_1_4096;
-#endif // GGML_OPENCL_USE_ADRENO_KERNELS
-};
-
-static ggml_backend_device g_ggml_backend_opencl_device;
-static ggml_backend_opencl_device_context g_ggml_ctx_dev_main {
- /*.platform =*/ nullptr,
- /*.platform_nane =*/ "",
- /*.device =*/ nullptr,
- /*.device_name =*/ "",
-};
-
-static int ggml_backend_opencl_n_devices = 0;
-
-// Profiling
-#ifdef GGML_OPENCL_PROFILING
-struct ProfilingInfo {
- std::string op_name;
- std::string kernel_name;
-
- cl_kernel kernel;
- cl_event evt;
-
- cl_ulong cmd_queued;
- cl_ulong cmd_submit;
- cl_ulong cmd_start;
- cl_ulong cmd_end;
- cl_ulong overhead_start;
- cl_ulong overhead_end;
- // For the times below, see spec for clGetEventProfilingInfo
- // The time kernel spent in cmd queue - SUBMIT - QUEUED
- cl_ulong cmd_queued_duration_ns;
- // The time kernel spent for submission - START - SUBMIT
- cl_ulong cmd_submit_duration_ns;
- // Kernel execution time in nanoseconds - END - START
- cl_ulong cmd_duration_ns;
- // The time for the kernel to complete - COMPLETE - END
- cl_ulong cmd_complete_duration_ns;
- // Total time to finish the kernel - COMPELTE - QUEUED
- cl_ulong cmd_total_duration_ns;
- // Global and local work sizes.
- size_t global_size[3];
- size_t local_size[3];
- // Op output size.
- size_t output_size[4];
-};
-
-std::vector g_profiling_info;
-#endif
-
-inline std::string read_file(const std::string &path) {
- std::ifstream ifs(path);
- if (!ifs) {
- return "";
- }
- std::string text;
- ifs.seekg(0, std::ios::end);
- text.resize(ifs.tellg());
- ifs.seekg(0, std::ios::beg);
- ifs.read(&text[0], text.size());
- return text;
-}
-
-static cl_program build_program_from_source(cl_context ctx, cl_device_id dev, const char* program_buffer, const std::string &compile_opts) {
- cl_program p;
- char *program_log;
- size_t program_size;
- size_t log_size;
- int err;
-
- program_size = strlen(program_buffer);
-
- p = clCreateProgramWithSource(ctx, 1, (const char**)&program_buffer, &program_size, &err);
- if(err < 0) {
- GGML_LOG_ERROR("OpenCL error creating program");
- exit(1);
- }
-
- err = clBuildProgram(p, 0, NULL, compile_opts.c_str(), NULL, NULL);
- if(err < 0) {
- clGetProgramBuildInfo(p, dev, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
- program_log = (char*) malloc(log_size + 1);
- program_log[log_size] = '\0';
- clGetProgramBuildInfo(p, dev, CL_PROGRAM_BUILD_LOG, log_size + 1, program_log, NULL);
- GGML_LOG_ERROR("ggml_opencl: kernel compile error:\n\n%s\n", program_log);
- free(program_log);
- exit(1);
- }
-
- return p;
-}
-
-static void load_cl_kernels(ggml_backend_opencl_context *backend_ctx, ggml_cl_version opencl_c_version) {
- cl_int err;
-
- // compiler options for general kernels
- auto opencl_c_std =
- std::string("CL") + std::to_string(opencl_c_version.major) + "." + std::to_string(opencl_c_version.minor);
- std::string compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable -cl-unsafe-math-optimizations"
- " -cl-finite-math-only -cl-fast-relaxed-math";
-
- GGML_LOG_INFO("ggml_opencl: loading OpenCL kernels");
-
- // add
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "add.cl.h"
- };
-#else
- const std::string kernel_src = read_file("add.cl");
-#endif
- backend_ctx->program_add =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_add = clCreateKernel(backend_ctx->program_add, "kernel_add", &err), err));
- CL_CHECK((backend_ctx->kernel_add_row = clCreateKernel(backend_ctx->program_add, "kernel_add_row", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // clamp
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "clamp.cl.h"
- };
-#else
- const std::string kernel_src = read_file("clamp.cl");
-#endif
- backend_ctx->program_clamp =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_clamp = clCreateKernel(backend_ctx->program_clamp, "kernel_clamp", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // cpy
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "cpy.cl.h"
- };
-#else
- const std::string kernel_src = read_file("cpy.cl");
-#endif
- backend_ctx->program_cpy =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_cpy_f16_f16 = clCreateKernel(backend_ctx->program_cpy, "kernel_cpy_f16_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_cpy_f16_f32 = clCreateKernel(backend_ctx->program_cpy, "kernel_cpy_f16_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_cpy_f32_f16 = clCreateKernel(backend_ctx->program_cpy, "kernel_cpy_f32_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_cpy_f32_f32 = clCreateKernel(backend_ctx->program_cpy, "kernel_cpy_f32_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // cvt
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "cvt.cl.h"
- };
-#else
- const std::string kernel_src = read_file("cvt.cl");
-#endif
- backend_ctx->program_cvt =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_convert_block_q4_0_noshuffle = clCreateKernel(backend_ctx->program_cvt, "kernel_convert_block_q4_0_noshuffle", &err), err));
- CL_CHECK((backend_ctx->kernel_convert_block_q4_0 = clCreateKernel(backend_ctx->program_cvt, "kernel_convert_block_q4_0", &err), err));
- CL_CHECK((backend_ctx->kernel_restore_block_q4_0 = clCreateKernel(backend_ctx->program_cvt, "kernel_restore_block_q4_0", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // diag_mask_inf
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "diag_mask_inf.cl.h"
- };
-#else
- const std::string kernel_src = read_file("diag_mask_inf.cl");
-#endif
- backend_ctx->program_diag_mask_inf =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_diag_mask_inf_8 = clCreateKernel(backend_ctx->program_diag_mask_inf, "kernel_diag_mask_inf_8", &err), err));
- CL_CHECK((backend_ctx->kernel_diag_mask_inf = clCreateKernel(backend_ctx->program_diag_mask_inf, "kernel_diag_mask_inf", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // gelu
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "gelu.cl.h"
- };
-#else
- const std::string kernel_src = read_file("gelu.cl");
-#endif
- backend_ctx->program_gelu =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_gelu = clCreateKernel(backend_ctx->program_gelu, "kernel_gelu", &err), err));
- CL_CHECK((backend_ctx->kernel_gelu_4 = clCreateKernel(backend_ctx->program_gelu, "kernel_gelu_4", &err), err));
- CL_CHECK((backend_ctx->kernel_gelu_quick = clCreateKernel(backend_ctx->program_gelu, "kernel_gelu_quick", &err), err));
- CL_CHECK((backend_ctx->kernel_gelu_quick_4 = clCreateKernel(backend_ctx->program_gelu, "kernel_gelu_quick_4", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // get_rows
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "get_rows.cl.h"
- };
-#else
- const std::string kernel_src = read_file("get_rows.cl");
-#endif
- backend_ctx->program_get_rows =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_get_rows_f32 = clCreateKernel(backend_ctx->program_get_rows, "kernel_get_rows_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_get_rows_f16 = clCreateKernel(backend_ctx->program_get_rows, "kernel_get_rows_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_get_rows_q4_0 = clCreateKernel(backend_ctx->program_get_rows, "kernel_get_rows_q4_0", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // im2col_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "im2col_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("im2col_f32.cl");
-#endif
- backend_ctx->program_im2col_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_im2col_f32 = clCreateKernel(backend_ctx->program_im2col_f32, "kernel_im2col_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // im2col_f16
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "im2col_f16.cl.h"
- };
-#else
- const std::string kernel_src = read_file("im2col_f16.cl");
-#endif
- backend_ctx->program_im2col_f16 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_im2col_f16 = clCreateKernel(backend_ctx->program_im2col_f16, "kernel_im2col_f16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q4_0_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q4_0_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q4_0_f32.cl");
-#endif
- backend_ctx->program_mul_mv_q4_0_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_q4_0_f32 = clCreateKernel(backend_ctx->program_mul_mv_q4_0_f32, "kernel_mul_mat_q4_0_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q4_0_f32_v
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q4_0_f32_v.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q4_0_f32_v.cl");
-#endif
- backend_ctx->program_mul_mv_q4_0_f32_v =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_q4_0_f32_v = clCreateKernel(backend_ctx->program_mul_mv_q4_0_f32_v, "kernel_mul_mat_q4_0_f32_v", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q4_0_f32_8x_flat
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q4_0_f32_8x_flat.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q4_0_f32_8x_flat.cl");
-#endif
- backend_ctx->program_mul_mv_q4_0_f32_8x_flat =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_q4_0_f32_8x_flat = clCreateKernel(backend_ctx->program_mul_mv_q4_0_f32_8x_flat, "kernel_mul_mat_q4_0_f32_8x_flat", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q4_0_f32_1d_8x_flat
- // This kernel does not compiler on Adreno cl compiler 38.01. Skip it for
- // those compiler versions since it is anyway not used for Adreno.
- if (backend_ctx->gpu_family != ADRENO ||
- backend_ctx->adreno_cl_compiler_version.newer_than_or_same(E031, 38, 11, 0) ||
- backend_ctx->adreno_cl_compiler_version.type == DX) {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q4_0_f32_1d_8x_flat.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q4_0_f32_1d_8x_flat.cl");
-#endif
- backend_ctx->program_mul_mv_q4_0_f32_1d_8x_flat =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_q4_0_f32_1d_8x_flat = clCreateKernel(backend_ctx->program_mul_mv_q4_0_f32_1d_8x_flat, "kernel_mul_mat_q4_0_f32_1d_8x_flat", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q4_0_f32_1d_16x_flat
- // This kernel does not compiler on Adreno cl compiler 38.01. Skip it for
- // those compiler versions since it is anyway not used for Adreno.
- if (backend_ctx->gpu_family != ADRENO ||
- backend_ctx->adreno_cl_compiler_version.newer_than_or_same(E031, 38, 11, 0) ||
- backend_ctx->adreno_cl_compiler_version.type == DX) {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q4_0_f32_1d_16x_flat.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q4_0_f32_1d_16x_flat.cl");
-#endif
- backend_ctx->program_mul_mv_q4_0_f32_1d_16x_flat =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_q4_0_f32_1d_16x_flat = clCreateKernel(backend_ctx->program_mul_mv_q4_0_f32_1d_16x_flat, "kernel_mul_mat_q4_0_f32_1d_16x_flat", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_q6_k
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_q6_k.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_q6_k.cl");
-#endif
- backend_ctx->program_mul_mv_q6_K =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mv_q6_K_f32 = clCreateKernel(backend_ctx->program_mul_mv_q6_K, "kernel_mul_mv_q6_K_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_f16_f16
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_f16_f16.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_f16_f16.cl");
-#endif
- backend_ctx->program_mul_mv_f16_f16 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_f16_f16 = clCreateKernel(backend_ctx->program_mul_mv_f16_f16, "kernel_mul_mat_f16_f16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_f16_f32_1row
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_f16_f32_1row.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_f16_f32_1row.cl");
-#endif
- backend_ctx->program_mul_mv_f16_f32_1row =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_f16_f32_1row = clCreateKernel(backend_ctx->program_mul_mv_f16_f32_1row, "kernel_mul_mat_f16_f32_1row", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_f16_f32_l4
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_f16_f32_l4.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_f16_f32_l4.cl");
-#endif
- backend_ctx->program_mul_mv_f16_f32_l4 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_f16_f32_l4 = clCreateKernel(backend_ctx->program_mul_mv_f16_f32_l4, "kernel_mul_mat_f16_f32_l4", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_f16_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_f16_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_f16_f32.cl");
-#endif
- backend_ctx->program_mul_mv_f16_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_f16_f32 = clCreateKernel(backend_ctx->program_mul_mv_f16_f32, "kernel_mul_mat_f16_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mv_f32_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul_mv_f32_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul_mv_f32_f32.cl");
-#endif
- backend_ctx->program_mul_mv_f32_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul_mat_f32_f32 = clCreateKernel(backend_ctx->program_mul_mv_f32_f32, "kernel_mul_mat_f32_f32", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "mul.cl.h"
- };
-#else
- const std::string kernel_src = read_file("mul.cl");
-#endif
- backend_ctx->program_mul =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_mul = clCreateKernel(backend_ctx->program_mul, "kernel_mul", &err), err));
- CL_CHECK((backend_ctx->kernel_mul_row = clCreateKernel(backend_ctx->program_mul, "kernel_mul_row", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // norm
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "norm.cl.h"
- };
-#else
- const std::string kernel_src = read_file("norm.cl");
-#endif
- backend_ctx->program_norm =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_norm = clCreateKernel(backend_ctx->program_norm, "kernel_norm", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // relu
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "relu.cl.h"
- };
-#else
- const std::string kernel_src = read_file("relu.cl");
-#endif
- backend_ctx->program_relu =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_relu = clCreateKernel(backend_ctx->program_relu, "kernel_relu", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // rms_norm
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "rms_norm.cl.h"
- };
-#else
- const std::string kernel_src = read_file("rms_norm.cl");
-#endif
- backend_ctx->program_rms_norm =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_rms_norm = clCreateKernel(backend_ctx->program_rms_norm, "kernel_rms_norm", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // rope
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "rope.cl.h"
- };
-#else
- const std::string kernel_src = read_file("rope.cl");
-#endif
- backend_ctx->program_rope =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_rope_norm_f32 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_norm_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_norm_f16 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_norm_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_neox_f32 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_neox_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_neox_f16 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_neox_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_multi_f32 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_multi_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_multi_f16 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_multi_f16", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_vision_f32 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_vision_f32", &err), err));
- CL_CHECK((backend_ctx->kernel_rope_vision_f16 = clCreateKernel(backend_ctx->program_rope, "kernel_rope_vision_f16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // scale
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "scale.cl.h"
- };
-#else
- const std::string kernel_src = read_file("scale.cl");
-#endif
- backend_ctx->program_scale =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_scale = clCreateKernel(backend_ctx->program_scale, "kernel_scale", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // silu
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "silu.cl.h"
- };
-#else
- const std::string kernel_src = read_file("silu.cl");
-#endif
- backend_ctx->program_silu =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_silu = clCreateKernel(backend_ctx->program_silu, "kernel_silu", &err), err));
- CL_CHECK((backend_ctx->kernel_silu_4 = clCreateKernel(backend_ctx->program_silu, "kernel_silu_4", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // softmax_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "softmax_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("softmax_f32.cl");
-#endif
- backend_ctx->program_softmax_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_soft_max = clCreateKernel(backend_ctx->program_softmax_f32, "kernel_soft_max", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // softmax_f16
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "softmax_f16.cl.h"
- };
-#else
- const std::string kernel_src = read_file("softmax_f16.cl");
-#endif
- backend_ctx->program_softmax_f16 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_soft_max_f16 = clCreateKernel(backend_ctx->program_softmax_f16, "kernel_soft_max_f16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // softmax_4_f32
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "softmax_4_f32.cl.h"
- };
-#else
- const std::string kernel_src = read_file("softmax_4_f32.cl");
-#endif
- backend_ctx->program_softmax_4_f32 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_soft_max_4 = clCreateKernel(backend_ctx->program_softmax_4_f32, "kernel_soft_max_4", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // softmax_4_f16
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "softmax_4_f16.cl.h"
- };
-#else
- const std::string kernel_src = read_file("softmax_4_f16.cl");
-#endif
- backend_ctx->program_softmax_4_f16 =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_soft_max_4_f16 = clCreateKernel(backend_ctx->program_softmax_4_f16, "kernel_soft_max_4_f16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // Adreno kernels
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- // transpose
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src {
- #include "transpose.cl.h"
- };
-#else
- const std::string kernel_src = read_file("transpose.cl");
-#endif
- backend_ctx->program_transpose =
- build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src.c_str(), compile_opts);
-
- CL_CHECK((backend_ctx->kernel_transpose_32_16 = clCreateKernel(backend_ctx->program_transpose, "kernel_transpose_32_16", &err), err));
- CL_CHECK((backend_ctx->kernel_transpose_32 = clCreateKernel(backend_ctx->program_transpose, "kernel_transpose_32", &err), err));
- CL_CHECK((backend_ctx->kernel_transpose_16 = clCreateKernel(backend_ctx->program_transpose, "kernel_transpose_16", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // gemv_noshuffle_general
- {
- std::string CL_gemv_compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable "
- " -DSIMDGROUP_WIDTH=" +
- std::to_string(backend_ctx->adreno_wave_size);
- if (backend_ctx->has_vector_subgroup_broadcast) {
- CL_gemv_compile_opts += " -DVECTOR_SUB_GROUP_BROADCAT ";
- }
-
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src_CL_gemv_general {
- #include "gemv_noshuffle_general.cl.h"
- };
-#else
- const std::string kernel_src_CL_gemv_general = read_file("gemv_noshuffle_general.cl");
-#endif
-
- backend_ctx->program_CL_gemv_general = build_program_from_source(
- backend_ctx->context, backend_ctx->device, kernel_src_CL_gemv_general.c_str(), CL_gemv_compile_opts);
-
- CL_CHECK((backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_general = clCreateKernel(backend_ctx->program_CL_gemv_general, "kernel_gemv_noshuffle", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // gemv_noshuffle
- {
- // Gemv 2048, 16384
- std::string CL_gemv_compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable "
- " -DLINE_STRIDE_A=2048 "
- " -DBLOCK_STRIDE_A=16384 "
- " -DSIMDGROUP_WIDTH=" +
- std::to_string(backend_ctx->adreno_wave_size);
- if (backend_ctx->has_vector_subgroup_broadcast) {
- CL_gemv_compile_opts += " -DVECTOR_SUB_GROUP_BROADCAT ";
- }
-
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src_CL_gemv {
- #include "gemv_noshuffle.cl.h"
- };
-#else
- const std::string kernel_src_CL_gemv = read_file("gemv_noshuffle.cl");
-#endif
-
- backend_ctx->program_CL_gemv_4096_1_4096 = build_program_from_source(
- backend_ctx->context, backend_ctx->device, kernel_src_CL_gemv.c_str(), CL_gemv_compile_opts);
- CL_CHECK((backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_4096 = clCreateKernel(backend_ctx->program_CL_gemv_4096_1_4096, "kernel_gemv_noshuffle", &err), err));
- GGML_LOG_CONT(".");
-
- // Gemv 2048, 16384
- CL_gemv_compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable "
- " -DLINE_STRIDE_A=2048 "
- " -DBLOCK_STRIDE_A=16384 "
- " -DSIMDGROUP_WIDTH=" +
- std::to_string(backend_ctx->adreno_wave_size);
- if (backend_ctx->has_vector_subgroup_broadcast) {
- CL_gemv_compile_opts += " -DVECTOR_SUB_GROUP_BROADCAT ";
- }
-
- backend_ctx->program_CL_gemv_4096_1_11008 = build_program_from_source(
- backend_ctx->context, backend_ctx->device, kernel_src_CL_gemv.c_str(), CL_gemv_compile_opts);
- CL_CHECK((backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_11008 = clCreateKernel(backend_ctx->program_CL_gemv_4096_1_11008, "kernel_gemv_noshuffle", &err), err));
- GGML_LOG_CONT(".");
-
- // Gemv 5504, 44032
- CL_gemv_compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable "
- " -DLINE_STRIDE_A=5504 "
- " -DBLOCK_STRIDE_A=44032 "
- " -DSIMDGROUP_WIDTH=" +
- std::to_string(backend_ctx->adreno_wave_size);
- if (backend_ctx->has_vector_subgroup_broadcast) {
- CL_gemv_compile_opts += " -DVECTOR_SUB_GROUP_BROADCAT ";
- }
-
- backend_ctx->program_CL_gemv_11008_1_4096 = build_program_from_source(
- backend_ctx->context, backend_ctx->device, kernel_src_CL_gemv.c_str(), CL_gemv_compile_opts);
- CL_CHECK((backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_11008_1_4096 = clCreateKernel(backend_ctx->program_CL_gemv_11008_1_4096, "kernel_gemv_noshuffle", &err), err));
- GGML_LOG_CONT(".");
-
- // Gemv 16000, 128000
- CL_gemv_compile_opts = std::string("-cl-std=") + opencl_c_std +
- " -cl-mad-enable "
- " -DLINE_STRIDE_A=16000 "
- " -DBLOCK_STRIDE_A=128000 "
- " -DSIMDGROUP_WIDTH=" +
- std::to_string(backend_ctx->adreno_wave_size);
-
- if (backend_ctx->has_vector_subgroup_broadcast) {
- CL_gemv_compile_opts += " -DVECTOR_SUB_GROUP_BROADCAT ";
- }
-
- backend_ctx->program_CL_gemv_32000_1_4096 = build_program_from_source(
- backend_ctx->context, backend_ctx->device, kernel_src_CL_gemv.c_str(), CL_gemv_compile_opts);
- CL_CHECK((backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_32000_1_4096 = clCreateKernel(backend_ctx->program_CL_gemv_32000_1_4096, "kernel_gemv_noshuffle", &err), err));
- GGML_LOG_CONT(".");
- }
-
- // mul_mat_Ab_Bi_8x4
- {
-#ifdef GGML_OPENCL_EMBED_KERNELS
- const std::string kernel_src_CL_gemm {
- #include "mul_mat_Ab_Bi_8x4.cl.h"
- };
-#else
- const std::string kernel_src_CL_gemm = read_file("mul_mat_Ab_Bi_8x4.cl");
-#endif
- backend_ctx->program_CL_gemm = build_program_from_source(backend_ctx->context, backend_ctx->device, kernel_src_CL_gemm.c_str(), compile_opts);
- CL_CHECK((backend_ctx->CL_mul_mat_Ab_Bi_8x4 = clCreateKernel(backend_ctx->program_CL_gemm, "kernel_mul_mat_Ab_Bi_8x4", &err), err));
- GGML_LOG_CONT(".");
- }
-#endif // GGML_OPENCL_USE_ADRENO_KERNELS
- GGML_LOG_CONT("\n");
-}
-
-static ggml_backend_opencl_context * ggml_cl2_init(ggml_backend_dev_t dev) {
- static bool initialized = false;
- static ggml_backend_opencl_context *backend_ctx = nullptr;
-
- if (initialized) {
- return backend_ctx;
- }
-
- ggml_backend_opencl_device_context *dev_ctx = (ggml_backend_opencl_device_context *)dev->context;
- GGML_ASSERT(dev_ctx);
- GGML_ASSERT(dev_ctx->platform == nullptr);
- GGML_ASSERT(dev_ctx->device == nullptr);
- GGML_ASSERT(backend_ctx == nullptr);
-
- initialized = true;
- backend_ctx = new ggml_backend_opencl_context();
- backend_ctx->gpu_family = GPU_FAMILY::UNKNOWN;
-
- cl_int err;
-
-#ifdef GGML_OPENCL_PROFILING
- GGML_LOG_INFO("ggml_opencl: OpenCL profiling enabled\n");
-#endif
-
- struct cl_device;
- struct cl_platform {
- cl_platform_id id;
- unsigned number;
- char name[128];
- char vendor[128];
- struct cl_device * devices;
- unsigned n_devices;
- struct cl_device * default_device;
- };
-
- struct cl_device {
- struct cl_platform * platform;
- cl_device_id id;
- unsigned number;
- cl_device_type type;
- char name[128];
- char version[128];
- };
-
- enum { NPLAT = 16, NDEV = 16 };
-
- struct cl_platform platforms[NPLAT];
- unsigned n_platforms = 0;
- struct cl_device devices[NDEV];
- unsigned n_devices = 0;
- struct cl_device * default_device = NULL;
-
- cl_platform_id platform_ids[NPLAT];
- if (clGetPlatformIDs(NPLAT, platform_ids, &n_platforms) != CL_SUCCESS) {
- GGML_LOG_ERROR("ggml_opencl: plaform IDs not available.\n");
- return backend_ctx;
- }
-
- for (unsigned i = 0; i < n_platforms; i++) {
- struct cl_platform * p = &platforms[i];
- p->number = i;
- p->id = platform_ids[i];
- CL_CHECK(clGetPlatformInfo(p->id, CL_PLATFORM_NAME, sizeof(p->name), &p->name, NULL));
- CL_CHECK(clGetPlatformInfo(p->id, CL_PLATFORM_VENDOR, sizeof(p->vendor), &p->vendor, NULL));
-
- cl_device_id device_ids[NDEV];
- cl_int clGetDeviceIDsError = clGetDeviceIDs(p->id, CL_DEVICE_TYPE_ALL, NDEV, device_ids, &p->n_devices);
- if (clGetDeviceIDsError == CL_DEVICE_NOT_FOUND) {
- p->n_devices = 0;
- } else {
- CL_CHECK(clGetDeviceIDsError);
- }
- p->devices = p->n_devices > 0 ? &devices[n_devices] : NULL;
- p->default_device = NULL;
-
- for (unsigned j = 0; j < p->n_devices; j++) {
- struct cl_device * d = &devices[n_devices];
- d->number = n_devices++;
- d->id = device_ids[j];
- d->platform = p;
- CL_CHECK(clGetDeviceInfo(d->id, CL_DEVICE_NAME, sizeof(d->name), &d->name, NULL));
- CL_CHECK(clGetDeviceInfo(d->id, CL_DEVICE_TYPE, sizeof(d->type), &d->type, NULL));
- CL_CHECK(clGetDeviceInfo(d->id, CL_DEVICE_VERSION, sizeof(d->version), &d->version, NULL));
-
- if (p->default_device == NULL && d->type == CL_DEVICE_TYPE_GPU) {
- p->default_device = d;
- }
- }
-
- if (default_device == NULL && p->default_device != NULL) {
- default_device = p->default_device;
- }
- }
-
- if (n_devices == 0) {
- GGML_LOG_ERROR("ggml_opencl: could find any OpenCL devices.\n");
- return backend_ctx;
- }
-
- char * user_platform_string = getenv("GGML_OPENCL_PLATFORM");
- char * user_device_string = getenv("GGML_OPENCL_DEVICE");
- int user_platform_number = -1;
- int user_device_number = -1;
-
- unsigned n;
- if (user_platform_string != NULL && sscanf(user_platform_string, " %u", &n) == 1 && n < n_platforms) {
- user_platform_number = (int)n;
- }
- if (user_device_string != NULL && sscanf(user_device_string, " %u", &n) == 1 && n < n_devices) {
- user_device_number = (int)n;
- }
- if (user_platform_number != -1 && user_device_number != -1) {
- cl_platform* platform = &platforms[user_platform_number];
- if ((unsigned)user_device_number >= platform->n_devices) {
- GGML_LOG_ERROR("ggml_opencl: invalid device number %d\n", user_device_number);
- exit(1);
- }
- default_device = &platform->devices[user_device_number];
- } else {
-
- struct cl_device * selected_devices = devices;
- unsigned n_selected_devices = n_devices;
-
- if (user_platform_number == -1 && user_platform_string != NULL && user_platform_string[0] != 0) {
- for (unsigned i = 0; i < n_platforms; i++) {
- struct cl_platform * p = &platforms[i];
- if (strstr(p->name, user_platform_string) != NULL ||
- strstr(p->vendor, user_platform_string) != NULL) {
- user_platform_number = (int)i;
- break;
- }
- }
- if (user_platform_number == -1) {
- GGML_LOG_ERROR("ggml_opencl: no platform matching '%s' was found.\n", user_platform_string);
- exit(1);
- }
- }
- if (user_platform_number != -1) {
- struct cl_platform * p = &platforms[user_platform_number];
- selected_devices = p->devices;
- n_selected_devices = p->n_devices;
- default_device = p->default_device;
- if (n_selected_devices == 0) {
- GGML_LOG_ERROR("ggml_opencl: selected platform '%s' does not have any devices.\n", p->name);
- exit(1);
- }
- }
-
- if (user_device_number == -1 && user_device_string != NULL && user_device_string[0] != 0) {
- for (unsigned i = 0; i < n_selected_devices; i++) {
- struct cl_device * d = &selected_devices[i];
- if (strstr(d->name, user_device_string) != NULL) {
- user_device_number = d->number;
- break;
- }
- }
- if (user_device_number == -1) {
- GGML_LOG_ERROR("ggml_opencl: no device matching '%s' was found.\n", user_device_string);
- exit(1);
- }
- }
- if (user_device_number != -1) {
- selected_devices = &devices[user_device_number];
- n_selected_devices = 1;
- default_device = &selected_devices[0];
- }
-
- GGML_ASSERT(n_selected_devices > 0);
-
- if (default_device == NULL) {
- default_device = &selected_devices[0];
- }
- }
-
- GGML_LOG_INFO("ggml_opencl: selecting platform: '%s'\n", default_device->platform->name);
- GGML_LOG_INFO("ggml_opencl: selecting device: '%s (%s)'\n", default_device->name, default_device->version);
- if (default_device->type != CL_DEVICE_TYPE_GPU) {
- GGML_LOG_WARN("ggml_opencl: warning, not a GPU: '%s'.\n", default_device->name);
- }
-
- dev_ctx->platform = default_device->platform->id;
- dev_ctx->device = default_device->id;
- backend_ctx->device = default_device->id;
-
- if (strstr(default_device->name, "Adreno") ||
- strstr(default_device->name, "Qualcomm") ||
- strstr(default_device->version, "Adreno")) {
- backend_ctx->gpu_family = GPU_FAMILY::ADRENO;
- // Usually device version contains the detailed device name
- backend_ctx->adreno_gen = get_adreno_gpu_gen(default_device->version);
- if (backend_ctx->adreno_gen == ADRENO_GPU_GEN::ADRENO_UNKNOWN) {
- backend_ctx->adreno_gen = get_adreno_gpu_gen(default_device->name);
- }
-
- // Use wave size of 64 for all Adreno GPUs.
- backend_ctx->adreno_wave_size = 64;
- } else if (strstr(default_device->name, "Intel")) {
- backend_ctx->gpu_family = GPU_FAMILY::INTEL;
- } else {
- GGML_LOG_ERROR("Unsupported GPU: %s\n", default_device->name);
- backend_ctx->gpu_family = GPU_FAMILY::UNKNOWN;
- return backend_ctx;
- }
-
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- if (backend_ctx->gpu_family != GPU_FAMILY::ADRENO) {
- GGML_LOG_ERROR("ggml_opencl: Adreno-specific kernels should not be enabled for non-Adreno GPUs; "
- "run on an Adreno GPU or recompile with CMake option `-DGGML_OPENCL_USE_ADRENO_KERNELS=OFF`\n");
- return backend_ctx;
- }
-#endif
-
- // Populate backend device name
- dev_ctx->platform_name = default_device->platform->name;
- dev_ctx->device_name = default_device->name;
- backend_ctx->device_name = default_device->name;
-
- // A local ref of cl_device_id for convenience
- cl_device_id device = backend_ctx->device;
-
- ggml_cl_version platform_version = get_opencl_platform_version(default_device->platform->id);
-
- // Check device OpenCL version, OpenCL 2.0 or above is required
- ggml_cl_version opencl_c_version = get_opencl_c_version(platform_version, device);
- if (opencl_c_version.major < 2) {
- GGML_LOG_ERROR("ggml_opencl: OpenCL 2.0 or above is required\n");
- return backend_ctx;
- }
-
- // Check driver version
- size_t driver_version_str_size;
- clGetDeviceInfo(device, CL_DRIVER_VERSION, 0, NULL, &driver_version_str_size);
- char *driver_version = (char *)alloca(driver_version_str_size + 1);
- clGetDeviceInfo(device, CL_DRIVER_VERSION, driver_version_str_size, driver_version, NULL);
- driver_version[driver_version_str_size] = '\0';
- GGML_LOG_INFO("ggml_opencl: OpenCL driver: %s\n", driver_version);
- backend_ctx->driver_version = driver_version;
-
- backend_ctx->adreno_cl_compiler_version = get_adreno_cl_compiler_version(driver_version);
- backend_ctx->has_vector_subgroup_broadcast =
- backend_ctx->adreno_cl_compiler_version.major >= 47 ||
- backend_ctx->adreno_cl_compiler_version.major == 17;
- GGML_LOG_INFO("ggml_opencl: vector subgroup broadcast support: %s\n",
- backend_ctx->has_vector_subgroup_broadcast ? "true" : "false");
-
- size_t ext_str_size;
- clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, 0, NULL, &ext_str_size);
- char *ext_buffer = (char *)alloca(ext_str_size + 1);
- clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, ext_str_size, ext_buffer, NULL);
- ext_buffer[ext_str_size] = '\0'; // ensure it is null terminated
- // Check if ext_buffer contains cl_khr_fp16
- backend_ctx->fp16_support = strstr(ext_buffer, "cl_khr_fp16") != NULL;
- GGML_LOG_INFO("ggml_opencl: device FP16 support: %s\n", backend_ctx->fp16_support ? "true" : "false");
-
- // fp16 is required
- if (!backend_ctx->fp16_support) {
- GGML_LOG_ERROR("ggml_opencl: device does not support FP16\n");
- return backend_ctx;
- }
-
- // If OpenCL 3.0 is supported, then check for cl_khr_subgroups, which becomes
- // optional in OpenCL 3.0 (cl_khr_subgroup is mandatory in OpenCL 2.x)
- if (opencl_c_version.major == 3 && strstr(ext_buffer, "cl_khr_subgroups") == NULL &&
- strstr(ext_buffer, "cl_intel_subgroups") == NULL) {
- GGML_LOG_ERROR("ggml_opencl: device does not support subgroups (cl_khr_subgroups or cl_intel_subgroups) "
- "(note that subgroups is an optional feature in OpenCL 3.0)\n");
- return backend_ctx;
- }
-
- cl_uint base_align_in_bits;
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(cl_uint), &base_align_in_bits, NULL));
- GGML_ASSERT(base_align_in_bits % 8u == 0);
- backend_ctx->alignment = base_align_in_bits / 8u;
- GGML_LOG_INFO("ggml_opencl: mem base addr align: %u\n", backend_ctx->alignment);
-
- clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(size_t), &backend_ctx->max_alloc_size, NULL);
- GGML_LOG_INFO("ggml_opencl: max mem alloc size: %zu MB\n", backend_ctx->max_alloc_size/1024/1024);
-
- // Check SVM.
- cl_device_svm_capabilities svm_caps;
- CL_CHECK(clGetDeviceInfo(device, CL_DEVICE_SVM_CAPABILITIES, sizeof(cl_device_svm_capabilities), &svm_caps, 0));
- GGML_LOG_INFO("ggml_opencl: SVM coarse grain buffer support: %s\n",
- svm_caps & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER ? "true" : "false");
- GGML_LOG_INFO("ggml_opencl: SVM fine grain buffer support: %s\n",
- svm_caps & CL_DEVICE_SVM_FINE_GRAIN_BUFFER ? "true" : "false");
- GGML_LOG_INFO("ggml_opencl: SVM fine grain system support: %s\n",
- svm_caps & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM ? "true" : "false");
- GGML_LOG_INFO("ggml_opencl: SVM atomics support: %s\n",
- svm_caps & CL_DEVICE_SVM_ATOMICS ? "true" : "false");
-
- // Print out configurations
-#ifdef GGML_OPENCL_SOA_Q
- GGML_LOG_INFO("ggml_opencl: flattening quantized weights representation as struct of arrays (GGML_OPENCL_SOA_Q)\n");
-#endif // GGML_OPENCL_SOA_Q
-
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- GGML_LOG_INFO("ggml_opencl: using kernels optimized for Adreno (GGML_OPENCL_USE_ADRENO_KERNELS)\n");
-#endif // GGML_OPENCL_USE_ADRENO_KERNELS
-
- cl_context_properties properties[] = {
- (intptr_t)CL_CONTEXT_PLATFORM, (intptr_t)dev_ctx->platform, 0
- };
-
- CL_CHECK((backend_ctx->context = clCreateContext(properties, 1, &device, NULL, NULL, &err), err));
-
- // A local ref of cl_context for convenience
- cl_context context = backend_ctx->context;
-
- //CL_CHECK((queue = clCreateCommandQueue(context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err),
- // (err != CL_INVALID_QUEUE_PROPERTIES && err != CL_INVALID_VALUE ? err :
- // (queue = clCreateCommandQueue(context, device, 0, &err), err)
- //)));
- cl_command_queue_properties command_queue_props = 0;
-#ifdef GGML_OPENCL_PROFILING
- command_queue_props |= CL_QUEUE_PROFILING_ENABLE;
-#endif
- CL_CHECK((backend_ctx->queue = clCreateCommandQueue(context, device, command_queue_props, &err), err));
-
- // Load kernels
- load_cl_kernels(backend_ctx, opencl_c_version);
-
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- // Allocate intermediate buffers and images
- size_t required_A_q_d_bytes = 311164928;
- size_t required_A_s_d_bytes = 38895616;
- size_t required_B_d_bytes = 45088768;
-
- // Ensure buffer sizes do not exceed the maximum allocation size
- size_t max_A_q_d_bytes = MIN(required_A_q_d_bytes, backend_ctx->max_alloc_size);
- size_t max_A_s_d_bytes = MIN(required_A_s_d_bytes, backend_ctx->max_alloc_size);
- size_t max_B_d_bytes = MIN(required_B_d_bytes, backend_ctx->max_alloc_size);
- if (required_A_q_d_bytes > backend_ctx->max_alloc_size) {
- GGML_LOG_WARN("ggml_opencl: A_q_d buffer size reduced from %zu to %zu due to device limitations.\n",
- required_A_q_d_bytes, max_A_q_d_bytes);
- }
- if (required_A_s_d_bytes > backend_ctx->max_alloc_size) {
- GGML_LOG_WARN("ggml_opencl: A_s_d buffer size reduced from %zu to %zu due to device limitations.\n",
- required_A_s_d_bytes, max_A_s_d_bytes);
- }
- if (required_B_d_bytes > backend_ctx->max_alloc_size) {
- GGML_LOG_WARN("ggml_opencl: B_d buffer size reduced from %zu to %zu due to device limitations.\n",
- required_B_d_bytes, max_B_d_bytes);
- }
-
- CL_CHECK((backend_ctx->A_q_d_max = clCreateBuffer(context, 0, max_A_q_d_bytes, NULL, &err), err));
- CL_CHECK((backend_ctx->A_s_d_max = clCreateBuffer(context, 0, max_A_s_d_bytes, NULL, &err), err));
- CL_CHECK((backend_ctx->B_d_max = clCreateBuffer(context, 0, max_B_d_bytes, NULL, &err), err));
-#endif // GGML_OPENCL_USE_ADRENO_KERNELS
-
- // For now we support a single devices
- ggml_backend_opencl_n_devices = 1;
-
- return backend_ctx;
-}
-
-static void ggml_cl2_free(void) {
-#ifdef GGML_OPENCL_PROFILING
- FILE * fperf = fopen("cl_profiling.csv", "w");
- if (!fperf) {
- GGML_LOG_ERROR("Failed to open cl_profiling.csv\n");
- return;
- }
-
- // Populate profiling info
- for (ProfilingInfo & info : g_profiling_info) {
- cl_ulong cmd_queued;
- cl_ulong cmd_submit;
- cl_ulong cmd_start;
- cl_ulong cmd_end;
- cl_ulong cmd_complete;
-
- CL_CHECK(clWaitForEvents(1, &info.evt));
- CL_CHECK(clGetEventProfilingInfo(
- info.evt, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &cmd_queued, NULL));
- CL_CHECK(clGetEventProfilingInfo(
- info.evt, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &cmd_submit, NULL));
- CL_CHECK(clGetEventProfilingInfo(
- info.evt, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &cmd_start, NULL));
- CL_CHECK(clGetEventProfilingInfo(
- info.evt, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &cmd_end, NULL));
- CL_CHECK(clGetEventProfilingInfo(
- info.evt, CL_PROFILING_COMMAND_COMPLETE, sizeof(cl_ulong), &cmd_complete, NULL));
- CL_CHECK(clReleaseEvent(info.evt));
-
- char kernel_name[512];
- CL_CHECK(clGetKernelInfo(info.kernel, CL_KERNEL_FUNCTION_NAME,
- sizeof(kernel_name), kernel_name, NULL));
- info.kernel_name = kernel_name;
-
- info.cmd_queued = cmd_queued;
- info.cmd_submit = cmd_submit;
- info.cmd_start = cmd_start;
- info.cmd_end = cmd_end;
-
- info.cmd_queued_duration_ns = cmd_submit - cmd_queued;
- info.cmd_submit_duration_ns = cmd_start - cmd_submit;
- info.cmd_duration_ns = cmd_end - cmd_start;
- info.cmd_complete_duration_ns = cmd_complete - cmd_end;
- info.cmd_total_duration_ns = cmd_complete - cmd_queued;
- }
-
- // Dump a csv
- float total_kernel_time = 0;
- fprintf(fperf, "op name, kernel name, queued duration (ms), submit duration(ms), exec duration (ms), complete duration (ms), total duration (ms), global size, local size, output size\n");
- for (const ProfilingInfo & info : g_profiling_info) {
- total_kernel_time += info.cmd_duration_ns/1.e6f;
- fprintf(fperf, "%s,%s,%f,%f,%f,%f,%f,%zux%zux%zu,%zux%zux%zu,%zux%zux%zux%zu\n",
- info.op_name.c_str(), info.kernel_name.c_str(),
- info.cmd_queued_duration_ns/1.e6f,
- info.cmd_submit_duration_ns/1.e6f,
- info.cmd_duration_ns/1.e6f,
- info.cmd_complete_duration_ns/1.e6f,
- info.cmd_total_duration_ns/1.e6f,
- info.global_size[0], info.global_size[1], info.global_size[2],
- info.local_size[0], info.local_size[1], info.local_size[2],
- info.output_size[0], info.output_size[1], info.output_size[2], info.output_size[3]);
- }
- fclose(fperf);
-
- GGML_LOG_INFO("ggml_opencl: total kernel time: %f\n", total_kernel_time);
-
- // Dump a simple chrome trace
- FILE* ftrace = fopen("cl_trace.json", "w");
- if (!ftrace) {
- GGML_LOG_ERROR("Failed to open cl_trace.json\n");
- return;
- }
-
- fprintf(ftrace, "[\n");
- for (const ProfilingInfo & info : g_profiling_info) {
- fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"B\", \"ts\": %lu, \"pid\": \"\", \"tid\": \"Host\"},\n",
- info.kernel_name.c_str(), info.cmd_queued/1000);
- fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"E\", \"ts\": %lu, \"pid\": \"\", \"tid\": \"Host\"},\n",
- info.kernel_name.c_str(), info.cmd_submit/1000);
-
- fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"B\", \"ts\": %lu, \"pid\": \"\", \"tid\": \"Device\"},\n",
- info.kernel_name.c_str(), info.cmd_start/1000);
- fprintf(ftrace, "{\"name\": \"%s\", \"cat\": \"OpenCL\", \"ph\": \"E\", \"ts\": %lu, \"pid\": \"\", \"tid\": \"Device\"},\n",
- info.kernel_name.c_str(), info.cmd_end/1000);
- }
- fclose(ftrace);
-#endif
-}
-
-//------------------------------------------------------------------------------
-// Tensor extra management
-//------------------------------------------------------------------------------
-struct ggml_tensor_extra_cl {
- // The buffer object that holds the data.
- cl_mem data_device;
- // The offset into the buffer object. This is primarily for scratch buffer
- // and view operation.
- // NB: this offset no longer includes view offset (view_offs). Whenever this
- // offset is used, view_offs should be considered.
- cl_ulong offset;
- // The actual size of the cl_mem object. This is needed when returning the
- // block to the pool.
- size_t actual_size;
-
- void reset() {
- data_device = nullptr;
- offset = 0;
- actual_size = 0;
- }
-};
-
-// Additional tensor extra structs for quantized tensors.
-// These tensors are loaded from files and should not be allocated in scratch --
-// they should always be allocated from the pool. Hence, they do not have an
-// `offset`, which indicate their locations in the scratch buffer.
-struct ggml_tensor_extra_cl_q4_0 {
- // Quantized values.
- cl_mem q = nullptr;
- // Quantized values in image1d_buffer_t.
- cl_mem q_img = nullptr;
- // Scales.
- cl_mem d = nullptr;
- // Scales in image1d_buffer_t.
- cl_mem d_img = nullptr;
- // Size of quantized values.
- size_t size_q = 0;
- // Size of scales.
- size_t size_d = 0;
-
- ~ggml_tensor_extra_cl_q4_0() {
- reset();
- }
-
- void reset() {
- // q and d are subbuffers into the bigger buffer allocated in ggml_backend_buffer.
- // They must be properly released so that the original buffer can be
- // properly released to avoid memory leak.
- if (q != nullptr) {
- CL_CHECK(clReleaseMemObject(q));
- q = nullptr;
- }
- if (d != nullptr) {
- CL_CHECK(clReleaseMemObject(d));
- d = nullptr;
- }
- // Currently, q_img and d_img are only initialized when SMALL_ALLOC is
- // enabled. They point to the images in ggml_backend_opencl_buffer_context.
- // So, there is no need to release them here.
- // TODO: initialize them for non SMALL_PATH path, or remove them.
- q_img = nullptr;
- d_img = nullptr;
- size_q = 0;
- size_d = 0;
- }
-};
-
-//------------------------------------------------------------------------------
-// Backend API
-//------------------------------------------------------------------------------
-
-//
-// backend
-//
-static const char * ggml_backend_opencl_name(ggml_backend_t backend) {
- return "OpenCL";
-
- UNUSED(backend);
-}
-
-static void ggml_backend_opencl_free(ggml_backend_t backend) {
- ggml_cl2_free();
-
- GGML_UNUSED(backend);
-}
-
-static void ggml_backend_opencl_set_tensor_async(ggml_backend_t backend, ggml_tensor * tensor, const void * data, size_t offset, size_t size) {
- GGML_UNUSED(backend);
- GGML_UNUSED(tensor);
- GGML_UNUSED(data);
- GGML_UNUSED(offset);
- GGML_UNUSED(size);
-}
-
-static void ggml_backend_opencl_get_tensor_async(ggml_backend_t backend, const ggml_tensor * tensor, void * data, size_t offset, size_t size) {
- GGML_UNUSED(backend);
- GGML_UNUSED(tensor);
- GGML_UNUSED(data);
- GGML_UNUSED(offset);
- GGML_UNUSED(size);
-}
-
-static bool ggml_backend_opencl_cpy_tensor_async(ggml_backend_t backend, const ggml_tensor * src, ggml_tensor * dst) {
- GGML_UNUSED(backend);
- GGML_UNUSED(src);
- GGML_UNUSED(dst);
- return false;
-}
-
-static void ggml_backend_opencl_synchronize(ggml_backend_t backend) {
- GGML_UNUSED(backend);
-}
-
-static ggml_status ggml_backend_opencl_graph_compute(ggml_backend_t backend, ggml_cgraph * cgraph) {
- for (int i = 0; i < cgraph->n_nodes; i++) {
- ggml_tensor * node = cgraph->nodes[i];
-
- if (node->op == GGML_OP_RESHAPE || node->op == GGML_OP_TRANSPOSE || node->op == GGML_OP_VIEW || node->op == GGML_OP_PERMUTE || node->op == GGML_OP_NONE) {
- continue;
- }
-
- bool ok = ggml_cl_compute_forward(backend, node);
- if (!ok) {
- GGML_LOG_ERROR("%s: error: op not supported %s (%s)\n", __func__, node->name, ggml_op_name(node->op));
- }
- GGML_ASSERT(ok);
- }
-
- return GGML_STATUS_SUCCESS;
-}
-
-static bool ggml_opencl_supports_op(ggml_backend_dev_t dev, const struct ggml_tensor * op) {
- GGML_UNUSED(dev);
-
- switch (op->op) {
- case GGML_OP_NONE:
- return true;
- case GGML_OP_GET_ROWS:
- switch (op->src[0]->type) {
- case GGML_TYPE_F32:
- case GGML_TYPE_F16:
- return true;
- case GGML_TYPE_Q4_0:
-#ifdef GGML_OPENCL_SOA_Q
- // We do not support flattened Q4_0 (and possibly other Q's)
- return false;
-#else // GGML_OPENCL_SOA_Q
- return true;
-#endif // GGML_OPENCL_SOA_Q
- default:
- return false;
- }
- case GGML_OP_CPY:
- case GGML_OP_DUP:
- case GGML_OP_CONT:
- switch (op->src[0]->type) {
- case GGML_TYPE_F32:
- switch (op->type) {
- case GGML_TYPE_F16:
- case GGML_TYPE_F32:
- return true;
- default:
- return false;
- }
- case GGML_TYPE_F16:
- switch (op->type) {
- case GGML_TYPE_F16:
- case GGML_TYPE_F32:
- return true;
- default:
- return false;
- }
- default:
- return false;
- }
- case GGML_OP_ADD:
- case GGML_OP_SCALE:
- case GGML_OP_MUL:
- return op->src[0]->type == GGML_TYPE_F32;
- case GGML_OP_UNARY:
- switch (ggml_get_unary_op(op)) {
- case GGML_UNARY_OP_GELU:
- case GGML_UNARY_OP_SILU:
- case GGML_UNARY_OP_RELU:
- case GGML_UNARY_OP_GELU_QUICK:
- return ggml_is_contiguous(op->src[0]) && op->src[0]->type == GGML_TYPE_F32;
- default:
- return false;
- }
- case GGML_OP_CLAMP:
- return op->src[0]->type == GGML_TYPE_F32;
- case GGML_OP_SOFT_MAX:
- case GGML_OP_NORM:
- case GGML_OP_RMS_NORM:
- return true;
- case GGML_OP_MUL_MAT:
- if (op->src[0]->type == GGML_TYPE_F16) {
- return true;
- } else if (op->src[0]->type == GGML_TYPE_F32) {
- return op->src[1]->type == GGML_TYPE_F32 && ggml_is_contiguous(op->src[0]) && ggml_is_contiguous(op->src[1]);
- } else if (op->src[0]->type == GGML_TYPE_Q4_0 ||
- op->src[0]->type == GGML_TYPE_Q6_K) {
- return op->src[1]->type == GGML_TYPE_F32 && ggml_is_contiguous(op->src[0]) && ggml_is_contiguous(op->src[1]);
- }
- return false;
- case GGML_OP_RESHAPE:
- case GGML_OP_VIEW:
- case GGML_OP_PERMUTE:
- case GGML_OP_TRANSPOSE:
- return true;
- case GGML_OP_DIAG_MASK_INF:
- return op->ne[3] == 1;
- case GGML_OP_ROPE: {
- const int mode = ((const int32_t *) op->op_params)[2];
- const bool is_mrope = mode & GGML_ROPE_TYPE_MROPE;
- const bool is_vision = mode == GGML_ROPE_TYPE_VISION;
- if (is_mrope && !is_vision) {
- if (op->src[0]->type == GGML_TYPE_F32 ||
- op->src[0]->type == GGML_TYPE_F16) {
- return true;
- }
- return false;
- }
- if (is_vision) {
- if (op->src[0]->type == GGML_TYPE_F32 ||
- op->src[0]->type == GGML_TYPE_F16) {
- return true;
- }
- return false;
- }
- return true;
- }
- case GGML_OP_IM2COL:
- return true;
- default:
- return false;
- }
-}
-
-// Forward declaration - implementation appears later in the file.
-static const char * ggml_backend_opencl_buffer_type_get_name(ggml_backend_buffer_type_t buffer_type);
-
-static ggml_guid_t ggml_backend_opencl_guid() {
- static ggml_guid guid = { 0xde, 0xe0, 0x70, 0xa2, 0x73, 0x4e, 0x4d, 0xbc, 0xb0, 0xc7, 0x4f, 0xd4, 0x6d, 0x4e, 0x90, 0xfe };
- return &guid;
-}
-
-static ggml_backend_i ggml_backend_opencl_i = {
- /* .get_name = */ ggml_backend_opencl_name,
- /* .free = */ ggml_backend_opencl_free,
- /* .set_tensor_async = */ NULL, /* ggml_backend_opencl_set_tensor_async */
- /* .get_tensor_async = */ NULL, /* ggml_backend_opencl_get_tensor_async */
- /* .cpy_tensor_async = */ NULL, /* ggml_backend_opencl_cpy_tensor_async */
- /* .synchronize = */ NULL, /* ggml_backend_opencl_synchronize */
- /* .graph_plan_create = */ NULL,
- /* .graph_plan_free = */ NULL,
- /* .graph_plan_update = */ NULL,
- /* .graph_plan_compute = */ NULL,
- /* .graph_compute = */ ggml_backend_opencl_graph_compute,
- /* .event_record = */ NULL,
- /* .event_wait = */ NULL,
-};
-
-ggml_backend_t ggml_backend_opencl_init(void) {
- ggml_backend_dev_t dev = ggml_backend_reg_dev_get(ggml_backend_opencl_reg(), 0);
- ggml_backend_opencl_context *backend_ctx = ggml_cl2_init(dev);
-
- ggml_backend_t backend = new ggml_backend {
- /* .guid = */ ggml_backend_opencl_guid(),
- /* .interface = */ ggml_backend_opencl_i,
- /* .device = */ dev,
- /* .context = */ backend_ctx
- };
-
- return backend;
-}
-
-bool ggml_backend_is_opencl(ggml_backend_t backend) {
- return backend && backend->iface.get_name == ggml_backend_opencl_name;
-}
-
-//
-// buffer
-//
-struct ggml_backend_opencl_buffer_context {
- // A buffer context can hold multiple cl_mem objects. This is for flattening
- // quantized weights and should be used with GGML_OPENCL_SMALL_ALLOC where
- // each tensor is allocated a separate buffer. When flattening is enabled
- // with small allocation, each tensor is backed by two cl_mem objects (for
- // quants and scales) packed into a backend_opencl_buffer.
- ggml_backend_opencl_buffer_context(cl_mem buf)
- : name("OpenCL") {
- buffer.push_back(buf);
- }
-
- ~ggml_backend_opencl_buffer_context() {
- for (cl_mem buf : buffer) {
- CL_CHECK(clReleaseMemObject(buf));
- }
- for (cl_mem im : img) {
- CL_CHECK(clReleaseMemObject(im));
- }
-
- // Delete all extras to trigger their destructors
- for (ggml_tensor_extra_cl * e : temp_tensor_extras) {
- delete e;
- }
- for (ggml_tensor_extra_cl * e : temp_tensor_extras_in_use) {
- delete e;
- }
- for (ggml_tensor_extra_cl_q4_0 * e : temp_tensor_extras_q4_0) {
- delete e;
- }
- for (ggml_tensor_extra_cl_q4_0 * e : temp_tensor_extras_q4_0_in_use) {
- delete e;
- }
- }
-
- ggml_tensor_extra_cl * ggml_opencl_alloc_temp_tensor_extra() {
- ggml_tensor_extra_cl * extra;
- if (temp_tensor_extras.empty()) {
- extra = new ggml_tensor_extra_cl();
- } else {
- extra = temp_tensor_extras.back();
- temp_tensor_extras.pop_back();
- }
-
- temp_tensor_extras_in_use.push_back(extra);
-
- extra->reset();
- return extra;
- }
-
- ggml_tensor_extra_cl_q4_0 * ggml_opencl_alloc_temp_tensor_extra_q4_0() {
- ggml_tensor_extra_cl_q4_0 * extra;
- if (temp_tensor_extras_q4_0.empty()) {
- extra = new ggml_tensor_extra_cl_q4_0();
- } else {
- extra = temp_tensor_extras_q4_0.back();
- temp_tensor_extras_q4_0.pop_back();
- }
-
- temp_tensor_extras_q4_0_in_use.push_back(extra);
-
- extra->reset();
- return extra;
- }
-
- void reset() {
- for (ggml_tensor_extra_cl * e : temp_tensor_extras_in_use) {
- temp_tensor_extras.push_back(e);
- }
- temp_tensor_extras_in_use.clear();
-
- for (ggml_tensor_extra_cl_q4_0 * e : temp_tensor_extras_q4_0_in_use) {
- temp_tensor_extras_q4_0.push_back(e);
- }
- temp_tensor_extras_q4_0_in_use.clear();
- }
-
- // Pools for extras. Available extras are in `temp_tensor_extras`. Extras
- // being used are in `temp_tensor_extras_in_use`. At the first run, new
- // extras get created and put in `in_use`. When the buffer is reset via
- // the `reset` callback, all extras in `in_use` get moved to available extras
- // for reuse.
- std::vector temp_tensor_extras;
- std::vector temp_tensor_extras_in_use;
- std::vector temp_tensor_extras_q4_0;
- std::vector temp_tensor_extras_q4_0_in_use;
-
- // The buffer_context is initially created by ggml_backend_buft_alloc_buffer
- // before any tensor is initialized (at the beginning of alloc_tensor_range).
- // Hence, there is alway a buffer object in this vector. When each tensor is
- // being initialized, this original buffer object will be released if both
- // flattening and small allocation are enabled, and additional buffer
- // objects will be created in init_tensor to represent flattened quantized
- // weights.
- std::vector buffer;
- // These are image1d_buffer_t objects that wrap around the quants and scales.
- // For Q4_0 quantization, there should be two of them - one for quants and
- // one for scales. They should be populated only when flattening and small
- // allocation are enabled.
- std::vector img;
- std::string name;
-};
-
-static void ggml_backend_opencl_buffer_free_buffer(ggml_backend_buffer_t buffer) {
- ggml_backend_opencl_buffer_context * ctx = (ggml_backend_opencl_buffer_context *) buffer->context;
- delete ctx;
-}
-
-static void * ggml_backend_opencl_buffer_get_base(ggml_backend_buffer_t buffer) {
- ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(buffer->buft->device);
- return (void *) (uintptr_t) backend_ctx->alignment;
-}
-
-static enum ggml_status ggml_backend_opencl_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor) {
- ggml_backend_opencl_buffer_context * ctx = (ggml_backend_opencl_buffer_context *) buffer->context;
-
- ggml_cl2_init(buffer->buft->device);
-
- if (tensor->view_src != nullptr) {
- GGML_ASSERT(tensor->view_src->buffer->buft == buffer->buft);
-
- ggml_tensor_extra_cl * view_extra = (ggml_tensor_extra_cl *) tensor->view_src->extra;
- GGML_ASSERT(view_extra && "view_extra is nullptr?");
-
- // Reuse extra of the parent tensor. The offset of this view tensor
- // becomes `extra->offset + view_offs` and needs to be calculated when
- // it is used. This changes is needed because of the change to
- // ggml_alloc.c in https://github.com/ggerganov/llama.cpp/pull/7640.
- // `buffer` passed in here will always be `tensor->buffer`. It is OK
- // to allocate extras from the same buffer context for ordinary
- // intermediate tensors. But for views into kv cache tensors, doing so
- // would mess up the extras used by kv cache.
- // Before #7640, `buffer` is for intermediate tensors, which is always
- // different from that of kv cache tensors.
- //
- // NB: now extra->offset no longer accounts for view_offs.
- // NB: this should not apply to weight tensors (for end-to-end runs, but
- // may apply for test-backend-ops).
- // FIXME: if any unexpected results are seen, double check the offset -
- // there could be other places that need fix.
- tensor->extra = view_extra;
- } else {
- {
- size_t offset = (char *) tensor->data - (char *) ggml_backend_opencl_buffer_get_base(buffer);
-
- ggml_tensor_extra_cl * extra = ctx->ggml_opencl_alloc_temp_tensor_extra();
- extra->offset = offset;
- extra->data_device = ctx->buffer[0];
- extra->actual_size = ggml_nbytes(tensor);
-
- tensor->extra = extra;
- }
- }
- return GGML_STATUS_SUCCESS;
-}
-
-// The optimized gemm and gemv kernels are used for large matrices without batch.
-// tensor is the quantized weights matrix.
-inline bool use_adreno_kernels(const ggml_backend_opencl_context *backend_ctx, const ggml_tensor *tensor) {
- int64_t threshold_ne0 = 512;
- int64_t threshold_ne1 = 512;
- if (!backend_ctx->adreno_cl_compiler_version.newer_than_or_same(E031, 38, 11, 0) &&
- backend_ctx->adreno_cl_compiler_version.type != DX) {
- threshold_ne0 = 128;
- threshold_ne1 = 128;
- }
- return tensor->ne[0] >= threshold_ne0 && tensor->ne[1] >= threshold_ne1 &&
- tensor->ne[2] == 1 && tensor->ne[3] == 1;
-}
-
-static void ggml_backend_opencl_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor, const void * data, size_t offset, size_t size) {
- ggml_backend_opencl_context *backend_ctx = ggml_cl2_init(buffer->buft->device);
-
- cl_context context = backend_ctx->context;
- cl_command_queue queue = backend_ctx->queue;
-
-#ifdef GGML_OPENCL_SOA_Q
- // We separate the quantized bits and scale from block_q4_0 by using an
- // additional kernel, where each thread handles a block. We first read the
- // original weights into a temporary buffer, then create two separate
- // buffers for quantized bits and scales, which are then populated by the
- // conversion kernel.
- if (tensor->type == GGML_TYPE_Q4_0) {
- // Tensors should have been preallocated, therefore they should
- // already have ggml_tensor_extra_cl as extra.
- ggml_tensor_extra_cl * extra_orig = (ggml_tensor_extra_cl *)tensor->extra;
- GGML_ASSERT(extra_orig && "Tesnors in OpenCL backend should have been allocated and initialized");
-
- // Allocate the new extra and create aliases from the original.
- ggml_backend_opencl_buffer_context * ctx = (ggml_backend_opencl_buffer_context *) buffer->context;
- ggml_tensor_extra_cl_q4_0 * extra = ctx->ggml_opencl_alloc_temp_tensor_extra_q4_0();
-
- size_t size_d = ggml_nelements(tensor)/ggml_blck_size(tensor->type)*sizeof(ggml_fp16_t);
- size_t size_q = ggml_nelements(tensor)/ggml_blck_size(tensor->type)*ggml_blck_size(tensor->type)/2;
- GGML_ASSERT(size_d + size_q == ggml_nbytes(tensor) && "Incorrect tensor size");
-
- cl_int err;
- cl_mem data_device = clCreateBuffer(context, CL_MEM_READ_WRITE,
- ggml_nbytes(tensor), NULL, &err);
- CL_CHECK(err);
- CL_CHECK(clEnqueueWriteBuffer(
- queue, data_device, CL_TRUE, 0,
- ggml_nbytes(tensor), data, 0, NULL, NULL));
-
- // We consider the specified offset arg as always, although For weights
- // the offset arg should be 0 (we do not assert this).
- //GGML_ASSERT(offset == 0);
-
- // We create subbuffers from the original tensor buffer for scales and
- // quants - i.e., scales and quants are aliases into the buffer obejct
- // that backs the original tensor. This is a cleaner way to adapt to the
- // new memory management.
- // In the old code, we allocate new buffers for scales and quants
- // respectively, which could still be done but would result in double
- // allocation; properly deallocating the preallocated buffer that backs
- // the tensors is tricky and would leak the backend specific information
- // into the general backend code.
- // Does this create misaligned subbuffers (alignment is 1024) in certain
- // cases ?
- cl_buffer_region region;
-
- // The original tensor memory is divided into scales and quants, i.e.,
- // we first store scales, then quants.
- // Create subbuffer for scales.
- region.origin = extra_orig->offset + tensor->view_offs + offset;
- region.size = size_d;
- extra->d = clCreateSubBuffer(
- extra_orig->data_device, CL_MEM_READ_WRITE,
- CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err);
- CL_CHECK(err);
-
- // Create subbuffer for quants.
- region.origin = extra_orig->offset + tensor->view_offs + offset + size_d;
- region.size = size_q;
- extra->q = clCreateSubBuffer(
- extra_orig->data_device, CL_MEM_READ_WRITE,
- CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err);
- CL_CHECK(err);
-
- //cl_kernel kernel = backend_ctx->kernel_convert_block_q4_0;
- #ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- cl_kernel kernel = backend_ctx->kernel_convert_block_q4_0;
-
- // The optimized kernels need weights in natural order, so unshuffle.
- if (use_adreno_kernels(backend_ctx, tensor)) {
- kernel = backend_ctx->kernel_convert_block_q4_0_noshuffle;
- }
- #else
- cl_kernel kernel = backend_ctx->kernel_convert_block_q4_0;
- #endif // GGML_OPENCL_USE_ADRENO_KERNELS
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &extra->q));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra->d));
-
- size_t global_work_size[] = {(size_t)ggml_nelements(tensor)/ggml_blck_size(tensor->type), 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
- CL_CHECK(clReleaseMemObject(data_device));
-
- tensor->extra = extra;
-
- // transpose the weights and scales
- #ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- // Only do transpose for large, non batched matrix
- // TODO: use preallocated images instead of sub-buffer then image
- if (use_adreno_kernels(backend_ctx, tensor)) {
- // <----------------------------------------------------------------------------------> //
- // start transpose
- // <----------------------------------------------------------------------------------> //
- int M = tensor->ne[1]; // ne01
- int K = tensor->ne[0]; // ne00
-
- //For matrix-vector multiplication kernel, we assume K is a multiple of 32
- GGML_ASSERT(K % 32 == 0);
- //For transpose kernels, we assume K is a multiple of 4 (satisfied by prior assert), and M is a multiple of 4
- GGML_ASSERT(M % 4 == 0);
-
- // transpose is out of place, so we need to allocate transposed buffers
- // <----------------------------------------------------------------------------------> //
- // use sub_buffer of max buffer size instead
-
- size_t q_size_bytes = K * M / 8 * sizeof(float);
- cl_buffer_region region;
- region.origin = 0;
- region.size = q_size_bytes;
- cl_mem qT_d = clCreateSubBuffer(
- backend_ctx->A_q_d_max,
- 0,
- CL_BUFFER_CREATE_TYPE_REGION,
- ®ion,
- &err);
- // cl_mem qT_d = clCreateBuffer(context, CL_MEM_READ_WRITE, q_size_bytes, NULL, &err);
- CL_CHECK(err);
-
- // size_t d_size_bytes = M * (K / 32) / 2 * sizeof(float);
- size_t d_size_bytes = M * (K / 32) * 2;
- region.origin = 0;
- region.size = d_size_bytes;
- cl_mem dT_d = clCreateSubBuffer(
- backend_ctx->A_s_d_max,
- 0,
- CL_BUFFER_CREATE_TYPE_REGION,
- ®ion,
- &err);
- // cl_mem dT_d = clCreateBuffer(context, CL_MEM_READ_WRITE, d_size_bytes, NULL, &err);
- CL_CHECK(err);
-
- // <----------------------------------------------------------------------------------> //
-
-
- // create images from the buffers
- // <----------------------------------------------------------------------------------> //
- cl_mem q_d_image1D;
- cl_mem d_d_image1D;
- cl_mem qT_d_image1D;
- cl_mem dT_d_image1D;
-
- cl_image_format img_fmt_1d = { CL_RGBA, CL_HALF_FLOAT };
- cl_image_desc img_desc_1d;
-
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.image_width = M * K / 4 / 4;
- img_desc_1d.buffer = extra->q;
- q_d_image1D = clCreateImage(context, 0, &img_fmt_1d, &img_desc_1d, NULL, &err);
- CL_CHECK(err);
-
- img_fmt_1d = { CL_RGBA, CL_HALF_FLOAT };
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.image_width = M * K / 4 / 4;
- img_desc_1d.buffer = qT_d;
- qT_d_image1D = clCreateImage(context, 0, &img_fmt_1d, &img_desc_1d, NULL, &err);
- CL_CHECK(err);
-
- img_fmt_1d = { CL_RGBA, CL_HALF_FLOAT };
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.image_width = M * K / 32 / 4;
- img_desc_1d.buffer = extra->d;
- d_d_image1D = clCreateImage(context, 0, &img_fmt_1d, &img_desc_1d, NULL, &err);
- CL_CHECK(err);
-
- img_fmt_1d = { CL_RGBA, CL_HALF_FLOAT };
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.image_width = M * K / 32 / 4;
- img_desc_1d.buffer = dT_d;
- dT_d_image1D = clCreateImage(context, 0, &img_fmt_1d, &img_desc_1d, NULL, &err);
- CL_CHECK(err);
- // <----------------------------------------------------------------------------------> //
-
- // set up and call the transpose kernels
- // <----------------------------------------------------------------------------------> //
- // weights
- int height_q = M / 4;
- int width_q = K / 4 / 4;
- kernel = backend_ctx->kernel_transpose_16;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &q_d_image1D));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &qT_d_image1D));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(int), &height_q));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(int), &width_q));
-
- size_t local_size_q[3] = {4, 16, 1};
- size_t global_size_q[3] = {static_cast(width_q), static_cast(height_q), 1};
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_size_q, local_size_q, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
-
- // scales
- int height_s = M / 4;
- int width_s = K / 32 / 4;
-
- kernel = backend_ctx->kernel_transpose_16;
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_d_image1D));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &dT_d_image1D));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(int), &height_s));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(int), &width_s));
-
- size_t local_size_s[3] = {4, 16, 1};
- size_t global_size_s[3] = {static_cast(width_s), static_cast(height_s), 1};
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_size_s, local_size_s, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
- // <----------------------------------------------------------------------------------> //
-
- // copy transposed buffer contents to original buffers
- // <----------------------------------------------------------------------------------> //
- // weights
- CL_CHECK(clEnqueueCopyBuffer(queue, qT_d, extra->q, 0, 0, q_size_bytes, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
-
- // scales
- CL_CHECK(clEnqueueCopyBuffer(queue, dT_d, extra->d, 0, 0, d_size_bytes, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
- // <----------------------------------------------------------------------------------> //
-
- // deallocate transpose buffers
- // <----------------------------------------------------------------------------------> //
- CL_CHECK(clReleaseMemObject(qT_d));
- CL_CHECK(clReleaseMemObject(dT_d));
-
- // deallocate temporary images
- CL_CHECK(clReleaseMemObject(q_d_image1D));
- CL_CHECK(clReleaseMemObject(d_d_image1D));
- CL_CHECK(clReleaseMemObject(qT_d_image1D));
- CL_CHECK(clReleaseMemObject(dT_d_image1D));
- // <----------------------------------------------------------------------------------> //
- // end transpose
- // <----------------------------------------------------------------------------------> //
- }
- #endif // GGML_OPENCL_USE_ADRENO_KERNELS
-
- return;
- }
-#endif // GGML_OPENCL_SOA_Q
-
- ggml_tensor_extra_cl * extra = (ggml_tensor_extra_cl *) tensor->extra;
- GGML_ASSERT(extra);
-
- CL_CHECK(clEnqueueWriteBuffer(
- queue, extra->data_device, CL_TRUE, extra->offset + offset,
- size, data, 0, NULL, NULL));
-
- GGML_UNUSED(buffer);
-}
-
-static void ggml_backend_opencl_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor * tensor, void * data, size_t offset, size_t size) {
- GGML_ASSERT(tensor->extra);
-
- ggml_backend_opencl_context *backend_ctx = ggml_cl2_init(buffer->buft->device);
-
- cl_context context = backend_ctx->context;
- cl_command_queue queue = backend_ctx->queue;
-
- // Make sure all previously submitted commands are finished.
- CL_CHECK(clFinish(queue));
-
-#ifdef GGML_OPENCL_SOA_Q
- // In end-to-end runs, get_tensor is usually used to get back the logits,
- // where we can simply do clEnqueueReadBuffer since they are f32.
- // However, in test-backend-ops, the GPU graph is copied to the CPU backend,
- // which requires reading back quantized weight tensors.
- // To properly support this, we need to restore block_q4_0 struct arrays
- // from the flattened buffers.
- if (tensor->type == GGML_TYPE_Q4_0) {
- ggml_tensor_extra_cl_q4_0 * extra = (ggml_tensor_extra_cl_q4_0 *)tensor->extra;
-
- cl_int err;
- cl_mem data_device = clCreateBuffer(context, CL_MEM_READ_WRITE,
- ggml_nbytes(tensor), NULL, &err);
- CL_CHECK(err);
-
- cl_kernel kernel = backend_ctx->kernel_restore_block_q4_0;
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra->q));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &extra->d));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &data_device));
-
- size_t global_work_size[] = {(size_t)ggml_nelements(tensor)/ggml_blck_size(tensor->type), 1, 1};
- size_t local_work_size[] = {1, 1, 1};
-
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL,
- global_work_size, local_work_size, 0, NULL, &evt));
- CL_CHECK(clWaitForEvents(1, &evt));
- CL_CHECK(clEnqueueReadBuffer(
- queue, data_device, CL_TRUE, offset,
- size, data, 0, NULL, NULL));
- CL_CHECK(clReleaseMemObject(data_device));
- return;
- }
-#endif // GGML_OPENCL_SOA_Q
-
- ggml_tensor_extra_cl * extra = (ggml_tensor_extra_cl *) tensor->extra;
-
- CL_CHECK(clEnqueueReadBuffer(
- queue, extra->data_device, CL_TRUE, extra->offset + tensor->view_offs + offset,
- size, data, 0, NULL, NULL));
-
- GGML_UNUSED(buffer);
-}
-
-static void ggml_backend_opencl_buffer_clear(ggml_backend_buffer_t buffer, uint8_t value) {
- ggml_backend_dev_t dev = buffer->buft->device;
- ggml_backend_opencl_context *backend_ctx = ggml_cl2_init(dev);
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_backend_opencl_buffer_context * ctx = (ggml_backend_opencl_buffer_context *) buffer->context;
- for (cl_mem buf : ctx->buffer) {
- CL_CHECK(clEnqueueFillBuffer(queue, buf, &value, sizeof(value), 0, buffer->size, 0, NULL, NULL));
- }
- CL_CHECK(clFinish(queue));
-}
-
-static void ggml_backend_opencl_buffer_reset(ggml_backend_buffer_t buffer) {
- ggml_backend_opencl_buffer_context * ctx = (ggml_backend_opencl_buffer_context *) buffer->context;
- ctx->reset();
-}
-
-static ggml_backend_buffer_i ggml_backend_opencl_buffer_interface = {
- /* .free_buffer = */ ggml_backend_opencl_buffer_free_buffer,
- /* .get_base = */ ggml_backend_opencl_buffer_get_base,
- /* .init_tensor = */ ggml_backend_opencl_buffer_init_tensor,
- /* .memset_tensor = */ NULL,
- /* .set_tensor = */ ggml_backend_opencl_buffer_set_tensor,
- /* .get_tensor = */ ggml_backend_opencl_buffer_get_tensor,
- /* .cpy_tensor = */ NULL,
- /* .clear = */ ggml_backend_opencl_buffer_clear,
- /* .reset = */ ggml_backend_opencl_buffer_reset,
-};
-
-//
-// buffer type
-//
-
-static const char * ggml_backend_opencl_buffer_type_get_name(ggml_backend_buffer_type_t buffer_type) {
- return "OpenCL";
-
- GGML_UNUSED(buffer_type);
-}
-
-static ggml_backend_buffer_t ggml_backend_opencl_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buffer_type, size_t size) {
- ggml_backend_opencl_context *backend_ctx = ggml_cl2_init(buffer_type->device);
-
- // clCreateBuffer returns -61 for size 0
- size = std::max(size, (size_t)1);
-
- cl_int err;
- cl_mem mem = clCreateBuffer(backend_ctx->context, CL_MEM_READ_WRITE, size, NULL, &err);
- if (err != CL_SUCCESS) {
- GGML_LOG_INFO("%s: failed to allocate %.2f MiB\n", __func__, size / 1024.0 / 1024.0);
- return nullptr;
- }
-
- ggml_backend_opencl_buffer_context * ctx = new ggml_backend_opencl_buffer_context(mem);
-
- return ggml_backend_buffer_init(buffer_type, ggml_backend_opencl_buffer_interface, ctx, size);
-}
-
-static size_t ggml_backend_opencl_buffer_type_get_alignment(ggml_backend_buffer_type_t buffer_type) {
- // FIXME: not thread safe, device may not be initialized yet
- static cl_uint alignment = -1;
- if (alignment == (cl_uint)-1) {
- ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(buffer_type->device);
- alignment = backend_ctx->alignment;
- }
- return alignment;
-}
-
-static size_t ggml_backend_opencl_buffer_type_get_max_size(ggml_backend_buffer_type_t buffer_type) {
- static size_t max_size = -1;
- if (max_size == (size_t)-1) {
- ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(buffer_type->device);
- max_size = backend_ctx->max_alloc_size;
- }
- return max_size;
-}
-
-static bool ggml_backend_opencl_buffer_type_supports_backend(ggml_backend_buffer_type_t buft, ggml_backend_t backend) {
- return ggml_backend_is_opencl(backend);
-
- UNUSED(buft);
-}
-
-static ggml_backend_buffer_type_i ggml_backend_opencl_buffer_type_interface = {
- /* .get_name = */ ggml_backend_opencl_buffer_type_get_name,
- /* .alloc_buffer = */ ggml_backend_opencl_buffer_type_alloc_buffer,
- /* .get_alignment = */ ggml_backend_opencl_buffer_type_get_alignment,
- /* .get_max_size = */ ggml_backend_opencl_buffer_type_get_max_size,
- /* .get_alloc_size = */ NULL,
- /* .is_host = */ NULL,
-};
-
-ggml_backend_buffer_type_t ggml_backend_opencl_buffer_type() {
- static ggml_backend_buffer_type buffer_type = {
- /* .iface = */ ggml_backend_opencl_buffer_type_interface,
- /* .device = */ &g_ggml_backend_opencl_device,
- /* .context = */ nullptr,
- };
-
- return &buffer_type;
-}
-
-//
-// backend device
-//
-
-static const char * ggml_backend_opencl_device_get_name(ggml_backend_dev_t dev) {
- return "GPUOpenCL";
-
- GGML_UNUSED(dev);
-}
-
-static const char * ggml_backend_opencl_device_get_description(ggml_backend_dev_t dev) {
- ggml_backend_opencl_device_context *dev_ctx = (ggml_backend_opencl_device_context *) dev->context;
- return dev_ctx->device_name.c_str();
-}
-
-static void ggml_backend_opencl_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) {
- *free = 1;
- *total = 1;
-
- GGML_UNUSED(dev);
-}
-
-static enum ggml_backend_dev_type ggml_backend_opencl_device_get_type(ggml_backend_dev_t dev) {
- return GGML_BACKEND_DEVICE_TYPE_GPU;
-
- GGML_UNUSED(dev);
-}
-
-static void ggml_backend_opencl_device_get_props(ggml_backend_dev_t dev, struct ggml_backend_dev_props * props) {
- props->name = ggml_backend_opencl_device_get_name(dev);
- props->description = ggml_backend_opencl_device_get_description(dev);
- props->type = ggml_backend_opencl_device_get_type(dev);
- ggml_backend_opencl_device_get_memory(dev, &props->memory_free, &props->memory_total);
- props->caps = ggml_backend_dev_caps {
- /* .async = */ false,
- /* .host_buffer = */ false,
- /* .buffer_from_host_ptr = */ false,
- /* .events = */ false,
- };
-}
-
-static ggml_backend_t ggml_backend_opencl_device_init(ggml_backend_dev_t dev, const char * params) {
- ggml_backend_opencl_context * backend_ctx = ggml_cl2_init(dev);
-
- ggml_backend_t backend = new ggml_backend {
- /* .guid = */ ggml_backend_opencl_guid(),
- /* .interface = */ ggml_backend_opencl_i,
- /* .device = */ dev,
- /* .context = */ backend_ctx,
- };
-
- return backend;
-
- GGML_UNUSED(params);
-}
-
-static ggml_backend_buffer_type_t ggml_backend_opencl_device_get_buffer_type(ggml_backend_dev_t dev) {
- return ggml_backend_opencl_buffer_type();
-
- GGML_UNUSED(dev);
-}
-
-static ggml_backend_buffer_t ggml_backend_opencl_device_buffer_from_ptr(ggml_backend_dev_t dev, void * ptr, size_t size, size_t max_tensor_size) {
- GGML_UNUSED(dev);
- GGML_UNUSED(ptr);
- GGML_UNUSED(size);
- GGML_UNUSED(max_tensor_size);
- return nullptr;
-}
-
-static bool ggml_backend_opencl_device_supports_op(ggml_backend_dev_t dev, const struct ggml_tensor * op) {
- return ggml_opencl_supports_op(dev, op);
-}
-
-static bool ggml_backend_opencl_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) {
- return buft->iface.get_name == ggml_backend_opencl_buffer_type_get_name;
-
- GGML_UNUSED(dev);
-}
-
-static struct ggml_backend_device_i ggml_backend_opencl_device_i = {
- /* .get_name = */ ggml_backend_opencl_device_get_name,
- /* .get_description = */ ggml_backend_opencl_device_get_description,
- /* .get_memory = */ ggml_backend_opencl_device_get_memory,
- /* .get_type = */ ggml_backend_opencl_device_get_type,
- /* .get_props = */ ggml_backend_opencl_device_get_props,
- /* .init_backend = */ ggml_backend_opencl_device_init,
- /* .get_buffer_type = */ ggml_backend_opencl_device_get_buffer_type,
- /* .get_host_buffer_type = */ NULL,
- /* .buffer_from_host_ptr = */ ggml_backend_opencl_device_buffer_from_ptr,
- /* .supports_op = */ ggml_backend_opencl_device_supports_op,
- /* .supports_buft = */ ggml_backend_opencl_device_supports_buft,
- /* .offload_op = */ NULL,
- /* .event_new = */ NULL,
- /* .event_free = */ NULL,
- /* .event_synchronize = */ NULL,
-};
-
-// Backend registry
-
-static const char * ggml_backend_opencl_reg_get_name(ggml_backend_reg_t reg) {
- return "OpenCL";
-
- GGML_UNUSED(reg);
-}
-
-static size_t ggml_backend_opencl_reg_device_count(ggml_backend_reg_t reg) {
- return ggml_backend_opencl_n_devices;
-
- GGML_UNUSED(reg);
-}
-
-static ggml_backend_dev_t ggml_backend_opencl_reg_device_get(ggml_backend_reg_t reg, size_t index) {
- GGML_ASSERT(index == 0);
-
- return &g_ggml_backend_opencl_device;
-
- GGML_UNUSED(reg);
- GGML_UNUSED(index);
-}
-
-static struct ggml_backend_reg_i ggml_backend_opencl_reg_i = {
- /* .get_name = */ ggml_backend_opencl_reg_get_name,
- /* .device_count = */ ggml_backend_opencl_reg_device_count,
- /* .device_get = */ ggml_backend_opencl_reg_device_get,
- /* .get_proc_address = */ NULL,
-};
-
-ggml_backend_reg_t ggml_backend_opencl_reg(void) {
- // TODO: make this thread-safe somehow?
- static ggml_backend_reg reg;
- static bool initialized = false;
-
- if (!initialized) {
- reg = ggml_backend_reg {
- /* .api_version = */ GGML_BACKEND_API_VERSION,
- /* .iface = */ ggml_backend_opencl_reg_i,
- /* .context = */ NULL,
- };
-
- g_ggml_backend_opencl_device = ggml_backend_device {
- /* .iface = */ ggml_backend_opencl_device_i,
- /* .reg = */ ®,
- /* .context = */ &g_ggml_ctx_dev_main,
- };
-
- ggml_cl2_init(&g_ggml_backend_opencl_device);
-
- initialized = true;
- }
-
- return ®
-}
-
-GGML_BACKEND_DL_IMPL(ggml_backend_opencl_reg)
-
-//------------------------------------------------------------------------------
-// Debugging utils
-//------------------------------------------------------------------------------
-#if 0
-#define QK4_0 32
-typedef struct {
- ggml_fp16_t d; // delta
- uint8_t qs[QK4_0 / 2]; // nibbles / quants
-} block_q4_0;
-static_assert(sizeof(block_q4_0) == sizeof(ggml_fp16_t) + QK4_0 / 2,
- "wrong q4_0 block size/padding");
-
-#include
-#ifdef __cplusplus
-#include "half.hpp"
-#endif
-
-static void dump_tensor(ggml_backend_t backend, const struct ggml_tensor * tensor) {
- void * buf = malloc(ggml_nbytes(tensor));
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-#ifdef GGML_OPENCL_SOA_Q
- void * buf_q;
- void * buf_d;
-#endif
-
- // Make sure everything is done.
- CL_CHECK(clFinish(queue));
-
-#ifdef GGML_OPENCL_SOA_Q
- if (tensor->type == GGML_TYPE_Q4_0) {
- ggml_tensor_extra_cl_q4_0 * extra = (ggml_tensor_extra_cl_q4_0 *) tensor->extra;
- GGML_ASSERT(extra);
-
- size_t size_q = ggml_nelements(tensor)/QK4_0 * QK4_0/2;
- size_t size_d = ggml_nelements(tensor)/QK4_0 * sizeof(ggml_fp16_t);
- GGML_ASSERT(size_q + size_d == ggml_nbytes(tensor));
- buf_q = malloc(size_q);
- buf_d = malloc(size_d);
-
- CL_CHECK(clEnqueueReadBuffer(queue, extra->q, CL_TRUE, 0, size_q, buf_q, 0, NULL, NULL));
- CL_CHECK(clEnqueueReadBuffer(queue, extra->d, CL_TRUE, 0, size_d, buf_d, 0, NULL, NULL));
- CL_CHECK(clFinish(queue));
- } else {
- // Read out the tensor from GPU memory.
- ggml_tensor_extra_cl * extra = (ggml_tensor_extra_cl *) tensor->extra;
- GGML_ASSERT(extra);
-
- CL_CHECK(clEnqueueReadBuffer(queue, extra->data_device, CL_TRUE,
- extra->offset, ggml_nbytes(tensor), buf, 0, NULL, NULL));
- CL_CHECK(clFinish(queue));
- }
-#else
- // Read out the tensor from GPU memory.
- ggml_tensor_extra_cl * extra = (ggml_tensor_extra_cl *) tensor->extra;
- GGML_ASSERT(extra);
-
- CL_CHECK(clEnqueueReadBuffer(queue, extra->data_device, CL_TRUE,
- extra->offset, ggml_nbytes(tensor), buf, 0, NULL, NULL));
- CL_CHECK(clFinish(queue));
-#endif // GGML_OPENCL_SOA_Q
-
- // Open file and dump.
- char fname[512];
- sprintf(fname, "./tensor-dumps/%s.txt", tensor->name);
- FILE * f = fopen(fname, "w");
- if (!f) {
- printf("Failed to open %s\n", fname);
- return;
- }
-
- if (tensor->type == GGML_TYPE_F32) {
- float * data = (float *) buf;
- for (int i = 0; i < ggml_nelements(tensor); ++i) {
- if (isnan(data[i])) {
- printf("NaN found: %s\n", tensor->name);
- break;
- }
- fprintf(f, "%f\n", data[i]);
- }
- } else if (tensor->type == GGML_TYPE_I32) {
- int * data = (int *) buf;
- for (int i = 0; i < ggml_nelements(tensor); ++i) {
- if (isnan(data[i])) {
- printf("NaN found: %s\n", tensor->name);
- break;
- }
- fprintf(f, "%d\n", data[i]);
- }
- } else if (tensor->type == GGML_TYPE_F16) {
-#ifdef __cplusplus
- half_float::half * data = (half_float::half *) buf;
- for (int i = 0; i < ggml_nelements(tensor); ++i) {
- if (std::isnan(data[i])) {
- printf("NaN found: %s\n", tensor->name);
- break;
- }
- fprintf(f, "%f\n", float(data[i]));
- }
-#endif
- } else if (tensor->type == GGML_TYPE_Q4_0) {
-#ifdef GGML_OPENCL_SOA_Q
- ggml_fp16_t * data_d = (ggml_fp16_t *)buf_d;
- unsigned char * data_q = (unsigned char *)buf_q;
-
- for (int i = 0; i < ggml_nelements(tensor)/QK4_0; ++i) {
- fprintf(f, "%04x, ", data_d[i]);
- for (int k = 0; k < QK4_0/2; ++k) {
- fprintf(f, "%02x, ", data_q[k]);
- }
- fprintf(f, "\n");
- data_q += QK4_0/2;
- }
- free(buf_d);
- free(buf_q);
-#else
- block_q4_0 * data = (block_q4_0 *) buf;
- for (int i = 0; i < ggml_nelements(tensor)/QK4_0; ++i) {
- fprintf(f, "%04x, ", data[i].d);
- for (int k = 0; k < QK4_0/2; ++k) {
- fprintf(f, "%02x, ", data[i].qs[k]);
- }
- fprintf(f, "\n");
- }
-#endif // GGML_OPENCL_SOA_Q
- }
- free(buf);
- fflush(f);
- fclose(f);
-}
-#else
-#define dump_tensor(tensor)
-#endif
-
-//------------------------------------------------------------------------------
-// Profiling utility
-//------------------------------------------------------------------------------
-#ifdef GGML_OPENCL_PROFILING
-static void populateProfilingInfo(
- ProfilingInfo& info, cl_event evt, cl_kernel kernel,
- size_t global_size[3], size_t local_size[3],
- const ggml_tensor * tensor) {
- info.op_name = tensor->name;
- info.kernel = kernel;
- info.evt = evt;
-
- info.local_size[0] = local_size[0];
- info.local_size[1] = local_size[1];
- info.local_size[2] = local_size[2];
- info.global_size[0] = global_size[0];
- info.global_size[1] = global_size[1];
- info.global_size[2] = global_size[2];
- info.output_size[0] = tensor->ne[0];
- info.output_size[1] = tensor->ne[1];
- info.output_size[2] = tensor->ne[2];
- info.output_size[3] = tensor->ne[3];
-}
-#endif
-
-//------------------------------------------------------------------------------
-// Ops
-//------------------------------------------------------------------------------
-
-static bool ggml_cl_can_mul_mat(const struct ggml_tensor * src0, const struct ggml_tensor * src1, struct ggml_tensor * dst) {
- const int64_t ne10 = src1->ne[0];
-
- const int64_t ne0 = dst->ne[0];
- const int64_t ne1 = dst->ne[1];
-
- // TODO: find the optimal values for these
- return (src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16 || ggml_is_quantized(src0->type)) &&
- src1->type == GGML_TYPE_F32 &&
- dst->type == GGML_TYPE_F32 &&
- (ne0 >= 32 && ne1 >= 32 && ne10 >= 32);
-}
-
-static void ggml_cl_nop(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- UNUSED(backend);
- UNUSED(src0);
- UNUSED(src1);
- UNUSED(dst);
-}
-
-static void ggml_cl_get_rows(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const int ne10 = src1 ? src1->ne[0] : 0;
- const cl_ulong nb10 = src1 ? src1->nb[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0;
- const cl_ulong nb11 = src1 ? src1->nb[1] : 0;
- const cl_ulong nb1 = dst ? dst->nb[1] : 0;
- const cl_ulong nb2 = dst ? dst->nb[2] : 0;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel;
-
- switch (src0->type) {
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_get_rows_f32;
- break;
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_get_rows_f16;
- break;
- case GGML_TYPE_Q4_0:
- kernel = backend_ctx->kernel_get_rows_q4_0;
- break;
- default:
- GGML_ASSERT(false && "not implemented");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_ulong), &nb2));
-
- size_t global_work_size[] = {(size_t)ne10, (size_t)ne11, 1};
- size_t local_work_size[] = {1, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_add(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb00 = src0 ? src0->nb[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int ne10 = src1 ? src1->ne[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0;
- const int ne12 = src1 ? src1->ne[2] : 0;
- const int ne13 = src1 ? src1->ne[3] : 0; UNUSED(ne13);
-
- const cl_ulong nb10 = src1 ? src1->nb[0] : 0;
- const cl_ulong nb11 = src1 ? src1->nb[1] : 0;
- const cl_ulong nb12 = src1 ? src1->nb[2] : 0;
- const cl_ulong nb13 = src1 ? src1->nb[3] : 0; UNUSED(nb13);
-
- const int ne0 = dst ? dst->ne[0] : 0;
- const int ne1 = dst ? dst->ne[1] : 0;
- const int ne2 = dst ? dst->ne[2] : 0;
- const int ne3 = dst ? dst->ne[3] : 0;
-
- const cl_ulong nb0 = dst ? dst->nb[0] : 0;
- const cl_ulong nb1 = dst ? dst->nb[1] : 0;
- const cl_ulong nb2 = dst ? dst->nb[2] : 0;
- const cl_ulong nb3 = dst ? dst->nb[3] : 0;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- bool bcast_row = false;
- cl_kernel kernel;
-
- if (ggml_nelements(src1) == ne10 && ggml_is_contiguous(src1) && ne00 % 4 == 0 && ne10 % 4 == 0) {
- GGML_ASSERT(ggml_is_contiguous(src0));
-
- // src1 is a row
- GGML_ASSERT(ne11 == 1);
-
- bcast_row = true;
- int ne = ne00 / 4;
- kernel = backend_ctx->kernel_add_row;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne));
- } else {
- kernel = backend_ctx->kernel_add;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &ne11));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(int), &ne13));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(cl_ulong), &nb12));
- CL_CHECK(clSetKernelArg(kernel, 21, sizeof(cl_ulong), &nb13));
- CL_CHECK(clSetKernelArg(kernel, 22, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 23, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 24, sizeof(int), &ne2));
- CL_CHECK(clSetKernelArg(kernel, 25, sizeof(int), &ne3));
- CL_CHECK(clSetKernelArg(kernel, 26, sizeof(cl_ulong), &nb0));
- CL_CHECK(clSetKernelArg(kernel, 27, sizeof(cl_ulong), &nb1));
- CL_CHECK(clSetKernelArg(kernel, 28, sizeof(cl_ulong), &nb2));
- CL_CHECK(clSetKernelArg(kernel, 29, sizeof(cl_ulong), &nb3));
- }
-
- if (bcast_row) {
- int n = ggml_nelements(dst)/4;
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- } else {
- unsigned int nth = MIN(64, ne0);
- size_t global_work_size[] = {ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- }
-}
-
-static void ggml_cl_mul(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb00 = src0 ? src0->nb[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int ne10 = src1 ? src1->ne[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0;
- const int ne12 = src1 ? src1->ne[2] : 0;
- const int ne13 = src1 ? src1->ne[3] : 0; UNUSED(ne13);
-
- const cl_ulong nb10 = src1 ? src1->nb[0] : 0;
- const cl_ulong nb11 = src1 ? src1->nb[1] : 0;
- const cl_ulong nb12 = src1 ? src1->nb[2] : 0;
- const cl_ulong nb13 = src1 ? src1->nb[3] : 0; UNUSED(nb13);
-
- const int ne0 = dst ? dst->ne[0] : 0;
- const int ne1 = dst ? dst->ne[1] : 0;
- const int ne2 = dst ? dst->ne[2] : 0;
- const int ne3 = dst ? dst->ne[3] : 0;
-
- const cl_ulong nb0 = dst ? dst->nb[0] : 0;
- const cl_ulong nb1 = dst ? dst->nb[1] : 0;
- const cl_ulong nb2 = dst ? dst->nb[2] : 0;
- const cl_ulong nb3 = dst ? dst->nb[3] : 0;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- bool bcast_row = false;
- cl_kernel kernel;
-
- if (ggml_nelements(src1) == ne10 && ggml_is_contiguous(src1) && ne00 % 4 == 0 && ne10 % 4 == 0) {
- GGML_ASSERT(ggml_is_contiguous(src0));
-
- // src1 is a row
- GGML_ASSERT(ne11 == 1);
-
- bcast_row = true;
- int ne = ne00 / 4;
- kernel = backend_ctx->kernel_mul_row;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne));
- } else {
- kernel = backend_ctx->kernel_mul;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &ne11));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(int), &ne13));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(cl_ulong), &nb12));
- CL_CHECK(clSetKernelArg(kernel, 21, sizeof(cl_ulong), &nb13));
- CL_CHECK(clSetKernelArg(kernel, 22, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 23, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 24, sizeof(int), &ne2));
- CL_CHECK(clSetKernelArg(kernel, 25, sizeof(int), &ne3));
- CL_CHECK(clSetKernelArg(kernel, 26, sizeof(cl_ulong), &nb0));
- CL_CHECK(clSetKernelArg(kernel, 27, sizeof(cl_ulong), &nb1));
- CL_CHECK(clSetKernelArg(kernel, 28, sizeof(cl_ulong), &nb2));
- CL_CHECK(clSetKernelArg(kernel, 29, sizeof(cl_ulong), &nb3));
- }
-
- if (bcast_row) {
- int n = ggml_nelements(dst)/4;
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- } else {
- unsigned int nth = MIN(64, ne0);
- size_t global_work_size[] = {ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- }
-}
-
-static void ggml_cl_gelu(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel;
-
- int n = ggml_nelements(dst);
-
- if (n % 4 == 0) {
- kernel = backend_ctx->kernel_gelu_4;
- n /= 4;
- } else {
- kernel = backend_ctx->kernel_gelu;
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt);
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL);
-#endif
-}
-
-static void ggml_cl_gelu_quick(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel;
-
- int n = ggml_nelements(dst);
-
- if (n % 4 == 0) {
- kernel = backend_ctx->kernel_gelu_quick_4;
- n /= 4;
- } else {
- kernel = backend_ctx->kernel_gelu_quick;
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt);
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL);
-#endif
-}
-
-static void ggml_cl_silu(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel;
-
- int n = ggml_nelements(dst);
-
- if (n % 4 == 0) {
- kernel = backend_ctx->kernel_silu_4;
- n /= 4;
- } else {
- kernel = backend_ctx->kernel_silu;
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_relu(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel = backend_ctx->kernel_relu;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
-
- const int64_t n = ggml_nelements(dst);
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_clamp(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- float min;
- float max;
- memcpy(&min, ((int32_t *) dst->op_params) + 0, sizeof(float));
- memcpy(&max, ((int32_t *) dst->op_params) + 1, sizeof(float));
-
- cl_kernel kernel = backend_ctx->kernel_clamp;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(float), &min));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(float), &max));
-
- const int64_t n = ggml_nelements(dst);
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_norm(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- float eps;
- memcpy(&eps, dst->op_params, sizeof(float));
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int nth = MIN(64, ne00);
-
- cl_kernel kernel = backend_ctx->kernel_norm;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(float), &eps));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(float)*nth, NULL));
-
- size_t global_work_size[] = {(size_t)ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {(size_t)nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_rms_norm(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- //ggml_backend_opencl_device_context * dev_ctx =
- // (ggml_backend_opencl_device_context *)backend->device->context;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- float eps;
- memcpy(&eps, dst->op_params, sizeof(float));
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- GGML_ASSERT(ne00 % 4 == 0);
-
- const int nth = MIN(64, ne00);
-
- size_t global_work_size[] = {(size_t)ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {(size_t)nth, 1, 1};
-
- cl_kernel kernel = backend_ctx->kernel_rms_norm;
-
- // Note, this kernel declares local memory in kernel args and the size
- // depends on subgroup size.
- // Note, this requires OpenCL 2.1 and above
- // For now we use fixed subgroup size to simplify support for OpenCL 2.0.
- size_t sgs;
- //CL_CHECK(clGetKernelSubGroupInfo(kernel, dev_ctx->device,
- // CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE,
- // sizeof(local_work_size), local_work_size,
- // sizeof(size_t), &sgs, NULL));
- if (backend_ctx->gpu_family == ADRENO) {
- sgs = 64;
- } else if (backend_ctx->gpu_family == INTEL) {
- sgs = 32;
- } else {
- GGML_ASSERT(false && "Unsupported GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(float), &eps));
- // This is local memory - the size depends on subgroup size.
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(float)*nth/sgs, NULL));
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_mul_mat(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- const enum ggml_type src0t = src0 ? src0->type : GGML_TYPE_COUNT;
- const enum ggml_type src1t = src1 ? src1->type : GGML_TYPE_COUNT;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
-#ifdef GGML_OPENCL_SOA_Q
- ggml_tensor_extra_cl_q4_0 * extra0_q4_0 = (ggml_tensor_extra_cl_q4_0 *)src0->extra;
-#endif
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb00 = src0 ? src0->nb[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int ne10 = src1 ? src1->ne[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0;
- const int ne12 = src1 ? src1->ne[2] : 0;
- const int ne13 = src1 ? src1->ne[3] : 0;
-
- const cl_ulong nb10 = src1 ? src1->nb[0] : 0;
- const cl_ulong nb11 = src1 ? src1->nb[1] : 0;
- const cl_ulong nb12 = src1 ? src1->nb[2] : 0;
- const cl_ulong nb13 = src1 ? src1->nb[3] : 0;
-
- const int ne0 = dst ? dst->ne[0] : 0;
- const int ne1 = dst ? dst->ne[1] : 0;
-
- int r2 = ne12/ne02;
- int r3 = ne13/ne03;
-
- GGML_ASSERT(ne00 == ne10);
-
- int nth0 = 32;
- int nth1 = 1;
- int nrows = 1;
- // The number of values produced by each subgroup
- int ndst = 4;
-
- cl_kernel kernel;
-
-#ifdef GGML_OPENCL_USE_ADRENO_KERNELS
- cl_context context = backend_ctx->context;
-
- if (ne01 && ne1 && use_adreno_kernels(backend_ctx, src0)) {
-
- // init CL objects
- // <--------------------------------------------> //
- cl_int status;
- cl_image_format img_fmt_1d;
- cl_image_desc img_desc_1d;
- cl_buffer_region region;
- cl_mem A_image1d = nullptr;
- cl_mem B_image1d = nullptr;
- cl_mem B_sub_buffer = nullptr;
- cl_mem C_d = nullptr;
- // for B transpose
- cl_mem B_d = nullptr;
- cl_mem B_d_input_image = nullptr;
- // <--------------------------------------------> //
-
- // define matrix dimensions
- // <--------------------------------------------> //
- int M = ne01;
- int N = ne1;
- int K = ne00;
- int padding;
- // <--------------------------------------------> //
-
- // q4_0 x fp32
- if(src0t == GGML_TYPE_Q4_0 && src1t == GGML_TYPE_F32) {
- // TODO: remove duplicate definitions of image description + format -- move to top
-
- // create an image for A
- // <--------------------------------------------> //
- if (N == 1) {
- img_fmt_1d = { CL_R, CL_UNSIGNED_INT32};
- } else {
- img_fmt_1d = { CL_R, CL_FLOAT};
- }
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.image_width = M * K / 2 / 4; // Divide by 4 for char -> float
- img_desc_1d.buffer = extra0_q4_0->q;
- A_image1d = clCreateImage(
- context,
- CL_MEM_READ_ONLY,
- &img_fmt_1d,
- &img_desc_1d,
- NULL,
- &status);
- CL_CHECK(status);
- // <--------------------------------------------> //
-
-
- // create a sub_buffer for B
- // <--------------------------------------------> //
- region.origin = (extra1->offset);
- region.size = K * N * sizeof(float);
- B_sub_buffer = clCreateSubBuffer(
- extra1->data_device,
- 0,
- CL_BUFFER_CREATE_TYPE_REGION,
- ®ion,
- &status);
- CL_CHECK(status);
- // <--------------------------------------------> //
-
- // transpose activation for Skyler's gemm
- if (N != 1) {
- //how many extra elements beyond multiple of 8
- int extra_elements = N % 8;
-
- //how much padding to add
- padding = 0;
- if (extra_elements > 0){
- padding = 8 - extra_elements;
- }
-
- // Specify the starting offset (in bytes)
- region.origin = 0;
- // Specify the size of the sub-buffer (divide by 2 for FP16)
- region.size = K * (N + padding) * sizeof(float)/2;
- B_d = clCreateSubBuffer(
- backend_ctx->B_d_max,
- 0,
- CL_BUFFER_CREATE_TYPE_REGION,
- ®ion,
- &status);
- CL_CHECK(status);
-
- cl_image_format image_format_B_d_input = { CL_RGBA, CL_FLOAT };
- cl_image_desc image_desc_B_d_input = {
- CL_MEM_OBJECT_IMAGE1D_BUFFER,
- static_cast(K * N / 4),
- 0, 0, 0, 0, 0, 0, 0, { B_sub_buffer }
- };
- B_d_input_image = clCreateImage(
- context,
- 0,
- &image_format_B_d_input,
- &image_desc_B_d_input,
- NULL,
- &status);
- CL_CHECK(status);
-
- cl_image_format image_format_B_d_output = { CL_RGBA, CL_HALF_FLOAT }; //(CL_HALF_FLOAT for FP16)
- cl_image_desc image_desc_B_d_output = {
- CL_MEM_OBJECT_IMAGE1D_BUFFER,
- static_cast(K * (N + padding)/4),
- 0, 0, 0, 0, 0, 0, 0, { B_d }
- };
- B_image1d = clCreateImage(
- context,
- 0,
- &image_format_B_d_output,
- &image_desc_B_d_output,
- NULL,
- &status);
- CL_CHECK(status);
-
- int height_B = N/4;
- if (height_B == 0) {
- height_B = 1;
- }
- int width_B = K/4;
- int padded_height_B = (N + padding)/4;
-
- kernel = backend_ctx->kernel_transpose_32_16;
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &B_d_input_image));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &B_image1d));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(int), &height_B));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(int), &width_B));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &padded_height_B));
-
- size_t local_size_t[2] = { 1, 16 };
- //WGS tuning
- if (ne0 == 4096 && ne1 == 128 && ne10 == 4096) {
- local_size_t[0]=4;
- local_size_t[1]=8;
- } else if (ne0 == 11008 && ne1 == 128 && ne10 == 4096) {
- local_size_t[0]=2;
- local_size_t[1]=8;
- } else if(ne0 == 4096 && ne1 == 128 && ne10 == 11008) {
- local_size_t[0]=1;
- local_size_t[1]=8;
- } else if(ne0 == 32000 && ne1 == 128 && ne10 == 4096) {
- local_size_t[0]=2;
- local_size_t[1]=8;
- }
-
- size_t global_size_t[2] = {
- static_cast(width_B),
- static_cast(padded_height_B)
- };
-
- #ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_size_t, local_size_t, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_size_t, local_size_t, dst);
- #else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_size_t, local_size_t, 0, NULL, NULL));
- #endif
- } else {
- // no need to transpose B in other cases
- // create an image for B from sub_buffer
- // <--------------------------------------------> //
- img_fmt_1d = {CL_RGBA, CL_FLOAT};
-
- memset(&img_desc_1d, 0, sizeof(img_desc_1d));
- img_desc_1d.image_width = K * N / 4;
- img_desc_1d.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
- img_desc_1d.buffer = B_sub_buffer;
- B_image1d = clCreateImage(
- context,
- CL_MEM_READ_ONLY,
- &img_fmt_1d,
- &img_desc_1d,
- NULL,
- &status);
- CL_CHECK(status);
- // <--------------------------------------------> //
- }
-
- // choose gemm or gemv kernel
- // <--------------------------------------------> //
- if (N == 1) {
- kernel = backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_general;
- if (M == 4096 && K == 4096) {
- kernel = backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_4096;
- } else if (M == 4096 && K == 11008) {
- kernel = backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_4096_1_11008;
- } else if (M == 11008 && K == 4096) {
- kernel = backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_11008_1_4096;
- } else if (M == 32000 && K == 4096) {
- kernel = backend_ctx->CL_mul_mat_vec_q4_0_f32_1d_4x_flat_32000_1_4096;
- }
- } else {
- kernel = backend_ctx->CL_mul_mat_Ab_Bi_8x4;
- }
- // <--------------------------------------------> //
-
- // set kernel args
- // <--------------------------------------------> //
- cl_uint k_arg = 0;
-
- if (N == 1) {
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &A_image1d));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extra0_q4_0->d));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &B_image1d));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_ulong), &extra1->offset));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(cl_ulong), &extrad->offset));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, k_arg++, sizeof(int), &r3));
- } else {
- region.origin = extrad->offset; // Specify the starting offset (in bytes)
- region.size = M * N * sizeof(float); // Specify the size of the sub-buffer
- C_d = clCreateSubBuffer(extrad->data_device, CL_MEM_WRITE_ONLY, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &status);
- CL_CHECK(status);
-
- int padded_N = ne1 + padding;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0_q4_0->q)); //A_q_dextra0_q4_0->q
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &extra0_q4_0->d)); //A_s_d
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &B_image1d)); //B_d
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_mem), &C_d)); //C_d
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne01)); //M
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &padded_N)); //N with padding
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00)); //K
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne1)); //N without padding
- }
- // <--------------------------------------------> //
-
- // choose workgroup size
- // <--------------------------------------------> //
- size_t global_work_size[3] = {
- 64, static_cast((M+63)/64), static_cast((N+31)/32)};
- size_t local_work_size[3] = {64, 2, 4};
-
- global_work_size[0] = (size_t)(ceil((float)ne1/8));
- global_work_size[1] = (size_t)(ne01/4);
- global_work_size[2] = (size_t)(1);
-
- local_work_size[0] = (size_t)(1); //4x32 for FP32
- local_work_size[1] = (size_t)(128);
- local_work_size[2] = (size_t)(1);
-
- //WGS tuning
- if (ne0 == 4096 && ne1 == 128 && ne10 == 4096) {
- local_work_size[0] = 1;
- local_work_size[1] = 128;
- } else if (ne0 == 11008 && ne1 == 128 && ne10 == 4096) {
- local_work_size[0] = 2;
- local_work_size[1] = 64;
- } else if (ne0 == 4096 && ne1 == 128 && ne10 == 11008) {
- local_work_size[0] = 2;
- local_work_size[1] = 64;
- } else if (ne0 == 32000 && ne1 == 128 && ne10 == 4096) {
- local_work_size[0] = 2;
- local_work_size[1] = 64;
- }
-
- if (N == 1) {
- size_t wavesize = backend_ctx->adreno_wave_size;
- local_work_size[0] = wavesize; // localsize
- local_work_size[1] = 4; // reduce factor
- local_work_size[2] = 1;
-
- global_work_size[0] = (((M / 2) + wavesize - 1) / wavesize) * wavesize;
- global_work_size[1] = 4; // reduce factor
- global_work_size[2] = 1;
- }
- // <--------------------------------------------> //
-
- // enqueue kernel with profiling
- // <--------------------------------------------> //
- #ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
- // enqueue kernel without profiling
- #else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
- #endif
- // <--------------------------------------------> //
-
- // deallocate sub buffers and images
- // <--------------------------------------------> //
- CL_CHECK(clReleaseMemObject(A_image1d));
- CL_CHECK(clReleaseMemObject(B_sub_buffer));
- CL_CHECK(clReleaseMemObject(B_image1d));
-
- if (N != 1) {
- CL_CHECK(clReleaseMemObject(B_d));
- CL_CHECK(clReleaseMemObject(B_d_input_image));
- CL_CHECK(clReleaseMemObject(C_d));
- }
- // <--------------------------------------------> //
-
- return;
- }
- } // if (ne01 && ne1)
-#endif // GGML_OPENCL_USE_ADRENO_KERNELS
-
- if (!ggml_is_transposed(src0) &&
- !ggml_is_transposed(src1) &&
- src1t == GGML_TYPE_F32 &&
- ne00%32 == 0 &&
- ne11 > 2) {
-#ifdef GGML_OPENCL_SOA_Q
- // Set up kernel.
- switch(src0t) {
- case GGML_TYPE_Q4_0:
- // This should have been satisfied.
- GGML_ASSERT(ne11 == ne1);
- GGML_ASSERT(ne01 == ne0);
-
- if (backend_ctx->gpu_family == INTEL) {
- nth0 = 16;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32_1d_16x_flat;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 64;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32_1d_8x_flat;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0_q4_0->q));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &extra0_q4_0->d));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &r3));
- break;
- default:
- break;
- }
-
- // Launch kernel.
- if (src0t == GGML_TYPE_Q4_0) {
- size_t global_work_size[] = {(size_t)(ne01 + 7)/8*nth0, (size_t)ne11*nth1, (size_t)ne12*ne13};
- size_t local_work_size[] = {(size_t)nth0, (size_t)nth1, 1};
-
- if (backend_ctx->gpu_family == INTEL) {
- // Set global size for Intel. It uses 16x output values.
- global_work_size[0] = (size_t)(ne01 + 15)/16*nth0;
- global_work_size[1] = (size_t)ne11*nth1;
- global_work_size[2] = (size_t)ne12*ne13;
- }
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- return;
- }
-#else // GGML_OPENCL_SOA_Q
- // TODO: add block_q4_0 variant.
-#endif // GGML_OPENCL_SOA_Q
- }
-
- // use custom matrix x vector kernel
- switch (src0t) {
- case GGML_TYPE_F32:
- //GGML_ASSERT(ne02 == ne12);
- GGML_ASSERT(src1t == GGML_TYPE_F32);
- kernel = backend_ctx->kernel_mul_mat_f32_f32;
- nrows = 4;
-
- if (backend_ctx->gpu_family == INTEL) {
- nth0 = 32;
- nth1 = 1;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 64;
- nth1 = 1;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &ne11));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(cl_ulong), &nb12));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb13));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 21, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 22, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 23, sizeof(int), &r3));
- break;
- case GGML_TYPE_F16:
- //GGML_ASSERT(ne02 == ne12);
- if (backend_ctx->gpu_family == INTEL) {
- nth0 = 32;
- nth1 = 1;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 64;
- nth1 = 1;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- if (src1t == GGML_TYPE_F32) {
- if (ne11 * ne12 < 4) {
- kernel = backend_ctx->kernel_mul_mat_f16_f32_1row;
- } else if (ne00 >= 128 && ne01 >= 8 && ne00%4 == 0) {
- kernel = backend_ctx->kernel_mul_mat_f16_f32_l4;
- nrows = ne11;
- } else {
- kernel = backend_ctx->kernel_mul_mat_f16_f32;
- nrows = 4;
- }
- } else {
- kernel = backend_ctx->kernel_mul_mat_f16_f16;
- nrows = 4;
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &ne11));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(cl_ulong), &nb12));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb13));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 21, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 22, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 23, sizeof(int), &r3));
- break;
- case GGML_TYPE_Q4_0:
- // This should have been satisfied.
- GGML_ASSERT(ne11 == ne1);
- GGML_ASSERT(ne01 == ne0);
-
-#ifdef GGML_OPENCL_SOA_Q
- if (backend_ctx->gpu_family == INTEL) {
- nth0 = 16;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32_8x_flat;
- ndst = 8;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 64;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32_8x_flat;
- ndst =8;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0_q4_0->q));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), &extra0_q4_0->d));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &r3));
-#else // GGML_OPENCL_SOA_Q
- if (backend_ctx->gpu_family == INTEL) {
- // Use 1D local size. Each workgroup is a SIMD group. Each SIMD
- // group produces N_DST (4 for Q4_0 kernel) values in the result.
- // The number of workgroups on dim 0 (the leading dimension) is
- // the nearest multiple of 4 that covers ne0 (equals ne01).
- nth0 = 16;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32;
- ndst = 4;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 64;
- nth1 = 1;
-
- kernel = backend_ctx->kernel_mul_mat_q4_0_f32_v;
- ndst = 4;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &r3));
-#endif // GGML_OPENCL_SOA_Q
- break;
- case GGML_TYPE_Q4_1:
- case GGML_TYPE_Q8_0:
- case GGML_TYPE_Q2_K:
- case GGML_TYPE_Q3_K:
- case GGML_TYPE_Q4_K:
- case GGML_TYPE_Q5_K:
- case GGML_TYPE_Q6_K:
- kernel = backend_ctx->kernel_mul_mv_q6_K_f32;
-
- if (backend_ctx->gpu_family == INTEL) {
- nth0 = 2;
- nth1 = 16;
- } else if (backend_ctx->gpu_family == ADRENO) {
- nth0 = 2;
- nth1 = 64;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &r2));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &r3));
- break;
- default:
- GGML_ASSERT(false && "not implemented");
- }
-
- if (src0t == GGML_TYPE_Q4_0 ||
- src0t == GGML_TYPE_Q4_1 ||
- src0t == GGML_TYPE_Q8_0 ||
- src0t == GGML_TYPE_Q2_K) {
- // Each SIMD group produces N_DST values in the result. Assuming each
- // workgroup has N_SIMDGROUP SIMD groups, then each workgroup will
- // produce N_DST*N_SIMDGROUP values in the result. Hence, the grid size
- // (number of workgroups) will be a nearest multiple of
- // N_DST*N_SIMDGROUP to cover the size of the dimension. Below, 4 is
- // N_DST*N_SIMDGROUP (see the kernel for Q4_0 matmul).
- size_t global_work_size[] = {(size_t)(ne01 + ndst-1)/ndst*nth0, (size_t)ne11*nth1, (size_t)ne12*ne13};
- size_t local_work_size[] = {(size_t)nth0, (size_t)nth1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- } else if (src0t == GGML_TYPE_Q4_K) {
- GGML_ASSERT(false && "not implemented");
- } else if (src0t == GGML_TYPE_Q3_K) {
- GGML_ASSERT(false && "not implemented");
- } else if (src0t == GGML_TYPE_Q5_K) {
- GGML_ASSERT(false && "not implemented");
- } else if (src0t == GGML_TYPE_Q6_K) {
- size_t global_work_size[] = {(size_t)(ne01+1)/2*nth0, (size_t)ne11*nth1, (size_t)ne12*ne13};
- size_t local_work_size[] = {(size_t)nth0, (size_t)nth1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- } else {
- int64_t ny = (ne11 + nrows - 1)/nrows;
-
- size_t global_work_size[] = {(size_t)ne01*nth0, (size_t)ny*nth1, (size_t)ne12*ne13};
- size_t local_work_size[] = {(size_t)nth0, (size_t)nth1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- }
-}
-
-static void ggml_cl_scale(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
- GGML_UNUSED(src1);
-
- GGML_ASSERT(ggml_is_contiguous(src0));
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- float scale;
- memcpy(&scale, dst->op_params, sizeof(scale));
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel = backend_ctx->kernel_scale;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(float), &scale));
-
- int n = ggml_nelements(dst)/4;
-
- size_t global_work_size[] = {(size_t)n, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_cpy(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
-
- // GGML_OP_CPY happens between src0 and src1.
- // GGML_OP_DUP and GGML_OP_CONT happen between src0 and dst.
- UNUSED(dst);
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb00 = src0 ? src0->nb[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int ne10 = src1 ? src1->ne[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0;
- const int ne12 = src1 ? src1->ne[2] : 0;
- const int ne13 = src1 ? src1->ne[3] : 0;
-
- const cl_ulong nb10 = src1 ? src1->nb[0] : 0;
- const cl_ulong nb11 = src1 ? src1->nb[1] : 0;
- const cl_ulong nb12 = src1 ? src1->nb[2] : 0;
- const cl_ulong nb13 = src1 ? src1->nb[3] : 0;
-
- const enum ggml_type src0t = src0 ? src0->type : GGML_TYPE_COUNT;
- const enum ggml_type src1t = src1 ? src1->type : GGML_TYPE_COUNT;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
-
- cl_kernel kernel;
-
- switch (src0t) {
- case GGML_TYPE_F32:
- switch (src1t) {
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_cpy_f32_f16;
- break;
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_cpy_f32_f32;
- break;
- default:
- GGML_ASSERT(false && "not implemented");
- }
- break;
- case GGML_TYPE_F16:
- switch (src1t) {
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_cpy_f16_f16;
- break;
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_cpy_f16_f32;
- break;
- default:
- GGML_ASSERT(false && "not implemented");
- }
- break;
- default:
- GGML_ASSERT(false && "not implemented");
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(int), &ne10));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &ne11));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(int), &ne12));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &ne13));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(cl_ulong), &nb10));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(cl_ulong), &nb11));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(cl_ulong), &nb12));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(cl_ulong), &nb13));
-
- const int nth = MIN(64, ne00);
-
- size_t global_work_size[] = {(size_t)ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {(size_t)nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, src1);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_dup(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- ggml_cl_cpy(backend, src0, dst, nullptr);
- UNUSED(src1);
-}
-
-static void ggml_cl_diag_mask_inf(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- UNUSED(src1);
-
- int n_past = ((int32_t *)(dst->op_params))[0];
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_kernel kernel;
-
- if (ne00%8 == 0) {
- kernel = backend_ctx->kernel_diag_mask_inf_8;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &n_past));
-
- size_t global_work_size[] = {(size_t)ne00*ne01*ne02/8, 1, 1};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- } else {
- kernel = backend_ctx->kernel_diag_mask_inf;
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &n_past));
-
- size_t global_work_size[] = {(size_t)ne00, (size_t)ne01, (size_t)ne02};
- size_t local_work_size[] = {64, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
- }
-}
-
-static void ggml_cl_soft_max(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- // Softmax can now fuse KQ mask and KQ scale, which used to be two additional
- // ops before softmax. It now also fuses alibi if `max_bias > 0`. For llama,
- // alibi is not used; however, for some other models, it is used.
- // KQ_mask
- if (src1) {
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- }
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- ggml_tensor_extra_cl * extra1 = src1 ? (ggml_tensor_extra_cl *)src1->extra : nullptr;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- cl_ulong offset1 = extra1 ? extra1->offset + src1->view_offs : offset0;
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- float scale, max_bias;
- memcpy(&scale, dst->op_params + 0, sizeof(float));
- memcpy(&max_bias, dst->op_params + 1, sizeof(float));
-
- const int nrows_x = ggml_nrows(src0);
- const int nrows_y = src0->ne[1];
-
- const int n_head = nrows_x/nrows_y;
- const int n_head_log2 = 1u << (uint32_t) floorf(log2f((float) n_head));
-
- const float m0 = powf(2.0f, -(max_bias ) / n_head_log2);
- const float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
-
- const bool use_f16 = (src1 && src1->type == GGML_TYPE_F16);
-
- // Local size must be wave size. Each workgroup is a wave, working on a row,
- // where a row corresponds to leading dimension.
- int nth = MIN(32, ne00);
-
- if (backend_ctx->gpu_family == INTEL) {
- // This is the same as the initial value.
- nth = MIN(32, ne00);
- }
- else if (backend_ctx->gpu_family == ADRENO) {
- nth = 64;
- } else {
- GGML_ASSERT(false && "TODO: Unknown GPU");
- }
-
- cl_kernel kernel;
-
- if (ne00%4 == 0) {
- if (use_f16) {
- kernel = backend_ctx->kernel_soft_max_4_f16;
- } else {
- kernel = backend_ctx->kernel_soft_max_4;
- }
- } else {
- if (use_f16) {
- kernel = backend_ctx->kernel_soft_max_f16;
- } else {
- kernel = backend_ctx->kernel_soft_max;
- }
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), extra1 ? &extra1->data_device : &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(float), &scale));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(float), &max_bias));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(float), &m0));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(float), &m1));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(int), &n_head_log2));
-
- size_t global_work_size[] = {(size_t)ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {(size_t)nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_rope(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src0->extra);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra0 = (ggml_tensor_extra_cl *)src0->extra;
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset0 = extra0->offset + src0->view_offs;
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- ggml_tensor * src2 = dst->src[2];
- ggml_tensor_extra_cl * extra2 = src2 ? (ggml_tensor_extra_cl *)src2->extra : nullptr;
-
- cl_ulong offset2 = extra2 ? extra2->offset + src2->view_offs : offset0;
-
- const int ne00 = src0 ? src0->ne[0] : 0;
- const int ne01 = src0 ? src0->ne[1] : 0;
- const int ne02 = src0 ? src0->ne[2] : 0;
- const int ne03 = src0 ? src0->ne[3] : 0;
-
- const cl_ulong nb00 = src0 ? src0->nb[0] : 0;
- const cl_ulong nb01 = src0 ? src0->nb[1] : 0;
- const cl_ulong nb02 = src0 ? src0->nb[2] : 0;
- const cl_ulong nb03 = src0 ? src0->nb[3] : 0;
-
- const int ne10 = src1 ? src1->ne[0] : 0;
- const int ne11 = src1 ? src1->ne[1] : 0; UNUSED(ne11);
- const int ne12 = src1 ? src1->ne[2] : 0; UNUSED(ne12);
- const int ne13 = src1 ? src1->ne[3] : 0; UNUSED(ne13);
-
- const int ne0 = dst ? dst->ne[0] : 0;
- const int ne1 = dst ? dst->ne[1] : 0;
- const int ne2 = dst ? dst->ne[2] : 0;
- const int ne3 = dst ? dst->ne[3] : 0;
-
- const cl_ulong nb0 = dst ? dst->nb[0] : 0;
- const cl_ulong nb1 = dst ? dst->nb[1] : 0;
- const cl_ulong nb2 = dst ? dst->nb[2] : 0;
- const cl_ulong nb3 = dst ? dst->nb[3] : 0;
-
- GGML_ASSERT(ne10 % ne02 == 0);
- GGML_ASSERT(ne10 >= ne02);
-
- int nth = MIN(64, ne00);
-
- const int n_past = ((int *) dst->op_params)[0];
- const int n_dims = ((int *) dst->op_params)[1];
- const int mode = ((int *) dst->op_params)[2];
- const int n_ctx_orig = ((int32_t *) dst->op_params)[4];
-
- float freq_base;
- float freq_scale;
- float ext_factor;
- float attn_factor;
- float beta_fast;
- float beta_slow;
- int32_t sections[4];
-
- memcpy(&freq_base, (int32_t *) dst->op_params + 5, sizeof(float));
- memcpy(&freq_scale, (int32_t *) dst->op_params + 6, sizeof(float));
- memcpy(&ext_factor, (int32_t *) dst->op_params + 7, sizeof(float));
- memcpy(&attn_factor, (int32_t *) dst->op_params + 8, sizeof(float));
- memcpy(&beta_fast, (int32_t *) dst->op_params + 9, sizeof(float));
- memcpy(&beta_slow, (int32_t *) dst->op_params + 10, sizeof(float));
- memcpy(§ions, (int32_t *) dst->op_params + 11, sizeof(int32_t)*4);
-
- const bool is_neox = mode & 2;
- const bool is_mrope = mode & GGML_ROPE_TYPE_MROPE;
- const bool is_vision = mode == GGML_ROPE_TYPE_VISION;
-
- if (is_mrope) {
- GGML_ASSERT(sections[0] > 0 || sections[1] > 0 || sections[2] > 0);
- }
-
- if (is_vision) {
- GGML_ASSERT(n_dims == ne00/2);
- }
-
- cl_kernel kernel;
-
- if (is_neox) {
- switch (src0->type) {
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_rope_neox_f32;
- break;
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_rope_neox_f16;
- break;
- default:
- GGML_ASSERT(false);
- };
- } else if (is_mrope && !is_vision) {
- switch (src0->type) {
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_rope_multi_f32;
- break;
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_rope_multi_f16;
- break;
- default:
- GGML_ASSERT(false);
- };
- } else if (is_vision) {
- switch (src0->type) {
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_rope_vision_f32;
- break;
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_rope_vision_f16;
- break;
- default:
- GGML_ASSERT(false);
- }
- } else {
- switch (src0->type) {
- case GGML_TYPE_F32:
- kernel = backend_ctx->kernel_rope_norm_f32;
- break;
- case GGML_TYPE_F16:
- kernel = backend_ctx->kernel_rope_norm_f16;
- break;
- default:
- GGML_ASSERT(false);
- };
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset0));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_mem), extra2 ? &extra2->data_device : &extra0->data_device));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &offset2));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(int), &ne00));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(int), &ne01));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(int), &ne02));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(int), &ne03));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_ulong), &nb00));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_ulong), &nb01));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(cl_ulong), &nb02));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(cl_ulong), &nb03));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(int), &ne0));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(int), &ne1));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(int), &ne2));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(int), &ne3));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(cl_ulong), &nb0));
- CL_CHECK(clSetKernelArg(kernel, 21, sizeof(cl_ulong), &nb1));
- CL_CHECK(clSetKernelArg(kernel, 22, sizeof(cl_ulong), &nb2));
- CL_CHECK(clSetKernelArg(kernel, 23, sizeof(cl_ulong), &nb3));
- CL_CHECK(clSetKernelArg(kernel, 24, sizeof(int), &n_past));
- CL_CHECK(clSetKernelArg(kernel, 25, sizeof(int), &n_dims));
- CL_CHECK(clSetKernelArg(kernel, 26, sizeof(int), &n_ctx_orig));
- CL_CHECK(clSetKernelArg(kernel, 27, sizeof(float), &freq_base));
- CL_CHECK(clSetKernelArg(kernel, 28, sizeof(float), &freq_scale));
- CL_CHECK(clSetKernelArg(kernel, 29, sizeof(float), &ext_factor));
- CL_CHECK(clSetKernelArg(kernel, 30, sizeof(float), &attn_factor));
- CL_CHECK(clSetKernelArg(kernel, 31, sizeof(float), &beta_fast));
- CL_CHECK(clSetKernelArg(kernel, 32, sizeof(float), &beta_slow));
- if (is_mrope || is_vision) {
- CL_CHECK(clSetKernelArg(kernel, 33, sizeof(int32_t)*4, §ions));
- }
-
- size_t global_work_size[] = {(size_t)ne01*nth, (size_t)ne02, (size_t)ne03};
- size_t local_work_size[] = {(size_t)nth, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-static void ggml_cl_im2col(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst) {
- GGML_ASSERT(src0);
- GGML_ASSERT(src1);
- GGML_ASSERT(src1->extra);
- GGML_ASSERT(dst);
- GGML_ASSERT(dst->extra);
-
- // src0 - filter, src1 - input
- GGML_ASSERT(src1->type == GGML_TYPE_F32);
- GGML_ASSERT(dst->type == GGML_TYPE_F16 || dst->type == GGML_TYPE_F32);
-
- ggml_backend_opencl_context *backend_ctx = (ggml_backend_opencl_context *)backend->context;
- cl_command_queue queue = backend_ctx->queue;
-
- ggml_tensor_extra_cl * extra1 = (ggml_tensor_extra_cl *)src1->extra;
- ggml_tensor_extra_cl * extrad = (ggml_tensor_extra_cl *)dst->extra;
-
- cl_ulong offset1 = extra1->offset + src1->view_offs;
- cl_ulong offsetd = extrad->offset + dst->view_offs;
-
- const int32_t s0 = ((const int32_t*)(dst->op_params))[0];
- const int32_t s1 = ((const int32_t*)(dst->op_params))[1];
- const int32_t p0 = ((const int32_t*)(dst->op_params))[2];
- const int32_t p1 = ((const int32_t*)(dst->op_params))[3];
- const int32_t d0 = ((const int32_t*)(dst->op_params))[4];
- const int32_t d1 = ((const int32_t*)(dst->op_params))[5];
-
- const bool is_2D = ((const int32_t*)(dst->op_params))[6] == 1;
-
- const cl_long IC = src1->ne[is_2D ? 2 : 1];
- const cl_long IH = is_2D ? src1->ne[1] : 1;
- const cl_long IW = src1->ne[0];
-
- const cl_long KH = is_2D ? src0->ne[1] : 1;
- const cl_long KW = src0->ne[0];
-
- const cl_long OH = is_2D ? dst->ne[2] : 1;
- const cl_long OW = dst->ne[1];
-
- // nb is byte offset, src is type float32
- const cl_ulong delta_offset = src1->nb[is_2D ? 2 : 1]/4;
- const cl_long batch = src1->ne[is_2D ? 3 : 2];
- const cl_ulong batch_offset = src1->nb[is_2D ? 3 : 2]/4;
-
- const cl_long pelements = OW*KW*KH;
- const cl_long CHW = IC*KH*KW;
-
- cl_kernel kernel;
-
- if(dst->type == GGML_TYPE_F16) {
- kernel = backend_ctx->kernel_im2col_f16;
- } else {
- kernel = backend_ctx->kernel_im2col_f32;
- }
-
- CL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), &extra1->data_device));
- CL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_ulong), &offset1));
- CL_CHECK(clSetKernelArg(kernel, 2, sizeof(cl_mem), &extrad->data_device));
- CL_CHECK(clSetKernelArg(kernel, 3, sizeof(cl_ulong), &offsetd));
- CL_CHECK(clSetKernelArg(kernel, 4, sizeof(cl_ulong), &batch_offset));
- CL_CHECK(clSetKernelArg(kernel, 5, sizeof(cl_ulong), &delta_offset));
- CL_CHECK(clSetKernelArg(kernel, 6, sizeof(cl_long), &IW));
- CL_CHECK(clSetKernelArg(kernel, 7, sizeof(cl_long), &IH));
- CL_CHECK(clSetKernelArg(kernel, 8, sizeof(cl_long), &IC));
- CL_CHECK(clSetKernelArg(kernel, 9, sizeof(cl_long), &OW));
- CL_CHECK(clSetKernelArg(kernel, 10, sizeof(cl_long), &OH));
- CL_CHECK(clSetKernelArg(kernel, 11, sizeof(cl_long), &KW));
- CL_CHECK(clSetKernelArg(kernel, 12, sizeof(cl_long), &KH));
- CL_CHECK(clSetKernelArg(kernel, 13, sizeof(cl_long), &pelements));
- CL_CHECK(clSetKernelArg(kernel, 14, sizeof(cl_long), &CHW));
- CL_CHECK(clSetKernelArg(kernel, 15, sizeof(int), &s0));
- CL_CHECK(clSetKernelArg(kernel, 16, sizeof(int), &s1));
- CL_CHECK(clSetKernelArg(kernel, 17, sizeof(int), &p0));
- CL_CHECK(clSetKernelArg(kernel, 18, sizeof(int), &p1));
- CL_CHECK(clSetKernelArg(kernel, 19, sizeof(int), &d0));
- CL_CHECK(clSetKernelArg(kernel, 20, sizeof(int), &d1));
-
- const int num_blocks = (pelements + 256 - 1) / 256;
- size_t global_work_size[] = {(size_t)num_blocks*256, (size_t)OH, (size_t)batch*IC};
- size_t local_work_size[] = {256, 1, 1};
-
-#ifdef GGML_OPENCL_PROFILING
- cl_event evt;
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, &evt));
-
- g_profiling_info.emplace_back();
- populateProfilingInfo(g_profiling_info.back(), evt, kernel, global_work_size, local_work_size, dst);
-#else
- CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global_work_size, local_work_size, 0, NULL, NULL));
-#endif
-}
-
-//------------------------------------------------------------------------------
-// Op offloading
-//------------------------------------------------------------------------------
-
-typedef void (*ggml_cl_func_t)(ggml_backend_t backend, const ggml_tensor * src0, const ggml_tensor * src1, ggml_tensor * dst);
-
-bool ggml_cl_compute_forward(ggml_backend_t backend, struct ggml_tensor * tensor) {
- ggml_cl_func_t func = nullptr;
-
- ggml_tensor * src0 = tensor->src[0];
- ggml_tensor * src1 = tensor->src[1];
-
- const bool any_on_device = tensor->extra
- || (src0 != nullptr && src0->extra)
- || (src1 != nullptr && src1->extra);
-
- switch (tensor->op) {
- case GGML_OP_GET_ROWS:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_get_rows;
- break;
- case GGML_OP_CPY:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_cpy;
- break;
- case GGML_OP_DUP:
- case GGML_OP_CONT:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_dup;
- break;
- case GGML_OP_ADD:
- if (!any_on_device) {
- return false;
- }
- GGML_ASSERT(ggml_is_contiguous(src0));
- GGML_ASSERT(ggml_is_contiguous(src1));
- func = ggml_cl_add;
- break;
- case GGML_OP_MUL:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_mul;
- break;
- case GGML_OP_UNARY:
- switch (ggml_get_unary_op(tensor)) {
- case GGML_UNARY_OP_GELU:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_gelu;
- break;
- case GGML_UNARY_OP_GELU_QUICK:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_gelu_quick;
- break;
- case GGML_UNARY_OP_SILU:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_silu;
- break;
- case GGML_UNARY_OP_RELU:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_relu;
- break;
- default:
- return false;
- } break;
- case GGML_OP_CLAMP:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_clamp;
- break;
- case GGML_OP_NORM:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_norm;
- break;
- case GGML_OP_RMS_NORM:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_rms_norm;
- break;
- case GGML_OP_MUL_MAT:
- if (!any_on_device && !ggml_cl_can_mul_mat(tensor->src[0], tensor->src[1], tensor)) {
- return false;
- }
- func = ggml_cl_mul_mat;
- break;
- case GGML_OP_SCALE:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_scale;
- break;
- case GGML_OP_RESHAPE:
- case GGML_OP_VIEW:
- case GGML_OP_PERMUTE:
- case GGML_OP_TRANSPOSE:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_nop;
- break;
- case GGML_OP_DIAG_MASK_INF:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_diag_mask_inf;
- break;
- case GGML_OP_SOFT_MAX:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_soft_max;
- break;
- case GGML_OP_ROPE:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_rope;
- break;
- case GGML_OP_IM2COL:
- if (!any_on_device) {
- return false;
- }
- func = ggml_cl_im2col;
- break;
- default:
- return false;
- }
-
- func(backend, tensor->src[0], tensor->src[1], tensor);
- return true;
-}
diff --git a/ggml/src/ggml-opencl/kernels/add.cl b/ggml/src/ggml-opencl/kernels/add.cl
deleted file mode 100644
index f73f3c013..000000000
--- a/ggml/src/ggml-opencl/kernels/add.cl
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// add
-//------------------------------------------------------------------------------
-
-// general-purpose kernel for addition of two tensors
-// pros: works for non-contiguous tensors, supports broadcast across dims 1, 2 and 3
-// cons: not very efficient
-kernel void kernel_add(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global char * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- int ne13,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = src0 + offset0;
- src1 = src1 + offset1;
- dst = dst + offsetd;
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int i13 = i03 % ne13;
- int i12 = i02 % ne12;
- int i11 = i01 % ne11;
-
- global char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01;
- global char * src1_ptr = src1 + i13*nb13 + i12*nb12 + i11*nb11;
- global char * dst_ptr = dst + i03*nb3 + i02*nb2 + i01*nb1;
-
- for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) {
- const int i10 = i0 % ne10;
- *((global float *)(dst_ptr + i0*nb0)) = *((global float *)(src0_ptr + i0*nb00)) + *((global float *)(src1_ptr + i10*nb10));
- }
-}
-
-// assumption: src1 is a row
-// broadcast src1 into src0
-kernel void kernel_add_row(
- global float4 * src0,
- ulong offset0,
- global float4 * src1,
- ulong offset1,
- global float4 * dst,
- ulong offsetd,
- int ne
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- src1 = (global float4*)((global char*)src1 + offset1);
- dst = (global float4*)((global char*)dst + offsetd);
-
- // This performs better than using %.
- uint gid = get_global_id(0);
- uint idx1 = gid - (gid/ne)*ne; // get_global_id(0) % ne
- dst[gid] = src0[gid] + src1[idx1];
-}
diff --git a/ggml/src/ggml-opencl/kernels/clamp.cl b/ggml/src/ggml-opencl/kernels/clamp.cl
deleted file mode 100644
index ae6032444..000000000
--- a/ggml/src/ggml-opencl/kernels/clamp.cl
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// clamp
-//------------------------------------------------------------------------------
-kernel void kernel_clamp(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- float min,
- float max
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- dst[get_global_id(0)] = src0[get_global_id(0)] < min ?
- min :
- (src0[get_global_id(0)] > max ? max : src0[get_global_id(0)]);
-}
diff --git a/ggml/src/ggml-opencl/kernels/cpy.cl b/ggml/src/ggml-opencl/kernels/cpy.cl
deleted file mode 100644
index 9369351a6..000000000
--- a/ggml/src/ggml-opencl/kernels/cpy.cl
+++ /dev/null
@@ -1,184 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// cpy
-//------------------------------------------------------------------------------
-
-kernel void kernel_cpy_f16_f16(
- global half * src0,
- ulong offset0,
- global half * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = (global half*)((global char*)src0 + offset0);
- dst = (global half*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- int i3 = n / (ne2*ne1*ne0);
- int i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
- int i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
- int i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
-
- global half * dst_data = (global half *) ((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- global const half * src = (global half *)((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
- dst_data[i00] = src[0];
- }
-}
-
-kernel void kernel_cpy_f16_f32(
- global half * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
-
- src0 = (global half*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- int i3 = n / (ne2*ne1*ne0);
- int i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
- int i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
- int i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
-
- global float * dst_data = (global float *) ((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- global half * src = (global half *)((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
- dst_data[i00] = src[0];
- }
-}
-
-kernel void kernel_cpy_f32_f16(
- global float * src0,
- ulong offset0,
- global half * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global half*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- int i3 = n / (ne2*ne1*ne0);
- int i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
- int i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
- int i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
-
- global half * dst_data = (global half *) ((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- global const float * src = (global float *)((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
-
- dst_data[i00] = src[0];
- }
-}
-
-kernel void kernel_cpy_f32_f32(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int n = i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- int i3 = n / (ne2*ne1*ne0);
- int i2 = (n - i3*ne2*ne1*ne0) / (ne1*ne0);
- int i1 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0) / ne0;
- int i0 = (n - i3*ne2*ne1*ne0 - i2*ne1*ne0 - i1*ne0);
-
- global float * dst_data = (global float *) ((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- global const float * src = (global float *)((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01 + i00*nb00);
-
- dst_data[i00] = src[0];
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/cvt.cl b/ggml/src/ggml-opencl/kernels/cvt.cl
deleted file mode 100644
index fe7975e3d..000000000
--- a/ggml/src/ggml-opencl/kernels/cvt.cl
+++ /dev/null
@@ -1,118 +0,0 @@
-//------------------------------------------------------------------------------
-// This file is contains kernels for data conversion.
-// These kernels are used when loading the model, so its performance is less
-// important.
-//------------------------------------------------------------------------------
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-//------------------------------------------------------------------------------
-// kernel_convert_block_q4_0
-// Convert the block_q4_0 format to 2 separate arrays (AOS -> SOA).
-// This kernel does not deshuffle the bits.
-//------------------------------------------------------------------------------
-kernel void kernel_convert_block_q4_0(
- global struct block_q4_0 * src0,
- global uchar * dst_q,
- global half * dst_d
-) {
- global struct block_q4_0 * b = (global struct block_q4_0 *) src0 + get_global_id(0);
- global uchar * q = (global uchar *) dst_q + QK4_0/2*get_global_id(0);
- global half * d = (global half *) dst_d + get_global_id(0);
-
- *d = b->d;
-
- for (int i = 0; i < QK4_0/2; ++i) {
- q[i] = b->qs[i];
- }
-}
-
-kernel void kernel_restore_block_q4_0(
- global uchar * src_q,
- global half * src_d,
- global struct block_q4_0 * dst
-) {
- global struct block_q4_0 * b = (global struct block_q4_0 *) dst + get_global_id(0);
- global uchar * q = (global uchar *) src_q + QK4_0/2*get_global_id(0);
- global half * d = (global half *) src_d + get_global_id(0);
-
- b->d = *d;
- for (int i = 0; i < QK4_0/2; ++i) {
- b->qs[i] = q[i];
- }
-}
-
-//------------------------------------------------------------------------------
-// kernel_convert_block_q4_0_noshuffle
-// Flatten q4_0 weights and unshuffle the bits
-//------------------------------------------------------------------------------
-
-kernel void kernel_convert_block_q4_0_noshuffle(
- global struct block_q4_0 * src0,
- global uchar * dst_q,
- global half * dst_d
-) {
- global struct block_q4_0 * b = (global struct block_q4_0 *) src0 + get_global_id(0);
- global uchar * q = (global uchar *) dst_q + QK4_0/2*get_global_id(0);
- global half * d = (global half *) dst_d + get_global_id(0);
-
- *d = b->d;
- for (int i = 0; i < QK4_0/4; ++i) {
- uchar x0 = b->qs[2*i + 0];
- uchar x1 = b->qs[2*i + 1];
-
- q[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4);
- q[i + QK4_0/4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0);
-
-#ifdef ADRENO_GPU
- // Workaround for adreno - must have the following printf statement for
- // the kernel to work properly. Otherwise it produces incorrect result.
- // convert_uchar above also seems necessary.
- // Compare against a large number so that it does not print anything.
- // get_sub_group_local_id() also works.
- if (get_global_id(0) == 65536*4096) {
- printf("%04x - %02x\n", *(global ushort*)d, ((x0 & 0xF0) >> 4) | (x1 & 0xF0));
- }
-#endif
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/diag_mask_inf.cl b/ggml/src/ggml-opencl/kernels/diag_mask_inf.cl
deleted file mode 100644
index 36eff0439..000000000
--- a/ggml/src/ggml-opencl/kernels/diag_mask_inf.cl
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// diag_mask_inf kernels
-//------------------------------------------------------------------------------
-kernel void kernel_diag_mask_inf(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int n_past
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i02 = get_global_id(2);
- int i01 = get_global_id(1);
- int i00 = get_global_id(0);
-
- if (i00 > n_past + i01) {
- dst[i02*ne01*ne00 + i01*ne00 + i00] = -INFINITY;
- } else {
- dst[i02*ne01*ne00 + i01*ne00 + i00] = src0[i02*ne01*ne00 + i01*ne00 + i00];
- }
-}
-
-kernel void kernel_diag_mask_inf_8(
- global float4 * src0,
- ulong offset0,
- global float4 * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int n_past
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- dst = (global float4*)((global char*)dst + offsetd);
-
- int i = 2*get_global_id(0);
-
- dst[i+0] = src0[i+0];
- dst[i+1] = src0[i+1];
- int i4 = 4*i;
- int i02 = i4/(ne00*ne01); i4 -= i02*ne00*ne01;
- int i01 = i4/(ne00); i4 -= i01*ne00;
- int i00 = i4;
- for (int k = 3; k >= 0; --k) {
- if (i00 + 4 + k <= n_past + i01) {
- break;
- }
- (&dst[i+1])[k] = -INFINITY;
- if (i00 + k > n_past + i01) {
- (&dst[i])[k] = -INFINITY;
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/embed_kernel.py b/ggml/src/ggml-opencl/kernels/embed_kernel.py
deleted file mode 100644
index b5d1d7242..000000000
--- a/ggml/src/ggml-opencl/kernels/embed_kernel.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-
-import sys
-import logging
-logger = logging.getLogger("opencl-embed-kernel")
-
-
-def main():
- logging.basicConfig(level=logging.INFO)
-
- if len(sys.argv) != 3:
- logger.info("Usage: python embed_kernel.py ")
- sys.exit(1)
-
- ifile = open(sys.argv[1], "r")
- ofile = open(sys.argv[2], "w")
-
- for i in ifile:
- ofile.write('R"({})"\n'.format(i))
-
- ifile.close()
- ofile.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/ggml/src/ggml-opencl/kernels/gelu.cl b/ggml/src/ggml-opencl/kernels/gelu.cl
deleted file mode 100644
index 71c310cc9..000000000
--- a/ggml/src/ggml-opencl/kernels/gelu.cl
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// gelu
-//------------------------------------------------------------------------------
-#define GELU_COEF_A 0.044715f
-#define GELU_QUICK_COEF -1.702f
-#define SQRT_2_OVER_PI 0.79788456080286535587989211986876f
-
-kernel void kernel_gelu(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- float x = src0[get_global_id(0)];
-
- dst[get_global_id(0)] = 0.5f*x*(1.0f + tanh(SQRT_2_OVER_PI*x*(1.0f + GELU_COEF_A*x*x)));
-}
-
-kernel void kernel_gelu_4(
- global float4 * src0,
- ulong offset0,
- global float4 * dst,
- ulong offsetd
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- dst = (global float4*)((global char*)dst + offsetd);
-
- float4 x = src0[get_global_id(0)];
-
- dst[get_global_id(0)] = 0.5f*x*(1.0f + tanh(SQRT_2_OVER_PI*x*(1.0f + GELU_COEF_A*x*x)));
-}
-
-kernel void kernel_gelu_quick(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- float x = src0[get_global_id(0)];
- dst[get_global_id(0)] = x*(1.0f/(1.0f+exp(GELU_QUICK_COEF*x)));
-}
-
-kernel void kernel_gelu_quick_4(
- global float4 * src0,
- ulong offset0,
- global float4 * dst,
- ulong offsetd
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- dst = (global float4*)((global char*)dst + offsetd);
-
- float4 x = src0[get_global_id(0)];
- dst[get_global_id(0)] = x*(1.0f/(1.0f+exp(GELU_QUICK_COEF*x)));
-}
diff --git a/ggml/src/ggml-opencl/kernels/gemv_noshuffle.cl b/ggml/src/ggml-opencl/kernels/gemv_noshuffle.cl
deleted file mode 100644
index ee5c79f00..000000000
--- a/ggml/src/ggml-opencl/kernels/gemv_noshuffle.cl
+++ /dev/null
@@ -1,268 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-
-#ifdef cl_qcom_reqd_sub_group_size
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#endif
-
-// assume
-#define QK4_0 32
-#define N_SIMDGROUP 4
-
-#define dequantizeBlockAccum_ns_sgbroadcast_1_hi(total_sums, bits4, scale, y) \
- float shared_y; \
- shared_y = sub_group_broadcast(y.s0, 0); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 0); \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 0); \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 0); \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 0); \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 0); \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 0); \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 0); \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s0, 1); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 1); \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 1); \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 1); \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 1); \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 1); \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 1); \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 1); \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_1_lo(total_sums, bits4, scale, y) \
- shared_y = sub_group_broadcast(y.s0, 2); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 2); \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 2); \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 2); \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 2); \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 2); \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 2); \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 2); \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s0, 3); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 3); \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 3); \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 3); \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 3); \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 3); \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 3); \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 3); \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_8_hi(total_sums, bits4, scale, y) \
- float8 shared_y; \
- shared_y = sub_group_broadcast(y, 0); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
- shared_y = sub_group_broadcast(y, 1); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_8_lo(total_sums, bits4, scale, y) \
- shared_y = sub_group_broadcast(y, 2); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
- shared_y = sub_group_broadcast(y, 3); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-__kernel void kernel_gemv_noshuffle(
- __read_only image1d_buffer_t src0_q, // quantized A
- global half2 * src0_d, // A scales
- __read_only image1d_buffer_t src1, // B
- ulong offset1, // offset to B (0)
- global float * dst, // C
- ulong offsetd, // offset to C (0)
- uint K, // K
- int ne01, // M
- int ne02, // 1
- int ne10, // K
- int ne12, // 1
- int ne0, // M
- int ne1, // N
- int r2, // 1
- int r3)
-{
- uint groupId = get_local_id(1);
- uint gid = get_global_id(0);
- ushort slid = get_sub_group_local_id();
-
- __private uint4 regA;
- __private half2 regS;
- __private float8 regB;
-
- __private float2 totalSum = (float2)(0.0f);
-
- // loop along K in block granularity, skip 4 blocks every iter
- for (uint k = groupId; k < (K / QK4_0); k += N_SIMDGROUP) {
- regS = src0_d[gid + k * LINE_STRIDE_A]; // each fiber loads scale of two rows
- // first 4 fibers in each wave load 8 B values to its private scope
- if (slid < 4) {
- regB.s0123 = read_imagef(src1, (slid * 2 + k * 8));
- regB.s4567 = read_imagef(src1, (1 + slid * 2 + k * 8));
- }
-
- // load half weights for two blocks in consecutive rows
- regA.s0 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 0)).x;
- regA.s1 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 1)).x;
- regA.s2 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 2)).x;
- regA.s3 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 3)).x;
-#ifdef VECTOR_SUB_GROUP_BROADCAT
- dequantizeBlockAccum_ns_sgbroadcast_8_hi(totalSum, as_ushort8(regA), regS, regB);
-#else
- dequantizeBlockAccum_ns_sgbroadcast_1_hi(totalSum, as_ushort8(regA), regS, regB);
-#endif // VECTOR_SUB_GROUP_BROADCAT
-
- regA.s0 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 4)).x;
- regA.s1 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 5)).x;
- regA.s2 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 6)).x;
- regA.s3 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 7)).x;
-#ifdef VECTOR_SUB_GROUP_BROADCAT
- dequantizeBlockAccum_ns_sgbroadcast_8_lo(totalSum, as_ushort8(regA), regS, regB);
-#else
- dequantizeBlockAccum_ns_sgbroadcast_1_lo(totalSum, as_ushort8(regA), regS, regB);
-#endif // VECTOR_SUB_GROUP_BROADCAT
- }
-
- // reduction in local memory, assumes #wave=4
- __local float2 reduceLM[SIMDGROUP_WIDTH * 3];
- if (groupId == 1) reduceLM[SIMDGROUP_WIDTH * 0 + slid] = totalSum;
- if (groupId == 2) reduceLM[SIMDGROUP_WIDTH * 1 + slid] = totalSum;
- if (groupId == 3) reduceLM[SIMDGROUP_WIDTH * 2 + slid] = totalSum;
- barrier(CLK_LOCAL_MEM_FENCE);
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 0 + slid];
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 1 + slid];
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 2 + slid];
-
- // 2 outputs per fiber in wave 0
- if (groupId == 0) {
- dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
- }
-
-}
diff --git a/ggml/src/ggml-opencl/kernels/gemv_noshuffle_general.cl b/ggml/src/ggml-opencl/kernels/gemv_noshuffle_general.cl
deleted file mode 100644
index 469d3edef..000000000
--- a/ggml/src/ggml-opencl/kernels/gemv_noshuffle_general.cl
+++ /dev/null
@@ -1,274 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-
-#ifdef cl_qcom_reqd_sub_group_size
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#endif
-
-// assume
-#define QK4_0 32
-#define N_SIMDGROUP 4
-
-#define dequantizeBlockAccum_ns_sgbroadcast_1_hi(total_sums, bits4, scale, y) \
- float shared_y; \
- shared_y = sub_group_broadcast(y.s0, 0); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 0); \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 0); \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 0); \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 0); \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 0); \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 0); \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 0); \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s0, 1); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 1); \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 1); \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 1); \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 1); \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 1); \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 1); \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 1); \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_1_lo(total_sums, bits4, scale, y) \
- shared_y = sub_group_broadcast(y.s0, 2); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 2); \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 2); \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 2); \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 2); \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 2); \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 2); \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 2); \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s0, 3); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s1, 3); \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s2, 3); \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s3, 3); \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s4, 3); \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s5, 3); \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s6, 3); \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y; \
- shared_y = sub_group_broadcast(y.s7, 3); \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_8_hi(total_sums, bits4, scale, y) \
- float8 shared_y; \
- shared_y = sub_group_broadcast(y, 0); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
- shared_y = sub_group_broadcast(y, 1); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
-
-
-#define dequantizeBlockAccum_ns_sgbroadcast_8_lo(total_sums, bits4, scale, y) \
- shared_y = sub_group_broadcast(y, 2); \
- total_sums.s0 += ((bits4.s0 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s0 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s0 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s0 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s2 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s2 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s2 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s2 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s1 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s1 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s1 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s1 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s3 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s3 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s3 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s3 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
- shared_y = sub_group_broadcast(y, 3); \
- total_sums.s0 += ((bits4.s4 & 0x000F) - 8) * scale.s0 * shared_y.s0; \
- total_sums.s0 += (((bits4.s4 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s1; \
- total_sums.s0 += (((bits4.s4 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s2; \
- total_sums.s0 += (((bits4.s4 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s3; \
- total_sums.s0 += ((bits4.s6 & 0x000F) - 8) * scale.s0 * shared_y.s4; \
- total_sums.s0 += (((bits4.s6 & 0x00F0) >> 4) - 8) * scale.s0 * shared_y.s5; \
- total_sums.s0 += (((bits4.s6 & 0x0F00) >> 8) - 8) * scale.s0 * shared_y.s6; \
- total_sums.s0 += (((bits4.s6 & 0xF000) >> 12) - 8) * scale.s0 * shared_y.s7; \
- total_sums.s1 += ((bits4.s5 & 0x000F) - 8) * scale.s1 * shared_y.s0; \
- total_sums.s1 += (((bits4.s5 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s1; \
- total_sums.s1 += (((bits4.s5 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s2; \
- total_sums.s1 += (((bits4.s5 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s3; \
- total_sums.s1 += ((bits4.s7 & 0x000F) - 8) * scale.s1 * shared_y.s4; \
- total_sums.s1 += (((bits4.s7 & 0x00F0) >> 4) - 8) * scale.s1 * shared_y.s5; \
- total_sums.s1 += (((bits4.s7 & 0x0F00) >> 8) - 8) * scale.s1 * shared_y.s6; \
- total_sums.s1 += (((bits4.s7 & 0xF000) >> 12) - 8) * scale.s1 * shared_y.s7; \
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-__kernel void kernel_gemv_noshuffle(
- __read_only image1d_buffer_t src0_q, // quantized A
- global half2 * src0_d, // A scales
- __read_only image1d_buffer_t src1, // B
- ulong offset1, // offset to B (0)
- global float * dst, // C
- ulong offsetd, // offset to C (0)
- int ne00, // K
- int ne01, // M
- int ne02, // 1
- int ne10, // K
- int ne12, // 1
- int ne0, // M
- int ne1, // N
- int r2, // 1
- int r3)
-{
- uint groupId = get_local_id(1);
- uint gid = get_global_id(0);
- ushort slid = get_sub_group_local_id();
-
- uint K = ne00;
- uint M = ne01;
-
- uint LINE_STRIDE_A = M / 2;
- uint BLOCK_STRIDE_A = N_SIMDGROUP * M;
-
- __private uint4 regA;
- __private half2 regS;
- __private float8 regB;
-
- __private float2 totalSum = (float2)(0.0f);
-
- // loop along K in block granularity, skip 4 blocks every iter
- for (uint k = groupId; k < (K / QK4_0); k += N_SIMDGROUP) {
- regS = src0_d[gid + k * LINE_STRIDE_A]; // each fiber loads scale of two rows
- // first 4 fibers in each wave load 8 B values to its private scope
- if (slid < 4) {
- regB.s0123 = read_imagef(src1, (slid * 2 + k * 8));
- regB.s4567 = read_imagef(src1, (1 + slid * 2 + k * 8));
- }
-
- // load half weights for two blocks in consecutive rows
- regA.s0 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 0)).x;
- regA.s1 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 1)).x;
- regA.s2 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 2)).x;
- regA.s3 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 3)).x;
-#ifdef VECTOR_SUB_GROUP_BROADCAT
- dequantizeBlockAccum_ns_sgbroadcast_8_hi(totalSum, as_ushort8(regA), regS, regB);
-#else
- dequantizeBlockAccum_ns_sgbroadcast_1_hi(totalSum, as_ushort8(regA), regS, regB);
-#endif // VECTOR_SUB_GROUP_BROADCAT
-
- regA.s0 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 4)).x;
- regA.s1 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 5)).x;
- regA.s2 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 6)).x;
- regA.s3 = read_imageui(src0_q, (gid + k * BLOCK_STRIDE_A + LINE_STRIDE_A * 7)).x;
-#ifdef VECTOR_SUB_GROUP_BROADCAT
- dequantizeBlockAccum_ns_sgbroadcast_8_lo(totalSum, as_ushort8(regA), regS, regB);
-#else
- dequantizeBlockAccum_ns_sgbroadcast_1_lo(totalSum, as_ushort8(regA), regS, regB);
-#endif // VECTOR_SUB_GROUP_BROADCAT
- }
-
- // reduction in local memory, assumes #wave=4
- __local float2 reduceLM[SIMDGROUP_WIDTH * 3];
- if (groupId == 1) reduceLM[SIMDGROUP_WIDTH * 0 + slid] = totalSum;
- if (groupId == 2) reduceLM[SIMDGROUP_WIDTH * 1 + slid] = totalSum;
- if (groupId == 3) reduceLM[SIMDGROUP_WIDTH * 2 + slid] = totalSum;
- barrier(CLK_LOCAL_MEM_FENCE);
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 0 + slid];
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 1 + slid];
- if (groupId == 0) totalSum += reduceLM[SIMDGROUP_WIDTH * 2 + slid];
-
- // 2 outputs per fiber in wave 0
- if (groupId == 0) {
- dst = (global float*)((global char*)dst + offsetd);
- vstore2(totalSum, 0, &(dst[gid * 2]));
- }
-
-}
diff --git a/ggml/src/ggml-opencl/kernels/get_rows.cl b/ggml/src/ggml-opencl/kernels/get_rows.cl
deleted file mode 100644
index b3fea2923..000000000
--- a/ggml/src/ggml-opencl/kernels/get_rows.cl
+++ /dev/null
@@ -1,163 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-#define QK4_0 32
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-
-//------------------------------------------------------------------------------
-// dequantize_q4_0_f32, dequantize_q4_0_f16
-//------------------------------------------------------------------------------
-void dequantize_q4_0_f32(global struct block_q4_0 * xb, short il, float16 * reg) {
- global ushort * qs = ((global ushort *)xb + 1);
- float d1 = il ? (xb->d / 16.h) : xb->d;
- float d2 = d1 / 256.f;
- float md = -8.h * xb->d;
- ushort mask0 = il ? 0x00F0 : 0x000F;
- ushort mask1 = mask0 << 8;
-
- reg->s0 = d1 * (qs[0] & mask0) + md;
- reg->s1 = d2 * (qs[0] & mask1) + md;
-
- reg->s2 = d1 * (qs[1] & mask0) + md;
- reg->s3 = d2 * (qs[1] & mask1) + md;
-
- reg->s4 = d1 * (qs[2] & mask0) + md;
- reg->s5 = d2 * (qs[2] & mask1) + md;
-
- reg->s6 = d1 * (qs[3] & mask0) + md;
- reg->s7 = d2 * (qs[3] & mask1) + md;
-
- reg->s8 = d1 * (qs[4] & mask0) + md;
- reg->s9 = d2 * (qs[4] & mask1) + md;
-
- reg->sa = d1 * (qs[5] & mask0) + md;
- reg->sb = d2 * (qs[5] & mask1) + md;
-
- reg->sc = d1 * (qs[6] & mask0) + md;
- reg->sd = d2 * (qs[6] & mask1) + md;
-
- reg->se = d1 * (qs[7] & mask0) + md;
- reg->sf = d2 * (qs[7] & mask1) + md;
-}
-
-
-//------------------------------------------------------------------------------
-// get_rows
-//------------------------------------------------------------------------------
-kernel void kernel_get_rows_f32(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- ulong nb01,
- ulong nb02,
- int ne10,
- ulong nb10,
- ulong nb11,
- ulong nb1,
- ulong nb2
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i10 = get_group_id(0);
- int i11 = get_group_id(1);
-
- int r = ((global int *) ((global char *) src1 + i11*nb11 + i10*nb10))[0];
-
- int i02 = i11;
-
- for (int ind = get_local_id(0); ind < ne00; ind += get_local_size(0)) {
- ((global float *) ((global char *) dst + i11*nb2 + i10*nb1))[ind] =
- ((global float *) ((global char *) src0 + r*nb01 + i02*nb02))[ind];
- }
-}
-
-kernel void kernel_get_rows_f16(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- ulong nb01,
- ulong nb02,
- int ne10,
- ulong nb10,
- ulong nb11,
- ulong nb1,
- ulong nb2
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i10 = get_group_id(0);
- int i11 = get_group_id(1);
-
- int r = ((global int32_t *) ((global char *) src1 + i11*nb11 + i10*nb10))[0];
-
- int i02 = i11;
-
- for (int ind = get_local_id(0); ind < ne00; ind += get_local_size(0)) {
- ((global float *) ((global char *) dst + i11*nb2 + i10*nb1))[ind] =
- ((global half *) ((global char *) src0 + r*nb01 + i02*nb02))[ind];
- }
-}
-
-kernel void kernel_get_rows_q4_0(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- ulong nb01,
- ulong nb02,
- int ne10,
- ulong nb10,
- ulong nb11,
- ulong nb1,
- ulong nb2
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- const int NL = 2;
-
- int i10 = get_group_id(0);
- int i11 = get_group_id(1);
-
- int r = ((global int32_t *) ((global char *) src1 + i11*nb11 + i10*nb10))[0];
-
- int i02 = i11;
-
- for (int ind = get_local_id(0); ind < ne00/16; ind += get_local_size(0)) {
- float16 temp;
- dequantize_q4_0_f32(
- ((global struct block_q4_0 *) ((global char *) src0 + r*nb01 + i02*nb02)) + ind/NL, ind%NL, &temp);
- *(((global float16 *) ((global char *) dst + i11*nb2 + i10*nb1)) + ind) = temp;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/im2col_f16.cl b/ggml/src/ggml-opencl/kernels/im2col_f16.cl
deleted file mode 100644
index b84c89846..000000000
--- a/ggml/src/ggml-opencl/kernels/im2col_f16.cl
+++ /dev/null
@@ -1,57 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-kernel void kernel_im2col_f16(
- global float * src1,
- ulong offset1,
- global half * dst,
- ulong offsetd,
- ulong batch_offset,
- ulong delta_offset,
- long IW,
- long IH,
- long IC,
- long OW,
- long OH,
- long KW,
- long KH,
- long pelements,
- long CHW,
- int s0,
- int s1,
- int p0,
- int p1,
- int d0,
- int d1
-) {
- long i = get_global_id(0);
- if (i >= pelements) {
- return;
- }
-
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global half*)((global char*)dst + offsetd);
-
- long ksize = OW * (KH > 1 ? KW : 1);
- long kx = i / ksize;
- long kd = kx * ksize;
- long ky = (i - kd) / OW;
- long ix = i % OW;
-
- long oh = get_group_id(1);
- long batch = get_group_id(2) / IC;
- long ic = get_group_id(2) % IC;
-
- long iiw = ix * s0 + kx * d0 - p0;
- long iih = oh * s1 + ky * d1 - p1;
-
- long offset_dst =
- ((batch * OH + oh) * OW + ix) * CHW +
- (ic * (KW * KH) + ky * KW + kx);
-
- if (iih < 0 || iih >= IH || iiw < 0 || iiw >= IW) {
- dst[offset_dst] = 0.0f;
- } else {
- long offset_src = ic * delta_offset + batch * batch_offset;
- dst[offset_dst] = src1[offset_src + iih * IW + iiw];
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/im2col_f32.cl b/ggml/src/ggml-opencl/kernels/im2col_f32.cl
deleted file mode 100644
index 4bf65e4ea..000000000
--- a/ggml/src/ggml-opencl/kernels/im2col_f32.cl
+++ /dev/null
@@ -1,57 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-kernel void kernel_im2col_f32(
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- ulong batch_offset,
- ulong delta_offset,
- long IW,
- long IH,
- long IC,
- long OW,
- long OH,
- long KW,
- long KH,
- long pelements,
- long CHW,
- int s0,
- int s1,
- int p0,
- int p1,
- int d0,
- int d1
-) {
- long i = get_global_id(0);
- if (i >= pelements) {
- return;
- }
-
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- long ksize = OW * (KH > 1 ? KW : 1);
- long kx = i / ksize;
- long kd = kx * ksize;
- long ky = (i - kd) / OW;
- long ix = i % OW;
-
- long oh = get_group_id(1);
- long batch = get_group_id(2) / IC;
- long ic = get_group_id(2) % IC;
-
- long iiw = ix * s0 + kx * d0 - p0;
- long iih = oh * s1 + ky * d1 - p1;
-
- long offset_dst =
- ((batch * OH + oh) * OW + ix) * CHW +
- (ic * (KW * KH) + ky * KW + kx);
-
- if (iih < 0 || iih >= IH || iiw < 0 || iiw >= IW) {
- dst[offset_dst] = 0.0f;
- } else {
- long offset_src = ic * delta_offset + batch * batch_offset;
- dst[offset_dst] = src1[offset_src + iih * IW + iiw];
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul.cl b/ggml/src/ggml-opencl/kernels/mul.cl
deleted file mode 100644
index 2a2b4eb70..000000000
--- a/ggml/src/ggml-opencl/kernels/mul.cl
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// mul
-//------------------------------------------------------------------------------
-kernel void kernel_mul(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global char * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- int ne13,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3
-) {
- src0 = src0 + offset0;
- src1 = src1 + offset1;
- dst = dst + offsetd;
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- int i13 = i03 % ne13;
- int i12 = i02 % ne12;
- int i11 = i01 % ne11;
-
- global char * src0_ptr = src0 + i03*nb03 + i02*nb02 + i01*nb01;
- global char * src1_ptr = src1 + i13*nb13 + i12*nb12 + i11*nb11;
- global char * dst_ptr = dst + i03*nb3 + i02*nb2 + i01*nb1;
-
- for (int i0 = get_local_id(0); i0 < ne0; i0 += get_local_size(0)) {
- const int i10 = i0 % ne10;
- *((global float *)(dst_ptr + i0*nb0)) = *((global float *)(src0_ptr + i0*nb00)) * *((global float *)(src1_ptr + i10*nb10));
- }
-}
-
-// assumption: src1 is a row
-// broadcast src1 into src0
-kernel void kernel_mul_row(
- global float4 * src0,
- ulong offset0,
- global float4 * src1,
- ulong offset1,
- global float4 * dst,
- ulong offsetd,
- int ne
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- src1 = (global float4*)((global char*)src1 + offset1);
- dst = (global float4*)((global char*)dst + offsetd);
-
- // This performs better than using %.
- uint gid = get_global_id(0);
- uint idx1 = gid - (gid/ne)*ne; // get_global_id(0) % ne
- dst[gid] = src0[gid] * src1[idx1];
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mat_Ab_Bi_8x4.cl b/ggml/src/ggml-opencl/kernels/mul_mat_Ab_Bi_8x4.cl
deleted file mode 100644
index ecb577b99..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mat_Ab_Bi_8x4.cl
+++ /dev/null
@@ -1,139 +0,0 @@
-// src0_q, src0_d, src1 are transposed as a preprocessing step
-// 4-bit weights are transposed in groups of 4 (unsigned short int)
-// consider weights originally "next to each other", now "on top of each other"
-// each fiber computes a 8x4 tile of output elements
-// using unshuffled weights
-
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-
-#ifdef cl_qcom_reqd_sub_group_size
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_128
-#endif
-
-kernel void kernel_mul_mat_Ab_Bi_8x4(
- global const ushort * src0_q, // quantized A
- global const half * src0_d, // A scales
- __read_only image1d_buffer_t src1, // B (1d image)
- global float * dst, // C
- int m, // M
- int n, // N with padding
- int k, // K
- int n_no_padding // N without padding
-) {
-
- int m_4 = m >> 2;
- int n_4 = n >> 2;
-
- int gy = get_global_id(0);
- int gx = get_global_id(1);
- int gx_2 = gx << 2;
-
- half8 c0 = 0, c1 = 0, c2 = 0, c3 = 0; // 8x4 output elements
- half8 B; // registers for activations
- half4 dequantized_weights; // registers for dequantized weights
- __global const ushort* weight_ptr = src0_q + gx_2; // pointer for weights
- __global const half* scale_ptr = src0_d + gx_2; // pointer for scales
-
- for(int i=0; i> 4) - 8) * scale.s0; // dequantize a row of the 16 weights
- dequantized_weights.s1 = (((bits4.s1 & (0x00F0)) >> 4) - 8) * scale.s1;
- dequantized_weights.s2 = (((bits4.s2 & (0x00F0)) >> 4) - 8) * scale.s2;
- dequantized_weights.s3 = (((bits4.s3 & (0x00F0)) >> 4) - 8) * scale.s3;
- c0 += B * dequantized_weights.s0; //vector-scalar multiplication to accumulate
- c1 += B * dequantized_weights.s1;
- c2 += B * dequantized_weights.s2;
- c3 += B * dequantized_weights.s3;
-
- // j=2
- B.s0123 = read_imageh(src1, gy*2 + (i+2)*(n_4));
- B.s4567 = read_imageh(src1, gy*2 + (i+2)*(n_4)+1);
- dequantized_weights.s0 = (((bits4.s0 & (0x0F00)) >> 8) - 8) * scale.s0; // dequantize a row of the 16 weights
- dequantized_weights.s1 = (((bits4.s1 & (0x0F00)) >> 8) - 8) * scale.s1;
- dequantized_weights.s2 = (((bits4.s2 & (0x0F00)) >> 8) - 8) * scale.s2;
- dequantized_weights.s3 = (((bits4.s3 & (0x0F00)) >> 8) - 8) * scale.s3;
- c0 += B * dequantized_weights.s0; // vector-scalar multiplication to accumulate
- c1 += B * dequantized_weights.s1;
- c2 += B * dequantized_weights.s2;
- c3 += B * dequantized_weights.s3;
-
- // j=3
- B.s0123 = read_imageh(src1, gy*2 + (i+3)*(n_4));
- B.s4567 = read_imageh(src1, gy*2 + (i+3)*(n_4)+1);
- dequantized_weights.s0 = (((bits4.s0 & (0xF000)) >> 12) - 8) * scale.s0; // dequantize a row of the 16 weights
- dequantized_weights.s1 = (((bits4.s1 & (0xF000)) >> 12) - 8) * scale.s1;
- dequantized_weights.s2 = (((bits4.s2 & (0xF000)) >> 12) - 8) * scale.s2;
- dequantized_weights.s3 = (((bits4.s3 & (0xF000)) >> 12) - 8) * scale.s3;
- c0 += B * dequantized_weights.s0; // vector-scalar multiplication to accumulate
- c1 += B * dequantized_weights.s1;
- c2 += B * dequantized_weights.s2;
- c3 += B * dequantized_weights.s3;
- }
-
- int idx = (gy<<3)*m + (gx<<2); // vectorized store 16 elements
-
- // conditional check if store is to a valid location. Required when N is not a multiple of 8
- // if statements allow registers to be reused for each store
- // provides a performance boost due to reduced register footprint, which increases number of concurrent waves
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s0, c1.s0, c2.s0, c3.s0), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s1, c1.s1, c2.s1, c3.s1), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s2, c1.s2, c2.s2, c3.s2), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s3, c1.s3, c2.s3, c3.s3), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s4, c1.s4, c2.s4, c3.s4), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s5, c1.s5, c2.s5, c3.s5), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s6, c1.s6, c2.s6, c3.s6), 0, dst + idx);
- idx += m;
- }
- if(idx+3 < m*n_no_padding){
- vstore4((float4)(c0.s7, c1.s7, c2.s7, c3.s7), 0, dst + idx);
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f16.cl b/ggml/src/ggml-opencl/kernels/mul_mv_f16_f16.cl
deleted file mode 100644
index 9393b5494..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f16.cl
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define N_F16_F16 4
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_f16_f16(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int r2,
- int r3)
-{
- src0 = (global char*)((global char*)src0 + offset0);
- src1 = (global char*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int r0 = get_group_id(0);
- int rb = get_group_id(1)*N_F16_F16;
- int im = get_group_id(2);
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = r0*nb01 + (i12/r2)*nb02 + (i13/r3)*nb03;
-
- global half * x = (global half *) (src0 + offset_src0);
-
- if (ne00 < 128) {
- for (int row = 0; row < N_F16_F16; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global half * y = (global half *) (src1 + offset_src1);
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00; i += get_max_sub_group_size()) {
- sumf += (half) x[i] * (half) y[i];
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- } else {
- global half4 * x4 = (global half4 *)x;
- for (int row = 0; row < N_F16_F16; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global half * y = (global half *) (src1 + offset_src1);
- global half4 * y4 = (global half4 *) y;
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00/4; i += get_max_sub_group_size()) {
- sumf += (half) x4[i].s0 * y4[i].s0;
- sumf += (half) x4[i].s1 * y4[i].s1;
- sumf += (half) x4[i].s2 * y4[i].s2;
- sumf += (half) x4[i].s3 * y4[i].s3;
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- for (int i = 4*(ne00/4); i < ne00; ++i) {
- all_sum += (half) x[i] * y[i];
- }
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32.cl b/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32.cl
deleted file mode 100644
index e52d3c6d4..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32.cl
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define N_F16_F32 4
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_f16_f32(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global char*)((global char*)src0 + offset0);
- src1 = (global char*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int r0 = get_group_id(0);
- int rb = get_group_id(1)*N_F16_F32;
- int im = get_group_id(2);
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = r0*nb01 + (i12/r2)*nb02 + (i13/r3)*nb03;
-
- global half * x = (global half *) (src0 + offset_src0);
-
- if (ne00 < 128) {
- for (int row = 0; row < N_F16_F32; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global float * y = (global float *) (src1 + offset_src1);
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00; i += get_max_sub_group_size()) {
- sumf += convert_float(x[i]) * y[i];
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- } else {
- global half4 * x4 = (global half4 *)x;
- for (int row = 0; row < N_F16_F32; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global float * y = (global float *) (src1 + offset_src1);
- global float4 * y4 = (global float4 *) y;
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00/4; i += get_max_sub_group_size()) {
- sumf += convert_float(x4[i].s0) * y4[i].s0;
- sumf += convert_float(x4[i].s1) * y4[i].s1;
- sumf += convert_float(x4[i].s2) * y4[i].s2;
- sumf += convert_float(x4[i].s3) * y4[i].s3;
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- for (int i = 4*(ne00/4); i < ne00; ++i) {
- all_sum += (float) x[i] * y[i];
- }
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_1row.cl b/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_1row.cl
deleted file mode 100644
index 28d30212c..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_1row.cl
+++ /dev/null
@@ -1,94 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_f16_f32_1row(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global char*)((global char*)src0 + offset0);
- src1 = (global char*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = r0*nb01 + (i12/r2)*nb02 + (i13/r3)*nb03;
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global half * x = (global half *) (src0 + offset_src0);
- global float * y = (global float *) (src1 + offset_src1);
-
- float sumf = 0;
- if (ne00 < 128) {
- for (int i = get_sub_group_local_id(); i < ne00; i += get_max_sub_group_size()) {
- sumf += (float) x[i] * (float) y[i];
- }
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- } else {
- global half4 * x4 = (global half4 *) x;
- global float4 * y4 = (global float4 *) y;
- for (int i = get_sub_group_local_id(); i < ne00/4; i += get_max_sub_group_size()) {
- sumf += (float) x4[i].s0 * y4[i].s0;
- sumf += (float) x4[i].s1 * y4[i].s1;
- sumf += (float) x4[i].s2 * y4[i].s2;
- sumf += (float) x4[i].s3 * y4[i].s3;
- }
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- for (int i = 4*(ne00/4); i < ne00; ++i) {
- all_sum += (float) x[i] * y[i];
- }
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
-
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl b/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl
deleted file mode 100644
index cdf8197c4..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-// Assumes row size (ne00) is a multiple of 4
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_f16_f32_l4(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global char*)((global char*)src0 + offset0);
- src1 = (global char*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int nrows = ne11;
- int r0 = get_group_id(0);
- int im = get_group_id(2);
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = r0*nb01 + (i12/r2)*nb02 + (i13/r3)*nb03;
-
- global half4 * x4 = (global half4 *) (src0 + offset_src0);
-
- for (int r1 = 0; r1 < nrows; ++r1) {
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global float4 * y4 = (global float4 *) (src1 + offset_src1);
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00/4; i += get_max_sub_group_size()) {
- sumf += convert_float(x4[i].s0) * y4[i].s0;
- sumf += convert_float(x4[i].s1) * y4[i].s1;
- sumf += convert_float(x4[i].s2) * y4[i].s2;
- sumf += convert_float(x4[i].s3) * y4[i].s3;
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_f32_f32.cl b/ggml/src/ggml-opencl/kernels/mul_mv_f32_f32.cl
deleted file mode 100644
index ec71b8756..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_f32_f32.cl
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define N_F32_F32 4
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_f32_f32(
- global char * src0,
- ulong offset0,
- global char * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne10,
- int ne11,
- int ne12,
- ulong nb10,
- ulong nb11,
- ulong nb12,
- ulong nb13,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global char*)((global char*)src0 + offset0);
- src1 = (global char*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int r0 = get_group_id(0);
- int rb = get_group_id(1)*N_F32_F32;
- int im = get_group_id(2);
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = r0*nb01 + (i12/r2)*nb02 + (i13/r3)*nb03;
-
- global float * x = (global float *) (src0 + offset_src0);
-
- if (ne00 < 128) {
- for (int row = 0; row < N_F32_F32; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global float * y = (global float *) (src1 + offset_src1);
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00; i += get_max_sub_group_size()) {
- sumf += (float) x[i] * (float) y[i];
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- } else {
- global float4 * x4 = (global float4 *)x;
- for (int row = 0; row < N_F32_F32; ++row) {
- int r1 = rb + row;
- if (r1 >= ne11) {
- break;
- }
-
- ulong offset_src1 = r1*nb11 + (i12 )*nb12 + (i13 )*nb13;
-
- global float * y = (global float *) (src1 + offset_src1);
- global float4 * y4 = (global float4 *) y;
-
- float sumf = 0;
- for (int i = get_sub_group_local_id(); i < ne00/4; i += get_max_sub_group_size()) {
- sumf += (float) x4[i].s0 * y4[i].s0;
- sumf += (float) x4[i].s1 * y4[i].s1;
- sumf += (float) x4[i].s2 * y4[i].s2;
- sumf += (float) x4[i].s3 * y4[i].s3;
- }
-
- float all_sum = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- for (int i = 4*(ne00/4); i < ne00; ++i) {
- all_sum += (float) x[i] * y[i];
- }
- dst[im*ne1*ne0 + r1*ne0 + r0] = all_sum;
- }
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32.cl
deleted file mode 100644
index 52141e0ed..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32.cl
+++ /dev/null
@@ -1,192 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-//------------------------------------------------------------------------------
-// mul_vec_q_n_f32
-//------------------------------------------------------------------------------
-// function for calculate inner product between half a q4_0 block and 16 floats (yl), sumy is SUM(yl[i])
-// il indicates where the q4 quants begin (0 or QK4_0/4)
-// we assume that the yl's have been multiplied with the appropriate scale factor
-// that corresponds to the missing bit shifts (1, 1/16, 1/256, 1/4096)
-inline float block_q_4_0_dot_y(
- global struct block_q4_0 * qb_curr,
- float sumy,
- private float * yl,
- int il
-) {
- float d = qb_curr->d;
- float2 acc = 0.f;
- global ushort * qs = ((global ushort *)qb_curr + 1 + il/2);
- for (int i = 0; i < 8; i+=2) {
- acc.s0 += yl[i + 0] * (qs[i / 2] & 0x000F)
- + yl[i + 1] * (qs[i / 2] & 0x0F00);
- acc.s1 += yl[i + 8] * (qs[i / 2] & 0x00F0)
- + yl[i + 9] * (qs[i / 2] & 0xF000);
- }
- return d * (sumy * -8.f + acc.s0 + acc.s1);
-}
-
-#ifdef INTEL_GPU
-#define N_DST 4 // each SIMD group works on 4 rows
-#define N_SIMDGROUP 1 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // assuming SIMD group size is 16
-#elif defined (ADRENO_GPU)
-#define N_DST 4
-#define N_SIMDGROUP 1
-#define N_SIMDWIDTH 64
-#endif
-
-inline void mul_vec_q_n_f32(
- global void * src0,
- global float * src1,
- global float * dst,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
-
- const ulong nb = ne00/QK4_0;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- // (r0 * N_SIMDGROUP + get_sub_group_id()) is essenatially the linear global
- // id of a SIMD group in the grid.
- int first_row = (r0 * N_SIMDGROUP + get_sub_group_id()) * N_DST;
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset0 = first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
-
- global struct block_q4_0 * x = (global struct block_q4_0 *) src0 + offset0;
- global float * y = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float yl[16]; // src1 vector cache
- float sumf[N_DST]={0.f};
-
- int ix = get_sub_group_local_id()/2;
- int il = 8*(get_sub_group_local_id()%2);
-
- global float * yb = y + ix * QK4_0 + il;
-
- // each thread in a SIMD group deals with half a block.
- for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/2) {
- float sumy = 0;
- for (int i = 0; i < 8; i += 2) {
- sumy += yb[i] + yb[i+1];
- yl[i+0] = yb[i+ 0];
- yl[i+1] = yb[i+ 1]/256.f;
- sumy += yb[i+16] + yb[i+17];
- yl[i+8] = yb[i+16]/16.f;
- yl[i+9] = yb[i+17]/4096.f;
- }
-
- for (int row = 0; row < N_DST; row++) {
- sumf[row] += block_q_4_0_dot_y(x+ib+row*nb, sumy, yl, il);
- }
-
- // One thread in a SIMD group (i.e., subgroup) handles a half block,
- // hence then entire SIMD group handles SIMDWIDTH/2 blocks.
- // y points to the activation matrix (of type float). Therefore for
- // one thread, the # of blocks y should advance is SIMDWIDTH/2 (because
- // SIMDWIDTH/2 blocks are processed by a SIMD group) - in terms of
- // floats, it is QK4_0 * (SIMDWIDTH/2), where QK4_0 is the block size.
- yb += QK4_0 * (N_SIMDWIDTH/2);
- }
-
- // The above does not work for Adreno - it produces incorrect results for
- // row = 1, 2, 3 and only row = 0 gives the correct result.
- // If N_DST is changed, the below array must be initialized accordingly.
- // This also seems to perform better on Intel.
- float tot[N_DST] = {
- sub_group_reduce_add(sumf[0]), sub_group_reduce_add(sumf[1]),
- sub_group_reduce_add(sumf[2]), sub_group_reduce_add(sumf[3])};
- for (int row = 0; row < N_DST; ++row) {
- if (get_sub_group_local_id() == 0 && first_row + row < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + row] = tot[row];
- }
- }
-}
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_q4_0_f32(
- global void * src0,
- ulong offset0,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- mul_vec_q_n_f32(src0, src1, dst, ne00, ne01, ne02, ne10, ne12, ne0, ne1, r2, r3);
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_16x_flat.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_16x_flat.cl
deleted file mode 100644
index 3eebab8f0..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_16x_flat.cl
+++ /dev/null
@@ -1,307 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-inline float mm_block_q_4_0_dot_y_flat(
- global uchar * x,
- global half * dh,
- float sumy,
- float16 yl,
- int il
-) {
- float d = *dh;
- global ushort * qs = ((global ushort *)x + il/2);
- float acc = 0.f;
-
- acc += yl.s0 * (qs[0] & 0x000F);
- acc += yl.s1 * (qs[0] & 0x0F00);
- acc += yl.s8 * (qs[0] & 0x00F0);
- acc += yl.s9 * (qs[0] & 0xF000);
-
- acc += yl.s2 * (qs[1] & 0x000F);
- acc += yl.s3 * (qs[1] & 0x0F00);
- acc += yl.sa * (qs[1] & 0x00F0);
- acc += yl.sb * (qs[1] & 0xF000);
-
- acc += yl.s4 * (qs[2] & 0x000F);
- acc += yl.s5 * (qs[2] & 0x0F00);
- acc += yl.sc * (qs[2] & 0x00F0);
- acc += yl.sd * (qs[2] & 0xF000);
-
- acc += yl.s6 * (qs[3] & 0x000F);
- acc += yl.s7 * (qs[3] & 0x0F00);
- acc += yl.se * (qs[3] & 0x00F0);
- acc += yl.sf * (qs[3] & 0xF000);
-
- return d * (sumy * -8.f + acc);
-}
-
-#ifdef INTEL_GPU
-#define N_DST 16 // each SIMD group works on 8 rows (in weights matrix)
-#define N_SIMDGROUP 1 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // assuming SIMD group size is 16
-#elif defined (ADRENO_GPU)
-#define N_DST 16
-#define N_SIMDGROUP 1
-#define N_SIMDWIDTH 64
-#endif
-//
-// This variant performs 1d blocking with 16x output.
-// Eeach simdgroup outputs 16 values on `n0` dim (row in the output matrix).
-//
-inline void mul_mat_q_n_f32_1d_16x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- global float * dst,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- const int nb = ne00/QK4_0;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- // (r0 * N_SIMDGROUP + get_sub_group_id()) is the linear global id of
- // a SIMD group in the grid. Each SIMD group produces N_DST values in the
- // result, hence uses nb blocks, i.e., the offset becomes first_row*nb.
- // Currently with llama2 7B, im is always 0.
- // TODO: how to handle im/gqa*(nb*ne0)?
- int first_row = (r0 * N_SIMDGROUP + get_sub_group_id()) * N_DST;
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- // The number of scales is the same as the number of blocks.
- ulong offset0_d = first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
- // Each block contains QK4_0/2 uchars, hence offset for qs is as follows.
- ulong offset0_q = (first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02)) * QK4_0/2;
-
- global uchar * x = (global uchar *) src0_q + offset0_q;
- global half * d = (global half *) src0_d + offset0_d;
- global float * y = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float16 yl;
- float16 sumf = (float16)(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
-
- int ix = get_sub_group_local_id()/2;
- int il = 8*(get_sub_group_local_id()%2);
-
- global float * yb = y + ix*QK4_0 + il;
-
- for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/2) {
- float sumy = 0.f;
-
- sumy += yb[0];
- sumy += yb[1];
- sumy += yb[2];
- sumy += yb[3];
- sumy += yb[4];
- sumy += yb[5];
- sumy += yb[6];
- sumy += yb[7];
-
- sumy += yb[16];
- sumy += yb[17];
- sumy += yb[18];
- sumy += yb[19];
- sumy += yb[20];
- sumy += yb[21];
- sumy += yb[22];
- sumy += yb[23];
-
- yl.s0 = yb[0];
- yl.s1 = yb[1]/256.f;
-
- yl.s2 = yb[2];
- yl.s3 = yb[3]/256.f;
-
- yl.s4 = yb[4];
- yl.s5 = yb[5]/256.f;
-
- yl.s6 = yb[6];
- yl.s7 = yb[7]/256.f;
-
- yl.s8 = yb[16]/16.f;
- yl.s9 = yb[17]/4096.f;
-
- yl.sa = yb[18]/16.f;
- yl.sb = yb[19]/4096.f;
-
- yl.sc = yb[20]/16.f;
- yl.sd = yb[21]/4096.f;
-
- yl.se = yb[22]/16.f;
- yl.sf = yb[23]/4096.f;
-
- sumf.s0 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 0*nb*QK4_0/2, d + ib + 0*nb, sumy, yl, il);
- sumf.s1 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 1*nb*QK4_0/2, d + ib + 1*nb, sumy, yl, il);
- sumf.s2 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 2*nb*QK4_0/2, d + ib + 2*nb, sumy, yl, il);
- sumf.s3 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 3*nb*QK4_0/2, d + ib + 3*nb, sumy, yl, il);
-
- sumf.s4 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 4*nb*QK4_0/2, d + ib + 4*nb, sumy, yl, il);
- sumf.s5 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 5*nb*QK4_0/2, d + ib + 5*nb, sumy, yl, il);
- sumf.s6 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 6*nb*QK4_0/2, d + ib + 6*nb, sumy, yl, il);
- sumf.s7 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 7*nb*QK4_0/2, d + ib + 7*nb, sumy, yl, il);
-
- sumf.s8 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 8*nb*QK4_0/2, d + ib + 8*nb, sumy, yl, il);
- sumf.s9 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 9*nb*QK4_0/2, d + ib + 9*nb, sumy, yl, il);
- sumf.sa += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 10*nb*QK4_0/2, d + ib + 10*nb, sumy, yl, il);
- sumf.sb += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 11*nb*QK4_0/2, d + ib + 11*nb, sumy, yl, il);
-
- sumf.sc += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 12*nb*QK4_0/2, d + ib + 12*nb, sumy, yl, il);
- sumf.sd += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 13*nb*QK4_0/2, d + ib + 13*nb, sumy, yl, il);
- sumf.se += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 14*nb*QK4_0/2, d + ib + 14*nb, sumy, yl, il);
- sumf.sf += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 15*nb*QK4_0/2, d + ib + 15*nb, sumy, yl, il);
-
- yb += QK4_0 * (N_SIMDWIDTH/2);
- }
-
- float16 tot = (float16)(
- sub_group_reduce_add(sumf.s0), sub_group_reduce_add(sumf.s1),
- sub_group_reduce_add(sumf.s2), sub_group_reduce_add(sumf.s3),
- sub_group_reduce_add(sumf.s4), sub_group_reduce_add(sumf.s5),
- sub_group_reduce_add(sumf.s6), sub_group_reduce_add(sumf.s7),
-
- sub_group_reduce_add(sumf.s8), sub_group_reduce_add(sumf.s9),
- sub_group_reduce_add(sumf.sa), sub_group_reduce_add(sumf.sb),
- sub_group_reduce_add(sumf.sc), sub_group_reduce_add(sumf.sd),
- sub_group_reduce_add(sumf.se), sub_group_reduce_add(sumf.sf)
- );
-
- if (get_sub_group_local_id() == 0) {
- if (first_row + 0 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 0] = tot.s0;
- }
- if (first_row + 1 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 1] = tot.s1;
- }
- if (first_row + 2 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 2] = tot.s2;
- }
- if (first_row + 3 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 3] = tot.s3;
- }
-
- if (first_row + 4 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 4] = tot.s4;
- }
- if (first_row + 5 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 5] = tot.s5;
- }
- if (first_row + 6 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 6] = tot.s6;
- }
- if (first_row + 7 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 7] = tot.s7;
- }
-
- if (first_row + 8 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 8] = tot.s8;
- }
- if (first_row + 9 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 9] = tot.s9;
- }
- if (first_row + 10 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 10] = tot.sa;
- }
- if (first_row + 11 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 11] = tot.sb;
- }
-
- if (first_row + 12 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 12] = tot.sc;
- }
- if (first_row + 13 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 13] = tot.sd;
- }
- if (first_row + 14 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 14] = tot.se;
- }
- if (first_row + 15 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 15] = tot.sf;
- }
- }
-}
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_q4_0_f32_1d_16x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- mul_mat_q_n_f32_1d_16x_flat(src0_q, src0_d, src1, dst, ne00, ne01, ne02, ne10, ne12, ne0, ne1, r2, r3);
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_8x_flat.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_8x_flat.cl
deleted file mode 100644
index 38024d00a..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_8x_flat.cl
+++ /dev/null
@@ -1,265 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-inline float mm_block_q_4_0_dot_y_flat(
- global uchar * x,
- global half * dh,
- float sumy,
- float16 yl,
- int il
-) {
- float d = *dh;
- global ushort * qs = ((global ushort *)x + il/2);
- float acc = 0.f;
-
- acc += yl.s0 * (qs[0] & 0x000F);
- acc += yl.s1 * (qs[0] & 0x0F00);
- acc += yl.s8 * (qs[0] & 0x00F0);
- acc += yl.s9 * (qs[0] & 0xF000);
-
- acc += yl.s2 * (qs[1] & 0x000F);
- acc += yl.s3 * (qs[1] & 0x0F00);
- acc += yl.sa * (qs[1] & 0x00F0);
- acc += yl.sb * (qs[1] & 0xF000);
-
- acc += yl.s4 * (qs[2] & 0x000F);
- acc += yl.s5 * (qs[2] & 0x0F00);
- acc += yl.sc * (qs[2] & 0x00F0);
- acc += yl.sd * (qs[2] & 0xF000);
-
- acc += yl.s6 * (qs[3] & 0x000F);
- acc += yl.s7 * (qs[3] & 0x0F00);
- acc += yl.se * (qs[3] & 0x00F0);
- acc += yl.sf * (qs[3] & 0xF000);
-
- return d * (sumy * -8.f + acc);
-}
-
-#ifdef INTEL_GPU
-#define N_DST 8 // each SIMD group works on 8 rows (in weights matrix)
-#define N_SIMDGROUP 1 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // assuming SIMD group size is 16
-#elif defined (ADRENO_GPU)
-#define N_DST 8
-#define N_SIMDGROUP 1
-#define N_SIMDWIDTH 64
-#endif
-//
-// This variant performs 1d blocking with 8x output.
-// Eeach simdgroup outputs 8 values on `n0` dim (row in the output matrix).
-//
-inline void mul_mat_q_n_f32_1d_8x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- global float * dst,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- const int nb = ne00/QK4_0;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- // (r0 * N_SIMDGROUP + get_sub_group_id()) is the linear global id of
- // a SIMD group in the grid. Each SIMD group produces N_DST values in the
- // result, hence uses nb blocks, i.e., the offset becomes first_row*nb.
- // Currently with llama2 7B, im is always 0.
- // TODO: how to handle im/gqa*(nb*ne0)?
- int first_row = (r0 * N_SIMDGROUP + get_sub_group_id()) * N_DST;
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- // The number of scales is the same as the number of blocks.
- ulong offset0_d = first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
- // Each block contains QK4_0/2 uchars, hence offset for qs is as follows.
- ulong offset0_q = (first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02)) * QK4_0/2;
-
- global uchar * x = (global uchar *) src0_q + offset0_q;
- global half * d = (global half *) src0_d + offset0_d;
- global float * y = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float16 yl;
- float8 sumf = (float8)(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
-
- int ix = get_sub_group_local_id()/2;
- int il = 8*(get_sub_group_local_id()%2);
-
- global float * yb = y + ix*QK4_0 + il;
-
- for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/2) {
- float sumy = 0.f;
-
- sumy += yb[0];
- sumy += yb[1];
- sumy += yb[2];
- sumy += yb[3];
- sumy += yb[4];
- sumy += yb[5];
- sumy += yb[6];
- sumy += yb[7];
-
- sumy += yb[16];
- sumy += yb[17];
- sumy += yb[18];
- sumy += yb[19];
- sumy += yb[20];
- sumy += yb[21];
- sumy += yb[22];
- sumy += yb[23];
-
- yl.s0 = yb[0];
- yl.s1 = yb[1]/256.f;
-
- yl.s2 = yb[2];
- yl.s3 = yb[3]/256.f;
-
- yl.s4 = yb[4];
- yl.s5 = yb[5]/256.f;
-
- yl.s6 = yb[6];
- yl.s7 = yb[7]/256.f;
-
- yl.s8 = yb[16]/16.f;
- yl.s9 = yb[17]/4096.f;
-
- yl.sa = yb[18]/16.f;
- yl.sb = yb[19]/4096.f;
-
- yl.sc = yb[20]/16.f;
- yl.sd = yb[21]/4096.f;
-
- yl.se = yb[22]/16.f;
- yl.sf = yb[23]/4096.f;
-
- sumf.s0 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 0*nb*QK4_0/2, d + ib + 0*nb, sumy, yl, il);
- sumf.s1 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 1*nb*QK4_0/2, d + ib + 1*nb, sumy, yl, il);
- sumf.s2 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 2*nb*QK4_0/2, d + ib + 2*nb, sumy, yl, il);
- sumf.s3 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 3*nb*QK4_0/2, d + ib + 3*nb, sumy, yl, il);
-
- sumf.s4 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 4*nb*QK4_0/2, d + ib + 4*nb, sumy, yl, il);
- sumf.s5 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 5*nb*QK4_0/2, d + ib + 5*nb, sumy, yl, il);
- sumf.s6 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 6*nb*QK4_0/2, d + ib + 6*nb, sumy, yl, il);
- sumf.s7 += mm_block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 7*nb*QK4_0/2, d + ib + 7*nb, sumy, yl, il);
-
- yb += QK4_0 * (N_SIMDWIDTH/2);
- }
-
- float8 tot = (float8)(
- sub_group_reduce_add(sumf.s0), sub_group_reduce_add(sumf.s1),
- sub_group_reduce_add(sumf.s2), sub_group_reduce_add(sumf.s3),
- sub_group_reduce_add(sumf.s4), sub_group_reduce_add(sumf.s5),
- sub_group_reduce_add(sumf.s6), sub_group_reduce_add(sumf.s7)
- );
-
- if (get_sub_group_local_id() == 0) {
- if (first_row + 0 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 0] = tot.s0;
- }
- if (first_row + 1 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 1] = tot.s1;
- }
- if (first_row + 2 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 2] = tot.s2;
- }
- if (first_row + 3 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 3] = tot.s3;
- }
-
- if (first_row + 4 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 4] = tot.s4;
- }
- if (first_row + 5 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 5] = tot.s5;
- }
- if (first_row + 6 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 6] = tot.s6;
- }
- if (first_row + 7 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 7] = tot.s7;
- }
- }
-}
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_q4_0_f32_1d_8x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- mul_mat_q_n_f32_1d_8x_flat(src0_q, src0_d, src1, dst, ne00, ne01, ne02, ne10, ne12, ne0, ne1, r2, r3);
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_8x_flat.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_8x_flat.cl
deleted file mode 100644
index aed1ce7b2..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_8x_flat.cl
+++ /dev/null
@@ -1,272 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-// This function requires the original shuffled weights.
-// As a reminder, the original weights are shuffled so that (q[0], q[16]) are
-// packed together in a byte, so are (q[1], q[17]) and so on.
-inline float block_q_4_0_dot_y_flat(
- global uchar * x,
- global half * dh,
- float sumy,
- float16 yl,
- int il
-) {
- float d = *dh;
- global ushort * qs = ((global ushort *)x + il/2);
- float acc = 0.f;
-
- acc += yl.s0 * (qs[0] & 0x000F);
- acc += yl.s1 * (qs[0] & 0x0F00);
- acc += yl.s8 * (qs[0] & 0x00F0);
- acc += yl.s9 * (qs[0] & 0xF000);
-
- acc += yl.s2 * (qs[1] & 0x000F);
- acc += yl.s3 * (qs[1] & 0x0F00);
- acc += yl.sa * (qs[1] & 0x00F0);
- acc += yl.sb * (qs[1] & 0xF000);
-
- acc += yl.s4 * (qs[2] & 0x000F);
- acc += yl.s5 * (qs[2] & 0x0F00);
- acc += yl.sc * (qs[2] & 0x00F0);
- acc += yl.sd * (qs[2] & 0xF000);
-
- acc += yl.s6 * (qs[3] & 0x000F);
- acc += yl.s7 * (qs[3] & 0x0F00);
- acc += yl.se * (qs[3] & 0x00F0);
- acc += yl.sf * (qs[3] & 0xF000);
-
- return d * (sumy * -8.f + acc);
-}
-
-//
-// This variant outputs 8 values.
-//
-#undef N_DST
-#undef N_SIMDGROUP
-#undef N_SIMDWIDTH
-
-#ifdef INTEL_GPU
-#define N_DST 8 // each SIMD group works on 8 rows
-#define N_SIMDGROUP 1 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // assuming SIMD group size is 32
-#elif defined (ADRENO_GPU)
-#define N_DST 8
-#define N_SIMDGROUP 1
-#define N_SIMDWIDTH 64
-#endif
-
-inline void mul_vec_q_n_f32_8x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- global float * dst,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- const ulong nb = ne00/QK4_0;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- // (r0 * N_SIMDGROUP + get_sub_group_id()) is the linear global id of
- // a SIMD group in the grid. Each SIMD group produces N_DST values in the
- // result, hence uses nb blocks, i.e., the offset becomes first_row*nb.
- // Currently with llama2 7B, im is always 0.
- // TODO: how to handle im/gqa*(nb*ne0)?
- int first_row = (r0 * N_SIMDGROUP + get_sub_group_id()) * N_DST;
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- // The number of scales is the same as the number of blocks.
- ulong offset0_d = first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
- // Each block contains QK4_0/2 uchars, hence offset for qs is as follows.
- ulong offset0_q = (first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02)) * QK4_0/2;
-
- global uchar * x = (global uchar *) src0_q + offset0_q;
- global half * d = (global half *) src0_d + offset0_d;
- global float * y = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float16 yl;
- float8 sumf = 0.f;
-
- int ix = get_sub_group_local_id()/2;
- int il = 8*(get_sub_group_local_id()%2);
-
- global float * yb = y + ix*QK4_0 + il;
-
- for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/2) {
- float sumy = 0.f;
-
- sumy += yb[0];
- sumy += yb[1];
- sumy += yb[2];
- sumy += yb[3];
- sumy += yb[4];
- sumy += yb[5];
- sumy += yb[6];
- sumy += yb[7];
-
- sumy += yb[16];
- sumy += yb[17];
- sumy += yb[18];
- sumy += yb[19];
- sumy += yb[20];
- sumy += yb[21];
- sumy += yb[22];
- sumy += yb[23];
-
- yl.s0 = yb[0];
- yl.s1 = yb[1]/256.f;
-
- yl.s2 = yb[2];
- yl.s3 = yb[3]/256.f;
-
- yl.s4 = yb[4];
- yl.s5 = yb[5]/256.f;
-
- yl.s6 = yb[6];
- yl.s7 = yb[7]/256.f;
-
- yl.s8 = yb[16]/16.f;
- yl.s9 = yb[17]/4096.f;
-
- yl.sa = yb[18]/16.f;
- yl.sb = yb[19]/4096.f;
-
- yl.sc = yb[20]/16.f;
- yl.sd = yb[21]/4096.f;
-
- yl.se = yb[22]/16.f;
- yl.sf = yb[23]/4096.f;
-
- sumf.s0 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 0*nb*QK4_0/2, d + ib + 0*nb, sumy, yl, il);
- sumf.s1 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 1*nb*QK4_0/2, d + ib + 1*nb, sumy, yl, il);
- sumf.s2 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 2*nb*QK4_0/2, d + ib + 2*nb, sumy, yl, il);
- sumf.s3 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 3*nb*QK4_0/2, d + ib + 3*nb, sumy, yl, il);
-
- sumf.s4 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 4*nb*QK4_0/2, d + ib + 4*nb, sumy, yl, il);
- sumf.s5 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 5*nb*QK4_0/2, d + ib + 5*nb, sumy, yl, il);
- sumf.s6 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 6*nb*QK4_0/2, d + ib + 6*nb, sumy, yl, il);
- sumf.s7 += block_q_4_0_dot_y_flat(x + ib*QK4_0/2 + 7*nb*QK4_0/2, d + ib + 7*nb, sumy, yl, il);
-
- yb += QK4_0 * (N_SIMDWIDTH/2);
- }
-
- float8 tot = (float8)(
- sub_group_reduce_add(sumf.s0), sub_group_reduce_add(sumf.s1),
- sub_group_reduce_add(sumf.s2), sub_group_reduce_add(sumf.s3),
- sub_group_reduce_add(sumf.s4), sub_group_reduce_add(sumf.s5),
- sub_group_reduce_add(sumf.s6), sub_group_reduce_add(sumf.s7)
- );
-
- if (get_sub_group_local_id() == 0) {
- if (first_row + 0 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 0] = tot.s0;
- }
- if (first_row + 1 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 1] = tot.s1;
- }
- if (first_row + 2 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 2] = tot.s2;
- }
- if (first_row + 3 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 3] = tot.s3;
- }
-
- if (first_row + 4 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 4] = tot.s4;
- }
- if (first_row + 5 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 5] = tot.s5;
- }
- if (first_row + 6 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 6] = tot.s6;
- }
- if (first_row + 7 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 7] = tot.s7;
- }
- }
-}
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_q4_0_f32_8x_flat(
- global uchar * src0_q,
- global half * src0_d,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- mul_vec_q_n_f32_8x_flat(src0_q, src0_d, src1, dst, ne00, ne01, ne02, ne10, ne12, ne0, ne1, r2, r3);
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_v.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_v.cl
deleted file mode 100644
index 929552179..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_v.cl
+++ /dev/null
@@ -1,254 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q4_0
-//------------------------------------------------------------------------------
-struct block_q4_0
-{
- half d;
- uint8_t qs[QK4_0 / 2];
-};
-
-//
-// This variant unrolls the loops and uses vector types instead of pointers.
-// It improves performance on Adreno but not so much on Intel.
-//
-inline float block_q_4_0_dot_y_v(
- global struct block_q4_0 * qb_curr,
- float sumy,
- float16 yl,
- int il
-) {
- float d = qb_curr->d;
- float acc = 0.f;
- global ushort * qs = ((global ushort *)qb_curr + 1 + il/2);
-
- acc += yl.s0 * (qs[0] & 0x000F);
- acc += yl.s1 * (qs[0] & 0x0F00);
- acc += yl.s8 * (qs[0] & 0x00F0);
- acc += yl.s9 * (qs[0] & 0xF000);
-
- acc += yl.s2 * (qs[1] & 0x000F);
- acc += yl.s3 * (qs[1] & 0x0F00);
- acc += yl.sa * (qs[1] & 0x00F0);
- acc += yl.sb * (qs[1] & 0xF000);
-
- acc += yl.s4 * (qs[2] & 0x000F);
- acc += yl.s5 * (qs[2] & 0x0F00);
- acc += yl.sc * (qs[2] & 0x00F0);
- acc += yl.sd * (qs[2] & 0xF000);
-
- acc += yl.s6 * (qs[3] & 0x000F);
- acc += yl.s7 * (qs[3] & 0x0F00);
- acc += yl.se * (qs[3] & 0x00F0);
- acc += yl.sf * (qs[3] & 0xF000);
-
- return d * (sumy * -8.f + acc);
-}
-
-#undef N_DST
-#undef N_SIMDGROUP
-#undef N_SIMDWIDTH
-
-#ifdef INTEL_GPU
-#define N_DST 4 // each SIMD group works on 4 rows
-#define N_SIMDGROUP 1 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // assuming SIMD group size is 16
-#elif defined (ADRENO_GPU)
-#define N_DST 4
-#define N_SIMDGROUP 1
-#define N_SIMDWIDTH 64
-#endif
-
-inline void mul_vec_q_n_f32_v(
- global void * src0,
- global float * src1,
- global float * dst,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- const ulong nb = ne00/QK4_0;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- // (r0 * N_SIMDGROUP + get_sub_group_id()) is essenatially the linear global
- // id of a SIMD group in the grid.
- int first_row = (r0 * N_SIMDGROUP + get_sub_group_id()) * N_DST;
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset0 = first_row * nb + (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
-
- global struct block_q4_0 * x = (global struct block_q4_0 *) src0 + offset0;
- global float * y = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float16 yl; // src1 vector cache
- float4 sumf = (float4)(0.f, 0.f, 0.f, 0.f);
-
- int ix = get_sub_group_local_id()/2;
- int il = 8*(get_sub_group_local_id()%2);
-
- global float * yb = y + ix * QK4_0 + il;
-
- // each thread in a SIMD group deals with half a block.
- for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/2) {
- float sumy = 0;
-
- sumy += yb[0];
- sumy += yb[1];
- sumy += yb[2];
- sumy += yb[3];
- sumy += yb[4];
- sumy += yb[5];
- sumy += yb[6];
- sumy += yb[7];
-
- sumy += yb[16];
- sumy += yb[17];
- sumy += yb[18];
- sumy += yb[19];
- sumy += yb[20];
- sumy += yb[21];
- sumy += yb[22];
- sumy += yb[23];
-
-
- yl.s0 = yb[0];
- yl.s1 = yb[1]/256.f;
-
- yl.s2 = yb[2];
- yl.s3 = yb[3]/256.f;
-
- yl.s4 = yb[4];
- yl.s5 = yb[5]/256.f;
-
- yl.s6 = yb[6];
- yl.s7 = yb[7]/256.f;
-
- yl.s8 = yb[16]/16.f;
- yl.s9 = yb[17]/4096.f;
-
- yl.sa = yb[18]/16.f;
- yl.sb = yb[19]/4096.f;
-
- yl.sc = yb[20]/16.f;
- yl.sd = yb[21]/4096.f;
-
- yl.se = yb[22]/16.f;
- yl.sf = yb[23]/4096.f;
-
- sumf.s0 += block_q_4_0_dot_y_v(x+ib+0*nb, sumy, yl, il);
- sumf.s1 += block_q_4_0_dot_y_v(x+ib+1*nb, sumy, yl, il);
- sumf.s2 += block_q_4_0_dot_y_v(x+ib+2*nb, sumy, yl, il);
- sumf.s3 += block_q_4_0_dot_y_v(x+ib+3*nb, sumy, yl, il);
-
- // One thread in a SIMD group (i.e., subgroup) handles a half block,
- // hence then entire SIMD group handles SIMDWIDTH/2 blocks.
- // y points to the activation matrix (of type float). Therefore for
- // one thread, the # of blocks y should advance is SIMDWIDTH/2 (because
- // SIMDWIDTH/2 blocks are processed by a SIMD group) - in terms of
- // floats, it is QK4_0 * (SIMDWIDTH/2), where QK4_0 is the block size.
- yb += QK4_0 * (N_SIMDWIDTH/2);
- }
-
- // The above does not work for Adreno - it produces incorrect results for
- // row = 1, 2, 3 and only row = 0 gives the correct result.
- // If N_DST is changed, the below array must be initialized accordingly.
- // This also seems to perform better on Intel.
- float4 tot = (float4)(
- sub_group_reduce_add(sumf.s0), sub_group_reduce_add(sumf.s1),
- sub_group_reduce_add(sumf.s2), sub_group_reduce_add(sumf.s3)
- );
-
- if (get_sub_group_local_id() == 0) {
- if (first_row + 0 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 0] = tot.s0;
- }
- if (first_row + 1 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 1] = tot.s1;
- }
- if (first_row + 2 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 2] = tot.s2;
- }
- if (first_row + 3 < ne01) {
- dst[r1*ne0 + im*ne0*ne1 + first_row + 3] = tot.s3;
- }
- }
-}
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mat_q4_0_f32_v(
- global void * src0,
- ulong offset0,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- mul_vec_q_n_f32_v(src0, src1, dst, ne00, ne01, ne02, ne10, ne12, ne0, ne1, r2, r3);
-}
diff --git a/ggml/src/ggml-opencl/kernels/mul_mv_q6_k.cl b/ggml/src/ggml-opencl/kernels/mul_mv_q6_k.cl
deleted file mode 100644
index 8a17b9aae..000000000
--- a/ggml/src/ggml-opencl/kernels/mul_mv_q6_k.cl
+++ /dev/null
@@ -1,190 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#define QK4_0 32
-#define QR4_0 2
-#define QK4_1 32
-#define QR4_1 2
-#define QK5_0 32
-#define QR5_0 2
-#define QK5_1 32
-#define QR5_1 2
-#define QK8_0 32
-#define QR8_0 1
-#define QK_K 256
-#define K_QUANTS_PER_ITERATION 2
-
-typedef char int8_t;
-typedef uchar uint8_t;
-typedef short int16_t;
-typedef ushort uint16_t;
-typedef int int32_t;
-typedef uint uint32_t;
-
-//------------------------------------------------------------------------------
-// block_q6_K
-//------------------------------------------------------------------------------
-// 6-bit quantization
-// weight is represented as x = a * q
-// 16 blocks of 16 elements each
-// Effectively 6.5625 bits per weight
-typedef struct {
- uint8_t ql[QK_K/2]; // quants, lower 4 bits
- uint8_t qh[QK_K/4]; // quants, upper 2 bits
- int8_t scales[QK_K/16]; // scales, quantized with 8 bits
- half d; // super-block scale
-} block_q6_K;
-
-//------------------------------------------------------------------------------
-// kernel_mul_mv_q6_K_f32
-//------------------------------------------------------------------------------
-
-#undef N_DST
-#undef N_SIMDGROUP
-#undef N_SIMDWIDTH
-
-#ifdef INTEL_GPU
-#define N_DST 1 // number of rows each SIMD group works on
-#define N_SIMDGROUP 2 // number of SIMD groups in a thread group
-#define N_SIMDWIDTH 16 // SIMD group size
-#elif defined (ADRENO_GPU)
-#define N_DST 1
-#define N_SIMDGROUP 2
-#define N_SIMDWIDTH 64
-#endif
-
-#define BLOCK_STRIDE (N_SIMDWIDTH/16) // number of blocks each subgroup processes
-
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_16
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_mul_mv_q6_K_f32(
- global void * src0,
- ulong offset0,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne10,
- int ne12,
- int ne0,
- int ne1,
- int r2,
- int r3
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- uchar kmask1 = 0x03;
- uchar kmask2 = 0x0C;
- uchar kmask3 = 0x30;
- uchar kmask4 = 0xC0;
-
- int nb = ne00/QK_K;
-
- int r0 = get_group_id(0);
- int r1 = get_group_id(1);
- int im = get_group_id(2);
-
- int row = N_SIMDGROUP * r0 + get_sub_group_id();
-
- int i12 = im%ne12;
- int i13 = im/ne12;
-
- ulong offset_src0 = (i12/r2)*(nb*ne01) + (i13/r3)*(nb*ne01*ne02);
-
- global block_q6_K * x = (global block_q6_K *) src0 + row*nb + offset_src0;
- global float * yy = (global float *) src1 + r1*ne10 + im*ne00*ne1;
-
- float sumf = 0;
-
- // For Q6_K quantization, 16 values forms a subblock, 16 subblock forms a
- // block. Values in a subblock shares a scale that is quantized with 8 bits;
- // the entire block shares a single floating point scale.
- // For work distribution, each thread processes a subblock (16 weights), hence
- // 16 threads process a (super) block -- a subgroup thus handles SIMDWIDTH/16
- // (super) blocks -- this is the block stride.
- // The 16 threads that process a (super) block are split into 2 portions, each has
- // 8 threads; each portion works on 8 subblocks.
- // For subgroup of 16 threads, the entire subgroup works on a single (super) block
- // before moving to the next (super) block. Thread0 - thread7 work on the
- // first 8 subblocks; thread8 - thread15 works on the last 8 subblocks.
- // Thread0 - thread3 work on subblocks 0, 2, 4, 6; thread4 - thread7 work on
- // subblocks 1, 3, 5, 7. Each thread does not work on an entire subblock, but
- // works on a total of 16 weight values.
- int tid = get_sub_group_local_id()/BLOCK_STRIDE; // first block_stride groups have tid=0
- int ix = get_sub_group_local_id()%BLOCK_STRIDE; // first block is 0..block_stride-1
- int ip = tid/8; // first or second half of (super) block (0 or 1)
- int il = tid%8; // each half has 8 parts, one per scale
- int n = 4; // 4 scales at a time (and 4 sums)
- int l0 = n*il; // offset into half-block, 0..28
- int is = 8*ip + l0/16; // 0, 1, 8, 9
-
- int y_offset = 128*ip + l0;
- int q_offset_l = 64*ip + l0;
- int q_offset_h = 32*ip + l0;
-
- for (int i = ix; i < nb; i += BLOCK_STRIDE) {
-
- global uint8_t * q1 = x[i].ql + q_offset_l;
- global uint8_t * q2 = q1 + QK_K/8;
- global uint8_t * qh = x[i].qh + q_offset_h;
- global int8_t * sc = x[i].scales + is;
-
- global float * y = yy + i * QK_K + y_offset;
-
- float dall = x[i].d;
-
- float4 sums = {0.f, 0.f, 0.f, 0.f};
-
- sums.s0 += y[0+ 0] * ((float)((q1[0] & 0xF) | ((qh[0] & kmask1) << 4)) - 32.f);
- sums.s1 += y[0+32] * ((float)((q2[0] & 0xF) | ((qh[0] & kmask2) << 2)) - 32.f);
- sums.s2 += y[0+64] * ((float)((q1[0] >> 4) | ((qh[0] & kmask3) << 0)) - 32.f);
- sums.s3 += y[0+96] * ((float)((q2[0] >> 4) | ((qh[0] & kmask4) >> 2)) - 32.f);
-
- sums.s0 += y[1+ 0] * ((float)((q1[1] & 0xF) | ((qh[1] & kmask1) << 4)) - 32.f);
- sums.s1 += y[1+32] * ((float)((q2[1] & 0xF) | ((qh[1] & kmask2) << 2)) - 32.f);
- sums.s2 += y[1+64] * ((float)((q1[1] >> 4) | ((qh[1] & kmask3) << 0)) - 32.f);
- sums.s3 += y[1+96] * ((float)((q2[1] >> 4) | ((qh[1] & kmask4) >> 2)) - 32.f);
-
- sums.s0 += y[2+ 0] * ((float)((q1[2] & 0xF) | ((qh[2] & kmask1) << 4)) - 32.f);
- sums.s1 += y[2+32] * ((float)((q2[2] & 0xF) | ((qh[2] & kmask2) << 2)) - 32.f);
- sums.s2 += y[2+64] * ((float)((q1[2] >> 4) | ((qh[2] & kmask3) << 0)) - 32.f);
- sums.s3 += y[2+96] * ((float)((q2[2] >> 4) | ((qh[2] & kmask4) >> 2)) - 32.f);
-
- sums.s0 += y[3+ 0] * ((float)((q1[3] & 0xF) | ((qh[3] & kmask1) << 4)) - 32.f);
- sums.s1 += y[3+32] * ((float)((q2[3] & 0xF) | ((qh[3] & kmask2) << 2)) - 32.f);
- sums.s2 += y[3+64] * ((float)((q1[3] >> 4) | ((qh[3] & kmask3) << 0)) - 32.f);
- sums.s3 += y[3+96] * ((float)((q2[3] >> 4) | ((qh[3] & kmask4) >> 2)) - 32.f);
-
- sumf += dall * (sums.s0 * sc[0] + sums.s1 * sc[2] + sums.s2 * sc[4] + sums.s3 * sc[6]);
- }
-
- float tot = sub_group_reduce_add(sumf);
- if (get_sub_group_local_id() == 0) {
- dst[r1*ne0 + im*ne0*ne1 + row] = tot;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/norm.cl b/ggml/src/ggml-opencl/kernels/norm.cl
deleted file mode 100644
index 43167ba4d..000000000
--- a/ggml/src/ggml-opencl/kernels/norm.cl
+++ /dev/null
@@ -1,81 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-//------------------------------------------------------------------------------
-// norm
-//------------------------------------------------------------------------------
-kernel void kernel_norm(
- global void * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- float eps,
- local float * sum
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- dst = (global void*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float * x = (global float *) ((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01);
-
- // MEAN
- // parallel sum
- sum[get_local_id(0)] = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- sum[get_local_id(0)] += x[i00];
- }
- // reduce
- barrier(CLK_LOCAL_MEM_FENCE);
- for (uint i = get_local_size(0)/2; i > 0; i /= 2) {
- if (get_local_id(0) < i) {
- sum[get_local_id(0)] += sum[get_local_id(0) + i];
- }
- barrier(CLK_LOCAL_MEM_FENCE);
- }
- float mean = sum[0] / ne00;
-
- // recenter and VARIANCE
- barrier(CLK_LOCAL_MEM_FENCE);
- global float * y = dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
- sum[get_local_id(0)] = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- y[i00] = x[i00] - mean;
- sum[get_local_id(0)] += y[i00] * y[i00];
- }
-
- // reduce
- barrier(CLK_LOCAL_MEM_FENCE);
- for (uint i = get_local_size(0)/2; i > 0; i /= 2) {
- if (get_local_id(0) < i) {
- sum[get_local_id(0)] += sum[get_local_id(0) + i];
- }
- barrier(CLK_LOCAL_MEM_FENCE);
- }
- float variance = sum[0] / ne00;
-
- float scale = 1.0f/sqrt(variance + eps);
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- y[i00] = y[i00] * scale;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/relu.cl b/ggml/src/ggml-opencl/kernels/relu.cl
deleted file mode 100644
index 60ff28a61..000000000
--- a/ggml/src/ggml-opencl/kernels/relu.cl
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// relu
-//------------------------------------------------------------------------------
-kernel void kernel_relu(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- dst[get_global_id(0)] = fmax(0.0f, src0[get_global_id(0)]);
-}
diff --git a/ggml/src/ggml-opencl/kernels/rms_norm.cl b/ggml/src/ggml-opencl/kernels/rms_norm.cl
deleted file mode 100644
index 9d21f3398..000000000
--- a/ggml/src/ggml-opencl/kernels/rms_norm.cl
+++ /dev/null
@@ -1,96 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-//------------------------------------------------------------------------------
-// rms_norm
-//------------------------------------------------------------------------------
-// This kernel depends on subgroup size.
-#ifdef INTEL_GPU
-REQD_SUBGROUP_SIZE_32
-#elif defined (ADRENO_GPU)
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_rms_norm(
- global void * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- float eps,
- local float * sum // Note, the size depends on number of subgroups
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float4 * x = (global float4 *) ((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01);
- global float * x_scalar = (global float *) x;
- float4 sumf = 0;
- float all_sum = 0;
-
- // parallel sum
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- sumf += x[i00] * x[i00];
- }
- all_sum = sumf.s0 + sumf.s1 + sumf.s2 + sumf.s3;
- all_sum = sub_group_reduce_add(all_sum);
- if (get_sub_group_local_id() == 0) {
- sum[get_sub_group_id()] = all_sum;
- }
-
- barrier(CLK_LOCAL_MEM_FENCE);
- // broadcast
- for (uint i = get_local_size(0) / get_max_sub_group_size() / 2; i > 0; i /= 2) {
- if (get_local_id(0) < i) {
- sum[get_local_id(0)] += sum[get_local_id(0) + i];
- }
- }
- if (get_local_id(0) == 0) {
- for (int i = 4 * (ne00 / 4); i < ne00; i++) {
- sum[0] += x_scalar[i];
- }
- sum[0] /= ne00;
- }
-
- barrier(CLK_LOCAL_MEM_FENCE);
-
- const float mean = sum[0];
- const float scale = 1.0f/sqrt(mean + eps);
-
- global float4 * y = (global float4 *) (dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00);
- global float * y_scalar = (global float *) y;
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- y[i00] = x[i00] * scale;
- }
- if (get_local_id(0) == 0) {
- for (int i00 = 4 * (ne00 / 4); i00 < ne00; i00++) {
- y_scalar[i00] = x_scalar[i00] * scale;
- }
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/rope.cl b/ggml/src/ggml-opencl/kernels/rope.cl
deleted file mode 100644
index 0247730c0..000000000
--- a/ggml/src/ggml-opencl/kernels/rope.cl
+++ /dev/null
@@ -1,721 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// kernel_rope
-//------------------------------------------------------------------------------
-float rope_yarn_ramp(float low, float high, int i0) {
- const float y = (i0 / 2 - low) / max(0.001f, high - low);
- return 1.0f - min(1.0f, max(0.0f, y));
-}
-
-// YaRN algorithm based on LlamaYaRNScaledRotaryEmbedding.py from https://github.com/jquesnelle/yarn
-// MIT licensed. Copyright (c) 2023 Jeffrey Quesnelle and Bowen Peng.
-float2 rope_yarn(
- float theta_extrap, float freq_scale, float2 corr_dims, int i0, float ext_factor, float mscale
-) {
- // Get n-d rotational scaling corrected for extrapolation
- float theta_interp = freq_scale * theta_extrap;
- float theta = theta_interp;
- if (ext_factor != 0.0f) {
- float ramp_mix = rope_yarn_ramp(corr_dims.s0, corr_dims.s1, i0) * ext_factor;
- theta = theta_interp * (1 - ramp_mix) + theta_extrap * ramp_mix;
-
- // Get n-d magnitude scaling corrected for interpolation
- mscale *= 1.0f + 0.1f * log(1.0f / freq_scale);
- }
- return (float2)(cos(theta) * mscale, sin(theta) * mscale);
-}
-
-// Apparently solving `n_rot = 2pi * x * base^((2 * max_pos_emb) / n_dims)` for x, we get
-// `corr_fac(n_rot) = n_dims * log(max_pos_emb / (n_rot * 2pi)) / (2 * log(base))`
-float rope_yarn_corr_factor(int n_dims, int n_ctx_orig, float n_rot, float base) {
- return n_dims * log(n_ctx_orig / (n_rot * 2 * M_PI_F)) / (2 * log(base));
-}
-
-float2 rope_yarn_corr_dims(
- int n_dims, int n_ctx_orig, float freq_base, float beta_fast, float beta_slow
-) {
- // start and end correction dims
- return (float2)(
- max(0.0f, floor(rope_yarn_corr_factor(n_dims, n_ctx_orig, beta_fast, freq_base))),
- min(n_dims - 1.0f, ceil(rope_yarn_corr_factor(n_dims, n_ctx_orig, beta_slow, freq_base)))
- );
-}
-
-kernel void kernel_rope_norm_f32(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- float theta_base = (float) pos[i2];
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global float * src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- float x0 = src[0];
- float x1 = src[1];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[1] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global float * src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_norm_f16(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- float theta_base = (float) pos[i2];
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global half * src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- float x0 = src[0];
- float x1 = src[1];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[1] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global half * src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_neox_f32(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- float theta_base = (float) pos[i2];
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- const float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global float * src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims/2];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims/2] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global float * const src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_neox_f16(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- float theta_base = (float) pos[i2];
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- const float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global half * src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims/2];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims/2] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global half * const src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_multi_f32(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow,
- int4 sections
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- const int sect_dims = sections.s0 + sections.s1 + sections.s2 + sections.s3;
- const int sec_w = sections.s1 + sections.s0;
-
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- const int sector = (i0 / 2) % sect_dims;
- float theta_base = 0.0f;
-
- if (sector < sections.s0) {
- theta_base = pos[i2];
- }
- else if (sector >= sections.s0 && sector < sec_w) {
- theta_base = pos[i2 + ne2 * 1];
- }
- else if (sector >= sec_w && sector < sec_w + sections.s2) {
- theta_base = pos[i2 + ne2 * 2];
- }
- else if (sector >= sec_w + sections.s2) {
- theta_base = pos[i2 + ne2 * 3];
- }
-
- const float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global float * src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims/2];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims/2] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global float * const src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_multi_f16(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global half * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow,
- int4 sections
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- const int sect_dims = sections.s0 + sections.s1 + sections.s2 + sections.s3;
- const int sec_w = sections.s1 + sections.s0;
-
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- if (i0 < n_dims) {
- int ic = i0/2;
-
- const int sector = (i0 / 2) % sect_dims;
- float theta_base = 0.0f;
-
- if (sector < sections.s0) {
- theta_base = pos[i2];
- }
- else if (sector >= sections.s0 && sector < sec_w) {
- theta_base = pos[i2 + ne2 * 1];
- }
- else if (sector >= sec_w && sector < sec_w + sections.s2) {
- theta_base = pos[i2 + ne2 * 2];
- }
- else if (sector >= sec_w + sections.s2) {
- theta_base = pos[i2 + ne2 * 3];
- }
-
- const float theta = theta_base * pow(freq_base, inv_ndims*i0);
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global half * src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims/2];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims/2] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- } else {
- global half * const src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
-
- dst_data[0] = src[0];
- dst_data[1] = src[1];
- }
- }
-}
-
-kernel void kernel_rope_vision_f32(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow,
- int4 sections
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- const int sect_dims = sections.s0 + sections.s1;
- const int sec_w = sections.s1 + sections.s0;
-
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- int ic = i0/2;
-
- const int sector = (i0/2) % sect_dims;
- float theta_base = 0.0f;
-
- if (sector < sections.s0) {
- const int p = sector;
- theta_base = pos[i2] * pow(freq_base, inv_ndims*2.0f*p);
- } else if (sector >= sections.s0 && sector < sec_w) {
- const int p = sector - sections.s0;
- theta_base = pos[i2 + ne2] * pow(freq_base, inv_ndims*2.0f*p);
- }
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta_base/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global float * src = (global float *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global float * dst_data = (global float *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- }
-}
-
-kernel void kernel_rope_vision_f16(
- global void * src0,
- ulong offset0,
- global int * src1,
- ulong offset1,
- global float * src2,
- ulong offset2,
- global half * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- int ne03,
- ulong nb00,
- ulong nb01,
- ulong nb02,
- ulong nb03,
- int ne0,
- int ne1,
- int ne2,
- int ne3,
- ulong nb0,
- ulong nb1,
- ulong nb2,
- ulong nb3,
- int n_past,
- int n_dims,
- int n_ctx_orig,
- float freq_base,
- float freq_scale,
- float ext_factor,
- float attn_factor,
- float beta_fast,
- float beta_slow,
- int4 sections
-) {
- src0 = (global void*)((global char*)src0 + offset0);
- src1 = (global int*)((global char*)src1 + offset1);
- src2 = (global float*)((global char*)src2 + offset2);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i3 = get_group_id(2);
- int i2 = get_group_id(1);
- int i1 = get_group_id(0);
-
- float2 corr_dims = rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow);
-
- global int * pos = src1;
-
- const int sect_dims = sections.s0 + sections.s1;
- const int sec_w = sections.s1 + sections.s0;
-
- float inv_ndims = -1.f/n_dims;
-
- for (int i0 = 2*get_local_id(0); i0 < ne0; i0 += 2*get_local_size(0)) {
- int ic = i0/2;
-
- const int sector = (i0/2) % sect_dims;
- float theta_base = 0.0f;
-
- if (sector < sections.s0) {
- const int p = sector;
- theta_base = pos[i2] * pow(freq_base, inv_ndims*2.0f*p);
- } else if (sector >= sections.s0 && sector < sec_w) {
- const int p = sector - sections.s0;
- theta_base = pos[i2 + ne2] * pow(freq_base, inv_ndims*2.0f*p);
- }
-
- const float freq_factor = src2 != src0 ? src2[ic] : 1.0f;
-
- float2 cos_sin_theta = rope_yarn(theta_base/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor);
-
- global half * src = (global half *)((global char *) src0 + i3*nb03 + i2*nb02 + i1*nb01 + ic*nb00);
- global half * dst_data = (global half *)((global char *) dst + i3*nb3 + i2*nb2 + i1*nb1 + ic*nb0);
-
- const float x0 = src[0];
- const float x1 = src[n_dims];
-
- dst_data[0] = x0*cos_sin_theta.s0 - x1*cos_sin_theta.s1;
- dst_data[n_dims] = x0*cos_sin_theta.s1 + x1*cos_sin_theta.s0;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/scale.cl b/ggml/src/ggml-opencl/kernels/scale.cl
deleted file mode 100644
index 8cfd518fa..000000000
--- a/ggml/src/ggml-opencl/kernels/scale.cl
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// scale
-//------------------------------------------------------------------------------
-kernel void kernel_scale(
- global float4 * src0,
- ulong offset0,
- global float4 * dst,
- ulong offsetd,
- float scale
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- dst = (global float4*)((global char*)dst + offsetd);
- dst[get_global_id(0)] = src0[get_global_id(0)] * scale;
-}
diff --git a/ggml/src/ggml-opencl/kernels/silu.cl b/ggml/src/ggml-opencl/kernels/silu.cl
deleted file mode 100644
index 1d95e1b50..000000000
--- a/ggml/src/ggml-opencl/kernels/silu.cl
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-//------------------------------------------------------------------------------
-// silu
-//------------------------------------------------------------------------------
-kernel void kernel_silu(
- global float * src0,
- ulong offset0,
- global float * dst,
- ulong offsetd
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- dst = (global float*)((global char*)dst + offsetd);
-
- float x = src0[get_global_id(0)];
- dst[get_global_id(0)] = x / (1.0f + exp(-x));
-}
-
-kernel void kernel_silu_4(
- global float4 * src0,
- ulong offset0,
- global float4 * dst,
- ulong offsetd
-) {
- src0 = (global float4*)((global char*)src0 + offset0);
- dst = (global float4*)((global char*)dst + offsetd);
-
- float4 x = src0[get_global_id(0)];
- dst[get_global_id(0)] = x / (1.0f + exp(-x));
-}
diff --git a/ggml/src/ggml-opencl/kernels/softmax_4_f16.cl b/ggml/src/ggml-opencl/kernels/softmax_4_f16.cl
deleted file mode 100644
index 62c05369a..000000000
--- a/ggml/src/ggml-opencl/kernels/softmax_4_f16.cl
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_soft_max_4_f16(
- global float * src0,
- ulong offset0,
- global half * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- float scale,
- float max_bias,
- float m0,
- float m1,
- int n_head_log2
-) {
- src0 = (global float *)((global char *)src0 + offset0);
- src1 = (global half *)((global char *)src1 + offset1);
- dst = (global float *)((global char *)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float4 * psrc4 = (global float4 *)(src0 + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00);
- global half4 * pmask = (global char *)src1 != (global char *)src0 ? (global half4 *)(src1 + i01*ne00) : 0;
- global float4 * pdst4 = (global float4 *)(dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00);
-
- float slope = 1.0f;
-
- // ALiBi
- if (max_bias > 0.0f) {
- int h = i02;
-
- float base = h < n_head_log2 ? m0 : m1;
- int exp = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1;
-
- slope = pow(base, exp);
- }
-
- // parallel max
- float4 lmax4 = -INFINITY;
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- lmax4 = fmax(lmax4, psrc4[i00]*scale + slope*(pmask ? convert_float4(pmask[i00]) : 0.0f));
- }
- float lmax = fmax(fmax(lmax4.s0, lmax4.s1), fmax(lmax4.s2, lmax4.s3));
-
- const float max = sub_group_reduce_max(lmax);
-
- // parallel sum
- float4 lsum4 = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- const float4 exp_psrc4 = exp((psrc4[i00]*scale + slope*(pmask ? convert_float4(pmask[i00]) : 0.0f)) - max);
- lsum4 += exp_psrc4;
- pdst4[i00] = exp_psrc4;
- }
- float lsum = lsum4.s0 + lsum4.s1 + lsum4.s2 + lsum4.s3;
-
- const float sum = sub_group_reduce_add(lsum);
-
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- pdst4[i00] /= sum;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/softmax_4_f32.cl b/ggml/src/ggml-opencl/kernels/softmax_4_f32.cl
deleted file mode 100644
index d562774ea..000000000
--- a/ggml/src/ggml-opencl/kernels/softmax_4_f32.cl
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_soft_max_4(
- global float * src0,
- ulong offset0,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- float scale,
- float max_bias,
- float m0,
- float m1,
- int n_head_log2
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float4 * psrc4 = (global float4 *)(src0 + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00);
- global float4 * pmask = src1 != src0 ? (global float4 *)(src1 + i01*ne00) : 0;
- global float4 * pdst4 = (global float4 *)(dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00);
-
- float slope = 1.0f;
-
- // ALiBi
- if (max_bias > 0.0f) {
- int h = i02;
-
- float base = h < n_head_log2 ? m0 : m1;
- int exp = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1;
-
- slope = pow(base, exp);
- }
-
- // parallel max
- float4 lmax4 = -INFINITY;
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- lmax4 = fmax(lmax4, psrc4[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f));
- }
- float lmax = fmax(fmax(lmax4.s0, lmax4.s1), fmax(lmax4.s2, lmax4.s3));
-
- const float max = sub_group_reduce_max(lmax);
-
- // parallel sum
- float4 lsum4 = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- const float4 exp_psrc4 = exp((psrc4[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f)) - max);
- lsum4 += exp_psrc4;
- pdst4[i00] = exp_psrc4;
- }
- float lsum = lsum4.s0 + lsum4.s1 + lsum4.s2 + lsum4.s3;
-
- const float sum = sub_group_reduce_add(lsum);
-
- for (int i00 = get_local_id(0); i00 < ne00/4; i00 += get_local_size(0)) {
- pdst4[i00] /= sum;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/softmax_f16.cl b/ggml/src/ggml-opencl/kernels/softmax_f16.cl
deleted file mode 100644
index d38d09967..000000000
--- a/ggml/src/ggml-opencl/kernels/softmax_f16.cl
+++ /dev/null
@@ -1,86 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_soft_max_f16(
- global float * src0,
- ulong offset0,
- global half * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- float scale,
- float max_bias,
- float m0,
- float m1,
- int n_head_log2
-) {
- src0 = (global float *)((global char *)src0 + offset0);
- src1 = (global half *)((global char *)src1 + offset1);
- dst = (global float *)((global char *)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float * psrc0 = src0 + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
- global half * pmask = (global char *)src1 != (global char *)src0 ? src1 + i01*ne00 : 0;
- global float * pdst = dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- float slope = 1.0f;
-
- // ALiBi
- if (max_bias > 0.0f) {
- int h = i02;
-
- float base = h < n_head_log2 ? m0 : m1;
- int exp = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1;
-
- slope = pow(base, exp);
- }
-
- // parallel max
- float lmax = -INFINITY;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- lmax = fmax(lmax, psrc0[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f));
- }
- float max = sub_group_reduce_max(lmax);
-
- // parallel sum
- float lsum = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- float exp_psrc0 = exp((psrc0[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f)) - max);
- lsum += exp_psrc0;
- // Remember the result of exp here. exp is expensive, so we really do not
- // wish to compute it twice.
- pdst[i00] = exp_psrc0;
- }
-
- const float sum = sub_group_reduce_add(lsum);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- pdst[i00] /= sum;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/softmax_f32.cl b/ggml/src/ggml-opencl/kernels/softmax_f32.cl
deleted file mode 100644
index 001b587ab..000000000
--- a/ggml/src/ggml-opencl/kernels/softmax_f32.cl
+++ /dev/null
@@ -1,86 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-#ifdef cl_intel_subgroups
-#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#else
-#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#endif
-
-#ifdef cl_intel_required_subgroup_size
-#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
-#define INTEL_GPU 1
-#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
-#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
-#elif defined(cl_qcom_reqd_sub_group_size)
-#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
-#define ADRENO_GPU 1
-#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half")))
-#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
-#endif
-
-#ifdef ADRENO_GPU
-REQD_SUBGROUP_SIZE_64
-#endif
-kernel void kernel_soft_max(
- global float * src0,
- ulong offset0,
- global float * src1,
- ulong offset1,
- global float * dst,
- ulong offsetd,
- int ne00,
- int ne01,
- int ne02,
- float scale,
- float max_bias,
- float m0,
- float m1,
- int n_head_log2
-) {
- src0 = (global float*)((global char*)src0 + offset0);
- src1 = (global float*)((global char*)src1 + offset1);
- dst = (global float*)((global char*)dst + offsetd);
-
- int i03 = get_group_id(2);
- int i02 = get_group_id(1);
- int i01 = get_group_id(0);
-
- global float * psrc0 = src0 + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
- global float * pmask = src1 != src0 ? src1 + i01*ne00 : 0;
- global float * pdst = dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
-
- float slope = 1.0f;
-
- // ALiBi
- if (max_bias > 0.0f) {
- int h = i02;
-
- float base = h < n_head_log2 ? m0 : m1;
- int exp = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1;
-
- slope = pow(base, exp);
- }
-
- // parallel max
- float lmax = -INFINITY;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- lmax = fmax(lmax, psrc0[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f));
- }
- float max = sub_group_reduce_max(lmax);
-
- // parallel sum
- float lsum = 0.0f;
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- float exp_psrc0 = exp((psrc0[i00]*scale + (pmask ? slope*pmask[i00] : 0.0f)) - max);
- lsum += exp_psrc0;
- // Remember the result of exp here. exp is expensive, so we really do not
- // wish to compute it twice.
- pdst[i00] = exp_psrc0;
- }
-
- const float sum = sub_group_reduce_add(lsum);
-
- for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
- pdst[i00] /= sum;
- }
-}
diff --git a/ggml/src/ggml-opencl/kernels/transpose.cl b/ggml/src/ggml-opencl/kernels/transpose.cl
deleted file mode 100644
index a11490b30..000000000
--- a/ggml/src/ggml-opencl/kernels/transpose.cl
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma OPENCL EXTENSION cl_khr_fp16 : enable
-
-// 16-bit transpose, loading/storing a 4x4 tile of elements
-kernel void kernel_transpose_16(
- __read_only image1d_buffer_t input,
- __write_only image1d_buffer_t output,
- const uint rows,
- const uint cols
-) {
-
- const int i = get_global_id(0);
- const int j = get_global_id(1);
- const int i_2 = i<<2;
- const int j_2 = j<<2;
-
- half4 temp0 = read_imageh(input, (j_2+0)*cols+i);
- half4 temp1 = read_imageh(input, (j_2+1)*cols+i);
- half4 temp2 = read_imageh(input, (j_2+2)*cols+i);
- half4 temp3 = read_imageh(input, (j_2+3)*cols+i);
-
- write_imageh(output, (i_2+0)*rows+j, (half4)(temp0.s0, temp1.s0, temp2.s0, temp3.s0));
- write_imageh(output, (i_2+1)*rows+j, (half4)(temp0.s1, temp1.s1, temp2.s1, temp3.s1));
- write_imageh(output, (i_2+2)*rows+j, (half4)(temp0.s2, temp1.s2, temp2.s2, temp3.s2));
- write_imageh(output, (i_2+3)*rows+j, (half4)(temp0.s3, temp1.s3, temp2.s3, temp3.s3));
-}
-
-// 32-bit transpose, loading/storing a 4x4 tile of elements
-kernel void kernel_transpose_32(
- __read_only image1d_buffer_t input,
- __write_only image1d_buffer_t output,
- const uint rows,
- const uint cols
-) {
-
- const int i = get_global_id(0);
- const int j = get_global_id(1);
- const int i_2 = i<<2;
- const int j_2 = j<<2;
-
- float4 temp0 = read_imagef(input, (j_2+0)*cols+i);
- float4 temp1 = read_imagef(input, (j_2+1)*cols+i);
- float4 temp2 = read_imagef(input, (j_2+2)*cols+i);
- float4 temp3 = read_imagef(input, (j_2+3)*cols+i);
-
- write_imagef(output, (i_2+0)*rows+j, (float4)(temp0.s0, temp1.s0, temp2.s0, temp3.s0));
- write_imagef(output, (i_2+1)*rows+j, (float4)(temp0.s1, temp1.s1, temp2.s1, temp3.s1));
- write_imagef(output, (i_2+2)*rows+j, (float4)(temp0.s2, temp1.s2, temp2.s2, temp3.s2));
- write_imagef(output, (i_2+3)*rows+j, (float4)(temp0.s3, temp1.s3, temp2.s3, temp3.s3));
-
-}
-
-// 32-bit transpose, loading/storing a 4x4 tile of elements
-// Only used for activations
-// converts to FP16
-// also adds zero padding for non multiple of 8 prompt lengths
-kernel void kernel_transpose_32_16(__read_only image1d_buffer_t input, __write_only image1d_buffer_t output, const uint rows, const uint cols, const uint padded_rows) {
-
- const int i = get_global_id(0);
- const int j = get_global_id(1);
- const int i_2 = i<<2;
- const int j_2 = j<<2;
- half4 temp0 = {0,0,0,0}; // initialize outputs to 0
- half4 temp1 = {0,0,0,0};
- half4 temp2 = {0,0,0,0};
- half4 temp3 = {0,0,0,0};
-
- if((j_2+0)*cols+i*4+3 < rows*cols*16){ // only load from a valid location. Otherwise keep register data as 0
- temp0 = read_imageh(input, (j_2+0)*cols+i);
- }
- if((j_2+1)*cols+i*4+3 < rows*cols*16){
- temp1 = read_imageh(input, (j_2+1)*cols+i);
- }
- if((j_2+2)*cols+i*4+3 < rows*cols*16){
- temp2 = read_imageh(input, (j_2+2)*cols+i);
- }
- if((j_2+3)*cols+i*4+3 < rows*cols*16){
- temp3 = read_imageh(input, (j_2+3)*cols+i);
- }
-
- write_imageh(output, (i_2+0)*padded_rows+j, (half4)(temp0.s0, temp1.s0, temp2.s0, temp3.s0)); // no conditionals for output, includes zero padding
- write_imageh(output, (i_2+1)*padded_rows+j, (half4)(temp0.s1, temp1.s1, temp2.s1, temp3.s1));
- write_imageh(output, (i_2+2)*padded_rows+j, (half4)(temp0.s2, temp1.s2, temp2.s2, temp3.s2));
- write_imageh(output, (i_2+3)*padded_rows+j, (half4)(temp0.s3, temp1.s3, temp2.s3, temp3.s3));
-}
diff --git a/ggml/src/ggml-rpc/ggml-rpc.cpp b/ggml/src/ggml-rpc/ggml-rpc.cpp
deleted file mode 100644
index 3189ae85d..000000000
--- a/ggml/src/ggml-rpc/ggml-rpc.cpp
+++ /dev/null
@@ -1,1683 +0,0 @@
-#include "ggml-rpc.h"
-#include "ggml-impl.h"
-#include "ggml-backend-impl.h"
-#include "ggml-cpp.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# ifndef NOMINMAX
-# define NOMINMAX
-# endif
-# include
-# include
-#else
-# include
-# include
-# include
-# include
-# include
-# include
-# include
-#endif
-#include
-#include
-#include
-
-namespace fs = std::filesystem;
-
-#ifdef _WIN32
-typedef SOCKET sockfd_t;
-using ssize_t = __int64;
-#else
-typedef int sockfd_t;
-#endif
-
-// cross-platform socket
-struct socket_t {
- sockfd_t fd;
- socket_t(sockfd_t fd) : fd(fd) {}
- ~socket_t() {
- GGML_PRINT_DEBUG("[%s] closing socket %d\n", __func__, this->fd);
-#ifdef _WIN32
- closesocket(this->fd);
-#else
- close(this->fd);
-#endif
- }
-};
-
-// all RPC structures must be packed
-#pragma pack(push, 1)
-// ggml_tensor is serialized into rpc_tensor
-struct rpc_tensor {
- uint64_t id;
- uint32_t type;
- uint64_t buffer;
- uint32_t ne[GGML_MAX_DIMS];
- uint32_t nb[GGML_MAX_DIMS];
- uint32_t op;
- int32_t op_params[GGML_MAX_OP_PARAMS / sizeof(int32_t)];
- int32_t flags;
- uint64_t src[GGML_MAX_SRC];
- uint64_t view_src;
- uint64_t view_offs;
- uint64_t data;
- char name[GGML_MAX_NAME];
-
- char padding[4];
-};
-
-static_assert(sizeof(rpc_tensor) % 8 == 0, "rpc_tensor size must be multiple of 8");
-
-// RPC commands
-enum rpc_cmd {
- RPC_CMD_ALLOC_BUFFER = 0,
- RPC_CMD_GET_ALIGNMENT,
- RPC_CMD_GET_MAX_SIZE,
- RPC_CMD_BUFFER_GET_BASE,
- RPC_CMD_FREE_BUFFER,
- RPC_CMD_BUFFER_CLEAR,
- RPC_CMD_SET_TENSOR,
- RPC_CMD_SET_TENSOR_HASH,
- RPC_CMD_GET_TENSOR,
- RPC_CMD_COPY_TENSOR,
- RPC_CMD_GRAPH_COMPUTE,
- RPC_CMD_GET_DEVICE_MEMORY,
- RPC_CMD_INIT_TENSOR,
- RPC_CMD_GET_ALLOC_SIZE,
- RPC_CMD_COUNT,
-};
-
-// Try RPC_CMD_SET_TENSOR_HASH first when data size is larger than this threshold
-const size_t HASH_THRESHOLD = 10 * 1024 * 1024;
-
-struct rpc_msg_get_alloc_size_req {
- rpc_tensor tensor;
-};
-
-struct rpc_msg_get_alloc_size_rsp {
- uint64_t alloc_size;
-};
-
-struct rpc_msg_init_tensor_req {
- rpc_tensor tensor;
-};
-
-struct rpc_msg_alloc_buffer_req {
- uint64_t size;
-};
-
-struct rpc_msg_alloc_buffer_rsp {
- uint64_t remote_ptr;
- uint64_t remote_size;
-};
-
-struct rpc_msg_get_alignment_rsp {
- uint64_t alignment;
-};
-
-struct rpc_msg_get_max_size_rsp {
- uint64_t max_size;
-};
-
-struct rpc_msg_buffer_get_base_req {
- uint64_t remote_ptr;
-};
-
-struct rpc_msg_buffer_get_base_rsp {
- uint64_t base_ptr;
-};
-
-struct rpc_msg_free_buffer_req {
- uint64_t remote_ptr;
-};
-
-struct rpc_msg_buffer_clear_req {
- uint64_t remote_ptr;
- uint8_t value;
-};
-
-struct rpc_msg_set_tensor_hash_rsp {
- uint8_t result;
-};
-
-struct rpc_msg_get_tensor_req {
- rpc_tensor tensor;
- uint64_t offset;
- uint64_t size;
-};
-
-struct rpc_msg_copy_tensor_req {
- rpc_tensor src;
- rpc_tensor dst;
-};
-
-struct rpc_msg_copy_tensor_rsp {
- uint8_t result;
-};
-
-struct rpc_msg_graph_compute_rsp {
- uint8_t result;
-};
-
-struct rpc_msg_get_device_memory_rsp {
- uint64_t free_mem;
- uint64_t total_mem;
-};
-#pragma pack(pop)
-
-// RPC data structures
-
-static ggml_guid_t ggml_backend_rpc_guid() {
- static ggml_guid guid = {0x99, 0x68, 0x5b, 0x6c, 0xd2, 0x83, 0x3d, 0x24, 0x25, 0x36, 0x72, 0xe1, 0x5b, 0x0e, 0x14, 0x03};
- return &guid;
-}
-
-struct ggml_backend_rpc_buffer_type_context {
- std::string endpoint;
- std::string name;
- size_t alignment;
- size_t max_size;
-};
-
-struct ggml_backend_rpc_context {
- std::string endpoint;
- std::string name;
-};
-
-struct ggml_backend_rpc_buffer_context {
- std::shared_ptr sock;
- void * base_ptr;
- uint64_t remote_ptr;
-};
-
-// RPC helper functions
-
-// Computes FNV-1a hash of the data
-static uint64_t fnv_hash(const uint8_t * data, size_t len) {
- const uint64_t fnv_prime = 0x100000001b3ULL;
- uint64_t hash = 0xcbf29ce484222325ULL;
-
- for (size_t i = 0; i < len; ++i) {
- hash ^= data[i];
- hash *= fnv_prime;
- }
- return hash;
-}
-
-static std::shared_ptr make_socket(sockfd_t fd) {
-#ifdef _WIN32
- if (fd == INVALID_SOCKET) {
- return nullptr;
- }
-#else
- if (fd < 0) {
- return nullptr;
- }
-#endif
- return std::make_shared(fd);
-}
-
-static bool set_no_delay(sockfd_t sockfd) {
- int flag = 1;
- // set TCP_NODELAY to disable Nagle's algorithm
- int ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
- return ret == 0;
-}
-
-static bool set_reuse_addr(sockfd_t sockfd) {
- int flag = 1;
- int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(int));
- return ret == 0;
-}
-
-static std::shared_ptr socket_connect(const char * host, int port) {
- struct sockaddr_in addr;
- auto sockfd = socket(AF_INET, SOCK_STREAM, 0);
- auto sock_ptr = make_socket(sockfd);
- if (sock_ptr == nullptr) {
- return nullptr;
- }
- if (!set_no_delay(sockfd)) {
- fprintf(stderr, "Failed to set TCP_NODELAY\n");
- return nullptr;
- }
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- struct hostent * server = gethostbyname(host);
- if (server == NULL) {
- fprintf(stderr, "Cannot resolve host '%s'\n", host);
- return nullptr;
- }
- memcpy(&addr.sin_addr.s_addr, server->h_addr, server->h_length);
- if (connect(sock_ptr->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- return nullptr;
- }
- return sock_ptr;
-}
-
-static std::shared_ptr socket_accept(sockfd_t srv_sockfd) {
- auto client_socket_fd = accept(srv_sockfd, NULL, NULL);
- auto client_socket = make_socket(client_socket_fd);
- if (client_socket == nullptr) {
- return nullptr;
- }
- if (!set_no_delay(client_socket_fd)) {
- fprintf(stderr, "Failed to set TCP_NODELAY\n");
- return nullptr;
- }
- return client_socket;
-}
-
-static std::shared_ptr create_server_socket(const char * host, int port) {
- auto sockfd = socket(AF_INET, SOCK_STREAM, 0);
- auto sock = make_socket(sockfd);
- if (sock == nullptr) {
- return nullptr;
- }
- if (!set_reuse_addr(sockfd)) {
- fprintf(stderr, "Failed to set SO_REUSEADDR\n");
- return nullptr;
- }
- if (inet_addr(host) == INADDR_NONE) {
- fprintf(stderr, "Invalid host address: %s\n", host);
- return nullptr;
- }
- struct sockaddr_in serv_addr;
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = inet_addr(host);
- serv_addr.sin_port = htons(port);
-
- if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
- return nullptr;
- }
- if (listen(sockfd, 1) < 0) {
- return nullptr;
- }
- return sock;
-}
-
-static bool send_data(sockfd_t sockfd, const void * data, size_t size) {
- size_t bytes_sent = 0;
- while (bytes_sent < size) {
- ssize_t n = send(sockfd, (const char *)data + bytes_sent, size - bytes_sent, 0);
- if (n < 0) {
- return false;
- }
- bytes_sent += n;
- }
- return true;
-}
-
-static bool recv_data(sockfd_t sockfd, void * data, size_t size) {
- size_t bytes_recv = 0;
- while (bytes_recv < size) {
- ssize_t n = recv(sockfd, (char *)data + bytes_recv, size - bytes_recv, 0);
- if (n <= 0) {
- return false;
- }
- bytes_recv += n;
- }
- return true;
-}
-
-static bool send_msg(sockfd_t sockfd, const void * msg, size_t msg_size) {
- if (!send_data(sockfd, &msg_size, sizeof(msg_size))) {
- return false;
- }
- return send_data(sockfd, msg, msg_size);
-}
-
-static bool recv_msg(sockfd_t sockfd, void * msg, size_t msg_size) {
- uint64_t size;
- if (!recv_data(sockfd, &size, sizeof(size))) {
- return false;
- }
- if (size != msg_size) {
- return false;
- }
- return recv_data(sockfd, msg, msg_size);
-}
-
-static bool recv_msg(sockfd_t sockfd, std::vector & input) {
- uint64_t size;
- if (!recv_data(sockfd, &size, sizeof(size))) {
- return false;
- }
- try {
- input.resize(size);
- } catch (const std::bad_alloc & e) {
- fprintf(stderr, "Failed to allocate input buffer of size %" PRIu64 "\n", size);
- return false;
- }
- return recv_data(sockfd, input.data(), size);
-}
-
-static bool parse_endpoint(const std::string & endpoint, std::string & host, int & port) {
- size_t pos = endpoint.find(':');
- if (pos == std::string::npos) {
- return false;
- }
- host = endpoint.substr(0, pos);
- port = std::stoi(endpoint.substr(pos + 1));
- return true;
-}
-
-// RPC request : | rpc_cmd (1 byte) | request_size (8 bytes) | request_data (request_size bytes) |
-// RPC response: | response_size (8 bytes) | response_data (response_size bytes) |
-static bool send_rpc_cmd(const std::shared_ptr & sock, enum rpc_cmd cmd, const void * input, size_t input_size, void * output, size_t output_size) {
- uint8_t cmd_byte = cmd;
- if (!send_data(sock->fd, &cmd_byte, sizeof(cmd_byte))) {
- return false;
- }
- if (!send_data(sock->fd, &input_size, sizeof(input_size))) {
- return false;
- }
- if (!send_data(sock->fd, input, input_size)) {
- return false;
- }
- // TODO: currently the output_size is always known, do we need support for commands with variable output size?
- // even if we do, we can skip sending output_size from the server for commands with known output size
- uint64_t out_size;
- if (!recv_data(sock->fd, &out_size, sizeof(out_size))) {
- return false;
- }
- if (out_size != output_size) {
- return false;
- }
- if (!recv_data(sock->fd, output, output_size)) {
- return false;
- }
- return true;
-}
-
-// RPC client-side implementation
-
-static std::shared_ptr get_socket(const std::string & endpoint) {
- static std::mutex mutex;
- std::lock_guard lock(mutex);
- static std::unordered_map> sockets;
- static bool initialized = false;
-
- auto it = sockets.find(endpoint);
- if (it != sockets.end()) {
- if (auto sock = it->second.lock()) {
- return sock;
- }
- }
- std::string host;
- int port;
- if (!parse_endpoint(endpoint, host, port)) {
- return nullptr;
- }
-#ifdef _WIN32
- if (!initialized) {
- WSADATA wsaData;
- int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (res != 0) {
- return nullptr;
- }
- initialized = true;
- }
-#else
- GGML_UNUSED(initialized);
-#endif
- auto sock = socket_connect(host.c_str(), port);
- if (sock == nullptr) {
- return nullptr;
- }
- GGML_PRINT_DEBUG("[%s] connected to %s, sockfd=%d\n", __func__, endpoint.c_str(), sock->fd);
- sockets[endpoint] = sock;
- return sock;
-}
-
-static void ggml_backend_rpc_buffer_free_buffer(ggml_backend_buffer_t buffer) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- rpc_msg_free_buffer_req request = {ctx->remote_ptr};
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_FREE_BUFFER, &request, sizeof(request), nullptr, 0);
- GGML_ASSERT(status);
- delete ctx;
-}
-
-static void * ggml_backend_rpc_buffer_get_base(ggml_backend_buffer_t buffer) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- if (ctx->base_ptr != nullptr) {
- return ctx->base_ptr;
- }
- rpc_msg_buffer_get_base_req request = {ctx->remote_ptr};
- rpc_msg_buffer_get_base_rsp response;
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_BUFFER_GET_BASE, &request, sizeof(request), &response, sizeof(response));
- GGML_ASSERT(status);
- ctx->base_ptr = reinterpret_cast(response.base_ptr);
- return ctx->base_ptr;
-}
-
-static rpc_tensor serialize_tensor(const ggml_tensor * tensor) {
- rpc_tensor result;
- result.id = reinterpret_cast(tensor);
- result.type = tensor->type;
- if (tensor->buffer) {
- ggml_backend_buffer_t buffer = tensor->buffer;
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- result.buffer = ctx->remote_ptr;
- } else {
- result.buffer = 0;
- }
- for (uint32_t i = 0; i < GGML_MAX_DIMS; i++) {
- result.ne[i] = tensor->ne[i];
- result.nb[i] = tensor->nb[i];
- }
- result.op = tensor->op;
- for (uint32_t i = 0; i < GGML_MAX_OP_PARAMS / sizeof(int32_t); i++) {
- result.op_params[i] = tensor->op_params[i];
- }
- result.flags = tensor->flags;
- for (uint32_t i = 0; i < GGML_MAX_SRC; i++) {
- result.src[i] = reinterpret_cast(tensor->src[i]);
- }
- result.view_src = reinterpret_cast(tensor->view_src);
- result.view_offs = tensor->view_offs;
- result.data = reinterpret_cast(tensor->data);
- snprintf(result.name, GGML_MAX_NAME, "%s", tensor->name);
- return result;
-}
-
-static enum ggml_status ggml_backend_rpc_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
-
- // CUDA backend on the server pads everything to 512 due to CUDA limitations.
- // Due to bandwidth constraints, we only call the server init tensor functions if necessary.
- // In particular, only quantized tensors need padding
- if (ggml_is_quantized(tensor->type) && (tensor->ne[0] % 512 != 0) && (tensor->view_src == nullptr)) {
- rpc_msg_init_tensor_req request;
-
- request.tensor = serialize_tensor(tensor);
-
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_INIT_TENSOR, &request, sizeof(request), nullptr, 0);
- GGML_ASSERT(status);
- }
- return GGML_STATUS_SUCCESS;
-}
-
-static void ggml_backend_rpc_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor, const void * data, size_t offset, size_t size) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- rpc_tensor rpc_tensor = serialize_tensor(tensor);
- if (size > HASH_THRESHOLD) {
- // input serialization format: | rpc_tensor | offset (8 bytes) | hash (8 bytes)
- size_t input_size = sizeof(rpc_tensor) + sizeof(uint64_t) + sizeof(uint64_t);
- std::vector input(input_size, 0);
- uint64_t hash = fnv_hash((const uint8_t*)data, size);
- memcpy(input.data(), &rpc_tensor, sizeof(rpc_tensor));
- memcpy(input.data() + sizeof(rpc_tensor), &offset, sizeof(offset));
- memcpy(input.data() + sizeof(rpc_tensor) + sizeof(offset), &hash, sizeof(hash));
- rpc_msg_set_tensor_hash_rsp response;
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_SET_TENSOR_HASH, input.data(), input.size(), &response, sizeof(response));
- GGML_ASSERT(status);
- if (response.result) {
- // the server has the same data, no need to send it
- return;
- }
- }
- // input serialization format: | rpc_tensor | offset (8 bytes) | data (size bytes)
- size_t input_size = sizeof(rpc_tensor) + sizeof(uint64_t) + size;
- std::vector input(input_size, 0);
- memcpy(input.data(), &rpc_tensor, sizeof(rpc_tensor));
- memcpy(input.data() + sizeof(rpc_tensor), &offset, sizeof(offset));
- memcpy(input.data() + sizeof(rpc_tensor) + sizeof(offset), data, size);
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_SET_TENSOR, input.data(), input.size(), nullptr, 0);
- GGML_ASSERT(status);
-}
-
-static void ggml_backend_rpc_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor * tensor, void * data, size_t offset, size_t size) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- rpc_msg_get_tensor_req request;
- request.tensor = serialize_tensor(tensor);
- request.offset = offset;
- request.size = size;
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_GET_TENSOR, &request, sizeof(request), data, size);
- GGML_ASSERT(status);
-}
-
-static bool ggml_backend_rpc_buffer_cpy_tensor(ggml_backend_buffer_t buffer, const ggml_tensor * src, ggml_tensor * dst) {
- // check if src and dst are on the same server
- ggml_backend_buffer_t src_buffer = src->buffer;
- ggml_backend_rpc_buffer_context * src_ctx = (ggml_backend_rpc_buffer_context *)src_buffer->context;
- ggml_backend_buffer_t dst_buffer = dst->buffer;
- ggml_backend_rpc_buffer_context * dst_ctx = (ggml_backend_rpc_buffer_context *)dst_buffer->context;
- if (src_ctx->sock != dst_ctx->sock) {
- return false;
- }
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- rpc_msg_copy_tensor_req request;
- request.src = serialize_tensor(src);
- request.dst = serialize_tensor(dst);
- rpc_msg_copy_tensor_rsp response;
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_COPY_TENSOR, &request, sizeof(request), &response, sizeof(response));
- GGML_ASSERT(status);
- return response.result;
-}
-
-static void ggml_backend_rpc_buffer_clear(ggml_backend_buffer_t buffer, uint8_t value) {
- ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
- rpc_msg_buffer_clear_req request = {ctx->remote_ptr, value};
- bool status = send_rpc_cmd(ctx->sock, RPC_CMD_BUFFER_CLEAR, &request, sizeof(request), nullptr, 0);
- GGML_ASSERT(status);
-}
-
-static ggml_backend_buffer_i ggml_backend_rpc_buffer_interface = {
- /* .free_buffer = */ ggml_backend_rpc_buffer_free_buffer,
- /* .get_base = */ ggml_backend_rpc_buffer_get_base,
- /* .init_tensor = */ ggml_backend_rpc_buffer_init_tensor,
- /* .memset_tensor = */ NULL,
- /* .set_tensor = */ ggml_backend_rpc_buffer_set_tensor,
- /* .get_tensor = */ ggml_backend_rpc_buffer_get_tensor,
- /* .cpy_tensor = */ ggml_backend_rpc_buffer_cpy_tensor,
- /* .clear = */ ggml_backend_rpc_buffer_clear,
- /* .reset = */ NULL,
-};
-
-static const char * ggml_backend_rpc_buffer_type_name(ggml_backend_buffer_type_t buft) {
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- return buft_ctx->name.c_str();
-}
-
-static ggml_backend_buffer_t ggml_backend_rpc_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft, size_t size) {
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- rpc_msg_alloc_buffer_req request = {size};
- rpc_msg_alloc_buffer_rsp response;
- auto sock = get_socket(buft_ctx->endpoint);
- bool status = send_rpc_cmd(sock, RPC_CMD_ALLOC_BUFFER, &request, sizeof(request), &response, sizeof(response));
- GGML_ASSERT(status);
- if (response.remote_ptr != 0) {
- ggml_backend_buffer_t buffer = ggml_backend_buffer_init(buft,
- ggml_backend_rpc_buffer_interface,
- new ggml_backend_rpc_buffer_context{sock, nullptr, response.remote_ptr},
- response.remote_size);
- return buffer;
- } else {
- return nullptr;
- }
-}
-
-static size_t get_alignment(const std::shared_ptr & sock) {
- rpc_msg_get_alignment_rsp response;
- bool status = send_rpc_cmd(sock, RPC_CMD_GET_ALIGNMENT, nullptr, 0, &response, sizeof(response));
- GGML_ASSERT(status);
- return response.alignment;
-}
-
-static size_t ggml_backend_rpc_buffer_type_get_alignment(ggml_backend_buffer_type_t buft) {
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- return buft_ctx->alignment;
-}
-
-static size_t get_max_size(const std::shared_ptr & sock) {
- rpc_msg_get_max_size_rsp response;
- bool status = send_rpc_cmd(sock, RPC_CMD_GET_MAX_SIZE, nullptr, 0, &response, sizeof(response));
- GGML_ASSERT(status);
- return response.max_size;
-}
-
-static size_t ggml_backend_rpc_get_max_size(ggml_backend_buffer_type_t buft) {
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- return buft_ctx->max_size;
-}
-
-static size_t ggml_backend_rpc_buffer_type_get_alloc_size(ggml_backend_buffer_type_t buft, const ggml_tensor * tensor) {
- // See comments in init_tensor.
- if (ggml_is_quantized(tensor->type) && (tensor->ne[0] % 512 != 0) && (tensor->view_src == nullptr)) {
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- auto sock = get_socket(buft_ctx->endpoint);
-
- rpc_msg_get_alloc_size_req request;
-
- request.tensor = serialize_tensor(tensor);
-
- rpc_msg_get_alloc_size_rsp response;
- bool status = send_rpc_cmd(sock, RPC_CMD_GET_ALLOC_SIZE, &request, sizeof(request), &response, sizeof(response));
- GGML_ASSERT(status);
-
- return response.alloc_size;
- } else {
- return ggml_nbytes(tensor);
- }
-}
-
-static ggml_backend_buffer_type_i ggml_backend_rpc_buffer_type_interface = {
- /* .get_name = */ ggml_backend_rpc_buffer_type_name,
- /* .alloc_buffer = */ ggml_backend_rpc_buffer_type_alloc_buffer,
- /* .get_alignment = */ ggml_backend_rpc_buffer_type_get_alignment,
- /* .get_max_size = */ ggml_backend_rpc_get_max_size,
- /* .get_alloc_size = */ ggml_backend_rpc_buffer_type_get_alloc_size,
- /* .is_host = */ NULL,
-};
-
-static const char * ggml_backend_rpc_name(ggml_backend_t backend) {
- ggml_backend_rpc_context * rpc_ctx = (ggml_backend_rpc_context *)backend->context;
-
- return rpc_ctx->name.c_str();
-}
-
-static void ggml_backend_rpc_free(ggml_backend_t backend) {
- ggml_backend_rpc_context * rpc_ctx = (ggml_backend_rpc_context *)backend->context;
- delete rpc_ctx;
- delete backend;
-}
-
-static void ggml_backend_rpc_synchronize(ggml_backend_t backend) {
- GGML_UNUSED(backend);
- // this is no-op because we don't have any async operations
-}
-
-static void add_tensor(ggml_tensor * tensor, std::vector & tensors, std::unordered_set & visited) {
- if (tensor == nullptr) {
- return;
- }
- if (visited.find(tensor) != visited.end()) {
- return;
- }
- visited.insert(tensor);
- for (int i = 0; i < GGML_MAX_SRC; i++) {
- add_tensor(tensor->src[i], tensors, visited);
- }
- add_tensor(tensor->view_src, tensors, visited);
- tensors.push_back(serialize_tensor(tensor));
-}
-
-static void serialize_graph(const ggml_cgraph * cgraph, std::vector & output) {
- uint32_t n_nodes = cgraph->n_nodes;
- std::vector tensors;
- std::unordered_set visited;
- for (uint32_t i = 0; i < n_nodes; i++) {
- add_tensor(cgraph->nodes[i], tensors, visited);
- }
- // serialization format:
- // | n_nodes (4 bytes) | nodes (n_nodes * sizeof(uint64_t) | n_tensors (4 bytes) | tensors (n_tensors * sizeof(rpc_tensor)) |
- uint32_t n_tensors = tensors.size();
- int output_size = sizeof(uint32_t) + n_nodes * sizeof(uint64_t) + sizeof(uint32_t) + n_tensors * sizeof(rpc_tensor);
- output.resize(output_size, 0);
- memcpy(output.data(), &n_nodes, sizeof(n_nodes));
- for (uint32_t i = 0; i < n_nodes; i++) {
- memcpy(output.data() + sizeof(n_nodes) + i * sizeof(uint64_t), &cgraph->nodes[i], sizeof(uint64_t));
- }
- uint32_t * out_ntensors = (uint32_t *)(output.data() + sizeof(n_nodes) + n_nodes * sizeof(uint64_t));
- *out_ntensors = n_tensors;
- rpc_tensor * out_tensors = (rpc_tensor *)(output.data() + sizeof(n_nodes) + n_nodes * sizeof(uint64_t) + sizeof(uint32_t));
- memcpy(out_tensors, tensors.data(), n_tensors * sizeof(rpc_tensor));
-}
-
-static enum ggml_status ggml_backend_rpc_graph_compute(ggml_backend_t backend, ggml_cgraph * cgraph) {
- ggml_backend_rpc_context * rpc_ctx = (ggml_backend_rpc_context *)backend->context;
- std::vector input;
- serialize_graph(cgraph, input);
- rpc_msg_graph_compute_rsp response;
- auto sock = get_socket(rpc_ctx->endpoint);
- bool status = send_rpc_cmd(sock, RPC_CMD_GRAPH_COMPUTE, input.data(), input.size(), &response, sizeof(response));
- GGML_ASSERT(status);
- return (enum ggml_status)response.result;
-}
-
-static ggml_backend_i ggml_backend_rpc_interface = {
- /* .get_name = */ ggml_backend_rpc_name,
- /* .free = */ ggml_backend_rpc_free,
- /* .set_tensor_async = */ NULL,
- /* .get_tensor_async = */ NULL,
- /* .cpy_tensor_async = */ NULL,
- /* .synchronize = */ ggml_backend_rpc_synchronize,
- /* .graph_plan_create = */ NULL,
- /* .graph_plan_free = */ NULL,
- /* .graph_plan_update = */ NULL,
- /* .graph_plan_compute = */ NULL,
- /* .graph_compute = */ ggml_backend_rpc_graph_compute,
- /* .event_record = */ NULL,
- /* .event_wait = */ NULL,
-};
-
-ggml_backend_buffer_type_t ggml_backend_rpc_buffer_type(const char * endpoint) {
- static std::mutex mutex;
- std::lock_guard lock(mutex);
- // NOTE: buffer types are allocated and never freed; this is by design
- static std::unordered_map buft_map;
- auto it = buft_map.find(endpoint);
- if (it != buft_map.end()) {
- return it->second;
- }
- auto sock = get_socket(endpoint);
- if (sock == nullptr) {
- fprintf(stderr, "Failed to connect to %s\n", endpoint);
- return nullptr;
- }
- size_t alignment = get_alignment(sock);
- size_t max_size = get_max_size(sock);
- ggml_backend_rpc_buffer_type_context * buft_ctx = new ggml_backend_rpc_buffer_type_context {
- /* .endpoint = */ endpoint,
- /* .name = */ "RPC[" + std::string(endpoint) + "]",
- /* .alignment = */ alignment,
- /* .max_size = */ max_size
- };
-
- ggml_backend_buffer_type_t buft = new ggml_backend_buffer_type {
- /* .iface = */ ggml_backend_rpc_buffer_type_interface,
- /* .device = */ ggml_backend_rpc_add_device(endpoint),
- /* .context = */ buft_ctx
- };
- buft_map[endpoint] = buft;
- return buft;
-}
-
-ggml_backend_t ggml_backend_rpc_init(const char * endpoint) {
- ggml_backend_rpc_context * ctx = new ggml_backend_rpc_context {
- /* .endpoint = */ endpoint,
- /* .name = */ "RPC[" + std::string(endpoint) + "]",
- };
-
- ggml_backend_t backend = new ggml_backend {
- /* .guid = */ ggml_backend_rpc_guid(),
- /* .interface = */ ggml_backend_rpc_interface,
- /* .device = */ ggml_backend_rpc_add_device(endpoint),
- /* .context = */ ctx
- };
- return backend;
-}
-
-bool ggml_backend_is_rpc(ggml_backend_t backend) {
- return backend != NULL && ggml_guid_matches(backend->guid, ggml_backend_rpc_guid());
-}
-
-static void get_device_memory(const std::shared_ptr & sock, size_t * free, size_t * total) {
- rpc_msg_get_device_memory_rsp response;
- bool status = send_rpc_cmd(sock, RPC_CMD_GET_DEVICE_MEMORY, nullptr, 0, &response, sizeof(response));
- GGML_ASSERT(status);
- *free = response.free_mem;
- *total = response.total_mem;
-}
-
-void ggml_backend_rpc_get_device_memory(const char * endpoint, size_t * free, size_t * total) {
- auto sock = get_socket(endpoint);
- if (sock == nullptr) {
- *free = 0;
- *total = 0;
- return;
- }
- get_device_memory(sock, free, total);
-}
-
-// RPC server-side implementation
-
-class rpc_server {
-public:
- rpc_server(ggml_backend_t backend, const char * cache_dir)
- : backend(backend), cache_dir(cache_dir) {
- }
- ~rpc_server();
-
- void alloc_buffer(const rpc_msg_alloc_buffer_req & request, rpc_msg_alloc_buffer_rsp & response);
- void get_alignment(rpc_msg_get_alignment_rsp & response);
- void get_max_size(rpc_msg_get_max_size_rsp & response);
- bool buffer_get_base(const rpc_msg_buffer_get_base_req & request, rpc_msg_buffer_get_base_rsp & response);
- bool free_buffer(const rpc_msg_free_buffer_req & request);
- bool buffer_clear(const rpc_msg_buffer_clear_req & request);
- bool set_tensor(const std::vector & input);
- bool set_tensor_hash(const std::vector & input, rpc_msg_set_tensor_hash_rsp & response);
- bool get_tensor(const rpc_msg_get_tensor_req & request, std::vector & response);
- bool copy_tensor(const rpc_msg_copy_tensor_req & request, rpc_msg_copy_tensor_rsp & response);
- bool graph_compute(const std::vector & input, rpc_msg_graph_compute_rsp & response);
- bool init_tensor(const rpc_msg_init_tensor_req & request);
- bool get_alloc_size(const rpc_msg_get_alloc_size_req & request, rpc_msg_get_alloc_size_rsp & response);
-
-private:
- bool get_cached_file(uint64_t hash, std::vector & data);
- ggml_tensor * deserialize_tensor(struct ggml_context * ctx, const rpc_tensor * tensor);
- ggml_tensor * create_node(uint64_t id,
- struct ggml_context * ctx,
- const std::unordered_map & tensor_ptrs,
- std::unordered_map & tensor_map);
-
-
- ggml_backend_t backend;
- const char * cache_dir;
- std::unordered_set buffers;
-};
-
-bool rpc_server::get_alloc_size(const rpc_msg_get_alloc_size_req & request, rpc_msg_get_alloc_size_rsp & response) {
- ggml_backend_buffer_type_t buft;
- struct ggml_init_params params {
- /*.mem_size =*/ ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
-
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- ggml_tensor * tensor = deserialize_tensor(ctx, &request.tensor);
-
- if (tensor == nullptr) {
- GGML_LOG_ERROR("Null tensor pointer passed to server get_alloc_size function.\n");
- return false;
- }
-
- if (tensor->buffer == nullptr) {
- //No buffer allocated.
- buft = ggml_backend_get_default_buffer_type(backend);
- } else {
- buft = tensor->buffer->buft;
- }
-
- response.alloc_size = ggml_backend_buft_get_alloc_size(buft,tensor);
-
- return true;
-}
-
-void rpc_server::alloc_buffer(const rpc_msg_alloc_buffer_req & request, rpc_msg_alloc_buffer_rsp & response) {
- ggml_backend_buffer_type_t buft = ggml_backend_get_default_buffer_type(backend);
- ggml_backend_buffer_t buffer = ggml_backend_buft_alloc_buffer(buft, request.size);
- response.remote_ptr = 0;
- response.remote_size = 0;
- if (buffer != nullptr) {
- response.remote_ptr = reinterpret_cast(buffer);
- response.remote_size = buffer->size;
- GGML_PRINT_DEBUG("[%s] size: %" PRIu64 " -> remote_ptr: %" PRIx64 ", remote_size: %" PRIu64 "\n", __func__, request.size, response.remote_ptr, response.remote_size);
- buffers.insert(buffer);
- } else {
- GGML_LOG_ERROR("[%s] size: %" PRIu64 " -> failed\n", __func__, request.size);
- }
-}
-
-void rpc_server::get_alignment(rpc_msg_get_alignment_rsp & response) {
- ggml_backend_buffer_type_t buft = ggml_backend_get_default_buffer_type(backend);
- size_t alignment = ggml_backend_buft_get_alignment(buft);
- GGML_PRINT_DEBUG("[%s] alignment: %lu\n", __func__, alignment);
- response.alignment = alignment;
-}
-
-void rpc_server::get_max_size(rpc_msg_get_max_size_rsp & response) {
- ggml_backend_buffer_type_t buft = ggml_backend_get_default_buffer_type(backend);
- size_t max_size = ggml_backend_buft_get_max_size(buft);
- GGML_PRINT_DEBUG("[%s] max_size: %lu\n", __func__, max_size);
- response.max_size = max_size;
-}
-
-bool rpc_server::buffer_get_base(const rpc_msg_buffer_get_base_req & request, rpc_msg_buffer_get_base_rsp & response) {
- GGML_PRINT_DEBUG("[%s] remote_ptr: %" PRIx64 "\n", __func__, request.remote_ptr);
- ggml_backend_buffer_t buffer = reinterpret_cast(request.remote_ptr);
- if (buffers.find(buffer) == buffers.end()) {
- GGML_LOG_ERROR("[%s] buffer not found\n", __func__);
- return false;
- }
- void * base = ggml_backend_buffer_get_base(buffer);
- response.base_ptr = reinterpret_cast(base);
- return true;
-}
-
-bool rpc_server::free_buffer(const rpc_msg_free_buffer_req & request) {
- GGML_PRINT_DEBUG("[%s] remote_ptr: %" PRIx64 "\n", __func__, request.remote_ptr);
- ggml_backend_buffer_t buffer = reinterpret_cast(request.remote_ptr);
- if (buffers.find(buffer) == buffers.end()) {
- GGML_LOG_ERROR("[%s] buffer not found\n", __func__);
- return false;
- }
- ggml_backend_buffer_free(buffer);
- buffers.erase(buffer);
- return true;
-}
-
-bool rpc_server::buffer_clear(const rpc_msg_buffer_clear_req & request) {
- GGML_PRINT_DEBUG("[%s] remote_ptr: %" PRIx64 ", value: %u\n", __func__, request.remote_ptr, request.value);
- ggml_backend_buffer_t buffer = reinterpret_cast(request.remote_ptr);
- if (buffers.find(buffer) == buffers.end()) {
- GGML_LOG_ERROR("[%s] buffer not found\n", __func__);
- return false;
- }
- ggml_backend_buffer_clear(buffer, request.value);
- return true;
-}
-
-ggml_tensor * rpc_server::deserialize_tensor(struct ggml_context * ctx, const rpc_tensor * tensor) {
- ggml_tensor * result = ggml_new_tensor_4d(ctx, (ggml_type) tensor->type,
- tensor->ne[0], tensor->ne[1], tensor->ne[2], tensor->ne[3]);
- for (uint32_t i = 0; i < GGML_MAX_DIMS; i++) {
- result->nb[i] = tensor->nb[i];
- }
- result->buffer = reinterpret_cast(tensor->buffer);
- if (result->buffer && buffers.find(result->buffer) == buffers.end()) {
- result->buffer = nullptr;
- }
-
- if (result->buffer) {
- // require that the tensor data does not go beyond the buffer end
- uint64_t tensor_size = (uint64_t) ggml_nbytes(result);
- uint64_t buffer_start = (uint64_t) ggml_backend_buffer_get_base(result->buffer);
- uint64_t buffer_size = (uint64_t) ggml_backend_buffer_get_size(result->buffer);
- GGML_ASSERT(tensor->data + tensor_size >= tensor->data); // check for overflow
- GGML_ASSERT(tensor->data >= buffer_start && tensor->data + tensor_size <= buffer_start + buffer_size);
- }
-
- result->op = (ggml_op) tensor->op;
- for (uint32_t i = 0; i < GGML_MAX_OP_PARAMS / sizeof(int32_t); i++) {
- result->op_params[i] = tensor->op_params[i];
- }
- result->flags = tensor->flags;
- result->data = reinterpret_cast(tensor->data);
- ggml_set_name(result, tensor->name);
- return result;
-}
-
-
-bool rpc_server::set_tensor(const std::vector & input) {
- // serialization format: | rpc_tensor | offset (8 bytes) | data (size bytes) |
- if (input.size() < sizeof(rpc_tensor) + sizeof(uint64_t)) {
- return false;
- }
- const rpc_tensor * in_tensor = (const rpc_tensor *)input.data();
- uint64_t offset;
- memcpy(&offset, input.data() + sizeof(rpc_tensor), sizeof(offset));
- const size_t size = input.size() - sizeof(rpc_tensor) - sizeof(offset);
-
- struct ggml_init_params params {
- /*.mem_size =*/ ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- ggml_tensor * tensor = deserialize_tensor(ctx, in_tensor);
- if (tensor == nullptr) {
- GGML_LOG_ERROR("[%s] error deserializing tensor\n", __func__);
- return false;
- }
- GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %zu\n", __func__, (void*)tensor->buffer, tensor->data, offset, size);
-
- // sanitize tensor->data
- {
- const size_t p0 = (size_t) ggml_backend_buffer_get_base(tensor->buffer);
- const size_t p1 = p0 + ggml_backend_buffer_get_size(tensor->buffer);
-
- if (in_tensor->data + offset < p0 || in_tensor->data + offset >= p1 || size > (p1 - in_tensor->data - offset)) {
- GGML_ABORT("[%s] tensor->data out of bounds\n", __func__);
- }
- }
-
- const void * data = input.data() + sizeof(rpc_tensor) + sizeof(offset);
- if (cache_dir && size > HASH_THRESHOLD) {
- uint64_t hash = fnv_hash((const uint8_t*)data, size);
- char hash_str[17];
- snprintf(hash_str, sizeof(hash_str), "%016" PRIx64, hash);
- // save to cache_dir/hash_str
- fs::path cache_file = fs::path(cache_dir) / hash_str;
- std::ofstream ofs(cache_file, std::ios::binary);
- ofs.write((const char *)data, size);
- printf("[%s] saved to '%s'\n", __func__, cache_file.c_str());
- }
- ggml_backend_tensor_set(tensor, data, offset, size);
- return true;
-}
-
-bool rpc_server::get_cached_file(uint64_t hash, std::vector & data) {
- if (!cache_dir) {
- return false;
- }
- char hash_str[17];
- snprintf(hash_str, sizeof(hash_str), "%016" PRIx64, hash);
- fs::path cache_file = fs::path(cache_dir) / hash_str;
- if (!fs::exists(cache_file)) {
- return false;
- }
- std::ifstream ifs(cache_file, std::ios::binary);
- ifs.seekg(0, std::ios::end);
- size_t size = ifs.tellg();
- ifs.seekg(0, std::ios::beg);
- data.resize(size);
- ifs.read((char *)data.data(), size);
- return true;
-}
-
-bool rpc_server::set_tensor_hash(const std::vector & input, rpc_msg_set_tensor_hash_rsp & response)
-{
- // serialization format: | rpc_tensor | offset (8 bytes) | hash (8 bytes) |
- if (input.size() != sizeof(rpc_tensor) + 16) {
- return false;
- }
- const rpc_tensor * in_tensor = (const rpc_tensor *)input.data();
- uint64_t offset;
- memcpy(&offset, input.data() + sizeof(rpc_tensor), sizeof(offset));
- const uint64_t * hash = (const uint64_t *)(input.data() + sizeof(rpc_tensor) + sizeof(offset));
- std::vector cached_file;
- if (!get_cached_file(*hash, cached_file)) {
- response.result = 0;
- return true;
- }
- size_t size = cached_file.size();
- struct ggml_init_params params {
- /*.mem_size =*/ ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- ggml_tensor * tensor = deserialize_tensor(ctx, in_tensor);
- if (tensor == nullptr) {
- GGML_LOG_ERROR("[%s] error deserializing tensor\n", __func__);
- return false;
- }
- GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %zu, hash: %" PRIx64 "\n", __func__, (void*)tensor->buffer, tensor->data, offset, size, *hash);
-
- // sanitize tensor->data
- {
- const size_t p0 = (size_t) ggml_backend_buffer_get_base(tensor->buffer);
- const size_t p1 = p0 + ggml_backend_buffer_get_size(tensor->buffer);
-
- if (in_tensor->data + offset < p0 || in_tensor->data + offset >= p1 || size > (p1 - in_tensor->data - offset)) {
- GGML_ABORT("[%s] tensor->data out of bounds\n", __func__);
- }
- }
- ggml_backend_tensor_set(tensor, cached_file.data(), offset, size);
- response.result = 1;
- return true;
-}
-
-bool rpc_server::init_tensor(const rpc_msg_init_tensor_req & request) {
- struct ggml_init_params params {
- /*.mem_size =*/ ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- ggml_tensor * tensor = deserialize_tensor(ctx, &request.tensor);
- if (tensor == nullptr) {
- GGML_LOG_ERROR("Null tensor pointer passed to server init_tensor function.\n");
- return false;
- }
-
- // Call the backend's buffer_init_tensor function
- ggml_backend_buffer_t buffer = tensor->buffer;
- if (buffer && buffer->iface.init_tensor) {
- buffer->iface.init_tensor(buffer, tensor);
- } else {
- GGML_LOG_ERROR("Null buffer for tensor passed to init_tensor function\n");
- }
-
- if (tensor->extra != nullptr) {
- // This pointer can either be passed around client/server, or probably better stored server-side and kept track of.
- // Currently unimplemented.
- GGML_LOG_ERROR("tensor->extra populated by the backend, this is currently unsupported.\n");
- return false;
- }
-
- return true;
-}
-
-bool rpc_server::get_tensor(const rpc_msg_get_tensor_req & request, std::vector & response) {
- struct ggml_init_params params {
- /*.mem_size =*/ ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- ggml_tensor * tensor = deserialize_tensor(ctx, &request.tensor);
- if (tensor == nullptr) {
- GGML_LOG_ERROR("[%s] error deserializing tensor\n", __func__);
- return false;
- }
- GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %" PRIu64 "\n", __func__, (void*)tensor->buffer, tensor->data, request.offset, request.size);
-
- // sanitize tensor->data
- {
- const size_t p0 = (size_t) ggml_backend_buffer_get_base(tensor->buffer);
- const size_t p1 = p0 + ggml_backend_buffer_get_size(tensor->buffer);
-
- if (request.tensor.data + request.offset < p0 ||
- request.tensor.data + request.offset >= p1 ||
- request.size > (p1 - request.tensor.data - request.offset)) {
- GGML_ABORT("[%s] tensor->data out of bounds\n", __func__);
- }
- }
-
- response.resize(request.size, 0);
- ggml_backend_tensor_get(tensor, response.data(), request.offset, request.size);
- return true;
-}
-
-bool rpc_server::copy_tensor(const rpc_msg_copy_tensor_req & request, rpc_msg_copy_tensor_rsp & response) {
- struct ggml_init_params params {
- /*.mem_size =*/ 2*ggml_tensor_overhead(),
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
-
- ggml_tensor * src = deserialize_tensor(ctx, &request.src);
- ggml_tensor * dst = deserialize_tensor(ctx, &request.dst);
- if (src == nullptr || dst == nullptr) {
- GGML_LOG_ERROR("[%s] error deserializing tensors\n", __func__);
- return false;
- }
-
- uint64_t src_size = (uint64_t) ggml_nbytes(src);
- uint64_t dst_data = (uint64_t) dst->data;
- uint64_t dst_base = (uint64_t) ggml_backend_buffer_get_base(dst->buffer);
- uint64_t dst_buf_sz = (uint64_t) ggml_backend_buffer_get_size(dst->buffer);
-
- if (dst_data + src_size > dst_base + dst_buf_sz) {
- GGML_PRINT_DEBUG("[%s] out-of-bounds write in rpc_server::copy_tensor:\n"
- " write range : [0x%" PRIx64 ", 0x%" PRIx64 "]\n"
- " buffer base: [0x%" PRIx64 ", 0x%" PRIx64 "]\n",
- __func__,
- dst_data,
- dst_data + src_size,
- dst_base,
- dst_base + dst_buf_sz);
- return false;
- }
-
- GGML_PRINT_DEBUG("[%s] src->buffer: %p, dst->buffer: %p\n",
- __func__, (void*) src->buffer, (void*) dst->buffer);
-
- response.result = ggml_backend_buffer_copy_tensor(src, dst);
- return true;
-}
-
-ggml_tensor * rpc_server::create_node(uint64_t id,
- struct ggml_context * ctx,
- const std::unordered_map & tensor_ptrs,
- std::unordered_map & tensor_map) {
- if (id == 0) {
- return nullptr;
- }
- if (tensor_map.find(id) != tensor_map.end()) {
- return tensor_map[id];
- }
- const rpc_tensor * tensor = tensor_ptrs.at(id);
- struct ggml_tensor * result = deserialize_tensor(ctx, tensor);
- if (result == nullptr) {
- return nullptr;
- }
- tensor_map[id] = result;
- for (int i = 0; i < GGML_MAX_SRC; i++) {
- result->src[i] = create_node(tensor->src[i], ctx, tensor_ptrs, tensor_map);
- }
- result->view_src = create_node(tensor->view_src, ctx, tensor_ptrs, tensor_map);
- result->view_offs = tensor->view_offs;
- return result;
-}
-
-bool rpc_server::graph_compute(const std::vector & input, rpc_msg_graph_compute_rsp & response) {
- // serialization format:
- // | n_nodes (4 bytes) | nodes (n_nodes * sizeof(uint64_t) | n_tensors (4 bytes) | tensors (n_tensors * sizeof(rpc_tensor)) |
- if (input.size() < sizeof(uint32_t)) {
- return false;
- }
- uint32_t n_nodes;
- memcpy(&n_nodes, input.data(), sizeof(n_nodes));
- if (input.size() < sizeof(uint32_t) + n_nodes*sizeof(uint64_t) + sizeof(uint32_t)) {
- return false;
- }
- const uint64_t * nodes = (const uint64_t *)(input.data() + sizeof(n_nodes));
- uint32_t n_tensors;
- memcpy(&n_tensors, input.data() + sizeof(n_nodes) + n_nodes*sizeof(uint64_t), sizeof(n_tensors));
- if (input.size() < sizeof(uint32_t) + n_nodes*sizeof(uint64_t) + sizeof(uint32_t) + n_tensors*sizeof(rpc_tensor)) {
- return false;
- }
- const rpc_tensor * tensors = (const rpc_tensor *)(input.data() + sizeof(n_nodes) + n_nodes*sizeof(uint64_t) + sizeof(n_tensors));
- GGML_PRINT_DEBUG("[%s] n_nodes: %u, n_tensors: %u\n", __func__, n_nodes, n_tensors);
-
- size_t buf_size = ggml_tensor_overhead()*(n_nodes + n_tensors) + ggml_graph_overhead_custom(n_nodes, false);
- struct ggml_init_params params = {
- /*.mem_size =*/ buf_size,
- /*.mem_buffer =*/ NULL,
- /*.no_alloc =*/ true,
- };
- ggml_context_ptr ctx_ptr { ggml_init(params) };
- GGML_ASSERT(ctx_ptr != nullptr);
- ggml_context * ctx = ctx_ptr.get();
- struct ggml_cgraph * graph = ggml_new_graph_custom(ctx, n_nodes, false);
- graph->n_nodes = n_nodes;
- std::unordered_map tensor_ptrs;
- for (uint32_t i = 0; i < n_tensors; i++) {
- tensor_ptrs[tensors[i].id] = &tensors[i];
- }
- std::unordered_map tensor_map;
- for (uint32_t i = 0; i < n_nodes; i++) {
- int64_t id;
- memcpy(&id, &nodes[i], sizeof(id));
- graph->nodes[i] = create_node(id, ctx, tensor_ptrs, tensor_map);
- }
- ggml_status status = ggml_backend_graph_compute(backend, graph);
- response.result = status;
- return true;
-}
-
-rpc_server::~rpc_server() {
- for (auto buffer : buffers) {
- ggml_backend_buffer_free(buffer);
- }
-}
-
-static void rpc_serve_client(ggml_backend_t backend, const char * cache_dir,
- sockfd_t sockfd, size_t free_mem, size_t total_mem) {
- rpc_server server(backend, cache_dir);
- while (true) {
- uint8_t cmd;
- if (!recv_data(sockfd, &cmd, 1)) {
- break;
- }
- if (cmd >= RPC_CMD_COUNT) {
- // fail fast if the command is invalid
- fprintf(stderr, "Unknown command: %d\n", cmd);
- break;
- }
- switch (cmd) {
- case RPC_CMD_ALLOC_BUFFER: {
- rpc_msg_alloc_buffer_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- rpc_msg_alloc_buffer_rsp response;
- server.alloc_buffer(request, response);
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_GET_ALLOC_SIZE: {
- rpc_msg_get_alloc_size_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- rpc_msg_get_alloc_size_rsp response;
- server.get_alloc_size(request, response);
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_GET_ALIGNMENT: {
- if (!recv_msg(sockfd, nullptr, 0)) {
- return;
- }
- rpc_msg_get_alignment_rsp response;
- server.get_alignment(response);
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_GET_MAX_SIZE: {
- if (!recv_msg(sockfd, nullptr, 0)) {
- return;
- }
- rpc_msg_get_max_size_rsp response;
- server.get_max_size(response);
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_BUFFER_GET_BASE: {
- rpc_msg_buffer_get_base_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- rpc_msg_buffer_get_base_rsp response;
- if (!server.buffer_get_base(request, response)) {
- return;
- }
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_FREE_BUFFER: {
- rpc_msg_free_buffer_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- if (!server.free_buffer(request)) {
- return;
- }
- if (!send_msg(sockfd, nullptr, 0)) {
- return;
- }
- break;
- }
- case RPC_CMD_BUFFER_CLEAR: {
- rpc_msg_buffer_clear_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- if (!server.buffer_clear(request)) {
- return;
- }
- if (!send_msg(sockfd, nullptr, 0)) {
- return;
- }
- break;
- }
- case RPC_CMD_SET_TENSOR: {
- std::vector input;
- if (!recv_msg(sockfd, input)) {
- return;
- }
- if (!server.set_tensor(input)) {
- return;
- }
- if (!send_msg(sockfd, nullptr, 0)) {
- return;
- }
- break;
- }
- case RPC_CMD_SET_TENSOR_HASH: {
- std::vector input;
- if (!recv_msg(sockfd, input)) {
- return;
- }
- rpc_msg_set_tensor_hash_rsp response;
- if (!server.set_tensor_hash(input, response)) {
- return;
- }
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_INIT_TENSOR: {
- rpc_msg_init_tensor_req request;
- if (!recv_msg(sockfd, &request,sizeof(request))) {
- return;
- }
- if (!server.init_tensor(request)) {
- return;
- }
- if (!send_msg(sockfd, nullptr, 0)) {
- return;
- }
- break;
- }
- case RPC_CMD_GET_TENSOR: {
- rpc_msg_get_tensor_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- std::vector response;
- if (!server.get_tensor(request, response)) {
- return;
- }
- if (!send_msg(sockfd, response.data(), response.size())) {
- return;
- }
- break;
- }
- case RPC_CMD_COPY_TENSOR: {
- rpc_msg_copy_tensor_req request;
- if (!recv_msg(sockfd, &request, sizeof(request))) {
- return;
- }
- rpc_msg_copy_tensor_rsp response;
- if (!server.copy_tensor(request, response)) {
- return;
- }
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_GRAPH_COMPUTE: {
- std::vector input;
- if (!recv_msg(sockfd, input)) {
- return;
- }
- rpc_msg_graph_compute_rsp response;
- if (!server.graph_compute(input, response)) {
- return;
- }
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- case RPC_CMD_GET_DEVICE_MEMORY: {
- if (!recv_msg(sockfd, nullptr, 0)) {
- return;
- }
- rpc_msg_get_device_memory_rsp response;
- response.free_mem = free_mem;
- response.total_mem = total_mem;
- if (!send_msg(sockfd, &response, sizeof(response))) {
- return;
- }
- break;
- }
- default: {
- fprintf(stderr, "Unknown command: %d\n", cmd);
- return;
- }
- }
- }
-}
-
-void ggml_backend_rpc_start_server(ggml_backend_t backend, const char * endpoint,
- const char * cache_dir,
- size_t free_mem, size_t total_mem) {
- std::string host;
- int port;
- if (!parse_endpoint(endpoint, host, port)) {
- return;
- }
-#ifdef _WIN32
- {
- WSADATA wsaData;
- int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (res != 0) {
- fprintf(stderr, "WSAStartup failed: %d\n", res);
- return;
- }
- }
-#endif
- auto server_socket = create_server_socket(host.c_str(), port);
- if (server_socket == nullptr) {
- fprintf(stderr, "Failed to create server socket\n");
- return;
- }
- while (true) {
- auto client_socket = socket_accept(server_socket->fd);
- if (client_socket == nullptr) {
- fprintf(stderr, "Failed to accept client connection\n");
- return;
- }
- printf("Accepted client connection, free_mem=%zu, total_mem=%zu\n", free_mem, total_mem);
- fflush(stdout);
- rpc_serve_client(backend, cache_dir, client_socket->fd, free_mem, total_mem);
- printf("Client connection closed\n");
- fflush(stdout);
- }
-#ifdef _WIN32
- WSACleanup();
-#endif
-}
-
-// device interface
-
-struct ggml_backend_rpc_device_context {
- std::string endpoint;
- std::string name;
-};
-
-static const char * ggml_backend_rpc_device_get_name(ggml_backend_dev_t dev) {
- ggml_backend_rpc_device_context * ctx = (ggml_backend_rpc_device_context *)dev->context;
-
- return ctx->name.c_str();
-}
-
-static const char * ggml_backend_rpc_device_get_description(ggml_backend_dev_t dev) {
- ggml_backend_rpc_device_context * ctx = (ggml_backend_rpc_device_context *)dev->context;
-
- return ctx->name.c_str();
-}
-
-static void ggml_backend_rpc_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) {
- ggml_backend_rpc_device_context * ctx = (ggml_backend_rpc_device_context *)dev->context;
-
- ggml_backend_rpc_get_device_memory(ctx->endpoint.c_str(), free, total);
-
- GGML_UNUSED(dev);
-}
-
-static enum ggml_backend_dev_type ggml_backend_rpc_device_get_type(ggml_backend_dev_t dev) {
- // TODO: obtain value from the server
- return GGML_BACKEND_DEVICE_TYPE_GPU;
-
- GGML_UNUSED(dev);
-}
-
-static void ggml_backend_rpc_device_get_props(ggml_backend_dev_t dev, struct ggml_backend_dev_props * props) {
- props->name = ggml_backend_rpc_device_get_name(dev);
- props->description = ggml_backend_rpc_device_get_description(dev);
- props->type = ggml_backend_rpc_device_get_type(dev);
- ggml_backend_rpc_device_get_memory(dev, &props->memory_free, &props->memory_total);
- props->caps = {
- /* .async = */ false,
- /* .host_buffer = */ false,
- /* .buffer_from_host_ptr = */ false,
- /* .events = */ false,
- };
-}
-
-static ggml_backend_t ggml_backend_rpc_device_init(ggml_backend_dev_t dev, const char * params) {
- ggml_backend_rpc_device_context * ctx = (ggml_backend_rpc_device_context *)dev->context;
-
- return ggml_backend_rpc_init(ctx->endpoint.c_str());
-
- GGML_UNUSED(params);
-}
-
-static ggml_backend_buffer_type_t ggml_backend_rpc_device_get_buffer_type(ggml_backend_dev_t dev) {
- ggml_backend_rpc_device_context * ctx = (ggml_backend_rpc_device_context *)dev->context;
-
- return ggml_backend_rpc_buffer_type(ctx->endpoint.c_str());
-
- GGML_UNUSED(dev);
-}
-
-static bool ggml_backend_rpc_device_supports_op(ggml_backend_dev_t dev, const struct ggml_tensor * op) {
- GGML_UNUSED(dev);
- GGML_UNUSED(op);
- //TODO: call the remote backend and cache the results
- return true;
-}
-
-static bool ggml_backend_rpc_device_supports_buft(ggml_backend_dev_t dev, ggml_backend_buffer_type_t buft) {
- if (!buft || buft->iface.get_name != ggml_backend_rpc_buffer_type_name) {
- return false;
- }
- ggml_backend_rpc_buffer_type_context * buft_ctx = (ggml_backend_rpc_buffer_type_context *)buft->context;
- ggml_backend_rpc_device_context * dev_ctx = (ggml_backend_rpc_device_context *)dev->context;
- return buft_ctx->endpoint == dev_ctx->endpoint;
-}
-
-static const struct ggml_backend_device_i ggml_backend_rpc_device_i = {
- /* .get_name = */ ggml_backend_rpc_device_get_name,
- /* .get_description = */ ggml_backend_rpc_device_get_description,
- /* .get_memory = */ ggml_backend_rpc_device_get_memory,
- /* .get_type = */ ggml_backend_rpc_device_get_type,
- /* .get_props = */ ggml_backend_rpc_device_get_props,
- /* .init_backend = */ ggml_backend_rpc_device_init,
- /* .get_buffer_type = */ ggml_backend_rpc_device_get_buffer_type,
- /* .get_host_buffer_type = */ NULL,
- /* .buffer_from_host_ptr = */ NULL,
- /* .supports_op = */ ggml_backend_rpc_device_supports_op,
- /* .supports_buft = */ ggml_backend_rpc_device_supports_buft,
- /* .offload_op = */ NULL,
- /* .event_new = */ NULL,
- /* .event_free = */ NULL,
- /* .event_synchronize = */ NULL,
-};
-
-// backend reg interface
-
-static const char * ggml_backend_rpc_reg_get_name(ggml_backend_reg_t reg) {
- return "RPC";
-
- GGML_UNUSED(reg);
-}
-
-static size_t ggml_backend_rpc_reg_get_device_count(ggml_backend_reg_t reg) {
- return 0;
-
- GGML_UNUSED(reg);
-}
-
-static ggml_backend_dev_t ggml_backend_rpc_reg_get_device(ggml_backend_reg_t reg, size_t index) {
- GGML_ABORT("The RPC backend does not have enumerated devices - use ggml_backend_add_device instead");
-
- GGML_UNUSED(reg);
- GGML_UNUSED(index);
-}
-
-static void * ggml_backend_rpc_get_proc_address(ggml_backend_reg_t reg, const char * name) {
- if (std::strcmp(name, "ggml_backend_rpc_add_device") == 0) {
- return (void *)ggml_backend_rpc_add_device;
- }
- return NULL;
-
- GGML_UNUSED(reg);
-}
-
-static const struct ggml_backend_reg_i ggml_backend_rpc_reg_i = {
- /* .get_name = */ ggml_backend_rpc_reg_get_name,
- /* .get_device_count = */ ggml_backend_rpc_reg_get_device_count,
- /* .get_device = */ ggml_backend_rpc_reg_get_device,
- /* .get_proc_address = */ ggml_backend_rpc_get_proc_address,
-};
-
-ggml_backend_reg_t ggml_backend_rpc_reg(void) {
- static struct ggml_backend_reg ggml_backend_rpc_reg = {
- /* .api_version = */ GGML_BACKEND_API_VERSION,
- /* .iface = */ ggml_backend_rpc_reg_i,
- /* .context = */ NULL,
- };
-
- return &ggml_backend_rpc_reg;
-}
-
-ggml_backend_dev_t ggml_backend_rpc_add_device(const char * endpoint) {
- static std::unordered_map dev_map;
-
- static std::mutex mutex;
- std::lock_guard lock(mutex);
-
- if (dev_map.find(endpoint) != dev_map.end()) {
- return dev_map[endpoint];
- }
-
- ggml_backend_rpc_device_context * ctx = new ggml_backend_rpc_device_context {
- /* .endpoint = */ endpoint,
- /* .name = */ "RPC[" + std::string(endpoint) + "]",
- };
-
- ggml_backend_dev_t dev = new ggml_backend_device {
- /* .iface = */ ggml_backend_rpc_device_i,
- /* .reg = */ ggml_backend_rpc_reg(),
- /* .context = */ ctx,
- };
-
- dev_map[endpoint] = dev;
-
- return dev;
-}
-
-GGML_BACKEND_DL_IMPL(ggml_backend_rpc_reg)
diff --git a/ggml/src/ggml-sycl/backend.hpp b/ggml/src/ggml-sycl/backend.hpp
deleted file mode 100644
index 73d807cab..000000000
--- a/ggml/src/ggml-sycl/backend.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_BACKEND_HPP
-#define GGML_SYCL_BACKEND_HPP
-
-#include "concat.hpp"
-#include "common.hpp"
-#include "conv.hpp"
-#include "convert.hpp"
-#include "dequantize.hpp"
-#include "dmmv.hpp"
-#include "mmq.hpp"
-#include "mmvq.hpp"
-#include "rope.hpp"
-#include "norm.hpp"
-#include "softmax.hpp"
-#include "tsembd.hpp"
-#include "im2col.hpp"
-#include "wkv.hpp"
-#include "outprod.hpp"
-#include "element_wise.hpp"
-#include "cpy.hpp"
-#include "gla.hpp"
-
-#endif // GGML_SYCL_BACKEND_HPP
diff --git a/ggml/src/ggml-sycl/common.cpp b/ggml/src/ggml-sycl/common.cpp
deleted file mode 100644
index 05fd5ef46..000000000
--- a/ggml/src/ggml-sycl/common.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#include "common.hpp"
-
-#include "ggml-backend-impl.h"
-#include "ggml-impl.h"
-
-int get_current_device_id() {
- return dpct::dev_mgr::instance().current_device_id();
-}
-
-void* ggml_sycl_host_malloc(size_t size) try {
- if (getenv("GGML_SYCL_NO_PINNED") != nullptr) {
- return nullptr;
- }
-
- void* ptr = nullptr;
- // allow to use dpct::get_in_order_queue() for host malloc
- dpct::err0 err = CHECK_TRY_ERROR(
- ptr = (void*)sycl::malloc_host(size, dpct::get_in_order_queue()));
-
- if (err != 0) {
- // clear the error
- GGML_LOG_ERROR("WARNING: failed to allocate %.2f MB of pinned memory: %s\n", size / 1024.0 / 1024.0, "syclGetErrorString is not supported");
- return nullptr;
- }
-
- return ptr;
-} catch (sycl::exception const& exc) {
- std::cerr << exc.what() << "Exception caught at file:" << __FILE__
- << ", line:" << __LINE__ << std::endl;
- std::exit(1);
-}
-
-void ggml_sycl_host_free(void* ptr) try {
- // allow to use dpct::get_in_order_queue() for host malloc
- SYCL_CHECK(CHECK_TRY_ERROR(sycl::free(ptr, dpct::get_in_order_queue())));
-} catch (sycl::exception const& exc) {
- std::cerr << exc.what() << "Exception caught at file:" << __FILE__
- << ", line:" << __LINE__ << std::endl;
- std::exit(1);
-}
-
-bool gpu_has_xmx(sycl::device &dev) {
- return dev.has(sycl::aspect::ext_intel_matrix);
-}
-
-int64_t downsample_sycl_global_range(int64_t accumulate_block_num, int64_t block_size) {
- const int64_t max_range = std::numeric_limits::max();
- int64_t sycl_down_blk_size = block_size;
- int64_t global_range = accumulate_block_num * sycl_down_blk_size;
- while(global_range > max_range) {
- sycl_down_blk_size /= 2;
- global_range = accumulate_block_num * sycl_down_blk_size;
- }
- return sycl_down_blk_size;
-}
-
-void release_extra_gpu(ggml_tensor_extra_gpu * extra, std::vector streams) {
- for (int i = 0; i < ggml_sycl_info().device_count; ++i) {
- for (int64_t is = 0; is < GGML_SYCL_MAX_STREAMS; ++is) {
- if (extra->events[i][is] != nullptr) {
- SYCL_CHECK(CHECK_TRY_ERROR(dpct::destroy_event(extra->events[i][is])));
- }
- }
- if (extra->data_device[i] != nullptr && streams.size()>0) {
- ggml_sycl_set_device(i);
- SYCL_CHECK(
- CHECK_TRY_ERROR(sycl::free(extra->data_device[i], *(streams[i]))));
- }
- }
- delete extra;
-}
diff --git a/ggml/src/ggml-sycl/common.hpp b/ggml/src/ggml-sycl/common.hpp
deleted file mode 100644
index 3e1ceeaa4..000000000
--- a/ggml/src/ggml-sycl/common.hpp
+++ /dev/null
@@ -1,779 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_COMMON_HPP
-#define GGML_SYCL_COMMON_HPP
-
-#include
-#include
-
-#include "dpct/helper.hpp"
-#include "ggml-sycl.h"
-#include "presets.hpp"
-#include "sycl_hw.hpp"
-
-
-#if GGML_SYCL_DNNL
-#include "dnnl.hpp"
-#include "dnnl_sycl.hpp"
-#endif
-
-#define GGML_COMMON_DECL_SYCL
-#define GGML_COMMON_IMPL_SYCL
-/* suppress warning spam */
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnested-anon-types"
-#include "ggml-common.h"
-#pragma clang diagnostic pop
-#include "ggml-impl.h"
-
-void* ggml_sycl_host_malloc(size_t size);
-void ggml_sycl_host_free(void* ptr);
-
-
-extern int g_ggml_sycl_debug;
-extern int g_ggml_sycl_disable_optimize;
-
-#define GGML_SYCL_DEBUG(...) \
- do { \
- if (g_ggml_sycl_debug) \
- fprintf(stderr, __VA_ARGS__); \
- } while (0)
-
-#define CHECK_TRY_ERROR(expr) \
- [&]() { \
- try { \
- expr; \
- return dpct::success; \
- } catch (std::exception const& e) { \
- std::cerr << e.what() << "\nException caught at file:" << __FILE__ \
- << ", line:" << __LINE__ << ", func:" << __func__ \
- << std::endl; \
- return dpct::default_error; \
- } \
- }()
-
-
-#define __SYCL_ARCH__ DPCT_COMPATIBILITY_TEMP
-#define VER_4VEC 610 // todo for hardward optimize.
-#define VER_GEN9 700 // todo for hardward optimize.
-#define VER_GEN12 1000000 // todo for hardward optimize.
-#define VER_GEN13 (VER_GEN12 + 1030) // todo for hardward optimize.
-
-#define GGML_SYCL_MAX_NODES 8192 // TODO: adapt to hardwares
-
-// define for XMX in Intel GPU
-// TODO: currently, it's not used for XMX really.
-#if !defined(GGML_SYCL_FORCE_MMQ)
- #define SYCL_USE_XMX
-#endif
-
-// max batch size to use MMQ kernels when tensor cores are available
-#define MMQ_MAX_BATCH_SIZE 32
-
-#if defined(_MSC_VER)
-#pragma warning(disable : 4244 4267) // possible loss of data
-#endif
-
-// dmmv = dequantize_mul_mat_vec
-#ifndef GGML_SYCL_DMMV_X
-#define GGML_SYCL_DMMV_X 32
-#endif
-#ifndef GGML_SYCL_MMV_Y
-#define GGML_SYCL_MMV_Y 1
-#endif
-
-typedef sycl::queue *queue_ptr;
-
-enum ggml_sycl_backend_gpu_mode {
- SYCL_UNSET_GPU_MODE = -1,
- SYCL_SINGLE_GPU_MODE = 0,
- SYCL_MUL_GPU_MODE
-};
-
-static_assert(sizeof(sycl::half) == sizeof(ggml_fp16_t), "wrong fp16 size");
-
-static void crash() {
- int* ptr = NULL;
- *ptr = 0;
-}
-
-[[noreturn]] static void ggml_sycl_error(
- const char* stmt,
- const char* func,
- const char* file,
- const int line,
- const char* msg) {
- fprintf(stderr, "SYCL error: %s: %s\n", stmt, msg);
- fprintf(stderr, " in function %s at %s:%d\n", func, file, line);
- GGML_ABORT("SYCL error");
-}
-
-#define SYCL_CHECK(err) \
- do { \
- auto err_ = (err); \
- if (err_ != 0) \
- ggml_sycl_error( \
- #err, \
- __func__, \
- __FILE__, \
- __LINE__, \
- "Meet error in this line code!"); \
- } while (0)
-
-#if DPCT_COMPAT_RT_VERSION >= 11100
-#define GGML_SYCL_ASSUME(x) __builtin_assume(x)
-#else
-#define GGML_SYCL_ASSUME(x)
-#endif // DPCT_COMPAT_RT_VERSION >= 11100
-
-#ifdef GGML_SYCL_F16
-typedef sycl::half dfloat; // dequantize float
-typedef sycl::half2 dfloat2;
-#else
-typedef float dfloat; // dequantize float
-typedef sycl::float2 dfloat2;
-#endif // GGML_SYCL_F16
-
-#define MMVQ_MAX_BATCH_SIZE 8
-
-static const int8_t kvalues_iq4nl[16]={-127, -104, -83, -65, -49, -35, -22, -10, 1, 13, 25, 38, 53, 69, 89, 113};
-
-static int g_all_sycl_device_count = -1;
-static bool g_ggml_backend_sycl_buffer_type_initialized = false;
-
-static ggml_sycl_backend_gpu_mode g_ggml_sycl_backend_gpu_mode =
- SYCL_UNSET_GPU_MODE;
-
-static void* g_scratch_buffer = nullptr;
-static size_t g_scratch_size = 0; // disabled by default
-static size_t g_scratch_offset = 0;
-
-[[noreturn]] static inline void bad_arch(const sycl::stream& stream_ct1) {
- stream_ct1 << "ERROR: ggml-sycl was compiled without support for the "
- "current GPU architecture.\n";
- // __trap();
- std::exit(1);
-
- (void)bad_arch; // suppress unused function warning
-}
-
-int get_current_device_id();
-
-inline dpct::err0 ggml_sycl_set_device(const int device) try {
- int current_device_id;
- SYCL_CHECK(CHECK_TRY_ERROR(current_device_id = get_current_device_id()));
-
- // GGML_SYCL_DEBUG("ggml_sycl_set_device device_id=%d,
- // current_device_id=%d\n", device, current_device);
- if (device == current_device_id) {
- return 0;
- }
-
- return CHECK_TRY_ERROR(dpct::select_device(device));
-} catch (sycl::exception const& exc) {
- std::cerr << exc.what() << "Exception caught at file:" << __FILE__
- << ", line:" << __LINE__ << std::endl;
- crash();
- std::exit(1);
-}
-
-//////////////////////
-struct optimize_feature {
- bool reorder=false;
-};
-
-struct sycl_device_info {
- int cc; // compute capability
- // int nsm; // number of streaming multiprocessors
- // size_t smpb; // max. shared memory per block
- bool vmm; // virtual memory support
- size_t total_vram;
- sycl_hw_info hw_info;
- optimize_feature opt_feature;
-};
-
-
-struct ggml_sycl_device_info {
- int device_count;
-
- sycl_device_info devices[GGML_SYCL_MAX_DEVICES] = {};
-
- std::array default_tensor_split = {};
-
- int max_work_group_sizes[GGML_SYCL_MAX_DEVICES] = {0};
-};
-
-const ggml_sycl_device_info & ggml_sycl_info();
-
-struct ggml_sycl_pool {
- virtual ~ggml_sycl_pool() = default;
-
- virtual void * alloc(size_t size, size_t * actual_size) = 0;
- virtual void free(void * ptr, size_t size) = 0;
-};
-
-template
-struct ggml_sycl_pool_alloc {
- ggml_sycl_pool * pool = nullptr;
- T * ptr = nullptr;
- size_t actual_size = 0;
-
- explicit ggml_sycl_pool_alloc(ggml_sycl_pool & pool) : pool(&pool) {
- }
-
- ggml_sycl_pool_alloc(ggml_sycl_pool & pool, size_t size) : pool(&pool) {
- alloc(size);
- }
-
- ~ggml_sycl_pool_alloc() {
- if (ptr != nullptr) {
- pool->free(ptr, actual_size);
- }
- }
-
- T * realloc(size_t size) {
- GGML_ASSERT(pool != nullptr);
- if (ptr)
- pool->free(ptr, actual_size);
- ptr = (T *) pool->alloc(size * sizeof(T), &this->actual_size);
- return ptr;
- }
-
- // size is in number of elements
- T * alloc(size_t size) {
- GGML_ASSERT(pool != nullptr);
- GGML_ASSERT(ptr == nullptr);
- ptr = (T *) pool->alloc(size * sizeof(T), &this->actual_size);
- return ptr;
- }
-
- T * alloc(ggml_sycl_pool & pool, size_t size) {
- this->pool = &pool;
- return alloc(size);
- }
-
- T * get() {
- return ptr;
- }
-
- ggml_sycl_pool_alloc() = default;
- ggml_sycl_pool_alloc(const ggml_sycl_pool_alloc &) = delete;
- ggml_sycl_pool_alloc(ggml_sycl_pool_alloc &&) = delete;
- ggml_sycl_pool_alloc& operator=(const ggml_sycl_pool_alloc &) = delete;
- ggml_sycl_pool_alloc& operator=(ggml_sycl_pool_alloc &&) = delete;
-};
-
-// backend interface
-
-struct ggml_tensor_extra_gpu {
- void* data_device[GGML_SYCL_MAX_DEVICES]; // 1 pointer for each device for split
- // tensors
- dpct::event_ptr events[GGML_SYCL_MAX_DEVICES]
- [GGML_SYCL_MAX_STREAMS]; // events for synchronizing multiple GPUs
- optimize_feature optimized_feature;
-};
-
-void release_extra_gpu(ggml_tensor_extra_gpu * extra, std::vector streams={});
-
-inline optimize_feature check_gpu_optimize_feature(syclex::architecture &arch) {
- optimize_feature opt;
-
- opt.reorder =
- (arch == syclex::architecture::intel_gpu_dg1 ||
- arch == syclex::architecture::intel_gpu_acm_g10 ||
- arch == syclex::architecture::intel_gpu_acm_g11 ||
- arch == syclex::architecture::intel_gpu_acm_g12 ||
- arch == syclex::architecture::intel_gpu_pvc ||
- arch == syclex::architecture::intel_gpu_pvc_vg ||
- arch == syclex::architecture::intel_gpu_mtl_u ||
- arch == syclex::architecture::intel_gpu_mtl_s ||
- arch == syclex::architecture::intel_gpu_mtl_h ||
- arch == syclex::architecture::intel_gpu_arl_u ||
- arch == syclex::architecture::intel_gpu_arl_s ||
- arch == syclex::architecture::intel_gpu_arl_h ||
- arch == syclex::architecture::intel_gpu_bmg_g21 ||
- arch == syclex::architecture::intel_gpu_lnl_m
- );
-
- return opt;
-}
-
-namespace sycl_ex = sycl::ext::oneapi::experimental;
-struct ggml_backend_sycl_context {
- int device;
- std::string name;
- optimize_feature opt_feature;
- bool optimized_graph=false;
-
- queue_ptr qptrs[GGML_SYCL_MAX_DEVICES][GGML_SYCL_MAX_STREAMS] = { { nullptr } };
-
- explicit ggml_backend_sycl_context(int device) :
- device(device),
- name(GGML_SYCL_NAME + std::to_string(device)) {
- opt_feature = ggml_sycl_info().devices[device].opt_feature;
- }
-
- queue_ptr stream(int device, int stream) {
- if (qptrs[device][stream] == nullptr) {
- qptrs[device][stream] = &(dpct::get_device(device).default_queue());
- }
- return qptrs[device][stream];
- }
-
- queue_ptr stream() {
- return stream(device, 0);
- }
-
-#if GGML_SYCL_DNNL
- dnnl::engine make_engine(sycl::queue* q) {
- // Get the device associated with the queue
- sycl::device dev = q->get_device();
- // Get the context associated with the queue
- sycl::context ctx = q->get_context();
- const dnnl::engine eng = dnnl::sycl_interop::make_engine(dev, ctx);
- return eng;
- }
-
- std::unordered_map stream_map;
- std::unordered_map engine_map;
- dnnl::stream stream_dnnl(int device, int _stream) {
- auto q = stream(device, _stream);
- return stream_dnnl(q);
- }
- dnnl::engine engine_dnnl(sycl::queue* qptr) {
- auto it = engine_map.find(qptr);
- if (it == engine_map.end()) {
- auto eng = make_engine(qptr);
- engine_map[qptr] = eng;
- return eng;
- }
- else
- {
- return it->second;
- }
- }
- dnnl::stream stream_dnnl(sycl::queue* qptr) {
- auto it = stream_map.find(qptr);
- if (it == stream_map.end()) {
- auto eng = engine_dnnl(qptr);
- auto stream = dnnl::sycl_interop::make_stream(eng, *qptr);
- stream_map[qptr] = stream;
- return stream;
- }
- else
- {
- return it->second;
- }
- }
- dnnl::stream stream_dnnl() {
- return stream_dnnl(device, 0);
- }
- dnnl::memory get_scratchpad_mem(const dnnl::memory::desc & scratchpad_md,
- const dnnl::engine & eng, const queue_ptr q) {
- ggml_sycl_pool_alloc * pool;
- auto it = scratchpad_map.find(q);
- if (it == scratchpad_map.end()) {
- scratchpad_map[q] = std::make_unique>(this->pool());
- pool = scratchpad_map[q].get();
- } else {
- pool = it->second.get();
- }
-
- size_t scratchpad_size = scratchpad_md.get_size();
- if (scratchpad_size > pool->actual_size) {
- pool->realloc(scratchpad_size);
- }
- void * mem_ptr = pool->get();
- return dnnl::memory(scratchpad_md, eng, mem_ptr);
- }
-#endif
-
- // pool
- std::unique_ptr pools[GGML_SYCL_MAX_DEVICES];
- std::unordered_map>> scratchpad_map;
-
- std::unique_ptr host_pools[GGML_SYCL_MAX_DEVICES];
-
- static std::unique_ptr new_pool_for_device(queue_ptr qptr, int device);
-
- static std::unique_ptr new_pool_for_host(queue_ptr qptr, int device);
-
- ggml_sycl_pool & pool(int device) {
- if (pools[device] == nullptr) {
- pools[device] = new_pool_for_device(stream(device,0), device);
- }
- return *pools[device];
- }
-
- ggml_sycl_pool & pool() {
- return pool(device);
- }
-
-#ifdef GGML_SYCL_GRAPH
- std::unique_ptr> exec_graph = nullptr;
-#endif
-
- ggml_sycl_pool & host_pool(int device) {
- if (host_pools[device] == nullptr) {
- host_pools[device] = new_pool_for_host(stream(device, 0), device);
- }
- return *host_pools[device];
- }
-
- ggml_sycl_pool & host_pool() { return host_pool(device); }
-};
-
-// common device functions
-
-static __dpct_inline__ float warp_reduce_sum(float x,
- const sycl::nd_item<3>& item_ct1) {
-#pragma unroll
- for (int mask = WARP_SIZE / 2; mask > 0; mask >>= 1) {
- /*
- DPCT1096:98: The right-most dimension of the work-group used in the SYCL
- kernel that calls this function may be less than "32". The function
- "dpct::permute_sub_group_by_xor" may return an unexpected result on the
- CPU device. Modify the size of the work-group to ensure that the value
- of the right-most dimension is a multiple of "32".
- */
- x += dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), x, mask);
- }
- return x;
-}
-
-static __dpct_inline__ sycl::float2
-warp_reduce_sum(sycl::float2 a, const sycl::nd_item<3>& item_ct1) {
-#pragma unroll
- for (int mask = WARP_SIZE / 2; mask > 0; mask >>= 1) {
- a.x() += dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), a.x(),
- mask);
- a.y() += dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), a.y(),
- mask);
- }
- return a;
-}
-
-static __dpct_inline__ float warp_reduce_max(float x,
- const sycl::nd_item<3>& item_ct1) {
-#pragma unroll
- for (int mask = WARP_SIZE / 2; mask > 0; mask >>= 1) {
- /*
- DPCT1096:97: The right-most dimension of the work-group used in the SYCL
- kernel that calls this function may be less than "32". The function
- "dpct::permute_sub_group_by_xor" may return an unexpected result on the
- CPU device. Modify the size of the work-group to ensure that the value
- of the right-most dimension is a multiple of "32".
- */
- x = sycl::fmax(x, dpct::permute_sub_group_by_xor(
- item_ct1.get_sub_group(), x, mask));
- }
- return x;
-}
-
-// Helper for vec loading aligned data
-template
-inline sycl::vec vec_aligned_load(const Tp* aligned_ptr) {
- return *reinterpret_cast*>(aligned_ptr);
-}
-
-// Helper for accessing pointers with no warnings
-template
-static __dpct_inline__ Tp* get_pointer(sycl::local_accessor acc) {
- return acc.template get_multi_ptr().get();
-}
-
-int64_t downsample_sycl_global_range(int64_t accumulate_block_num, int64_t block_size);
-
-template
-static void k_bin_bcast(const src0_t * src0, const src1_t * src1, dst_t * dst,
- int ne0, int ne1, int ne2, int ne3,
- int ne10, int ne11, int ne12, int ne13,
- /*int s0, */ int s1, int s2, int s3,
- /*int s00,*/ int s01, int s02, int s03,
- /*int s10,*/ int s11, int s12, int s13,
- const sycl::nd_item<3> &item_ct1) {
- const int i0s = item_ct1.get_local_range(2) * item_ct1.get_group(2) +
- item_ct1.get_local_id(2);
- const int i1 = (item_ct1.get_local_range(1) * item_ct1.get_group(1) +
- item_ct1.get_local_id(1));
- const int i2 = (item_ct1.get_local_range(0) * item_ct1.get_group(0) +
- item_ct1.get_local_id(0)) /
- ne3;
- const int i3 = (item_ct1.get_local_range(0) * item_ct1.get_group(0) +
- item_ct1.get_local_id(0)) %
- ne3;
-
- if (i0s >= ne0 || i1 >= ne1 || i2 >= ne2 || i3 >= ne3) {
- return;
- }
-
- const int i11 = i1 % ne11;
- const int i12 = i2 % ne12;
- const int i13 = i3 % ne13;
-
- const size_t i_src0 = i3*s03 + i2*s02 + i1*s01;
- const size_t i_src1 = i13*s13 + i12*s12 + i11*s11;
- const size_t i_dst = i3*s3 + i2*s2 + i1*s1;
-
- const src0_t * src0_row = src0 + i_src0;
- const src1_t * src1_row = src1 + i_src1;
- dst_t * dst_row = dst + i_dst;
-
- for (int i0 = i0s; i0 < ne0;
- i0 += item_ct1.get_local_range(2) * item_ct1.get_group_range(2)) {
- const int i10 = i0 % ne10;
- dst_row[i0] = (dst_t)bin_op(src0 ? (float)src0_row[i0] : 0.0f, (float)src1_row[i10]);
- }
-}
-
-template
-static void k_bin_bcast_unravel(const src0_t * src0, const src1_t * src1, dst_t * dst,
- int ne0, int ne1, int ne2, int ne3,
- int ne10, int ne11, int ne12, int ne13,
- /*int s0, */ int s1, int s2, int s3,
- /*int s00,*/ int s01, int s02, int s03,
- /*int s10,*/ int s11, int s12, int s13,
- const sycl::nd_item<3> &item_ct1) {
-
- const int i = item_ct1.get_local_range(2) * item_ct1.get_group(2) +
- item_ct1.get_local_id(2);
-
- const int i3 = i/(ne2*ne1*ne0);
- const int i2 = (i/(ne1*ne0)) % ne2;
- const int i1 = (i/ne0) % ne1;
- const int i0 = i % ne0;
-
- if (i0 >= ne0 || i1 >= ne1 || i2 >= ne2 || i3 >= ne3) {
- return;
- }
-
- const int i11 = i1 % ne11;
- const int i12 = i2 % ne12;
- const int i13 = i3 % ne13;
-
- const size_t i_src0 = i3*s03 + i2*s02 + i1*s01;
- const size_t i_src1 = i13*s13 + i12*s12 + i11*s11;
- const size_t i_dst = i3*s3 + i2*s2 + i1*s1;
-
- const src0_t * src0_row = src0 + i_src0;
- const src1_t * src1_row = src1 + i_src1;
- dst_t * dst_row = dst + i_dst;
-
- const int i10 = i0 % ne10;
- dst_row[i0] = (dst_t)bin_op(src0 ? (float)src0_row[i0] : 0.0f, (float)src1_row[i10]);
-}
-
-
-template
-struct bin_bcast_sycl {
- template
- void operator()(ggml_backend_sycl_context & ctx,
- const struct ggml_tensor *src0,
- const struct ggml_tensor *src1, struct ggml_tensor *dst,
- const src0_t *src0_dd, const src1_t *src1_dd, dst_t *dst_dd,
- queue_ptr stream) {
-
- GGML_TENSOR_BINARY_OP_LOCALS
-
- int nr0 = ne10/ne0;
- int nr1 = ne11/ne1;
- int nr2 = ne12/ne2;
- int nr3 = ne13/ne3;
-
- int nr[4] = { nr0, nr1, nr2, nr3 };
-
- // collapse dimensions until first broadcast dimension
- int64_t cne[] = {ne0, ne1, ne2, ne3};
- int64_t cne0[] = {ne00, ne01, ne02, ne03};
- int64_t cne1[] = {ne10, ne11, ne12, ne13};
- size_t cnb[] = {nb0, nb1, nb2, nb3};
- size_t cnb0[] = {nb00, nb01, nb02, nb03};
- size_t cnb1[] = {nb10, nb11, nb12, nb13};
- auto collapse = [](int64_t cne[]) {
- cne[0] *= cne[1];
- cne[1] = cne[2];
- cne[2] = cne[3];
- cne[3] = 1;
- };
-
- auto collapse_nb = [](size_t cnb[], int64_t cne[]) {
- cnb[1] *= cne[1];
- cnb[2] *= cne[2];
- cnb[3] *= cne[3];
- };
-
- if (ggml_is_contiguous(src0) && ggml_is_contiguous(src1) && ggml_is_contiguous(dst)) {
- for (int i = 0; i < 4; i++) {
- if (nr[i] != 1) {
- break;
- }
- if (i > 0) {
- collapse_nb(cnb, cne);
- collapse_nb(cnb0, cne0);
- collapse_nb(cnb1, cne1);
- collapse(cne);
- collapse(cne0);
- collapse(cne1);
- }
- }
- }
- {
- int64_t ne0 = cne[0];
- int64_t ne1 = cne[1];
- int64_t ne2 = cne[2];
- int64_t ne3 = cne[3];
-
- int64_t ne10 = cne1[0];
- int64_t ne11 = cne1[1];
- int64_t ne12 = cne1[2];
- int64_t ne13 = cne1[3];
-
- size_t nb0 = cnb[0];
- size_t nb1 = cnb[1];
- size_t nb2 = cnb[2];
- size_t nb3 = cnb[3];
-
- size_t nb00 = cnb0[0];
- size_t nb01 = cnb0[1];
- size_t nb02 = cnb0[2];
- size_t nb03 = cnb0[3];
-
- size_t nb10 = cnb1[0];
- size_t nb11 = cnb1[1];
- size_t nb12 = cnb1[2];
- size_t nb13 = cnb1[3];
-
- size_t s0 = nb0 / sizeof(dst_t);
- size_t s1 = nb1 / sizeof(dst_t);
- size_t s2 = nb2 / sizeof(dst_t);
- size_t s3 = nb3 / sizeof(dst_t);
-
- size_t s10 = nb10 / sizeof(src1_t);
- size_t s11 = nb11 / sizeof(src1_t);
- size_t s12 = nb12 / sizeof(src1_t);
- size_t s13 = nb13 / sizeof(src1_t);
-
- size_t s00 = nb00 / sizeof(src0_t);
- size_t s01 = nb01 / sizeof(src0_t);
- size_t s02 = nb02 / sizeof(src0_t);
- size_t s03 = nb03 / sizeof(src0_t);
-
- GGML_UNUSED(s00);
-
- GGML_ASSERT(nb0 % sizeof(dst_t) == 0);
- GGML_ASSERT(nb1 % sizeof(dst_t) == 0);
- GGML_ASSERT(nb2 % sizeof(dst_t) == 0);
- GGML_ASSERT(nb3 % sizeof(dst_t) == 0);
-
- GGML_ASSERT(nb00 % sizeof(src0_t) == 0);
- GGML_ASSERT(nb01 % sizeof(src0_t) == 0);
- GGML_ASSERT(nb02 % sizeof(src0_t) == 0);
- GGML_ASSERT(nb03 % sizeof(src0_t) == 0);
-
- GGML_ASSERT(nb10 % sizeof(src1_t) == 0);
- GGML_ASSERT(nb11 % sizeof(src1_t) == 0);
- GGML_ASSERT(nb12 % sizeof(src1_t) == 0);
- GGML_ASSERT(nb13 % sizeof(src1_t) == 0);
-
- GGML_ASSERT(s0 == 1);
- GGML_ASSERT(s10 == 1);
-
- const int block_size = 128;
-
- int64_t hne0 = std::max(ne0/2LL, 1LL);
-
- sycl::range<3> block_dims(1, 1, 1);
- block_dims[2] = std::min(hne0, block_size);
- block_dims[1] = std::min(
- ne1, block_size / (unsigned int)block_dims[2]);
- block_dims[0] = std::min(
- std::min(
- ne2 * ne3, block_size / (unsigned int)block_dims[2] /
- (unsigned int)block_dims[1]),
- 64U);
-
- sycl::range<3> block_nums(
- (ne2 * ne3 + block_dims[0] - 1) / block_dims[0],
- (ne1 + block_dims[1] - 1) / block_dims[1],
- (hne0 + block_dims[2] - 1) / block_dims[2]);
-
- if (block_nums[0] > 65535) {
- // this is the maximum number of blocks in z direction, fallback to 1D grid kernel
- int block_num = (ne0*ne1*ne2*ne3 + block_size - 1) / block_size;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, block_num) *
- sycl::range<3>(1, 1, block_size),
- sycl::range<3>(1, 1, block_size)),
- [=](sycl::nd_item<3> item_ct1) {
- k_bin_bcast_unravel(
- src0_dd, src1_dd, dst_dd, ne0, ne1, ne2, ne3,
- ne10, ne11, ne12, ne13, s1, s2, s3, s01, s02,
- s03, s11, s12, s13, item_ct1);
- });
- }
- } else {
- /*
- DPCT1049:16: The work-group size passed to the SYCL kernel may
- exceed the limit. To get the device limit, query
- info::device::max_work_group_size. Adjust the work-group size if
- needed.
- */
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) {
- k_bin_bcast(src0_dd, src1_dd, dst_dd, ne0, ne1,
- ne2, ne3, ne10, ne11, ne12, ne13,
- s1, s2, s3, s01, s02, s03, s11, s12, s13,
- item_ct1);
- });
- }
- }
- GGML_UNUSED(ctx);
- }
-};
-
-template
-inline void ggml_sycl_op_bin_bcast(ggml_backend_sycl_context & ctx, const ggml_tensor *src0,
- const ggml_tensor *src1, ggml_tensor *dst) {
- dpct::queue_ptr main_stream = ctx.stream();
-
- if (src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F32) {
- op()(ctx, src0, src1, dst, (const float *)src0->data, (const float *)src1->data, (float *)dst->data, main_stream);
- } else if (src0->type == GGML_TYPE_F16 && dst->type == GGML_TYPE_F16) {
- op()(ctx, src0, src1, dst, (const sycl::half *)src0->data, (const float *)src1->data,
- (sycl::half *)dst->data, main_stream);
- } else if (src0->type == GGML_TYPE_F16 && dst->type == GGML_TYPE_F32) {
- op()(ctx, src0, src1, dst, (const sycl::half *)src0->data, (const float *)src1->data, (float *)dst->data,
- main_stream);
- } else if (src0->type == GGML_TYPE_I32 && dst->type == GGML_TYPE_I32) {
- op()(ctx, src0, src1, dst, (const int32_t *)src0->data, (const int32_t *)src1->data, (int32_t *)dst->data,
- main_stream);
- } else if (src0->type == GGML_TYPE_I16 && dst->type == GGML_TYPE_I16) {
- op()(ctx, src0, src1, dst, (const int16_t *)src0->data, (const int16_t *)src1->data, (int16_t *)dst->data,
- main_stream);
- } else {
- fprintf(stderr, "%s: unsupported types: dst: %s, src0: %s, src1: %s\n", __func__,
- ggml_type_name(dst->type), ggml_type_name(src0->type), ggml_type_name(src1->type));
- GGML_ABORT("fatal error");
- }
-}
-
-bool gpu_has_xmx(sycl::device &dev);
-#endif // GGML_SYCL_COMMON_HPP
diff --git a/ggml/src/ggml-sycl/concat.cpp b/ggml/src/ggml-sycl/concat.cpp
deleted file mode 100644
index d41cfd3a6..000000000
--- a/ggml/src/ggml-sycl/concat.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#include "concat.hpp"
-#include "common.hpp"
-
-static void concat_f32_dim0(const float *x, const float *y, float *dst,
- const int ne0, const int ne00,
- const sycl::nd_item<3> &item_ct1) {
- int nidx = item_ct1.get_local_id(2) +
- item_ct1.get_group(2) * item_ct1.get_local_range(2);
- if (nidx >= ne0) {
- return;
- }
- // operation
- int offset_dst = nidx + item_ct1.get_group(1) * ne0 +
- item_ct1.get_group(0) * ne0 * item_ct1.get_group_range(1);
- if (nidx < ne00) { // src0
- int offset_src = nidx + item_ct1.get_group(1) * ne00 +
- item_ct1.get_group(0) * ne00 * item_ct1.get_group_range(1);
- dst[offset_dst] = x[offset_src];
- } else {
- int offset_src =
- nidx - ne00 + item_ct1.get_group(1) * (ne0 - ne00) +
- item_ct1.get_group(0) * (ne0 - ne00) * item_ct1.get_group_range(1);
- dst[offset_dst] = y[offset_src];
- }
-}
-
-static void concat_f32_dim1(const float *x, const float *y, float *dst,
- const int ne0, const int ne01,
- const sycl::nd_item<3> &item_ct1) {
- int nidx = item_ct1.get_local_id(2) +
- item_ct1.get_group(2) * item_ct1.get_local_range(2);
- if (nidx >= ne0) {
- return;
- }
- // operation
- int offset_dst = nidx + item_ct1.get_group(1) * ne0 +
- item_ct1.get_group(0) * ne0 * item_ct1.get_group_range(1);
- if (item_ct1.get_group(1) < (size_t) ne01) { // src0
- int offset_src =
- nidx + item_ct1.get_group(1) * ne0 + item_ct1.get_group(0) * ne0 * ne01;
- dst[offset_dst] = x[offset_src];
- } else {
- int offset_src =
- nidx + (item_ct1.get_group(1) - ne01) * ne0 +
- item_ct1.get_group(0) * ne0 * (item_ct1.get_group_range(1) - ne01);
- dst[offset_dst] = y[offset_src];
- }
-}
-
-static void concat_f32_dim2(const float *x, const float *y, float *dst,
- const int ne0, const int ne02,
- const sycl::nd_item<3> &item_ct1) {
- int nidx = item_ct1.get_local_id(2) +
- item_ct1.get_group(2) * item_ct1.get_local_range(2);
- if (nidx >= ne0) {
- return;
- }
- // operation
- int offset_dst = nidx + item_ct1.get_group(1) * ne0 +
- item_ct1.get_group(0) * ne0 * item_ct1.get_group_range(1);
- if (item_ct1.get_group(0) < (size_t) ne02) { // src0
- int offset_src = nidx + item_ct1.get_group(1) * ne0 +
- item_ct1.get_group(0) * ne0 * item_ct1.get_group_range(1);
- dst[offset_dst] = x[offset_src];
- } else {
- int offset_src =
- nidx + item_ct1.get_group(1) * ne0 +
- (item_ct1.get_group(0) - ne02) * ne0 * item_ct1.get_group_range(1);
- dst[offset_dst] = y[offset_src];
- }
-}
-
-static void concat_f32_sycl(const float *x, const float *y, float *dst,
- int ne00, int ne01, int ne02, int ne0, int ne1,
- int ne2, int dim, queue_ptr stream) {
- int num_blocks = (ne0 + SYCL_CONCAT_BLOCK_SIZE - 1) / SYCL_CONCAT_BLOCK_SIZE;
- sycl::range<3> gridDim(ne2, ne1, num_blocks);
- switch (dim) {
- case 0:
- stream->parallel_for(
- sycl::nd_range<3>(gridDim *
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- concat_f32_dim0(x, y, dst, ne0, ne00, item_ct1);
- });
- break;
- case 1:
- stream->parallel_for(
- sycl::nd_range<3>(gridDim *
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- concat_f32_dim1(x, y, dst, ne0, ne01, item_ct1);
- });
- break;
- // dim >=2 will be dispatched to the default path
- default:
- stream->parallel_for(
- sycl::nd_range<3>(gridDim *
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CONCAT_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- concat_f32_dim2(x, y, dst, ne0, ne02, item_ct1);
- });
- break;
- }
-}
-
-// non-contiguous kernel (slow)
-static void concat_f32_sycl_non_cont(
- queue_ptr stream, const char *src0, const char *src1, char *dst,
- int64_t ne00, int64_t ne01, int64_t ne02, int64_t ne03, uint64_t nb00,
- uint64_t nb01, uint64_t nb02, uint64_t nb03, int64_t /*ne10*/,
- int64_t /*ne11*/, int64_t /*ne12*/, int64_t /*ne13*/, uint64_t nb10,
- uint64_t nb11, uint64_t nb12, uint64_t nb13, int64_t ne0, int64_t ne1,
- int64_t ne2, int64_t ne3, uint64_t nb0, uint64_t nb1, uint64_t nb2,
- uint64_t nb3, int32_t dim) {
- sycl::range<3> gridDim(ne3, ne2, ne1);
- stream->parallel_for(
- sycl::nd_range<3>(gridDim, sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- int64_t i3 = item_ct1.get_group(0);
- int64_t i2 = item_ct1.get_group(1);
- int64_t i1 = item_ct1.get_group(2);
-
- int64_t o[4] = {0, 0, 0, 0};
- o[dim] = dim == 0 ? ne00 : (dim == 1 ? ne01 : (dim == 2 ? ne02 : ne03));
-
- const float *x;
-
- for (int i0 = item_ct1.get_local_id(2); i0 < ne0;
- i0 += item_ct1.get_local_range(2)) {
- if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
- x = (const float *)(src0 + (i3)*nb03 + (i2)*nb02 + (i1)*nb01 +
- (i0)*nb00);
- } else {
- x = (const float *)(src1 + (i3 - o[3]) * nb13 + (i2 - o[2]) * nb12 +
- (i1 - o[1]) * nb11 + (i0 - o[0]) * nb10);
- }
-
- float *y = (float *)(dst + i3 * nb3 + i2 * nb2 + i1 * nb1 + i0 * nb0);
-
- *y = *x;
- }
- });
-}
-
-void ggml_sycl_op_concat(ggml_backend_sycl_context & ctx, ggml_tensor *dst) {
- const ggml_tensor *src0 = dst->src[0];
- const ggml_tensor *src1 = dst->src[1];
- queue_ptr stream = ctx.stream();
-
- const int32_t dim = ((int32_t *)dst->op_params)[0];
-
- if (ggml_is_contiguous(src0) && ggml_is_contiguous(src1)) {
- const float *src0_d = (const float *)src0->data;
- const float *src1_d = (const float *)src1->data;
-
- float *dst_d = (float *)dst->data;
-
- if (dim != 3) {
- for (int i3 = 0; i3 < dst->ne[3]; i3++) {
- concat_f32_sycl(
- src0_d + i3 * (src0->nb[3] / 4), src1_d + i3 * (src1->nb[3] / 4),
- dst_d + i3 * (dst->nb[3] / 4), src0->ne[0], src0->ne[1],
- src0->ne[2], dst->ne[0], dst->ne[1], dst->ne[2], dim, stream);
- }
- } else {
- const size_t size0 = ggml_nbytes(src0);
- const size_t size1 = ggml_nbytes(src1);
-
- SYCL_CHECK(CHECK_TRY_ERROR(stream->memcpy(dst_d, src0_d, size0).wait()));
- SYCL_CHECK(CHECK_TRY_ERROR(
- stream->memcpy(dst_d + size0 / 4, src1_d, size1).wait()));
- }
- } else
- concat_f32_sycl_non_cont(
- stream, (const char *)src0->data, (const char *)src1->data,
- (char *)dst->data, src0->ne[0], src0->ne[1], src0->ne[2], src0->ne[3],
- src0->nb[0], src0->nb[1], src0->nb[2], src0->nb[3], src1->ne[0],
- src1->ne[1], src1->ne[2], src1->ne[3], src1->nb[0], src1->nb[1],
- src1->nb[2], src1->nb[3], dst->ne[0], dst->ne[1], dst->ne[2],
- dst->ne[3], dst->nb[0], dst->nb[1], dst->nb[2], dst->nb[3], dim);
-}
diff --git a/ggml/src/ggml-sycl/concat.hpp b/ggml/src/ggml-sycl/concat.hpp
deleted file mode 100644
index e5cb7314c..000000000
--- a/ggml/src/ggml-sycl/concat.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_CONCAT_HPP
-#define GGML_SYCL_CONCAT_HPP
-
-#include "common.hpp"
-
-void ggml_sycl_op_concat(ggml_backend_sycl_context & ctx, ggml_tensor *dst);
-
-#endif // GGML_SYCL_CONCAT_HPP
diff --git a/ggml/src/ggml-sycl/conv.cpp b/ggml/src/ggml-sycl/conv.cpp
deleted file mode 100644
index ddba601e1..000000000
--- a/ggml/src/ggml-sycl/conv.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#include "conv.hpp"
-
-static void conv_transpose_1d_kernel(
- const int s0, const int output_size,
- const int src0_ne0, const int src0_ne1, const int src0_ne2,
- const int src1_ne0, const int dst_ne0,
- const float * src0, const float * src1, float * dst,
- const sycl::nd_item<3> &item_ct1) {
- int global_index = item_ct1.get_local_id(2) +
- item_ct1.get_group(2) * item_ct1.get_local_range(2);
- if (global_index >= output_size) {
- return;
- }
-
- int out_index = global_index / dst_ne0;
-
- float accumulator = 0;
-
- for (int c = 0; c < src0_ne2; c++) {
- int idx = global_index % dst_ne0;
-
- int kernel_offset = (src0_ne0 * src0_ne1 * c) + (out_index * src0_ne0);
- int input_offset = src1_ne0 * c;
-
- for (int i = 0; i < src1_ne0; i++) {
- if (!(idx >= i*s0 && idx < i*s0 + src0_ne0)) {
- continue;
- }
- int weight_idx = idx - i*s0;
-
- float kernel_weight = src0[kernel_offset + weight_idx];
- float input_value = src1[input_offset+i];
-
- accumulator += kernel_weight * input_value;
- }
- }
- dst[global_index] = accumulator;
-}
-
-static void conv_transpose_1d_f32_f32_sycl(
- const int s0, const int output_size,
- const int src0_ne0, const int src0_ne1, const int src0_ne2,
- const int src1_ne0, const int dst_ne0,
- const float *src0, const float *src1, float *dst,
- const queue_ptr& stream) {
-
- const int num_blocks = (output_size + SYCL_CONV_TRANPOSE_1D_BLOCK_SIZE - 1) / SYCL_CONV_TRANPOSE_1D_BLOCK_SIZE;
- const sycl::range<3> block_dims(1, 1, SYCL_CONV_TRANPOSE_1D_BLOCK_SIZE);
- const sycl::range<3> block_nums(1, 1, num_blocks);
- stream->parallel_for(
- sycl::nd_range<3>(
- block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) {
- conv_transpose_1d_kernel(
- s0, output_size,
- src0_ne0, src0_ne1, src0_ne2,
- src1_ne0, dst_ne0,
- src0, src1, dst, item_ct1);
- });
-}
-
-void ggml_sycl_op_conv_transpose_1d(ggml_backend_sycl_context & ctx, ggml_tensor *dst) {
- const ggml_tensor *src0 = dst->src[0];
- const ggml_tensor *src1 = dst->src[1];
- const float * src0_d = (const float *)src0->data;
- const float * src1_d = (const float *)src1->data;
-
- float * dst_d = (float *)dst->data;
- dpct::queue_ptr stream = ctx.stream();
-
- GGML_ASSERT(src0->type == GGML_TYPE_F32);
- GGML_ASSERT( dst->type == GGML_TYPE_F32);
-
- GGML_ASSERT(ggml_is_contiguous(src0));
- GGML_ASSERT(ggml_is_contiguous(src1));
-
- const int32_t * opts = (const int32_t *)dst->op_params;
-
- const int s0 = opts[0];
-
- const int64_t output_size = ggml_nelements(dst);
-
- conv_transpose_1d_f32_f32_sycl(s0, output_size,
- src0->ne[0], src0->ne[1], src0->ne[2],
- src1->ne[0], dst->ne[0],
- src0_d, src1_d, dst_d, stream);
-}
-
diff --git a/ggml/src/ggml-sycl/conv.hpp b/ggml/src/ggml-sycl/conv.hpp
deleted file mode 100644
index f9e60dc75..000000000
--- a/ggml/src/ggml-sycl/conv.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_CONV_HPP
-#define GGML_SYCL_CONV_HPP
-
-#include "common.hpp"
-
-void ggml_sycl_op_conv_transpose_1d(ggml_backend_sycl_context & ctx, ggml_tensor *dst);
-
-#endif // GGML_SYCL_CONV_HPP
diff --git a/ggml/src/ggml-sycl/convert.cpp b/ggml/src/ggml-sycl/convert.cpp
deleted file mode 100644
index 76ac6a4dd..000000000
--- a/ggml/src/ggml-sycl/convert.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-#include "convert.hpp"
-#include "dequantize.hpp"
-#include "presets.hpp"
-
-template
-static void dequantize_block(const void * __restrict__ vx, dst_t * __restrict__ y, const int64_t k,
- const sycl::nd_item<3> &item_ct1) {
- const int64_t i = 2 * (item_ct1.get_local_range(2) * item_ct1.get_group(2) +
- item_ct1.get_local_id(2));
-
- if (i >= k) {
- return;
- }
-
- const int64_t ib = i/qk; // block index
- const int64_t iqs = (i%qk)/qr; // quant index
- const int64_t iybs = i - i%qk; // y block start index
- const int64_t y_offset = qr == 1 ? 1 : qk/2;
-
- // dequantize
- dfloat2 v;
- dequantize_kernel(vx, ib, iqs, v);
-
- y[iybs + iqs + 0] = v.x();
- y[iybs + iqs + y_offset] = v.y();
-}
-
-template
-static void dequantize_block_sycl(const void *__restrict__ vx,
- dst_t *__restrict__ y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t num_blocks = (k + 2*SYCL_DEQUANTIZE_BLOCK_SIZE - 1) / (2*SYCL_DEQUANTIZE_BLOCK_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
- stream->parallel_for(
- sycl::nd_range<3>(
- sycl::range<3>(1, 1, num_blocks) *
- sycl::range<3>(1, 1, SYCL_DEQUANTIZE_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_DEQUANTIZE_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block(vx, y, k, item_ct1);
- });
- }
-}
-
-template
-static void dequantize_row_q2_K_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
-#if QK_K == 256
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 64),
- sycl::range<3>(1, 1, 64)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q2_K(vx, y, item_ct1);
- });
- }
-#else
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q2_K(vx, y, item_ct1);
- });
- }
-
-#endif
-}
-
-template
-static void dequantize_row_q3_K_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
-#if QK_K == 256
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 64),
- sycl::range<3>(1, 1, 64)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q3_K(vx, y, item_ct1);
- });
- }
-#else
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q3_K(vx, y, item_ct1);
- });
- }
-#endif
-}
-
-template
-static void dequantize_row_q4_0_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb32 = k / 32;
- const int64_t nb = (k + 255) / 256;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q4_0(vx, y, nb32, item_ct1);
- });
- }
-}
-
-template
-static void dequantize_row_q4_0_sycl_reorder(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
-
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- int constexpr WARP_K = WARP_SIZE * QK4_0;
- const int n_warp = (k + WARP_K - 1) / WARP_K;
- GGML_ASSERT(k % 2 == 0);
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, n_warp) *
- sycl::range<3>(1, 1, WARP_SIZE),
- sycl::range<3>(1, 1, WARP_SIZE)),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]]{
- dequantize_block_q4_0_reorder(vx, y, k, item_ct1);
- });
-
-}
-
-template
-static void dequantize_row_q4_1_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb32 = k / 32;
- const int64_t nb = (k + 255) / 256;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q4_1(vx, y, nb32, item_ct1);
- });
- }
-}
-
-
-template
-static void dequantize_row_q4_K_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- sycl::local_accessor scale_local_acc(sycl::range<1>(12), cgh);
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q4_K(vx, y, get_pointer(scale_local_acc), item_ct1);
- });
- });
- }
-}
-
-template
-static void dequantize_row_q5_K_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
-#if QK_K == 256
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 64),
- sycl::range<3>(1, 1, 64)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q5_K(vx, y, item_ct1);
- });
- }
-#else
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q5_K(vx, y, item_ct1);
- });
- }
-
-#endif
-}
-
-template
-static void dequantize_row_q6_K_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
-#if QK_K == 256
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 64),
- sycl::range<3>(1, 1, 64)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q6_K(vx, y, item_ct1);
- });
- }
-#else
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_q6_K(vx, y, item_ct1);
- });
- }
-
-#endif
-}
-
-template
-static void dequantize_row_iq1_s_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq1_s(
- vx, y, item_ct1, iq1s_grid_gpu
- );
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq1_m_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq1_m(
- vx, y, item_ct1, iq1s_grid_gpu
- );
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq2_xxs_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq2_xxs(
- vx, y, item_ct1, iq2xxs_grid,
- ksigns_iq2xs, kmask_iq2xs);
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq2_xs_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq2_xs(
- vx, y, item_ct1, iq2xs_grid,
- ksigns_iq2xs, kmask_iq2xs);
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq2_s_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq2_s(vx, y, item_ct1);
- });
- });
- }
-}
-
-
-template
-static void dequantize_row_iq3_xxs_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq3_xxs(
- vx, y, item_ct1, iq3xxs_grid,
- ksigns_iq2xs, kmask_iq2xs);
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq3_s_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = k / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq3_s(
- vx, y, item_ct1, kmask_iq2xs, iq3s_grid);
- });
- });
- }
-}
-
-template
-static void dequantize_row_iq4_xs_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = (k + QK_K - 1) / QK_K;
-#if QK_K == 64
- dequantize_row_iq4_nl_sycl(vx, y, k, stream);
-#else
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq4_xs(vx, y, item_ct1);
- });
- });
- }
-#endif
-}
-
-template
-static void dequantize_row_iq4_nl_sycl(const void *vx, dst_t *y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t nb = (k + QK_K - 1) / QK_K;
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->submit([&](sycl::handler &cgh) {
- cgh.parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, nb) *
- sycl::range<3>(1, 1, 32),
- sycl::range<3>(1, 1, 32)),
- [=](sycl::nd_item<3> item_ct1) {
- dequantize_block_iq4_nl(vx, y, item_ct1);
- });
- });
- }
-}
-
-template
-static void convert_unary(const void * __restrict__ vx, dst_t * __restrict__ y, const int64_t k,
- const sycl::nd_item<3> &item_ct1) {
- const int64_t work_group_size = item_ct1.get_local_range(2);
- const int64_t global_id = item_ct1.get_local_id(2) + work_group_size * item_ct1.get_group(2);
-
- // make each work-item deal with more elements since sycl global range can not exceed max int
- const src_t * x = (const src_t *) vx;
- for (int64_t i = global_id; i < k; i += work_group_size * item_ct1.get_group_range(2)) {
- y[i] = x[i];
- }
-}
-
-template
-static void convert_unary_sycl(const void *__restrict__ vx,
- dst_t *__restrict__ y, const int64_t k,
- dpct::queue_ptr stream) {
- const int64_t num_blocks = (k + SYCL_DEQUANTIZE_BLOCK_SIZE - 1) / SYCL_DEQUANTIZE_BLOCK_SIZE;
-
- // decrease global range when it exceeds the max int
- int64_t local_size = downsample_sycl_global_range(num_blocks, SYCL_DEQUANTIZE_BLOCK_SIZE);
- sycl::range<3> block_nums(1, 1, num_blocks);
- sycl::range<3> local_range(1, 1, local_size);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * local_range, local_range),
- [=](sycl::nd_item<3> item_ct1) {
- convert_unary(vx, y, k, item_ct1);
- });
- }
-}
-
-to_fp16_sycl_t ggml_get_to_fp16_sycl(ggml_type type, ggml_tensor *dst) {
- switch (type) {
- case GGML_TYPE_Q4_0:
- if (dst->src[0]->extra &&
- ((ggml_tensor_extra_gpu*)dst->src[0]->extra)->optimized_feature.reorder) {
- return dequantize_row_q4_0_sycl_reorder;
- } else {
- return dequantize_block_sycl;
- }
- case GGML_TYPE_Q4_1:
- return dequantize_block_sycl;
- case GGML_TYPE_Q5_0:
- return dequantize_block_sycl;
- case GGML_TYPE_Q5_1:
- return dequantize_block_sycl;
- case GGML_TYPE_Q8_0:
- return dequantize_block_sycl;
- case GGML_TYPE_Q2_K:
- return dequantize_row_q2_K_sycl;
- case GGML_TYPE_Q3_K:
- return dequantize_row_q3_K_sycl;
- case GGML_TYPE_Q4_K:
- return dequantize_row_q4_K_sycl;
- case GGML_TYPE_Q5_K:
- return dequantize_row_q5_K_sycl;
- case GGML_TYPE_Q6_K:
- return dequantize_row_q6_K_sycl;
- case GGML_TYPE_IQ1_S:
- return dequantize_row_iq1_s_sycl;
- case GGML_TYPE_IQ1_M:
- return dequantize_row_iq1_m_sycl;
- case GGML_TYPE_IQ2_XXS:
- return dequantize_row_iq2_xxs_sycl;
- case GGML_TYPE_IQ2_XS:
- return dequantize_row_iq2_xs_sycl;
- case GGML_TYPE_IQ2_S:
- return dequantize_row_iq2_s_sycl;
- case GGML_TYPE_IQ3_XXS:
- return dequantize_row_iq3_xxs_sycl;
- case GGML_TYPE_IQ3_S:
- return dequantize_row_iq3_s_sycl;
- case GGML_TYPE_IQ4_XS:
- return dequantize_row_iq4_xs_sycl;
- case GGML_TYPE_IQ4_NL:
- return dequantize_row_iq4_nl_sycl;
- case GGML_TYPE_F32:
- return convert_unary_sycl;
- default:
- return nullptr;
- }
-}
-
-to_fp32_sycl_t ggml_get_to_fp32_sycl(ggml_type type, ggml_tensor *dst) {
- switch (type) {
- case GGML_TYPE_Q4_0:
- if (dst->src[0]->extra &&
- ((ggml_tensor_extra_gpu*)dst->src[0]->extra)->optimized_feature.reorder) {
- return dequantize_row_q4_0_sycl_reorder;
- } else {
- return dequantize_row_q4_0_sycl;
- }
- case GGML_TYPE_Q4_1:
- return dequantize_row_q4_1_sycl;
- case GGML_TYPE_Q5_0:
- return dequantize_block_sycl;
- case GGML_TYPE_Q5_1:
- return dequantize_block_sycl;
- case GGML_TYPE_Q8_0:
- return dequantize_block_sycl;
- case GGML_TYPE_Q2_K:
- return dequantize_row_q2_K_sycl;
- case GGML_TYPE_Q3_K:
- return dequantize_row_q3_K_sycl;
- case GGML_TYPE_Q4_K:
- return dequantize_row_q4_K_sycl;
- case GGML_TYPE_Q5_K:
- return dequantize_row_q5_K_sycl;
- case GGML_TYPE_Q6_K:
- return dequantize_row_q6_K_sycl;
- case GGML_TYPE_IQ1_S:
- return dequantize_row_iq1_s_sycl;
- case GGML_TYPE_IQ1_M:
- return dequantize_row_iq1_m_sycl;
- case GGML_TYPE_IQ2_XXS:
- return dequantize_row_iq2_xxs_sycl;
- case GGML_TYPE_IQ2_XS:
- return dequantize_row_iq2_xs_sycl;
- case GGML_TYPE_IQ2_S:
- return dequantize_row_iq2_s_sycl;
- case GGML_TYPE_IQ3_XXS:
- return dequantize_row_iq3_xxs_sycl;
- case GGML_TYPE_IQ3_S:
- return dequantize_row_iq3_s_sycl;
- case GGML_TYPE_IQ4_XS:
- return dequantize_row_iq4_xs_sycl;
- case GGML_TYPE_IQ4_NL:
- return dequantize_row_iq4_nl_sycl;
- case GGML_TYPE_F16:
- return convert_unary_sycl;
- default:
- return nullptr;
- }
-}
diff --git a/ggml/src/ggml-sycl/convert.hpp b/ggml/src/ggml-sycl/convert.hpp
deleted file mode 100644
index 355dae22b..000000000
--- a/ggml/src/ggml-sycl/convert.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_CONVERT_HPP
-#define GGML_SYCL_CONVERT_HPP
-
-#include "common.hpp"
-
-template
-using to_t_sycl_t = void (*)(const void *__restrict__ x, T *__restrict__ y,
- int64_t k, dpct::queue_ptr stream);
-typedef to_t_sycl_t to_fp32_sycl_t;
-typedef to_t_sycl_t to_fp16_sycl_t;
-
-to_fp16_sycl_t ggml_get_to_fp16_sycl(ggml_type type, ggml_tensor *dst);
-to_fp32_sycl_t ggml_get_to_fp32_sycl(ggml_type type, ggml_tensor *dst);
-
-#endif // GGML_SYCL_CONVERT_HPP
diff --git a/ggml/src/ggml-sycl/cpy.cpp b/ggml/src/ggml-sycl/cpy.cpp
deleted file mode 100644
index 5a2314589..000000000
--- a/ggml/src/ggml-sycl/cpy.cpp
+++ /dev/null
@@ -1,701 +0,0 @@
-#include "cpy.hpp"
-
-#include
-
-#include "dequantize.hpp"
-
-static __dpct_inline__ int best_index_int8(int n, const int8_t * val, float x) {
- if (x <= val[0]) {
- return 0;
- }
- if (x >= val[n - 1]) {
- return n - 1;
- }
- int ml = 0, mu = n - 1;
- while (mu - ml > 1) {
- int mav = (ml + mu) / 2;
- if (x < val[mav]) {
- mu = mav;
- } else {
- ml = mav;
- }
- }
- return x - val[mu - 1] < val[mu] - x ? mu - 1 : mu;
-}
-
-static void cpy_1_f32_f32(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- float * dsti = (float *) cdsti;
-
- *dsti = *xi;
-}
-
-static void cpy_1_f32_f16(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- sycl::half * dsti = (sycl::half *) cdsti;
-
- *dsti = sycl::vec(*xi).convert()[0];
-}
-
-static void cpy_1_f16_f16(const char * cxi, char * cdsti) {
- const sycl::half * xi = (const sycl::half *) cxi;
- sycl::half * dsti = (sycl::half *) cdsti;
-
- *dsti = *xi;
-}
-
-static void cpy_1_f16_f32(const char * cxi, char * cdsti) {
- const sycl::half * xi = (const sycl::half *) cxi;
- float * dsti = (float *) cdsti;
-
- *dsti = *xi;
-}
-
-static void cpy_1_i16_i16(const char * cxi, char * cdsti) {
- const int16_t * xi = (const int16_t *) cxi;
- int16_t * dsti = (int16_t *) cdsti;
-
- *dsti = *xi;
-}
-
-static void cpy_1_i32_i32(const char * cxi, char * cdsti) {
- const int32_t * xi = (const int32_t *) cxi;
- int32_t * dsti = (int32_t *) cdsti;
-
- *dsti = *xi;
-}
-
-template
-static void cpy_f32_f16(const char * cx, char * cdst, const int ne, const int ne00, const int ne01, const int ne02,
- const int nb00, const int nb01, const int nb02, const int nb03, const int ne10, const int ne11,
- const int ne12, const int nb10, const int nb11, const int nb12, const int nb13,
- const sycl::nd_item<3> & item_ct1) {
- const int i = item_ct1.get_local_range(2) * item_ct1.get_group(2) + item_ct1.get_local_id(2);
-
- if (i >= ne) {
- return;
- }
-
- // determine indices i02/i12, i01/i11, i00/i10 as a function of index i of flattened tensor
- // then combine those indices with the corresponding byte offsets to get the total offsets
- const int i03 = i / (ne00 * ne01 * ne02);
- const int i02 = (i - i03 * ne00 * ne01 * ne02) / (ne00 * ne01);
- const int i01 = (i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00) / ne00;
- const int i00 = i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00 - i01 * ne00;
- const int x_offset = i00 * nb00 + i01 * nb01 + i02 * nb02 + i03 * nb03;
-
- const int i13 = i / (ne10 * ne11 * ne12);
- const int i12 = (i - i13 * ne10 * ne11 * ne12) / (ne10 * ne11);
- const int i11 = (i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11) / ne10;
- const int i10 = i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11 - i11 * ne10;
- const int dst_offset = i10 * nb10 + i11 * nb11 + i12 * nb12 + i13 * nb13;
-
- cpy_1(cx + x_offset, cdst + dst_offset);
-}
-
-static void cpy_blck_f32_q8_0(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_q8_0 * dsti = (block_q8_0 *) cdsti;
-
- float amax = 0.0f; // absolute max
-
- for (int j = 0; j < QK8_0; j++) {
- const float v = xi[j];
- amax = sycl::fmax(amax, sycl::fabs((float) v));
- }
-
- const float d = amax / ((1 << 7) - 1);
- const float id = d ? 1.0f / d : 0.0f;
-
- dsti->d = d;
-
- for (int j = 0; j < QK8_0; ++j) {
- const float x0 = xi[j] * id;
-
- dsti->qs[j] = sycl::round((float) x0);
- }
-}
-
-static void cpy_blck_q8_0_f32(const char * cxi, char * cdsti) {
- float * cdstf = (float *) (cdsti);
-
- for (int j = 0; j < QK8_0; j += 2) {
- dfloat2 dq;
- dequantize_q8_0(cxi, 0, j, dq);
- *(cdstf + j) = dq.x();
- *(cdstf + j + 1) = dq.y();
- }
-}
-
-static void cpy_blck_f32_q4_0(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_q4_0 * dsti = (block_q4_0 *) cdsti;
-
- float amax = 0.0f;
- float vmax = 0.0f;
-
- for (int j = 0; j < QK4_0; ++j) {
- const float v = xi[j];
- if (amax < sycl::fabs((float) v)) {
- amax = sycl::fabs((float) v);
- vmax = v;
- }
- }
-
- const float d = vmax / -8;
- const float id = d ? 1.0f / d : 0.0f;
-
- dsti->d = d;
-
- for (int j = 0; j < QK4_0 / 2; ++j) {
- const float x0 = xi[0 + j] * id;
- const float x1 = xi[QK4_0 / 2 + j] * id;
-
- const uint8_t xi0 = dpct::min(15, (int8_t) (x0 + 8.5f));
- const uint8_t xi1 = dpct::min(15, (int8_t) (x1 + 8.5f));
-
- dsti->qs[j] = xi0;
- dsti->qs[j] |= xi1 << 4;
- }
-}
-
-static void cpy_blck_f32_q4_1(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_q4_1 * dsti = (block_q4_1 *) cdsti;
-
- float vmin = FLT_MAX;
- float vmax = -FLT_MAX;
-
- for (int j = 0; j < QK4_1; ++j) {
- const float v = xi[j];
-
- if (v < vmin) {
- vmin = v;
- }
- if (v > vmax) {
- vmax = v;
- }
- }
-
- const float d = (vmax - vmin) / ((1 << 4) - 1);
- const float id = d ? 1.0f / d : 0.0f;
-
- dsti->dm.x() = d;
- dsti->dm.y() = vmin;
-
- for (int j = 0; j < QK4_1 / 2; ++j) {
- const float x0 = (xi[0 + j] - vmin) * id;
- const float x1 = (xi[QK4_1 / 2 + j] - vmin) * id;
-
- const uint8_t xi0 = dpct::min(15, (int8_t) (x0 + 0.5f));
- const uint8_t xi1 = dpct::min(15, (int8_t) (x1 + 0.5f));
-
- dsti->qs[j] = xi0;
- dsti->qs[j] |= xi1 << 4;
- }
-}
-
-static void cpy_blck_f32_q5_0(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_q5_0 * dsti = (block_q5_0 *) cdsti;
-
- float amax = 0.0f;
- float vmax = 0.0f;
-
- for (int j = 0; j < QK5_0; ++j) {
- const float v = xi[j];
- if (amax < sycl::fabs((float) v)) {
- amax = sycl::fabs((float) v);
- vmax = v;
- }
- }
-
- const float d = vmax / -16;
- const float id = d ? 1.0f / d : 0.0f;
-
- dsti->d = d;
-
- uint32_t qh = 0;
- for (int j = 0; j < QK5_0 / 2; ++j) {
- const float x0 = xi[0 + j] * id;
- const float x1 = xi[QK5_0 / 2 + j] * id;
-
- const uint8_t xi0 = dpct::min(31, (int8_t) (x0 + 16.5f));
- const uint8_t xi1 = dpct::min(31, (int8_t) (x1 + 16.5f));
-
- dsti->qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
- qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
- qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_0 / 2);
- }
- memcpy(dsti->qh, &qh, sizeof(qh));
-}
-
-static void cpy_blck_f32_q5_1(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_q5_1 * dsti = (block_q5_1 *) cdsti;
-
- float min = xi[0];
- float max = xi[0];
-
- for (int j = 1; j < QK5_1; ++j) {
- const float v = xi[j];
- min = v < min ? v : min;
- max = v > max ? v : max;
- }
-
- const float d = (max - min) / 31;
- const float id = d ? 1.0f / d : 0.0f;
-
- dsti->dm.x() = d;
- dsti->dm.y() = min;
-
- uint32_t qh = 0;
- for (int j = 0; j < QK5_1 / 2; ++j) {
- const float x0 = (xi[0 + j] - min) * id;
- const float x1 = (xi[QK5_1 / 2 + j] - min) * id;
-
- const uint8_t xi0 = (uint8_t) (x0 + 0.5f);
- const uint8_t xi1 = (uint8_t) (x1 + 0.5f);
-
- dsti->qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
- qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
- qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_1 / 2);
- }
- memcpy(dsti->qh, &qh, sizeof(qh));
-}
-
-static void cpy_blck_f32_iq4_nl(const char * cxi, char * cdsti) {
- const float * xi = (const float *) cxi;
- block_iq4_nl * dsti = (block_iq4_nl *) cdsti;
-
- float amax = 0.0f;
- float vmax = 0.0f;
-
- for (int j = 0; j < QK4_NL; ++j) {
- const float v = xi[j];
- if (amax < sycl::fabs((float) v)) {
- amax = sycl::fabs((float) v);
- vmax = v;
- }
- }
-
- float d = vmax / kvalues_iq4nl[0];
- const float id = d ? 1.0f / d : 0.0f;
-
- float sumqx = 0, sumq2 = 0;
- for (int j = 0; j < QK4_NL / 2; ++j) {
- const float x0 = xi[0 + j] * id;
- const float x1 = xi[QK4_NL / 2 + j] * id;
- const uint8_t xi0 = best_index_int8(16, kvalues_iq4nl, x0);
- const uint8_t xi1 = best_index_int8(16, kvalues_iq4nl, x1);
- dsti->qs[j] = xi0 | (xi1 << 4);
- const float v0 = kvalues_iq4nl[xi0];
- const float v1 = kvalues_iq4nl[xi1];
- const float w0 = xi[0 + j] * xi[0 + j];
- const float w1 = xi[QK4_NL / 2 + j] * xi[QK4_NL / 2 + j];
- sumqx += w0 * v0 * xi[j] + w1 * v1 * xi[QK4_NL / 2 + j];
- sumq2 += w0 * v0 * v0 + w1 * v1 * v1;
- }
-
- dsti->d = sumq2 > 0 ? sumqx / sumq2 : d;
-}
-
-template static void cpy_blck_q_f32(const char * cxi, char * cdsti) {
- float * cdstf = (float *) (cdsti);
-
- for (int j = 0; j < qk / 2; j++) {
- dfloat2 dq;
- dequant(cxi, 0, j, dq);
- *(cdstf + j) = dq.x();
- *(cdstf + j + qk / 2) = dq.y();
- }
-}
-
-template
-static void cpy_f32_q(const char * cx, char * cdst, const int ne, const int ne00, const int ne01, const int ne02,
- const int nb00, const int nb01, const int nb02, const int nb03, const int ne10, const int ne11,
- const int ne12, const int nb10, const int nb11, const int nb12, const int nb13,
- const sycl::nd_item<3> & item_ct1) {
- const int i = (item_ct1.get_local_range(2) * item_ct1.get_group(2) + item_ct1.get_local_id(2)) * qk;
-
- if (i >= ne) {
- return;
- }
-
- const int i03 = i / (ne00 * ne01 * ne02);
- const int i02 = (i - i03 * ne00 * ne01 * ne02) / (ne00 * ne01);
- const int i01 = (i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00) / ne00;
- const int i00 = i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00 - i01 * ne00;
- const int x_offset = i00 * nb00 + i01 * nb01 + i02 * nb02 + i03 * nb03;
-
- const int i13 = i / (ne10 * ne11 * ne12);
- const int i12 = (i - i13 * ne10 * ne11 * ne12) / (ne10 * ne11);
- const int i11 = (i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11) / ne10;
- const int i10 = i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11 - i11 * ne10;
- const int dst_offset = (i10 / qk) * nb10 + i11 * nb11 + i12 * nb12 + i13 * nb13;
-
- cpy_blck(cx + x_offset, cdst + dst_offset);
-}
-
-template
-static void cpy_q_f32(const char * cx, char * cdst, const int ne, const int ne00, const int ne01, const int ne02,
- const int nb00, const int nb01, const int nb02, const int nb03, const int ne10, const int ne11,
- const int ne12, const int nb10, const int nb11, const int nb12, const int nb13,
- const sycl::nd_item<3> & item_ct1) {
- const int i = (item_ct1.get_local_range(2) * item_ct1.get_group(2) + item_ct1.get_local_id(2)) * qk;
-
- if (i >= ne) {
- return;
- }
-
- const int i03 = i / (ne00 * ne01 * ne02);
- const int i02 = (i - i03 * ne00 * ne01 * ne02) / (ne00 * ne01);
- const int i01 = (i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00) / ne00;
- const int i00 = i - i03 * ne00 * ne01 * ne02 - i02 * ne01 * ne00 - i01 * ne00;
- const int x_offset = (i00 / qk) * nb00 + i01 * nb01 + i02 * nb02 + i03 * nb03;
-
- const int i13 = i / (ne10 * ne11 * ne12);
- const int i12 = (i - i13 * ne10 * ne11 * ne12) / (ne10 * ne11);
- const int i11 = (i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11) / ne10;
- const int i10 = i - i13 * ne10 * ne11 * ne12 - i12 * ne10 * ne11 - i11 * ne10;
- const int dst_offset = i10 * nb10 + i11 * nb11 + i12 * nb12 + i13 * nb13;
-
- cpy_blck(cx + x_offset, cdst + dst_offset);
-}
-
-static void ggml_cpy_f16_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 });
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-static void ggml_cpy_f32_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 });
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-static void ggml_cpy_f32_f16_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 });
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-static void ggml_cpy_f32_q8_0_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK8_0 == 0);
- const int num_blocks = ne / QK8_0;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_q8_0_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = ne;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_q_f32(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_f32_q4_0_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK4_0 == 0);
- const int num_blocks = ne / QK4_0;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_q4_0_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = ne;
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)), [=](sycl::nd_item<3> item_ct1) {
- cpy_q_f32, QK4_0>(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02,
- nb03, ne10, ne11, ne12, nb10, nb11, nb12, nb13,
- item_ct1);
- });
-}
-
-static void ggml_cpy_f32_q4_1_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK4_1 == 0);
- const int num_blocks = ne / QK4_1;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_q4_1_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = ne;
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)), [=](sycl::nd_item<3> item_ct1) {
- cpy_q_f32, QK4_1>(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02,
- nb03, ne10, ne11, ne12, nb10, nb11, nb12, nb13,
- item_ct1);
- });
-}
-
-static void ggml_cpy_f32_q5_0_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK5_0 == 0);
- const int num_blocks = ne / QK5_0;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_q5_0_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = ne;
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)), [=](sycl::nd_item<3> item_ct1) {
- cpy_q_f32, QK5_0>(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02,
- nb03, ne10, ne11, ne12, nb10, nb11, nb12, nb13,
- item_ct1);
- });
-}
-
-static void ggml_cpy_f32_q5_1_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK5_1 == 0);
- const int num_blocks = ne / QK5_1;
- stream->parallel_for(sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03,
- ne10, ne11, ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_q5_1_f32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = ne;
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)), [=](sycl::nd_item<3> item_ct1) {
- cpy_q_f32, QK5_1>(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02,
- nb03, ne10, ne11, ne12, nb10, nb11, nb12, nb13,
- item_ct1);
- });
-}
-
-static void ggml_cpy_f32_iq4_nl_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- GGML_ASSERT(ne % QK4_NL == 0);
- const int num_blocks = ne / QK4_NL;
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks), sycl::range<3>(1, 1, 1)), [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_q(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11,
- ne12, nb10, nb11, nb12, nb13, item_ct1);
- });
-}
-
-static void ggml_cpy_f16_f16_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- dpct::has_capability_or_fail(stream->get_device(), { sycl::aspect::fp16 });
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-static void ggml_cpy_i16_i16_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- // dpct::has_capability_or_fail(stream->get_device(),
- // {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-static void ggml_cpy_i32_i32_sycl(const char * cx, char * cdst, const int ne, const int ne00, const int ne01,
- const int ne02, const int nb00, const int nb01, const int nb02, const int nb03,
- const int ne10, const int ne11, const int ne12, const int nb10, const int nb11,
- const int nb12, const int nb13, queue_ptr stream) {
- const int num_blocks = (ne + SYCL_CPY_BLOCK_SIZE - 1) / SYCL_CPY_BLOCK_SIZE;
- {
- // dpct::has_capability_or_fail(stream->get_device(),
- // {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, num_blocks) * sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE),
- sycl::range<3>(1, 1, SYCL_CPY_BLOCK_SIZE)),
- [=](sycl::nd_item<3> item_ct1) {
- cpy_f32_f16(cx, cdst, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, item_ct1);
- });
- }
-}
-
-void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1) try {
- const int64_t ne = ggml_nelements(src0);
- GGML_ASSERT(ne == ggml_nelements(src1));
-
- GGML_ASSERT(ggml_nbytes(src0) <= INT_MAX);
- GGML_ASSERT(ggml_nbytes(src1) <= INT_MAX);
-
- GGML_TENSOR_BINARY_OP_LOCALS01;
-
- SYCL_CHECK(ggml_sycl_set_device(ctx.device));
- queue_ptr main_stream = ctx.stream();
-
- char * src0_ddc = (char *) src0->data;
- char * src1_ddc = (char *) src1->data;
- GGML_SYCL_DEBUG("[SYCL] %s: Tensor supplied: %s to %s\n", __func__, ggml_type_name(src0->type),
- ggml_type_name(src1->type));
-
- if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_f32_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F16) {
- ggml_cpy_f32_f16_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_Q8_0) {
- ggml_cpy_f32_q8_0_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_Q4_0) {
- ggml_cpy_f32_q4_0_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_Q4_1) {
- ggml_cpy_f32_q4_1_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F16 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_f16_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F16 && src1->type == GGML_TYPE_F16) {
- ggml_cpy_f16_f16_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_I16 && src1->type == GGML_TYPE_I16) {
- ggml_cpy_i16_i16_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_I32 && src1->type == GGML_TYPE_I32) {
- ggml_cpy_i32_i32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_Q4_0 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_q4_0_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_Q4_1 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_q4_1_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_Q8_0 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_q8_0_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_Q5_0) {
- ggml_cpy_f32_q5_0_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_Q5_0 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_q5_0_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_Q5_1) {
- ggml_cpy_f32_q5_1_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_Q5_1 && src1->type == GGML_TYPE_F32) {
- ggml_cpy_q5_1_f32_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12, nb10,
- nb11, nb12, nb13, main_stream);
- } else if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_IQ4_NL) {
- ggml_cpy_f32_iq4_nl_sycl(src0_ddc, src1_ddc, ne, ne00, ne01, ne02, nb00, nb01, nb02, nb03, ne10, ne11, ne12,
- nb10, nb11, nb12, nb13, main_stream);
- } else {
- GGML_LOG_ERROR("%s: unsupported type combination (%s to %s)\n", __func__, ggml_type_name(src0->type),
- ggml_type_name(src1->type));
- GGML_ABORT("fatal error");
- }
-} catch (const sycl::exception & exc) {
- std::cerr << exc.what() << "Exception caught at file:" << __FILE__ << ", line:" << __LINE__ << std::endl;
- std::exit(1);
-}
-
-void ggml_sycl_dup(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
- // TODO: why do we pass dst as src1 here?
- GGML_SYCL_DEBUG("[SYCL] call %s\n", __func__);
- ggml_sycl_cpy(ctx, dst->src[0], dst);
- GGML_SYCL_DEBUG("[SYCL] call %s done\n", __func__);
-}
diff --git a/ggml/src/ggml-sycl/cpy.hpp b/ggml/src/ggml-sycl/cpy.hpp
deleted file mode 100644
index 0a0f561d2..000000000
--- a/ggml/src/ggml-sycl/cpy.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef GGML_SYCL_CPY_HPP
-#define GGML_SYCL_CPY_HPP
-
-#include "common.hpp"
-
-typedef void (*cpy_kernel_t)(const char * cx, char * cdst);
-
-void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1);
-void ggml_sycl_dup(ggml_backend_sycl_context & ctx, ggml_tensor * dst);
-
-#endif // GGML_SYCL_CPY_HPP
diff --git a/ggml/src/ggml-sycl/dequantize.hpp b/ggml/src/ggml-sycl/dequantize.hpp
deleted file mode 100644
index 651c2160d..000000000
--- a/ggml/src/ggml-sycl/dequantize.hpp
+++ /dev/null
@@ -1,753 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_DEQUANTIZE_HPP
-#define GGML_SYCL_DEQUANTIZE_HPP
-
-#include "common.hpp"
-
-typedef void (*dequantize_kernel_t)(const void * vx, const int64_t ib, const int iqs, dfloat2 & v);
-typedef void (*dequantize_kernel_t_reorder)(const void *d, const int64_t ib, const void *qs,
- const int iqs, dfloat2 &v);
-
-static __dpct_inline__ void dequantize_q4_0(const void *vx, const int64_t ib,
- const int iqs, dfloat2 &v) {
- const block_q4_0 * x = (const block_q4_0 *) vx;
-
- const dfloat d = x[ib].d;
-
- const int vui = x[ib].qs[iqs];
-
- v.x() = vui & 0xF;
- v.y() = vui >> 4;
-
-#ifdef GGML_SYCL_F16
- // v = v - {8.0f, 8.0f};
- // v = v * {d, d};
- v.s0() = (v.s0() - 8.0f) * d;
- v.s1() = (v.s1() - 8.0f) * d;
-
-#else
- v.x() = (v.x() - 8.0f) * d;
- v.y() = (v.y() - 8.0f) * d;
-#endif // GGML_SYCL_F16
-}
-
-static __dpct_inline__ void dequantize_q4_0_reorder(const void *d_ptr, const int64_t ib, const void *qs,
- const int iqs, dfloat2 &v) {
- // const block_q4_0 * x = (const block_q4_0 *) vx;
-
- const dfloat d = (const dfloat)*((const sycl::half*)d_ptr+ib);
-
- const int vui = *((const uint8_t *)qs+iqs);
-
- v.x() = vui & 0xF;
- v.y() = vui >> 4;
-
-#ifdef GGML_SYCL_F16
- // v = v - {8.0f, 8.0f};
- // v = v * {d, d};
- v.s0() = (v.s0() - 8.0f) * d;
- v.s1() = (v.s1() - 8.0f) * d;
-
-#else
- v.x() = (v.x() - 8.0f) * d;
- v.y() = (v.y() - 8.0f) * d;
-#endif // GGML_SYCL_F16
-}
-
-static __dpct_inline__ void dequantize_q4_1(const void *vx, const int64_t ib,
- const int iqs, dfloat2 &v) {
- const block_q4_1 * x = (const block_q4_1 *) vx;
-
- const dfloat d = x[ib].dm[0];
- const dfloat m = x[ib].dm[1];
-
- const int vui = x[ib].qs[iqs];
-
- v.x() = vui & 0xF;
- v.y() = vui >> 4;
-
-#ifdef GGML_SYCL_F16
- // v = v * {d, d};
- // v = v + {m, m};
- v.s0() = sycl::fma(v.s0(), d, m);
- v.s1() = sycl::fma(v.s1(), d, m);
-
-#else
- v.x() = sycl::fma(v.x(), d, m);
- v.y() = sycl::fma(v.y(), d, m);
-#endif // GGML_SYCL_F16
-}
-
-static __dpct_inline__ void dequantize_q5_0(const void *vx, const int64_t ib,
- const int iqs, dfloat2 &v) {
- const block_q5_0 * x = (const block_q5_0 *) vx;
-
- const dfloat d = x[ib].d;
-
- uint32_t qh;
- memcpy(&qh, x[ib].qh, sizeof(qh));
-
- const int xh_0 = ((qh >> (iqs + 0)) << 4) & 0x10;
- const int xh_1 = ((qh >> (iqs + 12)) ) & 0x10;
-
- v.x() = ((x[ib].qs[iqs] & 0xf) | xh_0);
- v.y() = ((x[ib].qs[iqs] >> 4) | xh_1);
-
-#ifdef GGML_SYCL_F16
- // v = v - {16.0f, 16.0f};
- // v = v * {d, d};
- v.s0() = (v.s0() - 16.0f) * d;
- v.s1() = (v.s1() - 16.0f) * d;
-
-#else
- v.x() = (v.x() - 16.0f) * d;
- v.y() = (v.y() - 16.0f) * d;
-#endif // GGML_SYCL_F16
-}
-
-static __dpct_inline__ void dequantize_q5_1(const void *vx, const int64_t ib,
- const int iqs, dfloat2 &v) {
- const block_q5_1 * x = (const block_q5_1 *) vx;
-
- const dfloat d = x[ib].dm[0];
- const dfloat m = x[ib].dm[1];
-
- uint32_t qh;
- memcpy(&qh, x[ib].qh, sizeof(qh));
-
- const int xh_0 = ((qh >> (iqs + 0)) << 4) & 0x10;
- const int xh_1 = ((qh >> (iqs + 12)) ) & 0x10;
-
- v.x() = ((x[ib].qs[iqs] & 0xf) | xh_0);
- v.y() = ((x[ib].qs[iqs] >> 4) | xh_1);
-
-#ifdef GGML_SYCL_F16
- // v = v * {d, d};
- // v = v + {m, m};
- v.s0() = sycl::fma(v.s0(), d, m);
- v.s1() = sycl::fma(v.s1(), d, m);
-#else
- v.x() = sycl::fma(v.x(), d, m);
- v.y() = sycl::fma(v.y(), d, m);
-#endif // GGML_SYCL_F16
-}
-
-static __dpct_inline__ void dequantize_q8_0(const void *vx, const int64_t ib,
- const int iqs, dfloat2 &v) {
- const block_q8_0 * x = (const block_q8_0 *) vx;
-
- const dfloat d = x[ib].d;
-
- v.x() = x[ib].qs[iqs + 0];
- v.y() = x[ib].qs[iqs + 1];
-
-#ifdef GGML_SYCL_F16
- // v = v * {d, d};
- v.s0() *= d;
- v.s1() *= d;
-#else
- v.x() *= d;
- v.y() *= d;
-#endif // GGML_SYCL_F16
-}
-
-template
-static void dequantize_block_q4_0(const void * __restrict__ vx, dst_t * __restrict__ yy, int64_t nb32,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
-
- // assume 32 threads
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/8;
- const int64_t ir = tid%8;
- const int64_t ib = 8*i + ir;
- if (ib >= nb32) {
- return;
- }
-
- dst_t * y = yy + 256*i + 32*ir + 4*il;
-
- const block_q4_0 * x = (const block_q4_0 *)vx + ib;
- const float d = sycl::vec(x->d)
- .convert()[0];
- const float dm = -8*d;
-
- const uint8_t * q = x->qs + 4*il;
-
- for (int l = 0; l < 4; ++l) {
- y[l+ 0] = d * (q[l] & 0xF) + dm;
- y[l+16] = d * (q[l] >> 4) + dm;
- }
-}
-
-template
-static void dequantize_block_q4_0_reorder(const void * __restrict__ vx, dst_t * __restrict__ yy, int64_t nb32,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
- auto k=nb32;
- // assume 32 threads
- const int64_t tid = item_ct1.get_local_id(2);
- const int lane_ib = i * WARP_SIZE + tid;
-
- if (lane_ib >= k / QK4_0) {
- return;
- }
-
- dst_t * y_ptr = yy + lane_ib * QK4_0;
-
- auto qs = (const uint8_t*)vx + lane_ib * QK4_0 / 2;
- auto s_ptr = (const sycl::half*)((const uint8_t*)vx + k / 2) + lane_ib;
-
- const float d = float(*s_ptr);
-
-#pragma unroll
- for (int l = 0; l < QK4_0 / 2; ++l) {
- int vq = qs[l];
- y_ptr[l + 0] = d * ((vq & 0xF) - 8);
- y_ptr[l + 16] = d * ((vq >> 4) - 8);
- }
-
-}
-
-template
-static void dequantize_block_q4_1(const void * __restrict__ vx, dst_t * __restrict__ yy, int64_t nb32,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
-
- // assume 32 threads
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/8;
- const int64_t ir = tid%8;
- const int64_t ib = 8*i + ir;
- if (ib >= nb32) {
- return;
- }
-
- dst_t * y = yy + 256*i + 32*ir + 4*il;
-
- const block_q4_1 * x = (const block_q4_1 *)vx + ib;
- const sycl::float2 d =
- x->dm.convert();
-
- const uint8_t * q = x->qs + 4*il;
-
- for (int l = 0; l < 4; ++l) {
- y[l + 0] = d.x() * (q[l] & 0xF) + d.y();
- y[l + 16] = d.x() * (q[l] >> 4) + d.y();
- }
-}
-
-
-//================================== k-quants
-
-template
-static void dequantize_block_q2_K(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_q2_K * x = (const block_q2_K *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t n = tid/32;
- const int64_t l = tid - 32*n;
- const int64_t is = 8*n + l/16;
-
- const uint8_t q = x[i].qs[32*n + l];
- dst_t * y = yy + i*QK_K + 128*n;
-
- float dall = x[i].dm[0];
- float dmin = x[i].dm[1];
- y[l+ 0] = dall * (x[i].scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x[i].scales[is+0] >> 4);
- y[l+32] = dall * (x[i].scales[is+2] & 0xF) * ((q >> 2) & 3) - dmin * (x[i].scales[is+2] >> 4);
- y[l+64] = dall * (x[i].scales[is+4] & 0xF) * ((q >> 4) & 3) - dmin * (x[i].scales[is+4] >> 4);
- y[l+96] = dall * (x[i].scales[is+6] & 0xF) * ((q >> 6) & 3) - dmin * (x[i].scales[is+6] >> 4);
-#else
- const int64_t is = tid/16; // 0 or 1
- const int64_t il = tid%16; // 0...15
- const uint8_t q = x[i].qs[il] >> (2*is);
- dst_t * y = yy + i*QK_K + 16*is + il;
-
- float dall = x[i].dm[0];
- float dmin = x[i].dm[1];
- y[ 0] = dall * (x[i].scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x[i].scales[is+0] >> 4);
- y[32] = dall * (x[i].scales[is+2] & 0xF) * ((q >> 4) & 3) - dmin * (x[i].scales[is+2] >> 4);
-#endif
-
-}
-
-template
-static void dequantize_block_q3_K(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_q3_K * x = (const block_q3_K *) vx;
-
-#if QK_K == 256
- const int64_t r = item_ct1.get_local_id(2) / 4;
- const int64_t tid = r/2;
- const int64_t is0 = r%2;
- const int64_t l0 = 16 * is0 + 4 * (item_ct1.get_local_id(2) % 4);
- const int64_t n = tid / 4;
- const int64_t j = tid - 4*n;
-
- uint8_t m = 1 << (4*n + j);
- int64_t is = 8*n + 2*j + is0;
- int shift = 2*j;
-
- int8_t us = is < 4 ? (x[i].scales[is-0] & 0xF) | (((x[i].scales[is+8] >> 0) & 3) << 4) :
- is < 8 ? (x[i].scales[is-0] & 0xF) | (((x[i].scales[is+4] >> 2) & 3) << 4) :
- is < 12 ? (x[i].scales[is-8] >> 4) | (((x[i].scales[is+0] >> 4) & 3) << 4) :
- (x[i].scales[is-8] >> 4) | (((x[i].scales[is-4] >> 6) & 3) << 4);
- float d_all = x[i].d;
- float dl = d_all * (us - 32);
-
- dst_t * y = yy + i*QK_K + 128*n + 32*j;
- const uint8_t * q = x[i].qs + 32*n;
- const uint8_t * hm = x[i].hmask;
-
- for (int l = l0; l < l0+4; ++l) y[l] = dl * ((int8_t)((q[l] >> shift) & 3) - ((hm[l] & m) ? 0 : 4));
-#else
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t is = tid/16; // 0 or 1
- const int64_t il = tid%16; // 0...15
- const int64_t im = il/8; // 0...1
- const int64_t in = il%8; // 0...7
-
- dst_t * y = yy + i*QK_K + 16*is + il;
-
- const uint8_t q = x[i].qs[il] >> (2*is);
- const uint8_t h = x[i].hmask[in] >> (2*is + im);
- const float d = (float)x[i].d;
-
- if (is == 0) {
- y[ 0] = d * ((x[i].scales[0] & 0xF) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4));
- y[32] = d * ((x[i].scales[1] & 0xF) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4));
- } else {
- y[ 0] = d * ((x[i].scales[0] >> 4) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4));
- y[32] = d * ((x[i].scales[1] >> 4) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4));
- }
-#endif
-
-}
-
-#if QK_K == 256
-static inline void get_scale_min_k4(int j, const uint8_t * q, uint8_t & d, uint8_t & m) {
- if (j < 4) {
- d = q[j] & 63;
- m = q[j + 4] & 63;
- } else {
- d = (q[j+4] & 0xF) | ((q[j-4] >> 6) << 4);
- m = (q[j+4] >> 4) | ((q[j-0] >> 6) << 4);
- }
-}
-#endif
-
-template
-static void dequantize_block_q4_K(const void * __restrict__ vx, dst_t * __restrict__ yy,
- uint8_t* scales_local, const sycl::nd_item<3> &item_ct1) {
- const block_q4_K * x = (const block_q4_K *) vx;
-
- const int64_t i = item_ct1.get_group(2);
-
-#if QK_K == 256
- // assume 32 threads
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/8;
- const int64_t ir = tid%8;
- const int64_t is = 2*il;
- const int64_t n = 4;
-
- dst_t * y = yy + i*QK_K + 64*il + n*ir;
-
- const sycl::half2 dm = x[i].dm;
- const float dall = dm[0];
- const float dmin = dm[1];
-
- if (tid < 12)
- scales_local[tid] = x[i].scales[tid];
- item_ct1.barrier(sycl::access::fence_space::local_space);
-
- uint8_t sc, m;
- get_scale_min_k4(is + 0, scales_local, sc, m);
- const float d1 = dall * sc;
- const float m1 = dmin * m;
- get_scale_min_k4(is + 1, scales_local, sc, m);
- const float d2 = dall * sc;
- const float m2 = dmin * m;
-
- sycl::vec q_vec = vec_aligned_load(x[i].qs + 32*il + n*ir);
- for (int l = 0; l < n; ++l) {
- y[l + 0] = d1 * (q_vec[l] & 0xF) - m1;
- y[l +32] = d2 * (q_vec[l] >> 4) - m2;
- }
-#else
- const int64_t tid = item_ct1.get_local_id(2);
- const uint8_t * q = x[i].qs;
- dst_t * y = yy + i*QK_K;
- const float d = (float)x[i].dm[0];
- const float m = (float)x[i].dm[1];
- y[tid+ 0] = d * (x[i].scales[0] & 0xF) * (q[tid] & 0xF) - m * (x[i].scales[0] >> 4);
- y[tid+32] = d * (x[i].scales[1] & 0xF) * (q[tid] >> 4) - m * (x[i].scales[1] >> 4);
-#endif
-}
-
-template
-static void dequantize_block_q5_K(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
- const block_q5_K * x = (const block_q5_K *) vx;
-
- const int64_t i = item_ct1.get_group(2);
-
-#if QK_K == 256
- // assume 64 threads - this is very slightly better than the one below
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/16; // il is in 0...3
- const int64_t ir = tid%16; // ir is in 0...15
- const int64_t is = 2*il; // is is in 0...6
-
- dst_t * y = yy + i*QK_K + 64*il + 2*ir;
-
- const float dall = x[i].dm[0];
- const float dmin = x[i].dm[1];
-
- const uint8_t * ql = x[i].qs + 32*il + 2*ir;
- const uint8_t * qh = x[i].qh + 2*ir;
-
- uint8_t sc, m;
- get_scale_min_k4(is + 0, x[i].scales, sc, m);
- const float d1 = dall * sc; const float m1 = dmin * m;
- get_scale_min_k4(is + 1, x[i].scales, sc, m);
- const float d2 = dall * sc; const float m2 = dmin * m;
-
- uint8_t hm = 1 << (2*il);
- y[ 0] = d1 * ((ql[ 0] & 0xF) + (qh[ 0] & hm ? 16 : 0)) - m1;
- y[ 1] = d1 * ((ql[ 1] & 0xF) + (qh[ 1] & hm ? 16 : 0)) - m1;
- hm <<= 1;
- y[32] = d2 * ((ql[ 0] >> 4) + (qh[ 0] & hm ? 16 : 0)) - m2;
- y[33] = d2 * ((ql[ 1] >> 4) + (qh[ 1] & hm ? 16 : 0)) - m2;
-#else
- const int64_t tid = item_ct1.get_local_id(2);
- const uint8_t q = x[i].qs[tid];
- const int64_t im = tid/8; // 0...3
- const int64_t in = tid%8; // 0...7
- const int64_t is = tid/16; // 0 or 1
- const uint8_t h = x[i].qh[in] >> im;
- const float d = x[i].d;
- dst_t * y = yy + i*QK_K + tid;
- y[ 0] = d * x[i].scales[is+0] * ((q & 0xF) - ((h >> 0) & 1 ? 0 : 16));
- y[32] = d * x[i].scales[is+2] * ((q >> 4) - ((h >> 4) & 1 ? 0 : 16));
-#endif
-}
-
-template
-static void dequantize_block_q6_K(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
- const block_q6_K * x = (const block_q6_K *) vx;
-
- const int64_t i = item_ct1.get_group(2);
-#if QK_K == 256
-
- // assume 64 threads - this is very slightly better than the one below
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t ip = tid/32; // ip is 0 or 1
- const int64_t il = tid - 32*ip; // 0...32
- const int64_t is = 8*ip + il/16;
-
- dst_t * y = yy + i*QK_K + 128*ip + il;
-
- const float d = x[i].d;
-
- const uint8_t * ql = x[i].ql + 64*ip + il;
- const uint8_t qh = x[i].qh[32*ip + il];
- const int8_t * sc = x[i].scales + is;
-
- y[ 0] = d * sc[0] * ((int8_t)((ql[ 0] & 0xF) | (((qh >> 0) & 3) << 4)) - 32);
- y[32] = d * sc[2] * ((int8_t)((ql[32] & 0xF) | (((qh >> 2) & 3) << 4)) - 32);
- y[64] = d * sc[4] * ((int8_t)((ql[ 0] >> 4) | (((qh >> 4) & 3) << 4)) - 32);
- y[96] = d * sc[6] * ((int8_t)((ql[32] >> 4) | (((qh >> 6) & 3) << 4)) - 32);
-#else
-
- // assume 32 threads
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t ip = tid/16; // 0 or 1
- const int64_t il = tid - 16*ip; // 0...15
-
- dst_t * y = yy + i*QK_K + 16*ip + il;
-
- const float d = x[i].d;
-
- const uint8_t ql = x[i].ql[16*ip + il];
- const uint8_t qh = x[i].qh[il] >> (2*ip);
- const int8_t * sc = x[i].scales;
-
- y[ 0] = d * sc[ip+0] * ((int8_t)((ql & 0xF) | (((qh >> 0) & 3) << 4)) - 32);
- y[32] = d * sc[ip+2] * ((int8_t)((ql >> 4) | (((qh >> 4) & 3) << 4)) - 32);
-#endif
-}
-
-template
-static void dequantize_block_iq2_xxs(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint64_t *iq2xxs_grid_ptr,
- const uint8_t *ksigns_iq2xs_ptr,
- const uint8_t *kmask_iq2xs_ptr) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq2_xxs * x = (const block_iq2_xxs *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint16_t * q2 = x[i].qs + 4*ib;
- const uint8_t * aux8 = (const uint8_t *)q2;
- const uint8_t * grid = (const uint8_t *)(iq2xxs_grid_ptr + aux8[il]);
- const uint32_t aux32 = q2[2] | (q2[3] << 16);
- const float d = (float)x[i].d * (0.5f + (aux32 >> 28)) * 0.25f;
- const uint8_t signs = ksigns_iq2xs_ptr[(aux32 >> 7*il) & 127];
- for (int j = 0; j < 8; ++j) y[j] = d * grid[j] * (signs & kmask_iq2xs_ptr[j] ? -1.f : 1.f);
-#else
- assert(false);
-#endif
-
-}
-
-template
-static void dequantize_block_iq2_xs(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint64_t *iq2xs_grid,
- const uint8_t *ksigns_iq2xs,
- const uint8_t *kmask_iq2xs) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq2_xs * x = (const block_iq2_xs *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint16_t * q2 = x[i].qs + 4*ib;
- const uint8_t * grid = (const uint8_t *)(iq2xs_grid + (q2[il] & 511));
- const float d = (float)x[i].d * (0.5f + ((x[i].scales[ib] >> 4*(il/2)) & 0xf)) * 0.25f;
- const uint8_t signs = ksigns_iq2xs[q2[il] >> 9];
- for (int j = 0; j < 8; ++j) y[j] = d * grid[j] * (signs & kmask_iq2xs[j] ? -1.f : 1.f);
-#else
- assert(false);
-#endif
-
-}
-
-template
-__dpct_inline__ static void
-dequantize_block_iq2_s(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq2_s * x = (const block_iq2_s *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint8_t * grid = (const uint8_t *)(iq2s_grid + (x[i].qs[4*ib+il] | ((x[i].qh[ib] << (8-2*il)) & 0x300)));
- const float d = (float)x[i].d * (0.5f + ((x[i].scales[ib] >> 4*(il/2)) & 0xf)) * 0.25f;
- const uint8_t signs = x[i].qs[QK_K/8+4*ib+il];
-#pragma unroll
- for (int j = 0; j < 8; ++j)
- y[j] = d * grid[j] * (signs & kmask_iq2xs[j] ? -1.f : 1.f);
-#else
- assert(false);
-
-#endif
-
-}
-
-template
-static void dequantize_block_iq3_xxs(const void * __restrict__ vx, dst_t * __restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint32_t *iq3xxs_grid,
- const uint8_t *ksigns_iq2xs,
- const uint8_t *kmask_iq2xs) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq3_xxs * x = (const block_iq3_xxs *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint8_t * q3 = x[i].qs + 8*ib;
- const uint16_t * gas = (const uint16_t *)(x[i].qs + QK_K/4) + 2*ib;
- const uint8_t * grid1 = (const uint8_t *)(iq3xxs_grid + q3[2*il+0]);
- const uint8_t * grid2 = (const uint8_t *)(iq3xxs_grid + q3[2*il+1]);
- const uint32_t aux32 = gas[0] | (gas[1] << 16);
- const float d = (float)x[i].d * (0.5f + (aux32 >> 28)) * 0.5f;
- const uint8_t signs = ksigns_iq2xs[(aux32 >> 7*il) & 127];
- for (int j = 0; j < 4; ++j) {
- y[j+0] = d * grid1[j] * (signs & kmask_iq2xs[j+0] ? -1.f : 1.f);
- y[j+4] = d * grid2[j] * (signs & kmask_iq2xs[j+4] ? -1.f : 1.f);
- }
-#else
- assert(false);
-#endif
-
-}
-
-template
-__dpct_inline__ static void
-dequantize_block_iq3_s(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint8_t *kmask_iq2xs, const uint32_t *iq3s_grid) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq3_s * x = (const block_iq3_s *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint8_t * qs = x[i].qs + 8*ib;
- const uint8_t * grid1 = (const uint8_t *)(iq3s_grid + (qs[2*il+0] | ((x[i].qh[ib] << (8-2*il)) & 256)));
- const uint8_t * grid2 = (const uint8_t *)(iq3s_grid + (qs[2*il+1] | ((x[i].qh[ib] << (7-2*il)) & 256)));
- const float d = (float)x[i].d * (1 + 2*((x[i].scales[ib/2] >> 4*(ib%2)) & 0xf));
- const uint8_t signs = x[i].signs[4*ib + il];
-#pragma unroll
- for (int j = 0; j < 4; ++j) {
- y[j+0] = d * grid1[j] * (signs & kmask_iq2xs[j+0] ? -1.f : 1.f);
- y[j+4] = d * grid2[j] * (signs & kmask_iq2xs[j+4] ? -1.f : 1.f);
- }
-#else
- assert(false);
-#endif
-
-}
-
-template
-__dpct_inline__ static void
-dequantize_block_iq1_s(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint32_t *iq1s_grid_gpu) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq1_s * x = (const block_iq1_s *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const float delta = x[i].qh[ib] & 0x8000 ? -1 - IQ1S_DELTA : -1 + IQ1S_DELTA;
- const float d = (float)x[i].d * (2*((x[i].qh[ib] >> 12) & 7) + 1);
- uint32_t grid32[2]; const int8_t * q = (const int8_t *)grid32;
- grid32[0] = iq1s_grid_gpu[x[i].qs[4*ib+il] | (((x[i].qh[ib] >> 3*il) & 7) << 8)];
- grid32[1] = (grid32[0] >> 4) & 0x0f0f0f0f;
- grid32[0] &= 0x0f0f0f0f;
-#pragma unroll
- for (int j = 0; j < 8; ++j) {
- y[j] = d * (q[j] + delta);
- }
-#else
- assert(false);
-#endif
-
-}
-
-template
-__dpct_inline__ static void
-dequantize_block_iq1_m(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1,
- const uint32_t *iq1s_grid_gpu) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq1_m * x = (const block_iq1_m *) vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
-#if QK_K == 256
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 8*il;
- const uint16_t * sc = (const uint16_t *)x[i].scales;
- iq1m_scale_t scale;
- scale.u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000);
- const int ib16 = 2*ib + il/2; // sc[ib16/4] >> 3*(ib16%4) -> sc[ib/2] >> 3*((2*ib+il/2)%4);
- const float d = (float)scale.f16 * (2*((sc[ib16/4] >> 3*(ib16%4)) & 0x7) + 1);
- const float delta = x[i].qh[2*ib+il/2] & (0x08 << 4*(il%2)) ? -1 - IQ1M_DELTA : -1 + IQ1M_DELTA;
- uint32_t grid32[2]; const int8_t * q = (const int8_t *)grid32;
- grid32[0] = iq1s_grid_gpu[x[i].qs[4*ib+il] | (((x[i].qh[2*ib+il/2] >> 4*(il%2)) & 7) << 8)];
- grid32[1] = (grid32[0] >> 4) & 0x0f0f0f0f;
- grid32[0] &= 0x0f0f0f0f;
-#pragma unroll
- for (int j = 0; j < 8; ++j) {
- y[j] = d * (q[j] + delta);
- }
-#else
- assert(false);
-#endif
-
-}
-
-template
-__dpct_inline__ static void
-dequantize_block_iq4_nl(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
-
- const int64_t i = item_ct1.get_group(2);
- const block_iq4_nl * x = (const block_iq4_nl *) vx + i*(QK_K/QK4_NL);
-
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 4*il;
- const uint8_t * q4 = x[ib].qs + 4*il;
- const float d = (float)x[ib].d;
-#pragma unroll
- for (int j = 0; j < 4; ++j) {
- y[j+ 0] = d * kvalues_iq4nl[q4[j] & 0xf];
- y[j+16] = d * kvalues_iq4nl[q4[j] >> 4];
- }
-
-}
-
-
-template
-__dpct_inline__ static void
-dequantize_block_iq4_xs(const void *__restrict__ vx, dst_t *__restrict__ yy,
- const sycl::nd_item<3> &item_ct1) {
- const int64_t i = item_ct1.get_group(2);
- const block_iq4_xs * x = (const block_iq4_xs *)vx;
-
- const int64_t tid = item_ct1.get_local_id(2);
- const int64_t il = tid/8; // 0...3
- const int64_t ib = tid%8; // 0...7
- dst_t * y = yy + i*QK_K + 32*ib + 4*il;
- const uint8_t * q4 = x[i].qs + 16*ib + 4*il;
- const float d = (float)x[i].d * ((((x[i].scales_l[ib/2] >> 4*(ib%2)) & 0xf) | (((x[i].scales_h >> 2*ib) & 3) << 4)) - 32);
-#pragma unroll
- for (int j = 0; j < 4; ++j) {
- y[j+ 0] = d * kvalues_iq4nl[q4[j] & 0xf];
- y[j+16] = d * kvalues_iq4nl[q4[j] >> 4];
- }
-}
-
-
-#endif // GGML_SYCL_DEQUANTIZE_HPP
diff --git a/ggml/src/ggml-sycl/dmmv.cpp b/ggml/src/ggml-sycl/dmmv.cpp
deleted file mode 100644
index 04a85fa35..000000000
--- a/ggml/src/ggml-sycl/dmmv.cpp
+++ /dev/null
@@ -1,1154 +0,0 @@
-#include "convert.hpp"
-#include "dmmv.hpp"
-#include "dequantize.hpp"
-#include "presets.hpp"
-
-static void convert_f16(const void * vx, const int64_t ib, const int iqs, dfloat2 & v){
- const sycl::half *x = (const sycl::half *)vx;
-
- // automatic half -> float type cast if dfloat == float
- v.x() = x[ib + iqs + 0];
- v.y() = x[ib + iqs + 1];
-}
-
-static void convert_f32(const void * vx, const int64_t ib, const int iqs, dfloat2 & v){
- const float * x = (const float *) vx;
-
- // automatic half -> float type cast if dfloat == float
- v.x() = x[ib + iqs + 0];
- v.y() = x[ib + iqs + 1];
-}
-
-template
-static void dequantize_mul_mat_vec(const void * __restrict__ vx, const dfloat * __restrict__ y, float * __restrict__ dst, const int ncols, const int nrows,
- const sycl::nd_item<3> &item_ct1) {
- // qk = quantized weights per x block
- // qr = number of quantized weights per data value in x block
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
-
- if (row >= nrows) {
- return;
- }
-
- const int tid = item_ct1.get_local_id(2);
-
- const int iter_stride = 2*GGML_SYCL_DMMV_X;
- const int vals_per_iter = iter_stride / WARP_SIZE; // num quantized vals per thread and i iter
- const int y_offset = qr == 1 ? 1 : qk/2;
-
-// partial sum for each thread
-#ifdef GGML_SYCL_F16
- sycl::half2 tmp = {0.0f, 0.0f}; // two sums for f16 to take advantage of half2 intrinsics
-#else
- float tmp = 0.0f;
-#endif // GGML_SYCL_F16
-
- for (int i = 0; i < ncols; i += iter_stride) {
- const int col = i + vals_per_iter*tid;
- const int ib = (row*ncols + col)/qk; // x block index
- const int iqs = (col%qk)/qr; // x quant index
- const int iybs = col - col%qk; // y block start index
-
-// processing >2 values per i iter is faster for fast GPUs
-#pragma unroll
- for (int j = 0; j < vals_per_iter; j += 2) {
- // process 2 vals per j iter
-
- // dequantize
- // for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val
- dfloat2 v;
- dequantize_kernel(vx, ib, iqs + j/qr, v);
-
- // matrix multiplication
- // for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2
-#ifdef GGML_SYCL_F16
- dfloat2 t1{y[iybs + iqs + j / qr + 0],
- y[iybs + iqs + j / qr + y_offset]};
-
- tmp += v * t1;
-#else
- tmp += v.x() * y[iybs + iqs + j / qr + 0];
- tmp += v.y() * y[iybs + iqs + j / qr + y_offset];
-#endif // GGML_SYCL_F16
- }
- }
-
- // sum up partial sums and write back result
- const int mask_start = ncols > GGML_SYCL_DMMV_X ? WARP_SIZE >> 1 : WARP_SIZE >> 2;
- for (int mask = mask_start; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (tid == 0) {
-#ifdef GGML_SYCL_F16
- dst[row] = tmp.x() + tmp.y();
-#else
- dst[row] = tmp;
-#endif // GGML_SYCL_F16
- }
-}
-
-template
-static void dequantize_mul_mat_vec_reorder(const void * __restrict__ vx, const dfloat * __restrict__ y, float * __restrict__ dst, const int ncols, const int nrows,
- const sycl::nd_item<3> &item_ct1) {
- // qk = quantized weights per x block
- // qr = number of quantized weights per data value in x block
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
-
- if (row >= nrows) {
- return;
- }
-
- const int tid = item_ct1.get_local_id(2);
-
-
- const int ncols_left = ncols % (QK4_0*WARP_SIZE);
- const int ncols_align = ncols - ncols_left;
- const int iter_stride = 8*2*GGML_SYCL_DMMV_X;
- const int vals_per_iter = iter_stride / WARP_SIZE; // num quantized vals per thread and i iter //64/16=4, 512/16/2= 16
- const int y_offset = qr == 1 ? 1 : qk/2;
-
-// partial sum for each thread
-#ifdef GGML_SYCL_F16
- sycl::half2 tmp = {0.0f, 0.0f}; // two sums for f16 to take advantage of half2 intrinsics
-#else
- float tmp = 0.0f;
-#endif // GGML_SYCL_F16
- const char *d_ptr = (const char*)vx+ncols*nrows/2;
- int i=0;
- for (i = 0; i < ncols_align; i += iter_stride) {
- const int col = i + vals_per_iter*tid;
- const int ib = (row*ncols + col)/qk; // x block index
- const int iqs = (col%qk)/qr; // x quant index
- const int iybs = col - col%qk; // y block start index
-
-// processing >2 values per i iter is faster for fast GPUs
-#pragma unroll
- for (int j = 0; j < vals_per_iter; j += 2) {
- // process 2 vals per j iter
-
- // dequantize
- // for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val
- dfloat2 v;
- dequantize_kernel_reorder((const void *)d_ptr, ib, (const void *)vx, ib * QK4_0 / 2 +iqs+j/qr, v);
-
- // matrix multiplication
- // for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2
-#ifdef GGML_SYCL_F16
- dfloat2 t1{y[iybs + iqs + j / qr + 0],
- y[iybs + iqs + j / qr + y_offset]};
-
- tmp += v * t1;
-#else
- tmp += v.x() * y[iybs + iqs + j / qr + 0];
- tmp += v.y() * y[iybs + iqs + j / qr + y_offset];
-#endif // GGML_SYCL_F16
- }
- }
-
- for (; i < ncols; i += iter_stride) {
- if (tid>=ncols_left/QK4_0) continue;
- const int col = i + vals_per_iter*tid;
- const int ib = (row*ncols + col)/qk; // x block index
- const int iqs = (col%qk)/qr; // x quant index
- const int iybs = col - col%qk; // y block start index
-
-// processing >2 values per i iter is faster for fast GPUs
-#pragma unroll
- for (int j = 0; j < vals_per_iter; j += 2) {
- // process 2 vals per j iter
-
- // dequantize
- // for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val
- dfloat2 v;
- dequantize_kernel_reorder((const void *)d_ptr, ib, (const void *)vx, ib * QK4_0 / 2 +iqs+j/qr, v);
-
- // matrix multiplication
- // for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2
-#ifdef GGML_SYCL_F16
- dfloat2 t1{y[iybs + iqs + j / qr + 0],
- y[iybs + iqs + j / qr + y_offset]};
-
- tmp += v * t1;
-#else
- tmp += v.x() * y[iybs + iqs + j / qr + 0];
- tmp += v.y() * y[iybs + iqs + j / qr + y_offset];
-#endif // GGML_SYCL_F16
- }
- }
-
- // sum up partial sums and write back result
- const int mask_start = ncols > GGML_SYCL_DMMV_X ? WARP_SIZE >> 1 : WARP_SIZE >> 2;
- for (int mask = mask_start; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (tid == 0) {
-#ifdef GGML_SYCL_F16
- dst[row] = tmp.x() + tmp.y();
-#else
- dst[row] = tmp;
-#endif // GGML_SYCL_F16
- }
-}
-
-static void convert_mul_mat_vec_f16_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec<1, 1, convert_f16>(vx, y, dst, ncols,
- nrows, item_ct1);
- });
- }
-}
-
-/*
-DPCT1110:4: The total declared local variable size in device function
-dequantize_mul_mat_vec_q2_k exceeds 128 bytes and may cause high register
-pressure. Consult with your hardware vendor to find the total register size
-available and adjust the code, or use smaller sub-group size to avoid high
-register pressure.
-*/
-static void dequantize_mul_mat_vec_q2_k(const void *__restrict__ vx,
- const float *__restrict__ yy,
- float *__restrict__ dst,
- const int ncols, int nrows,
- const sycl::nd_item<3> &item_ct1) {
-
- static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION");
-
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
- if (row > nrows) return;
-
- const int num_blocks_per_row = ncols / QK_K;
- const int ib0 = row*num_blocks_per_row;
-
- const block_q2_K * x = (const block_q2_K *)vx + ib0;
-
- float tmp = 0; // partial sum for thread in warp
-
-#if QK_K == 256
- const int tid =
- item_ct1.get_local_id(2) / K_QUANTS_PER_ITERATION; // 0...31 or 0...15
- const int ix =
- item_ct1.get_local_id(2) % K_QUANTS_PER_ITERATION; // 0 or 0,1
-
- const int step = 16/K_QUANTS_PER_ITERATION;
-
- const int im = tid/step; // 0 or 1. 0 computes 0..., 1 computes 128...
- const int in = tid - step*im; // 0...15 or 0...7
-
- const int l0 = K_QUANTS_PER_ITERATION*in; // 0...15 or 0...14 in steps of 2
- const int q_offset = 32*im + l0;
- const int s_offset = 8*im;
- const int y_offset = 128*im + l0;
-
- uint32_t aux[4];
- const uint8_t * d = (const uint8_t *)aux;
- const uint8_t * m = (const uint8_t *)(aux + 2);
-
- for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + y_offset;
- const uint8_t * q = x[i].qs + q_offset;
-
- const float dall = x[i].dm[0];
- const float dmin = x[i].dm[1];
-
- const uint32_t * a = (const uint32_t *)(x[i].scales + s_offset);
- aux[0] = a[0] & 0x0f0f0f0f;
- aux[1] = a[1] & 0x0f0f0f0f;
- aux[2] = (a[0] >> 4) & 0x0f0f0f0f;
- aux[3] = (a[1] >> 4) & 0x0f0f0f0f;
-
- float sum1 = 0, sum2 = 0;
- for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) {
- sum1 += y[l+ 0] * d[0] * ((q[l+ 0] >> 0) & 3)
- + y[l+32] * d[2] * ((q[l+ 0] >> 2) & 3)
- + y[l+64] * d[4] * ((q[l+ 0] >> 4) & 3)
- + y[l+96] * d[6] * ((q[l+ 0] >> 6) & 3)
- + y[l+16] * d[1] * ((q[l+16] >> 0) & 3)
- + y[l+48] * d[3] * ((q[l+16] >> 2) & 3)
- + y[l+80] * d[5] * ((q[l+16] >> 4) & 3)
- +y[l+112] * d[7] * ((q[l+16] >> 6) & 3);
- sum2 += y[l+ 0] * m[0] + y[l+32] * m[2] + y[l+64] * m[4] + y[ l+96] * m[6]
- + y[l+16] * m[1] + y[l+48] * m[3] + y[l+80] * m[5] + y[l+112] * m[7];
-
- }
- tmp += dall * sum1 - dmin * sum2;
-
- }
-#else
- const int tid = item_ct1.get_local_id(2) /
- (2 * K_QUANTS_PER_ITERATION); // 0...15 or 0...7
- const int ix = item_ct1.get_local_id(2) %
- (2 * K_QUANTS_PER_ITERATION); // 0....1 or 0...3
- const int offset = tid * K_QUANTS_PER_ITERATION;
-
- uint32_t uaux[2];
- const uint8_t * d = (const uint8_t *)uaux;
-
-
- for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + offset;
- const uint8_t * q = x[i].qs + offset;
- const uint32_t * s = (const uint32_t *)x[i].scales;
-
- uaux[0] = s[0] & 0x0f0f0f0f;
- uaux[1] = (s[0] >> 4) & 0x0f0f0f0f;
-
- const sycl::float2 dall =
- x[i].dm.convert();
-
- float sum1 = 0, sum2 = 0;
- for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) {
- const uint8_t ql = q[l];
- sum1 += y[l+ 0] * d[0] * ((ql >> 0) & 3)
- + y[l+16] * d[1] * ((ql >> 2) & 3)
- + y[l+32] * d[2] * ((ql >> 4) & 3)
- + y[l+48] * d[3] * ((ql >> 6) & 3);
- sum2 += y[l+0] * d[4] + y[l+16] * d[5] + y[l+32] * d[6] + y[l+48] * d[7];
- }
- tmp += dall.x() * sum1 - dall.y() * sum2;
- }
-
-#endif
-
- // sum up partial sums and write back result
-#pragma unroll
- for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (item_ct1.get_local_id(2) == 0) {
- dst[row] = tmp;
- }
-}
-
-/*
-DPCT1110:5: The total declared local variable size in device function
-dequantize_mul_mat_vec_q3_k exceeds 128 bytes and may cause high register
-pressure. Consult with your hardware vendor to find the total register size
-available and adjust the code, or use smaller sub-group size to avoid high
-register pressure.
-*/
-static void dequantize_mul_mat_vec_q3_k(const void *__restrict__ vx,
- const float *__restrict__ yy,
- float *__restrict__ dst,
- const int ncols, int nrows,
- const sycl::nd_item<3> &item_ct1) {
-
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
- if (row > nrows) return;
-
- const int num_blocks_per_row = ncols / QK_K;
- const int ib0 = row*num_blocks_per_row;
-
- const block_q3_K * x = (const block_q3_K *)vx + ib0;
-
- float tmp = 0; // partial sum for thread in warp
-
-#if QK_K == 256
-
- const uint16_t kmask1 = 0x0303;
- const uint16_t kmask2 = 0x0f0f;
-
- const int tid =
- item_ct1.get_local_id(2) / K_QUANTS_PER_ITERATION; // 0...31 or 0...16
- const int ix =
- item_ct1.get_local_id(2) % K_QUANTS_PER_ITERATION; // 0 or 0,1
-
- const int n = K_QUANTS_PER_ITERATION; // iterations in the inner loop
- const int step = 16/K_QUANTS_PER_ITERATION;
- const int im = tid/step; // 0 or 1. 0 computes 0..., 1 computes 128...
- const int in = tid - step*im; // 0....15 or 0...7
-
- const uint8_t m = 1 << (4*im);
-
- const int l0 = n*in; // 0...15 or 0...14 in steps of 2
- const int q_offset = 32*im + l0;
- const int y_offset = 128*im + l0;
-
- uint16_t utmp[4];
- const int8_t * s = (const int8_t *)utmp;
-
- const uint16_t s_shift = 4*im;
-
- for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + y_offset;
- const uint8_t * q = x[i].qs + q_offset;
- const uint8_t * h = x[i].hmask + l0;
-
- const uint16_t * a = (const uint16_t *)x[i].scales;
- utmp[0] = ((a[0] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 0)) & kmask1) << 4);
- utmp[1] = ((a[1] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 0)) & kmask1) << 4);
- utmp[2] = ((a[2] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 2)) & kmask1) << 4);
- utmp[3] = ((a[3] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 2)) & kmask1) << 4);
-
- const float d = x[i].d;
-
- float sum = 0;
- for (int l = 0; l < n; ++l) {
- sum += y[l+ 0] * (s[0] - 32) * (((q[l] >> 0) & 3) - (h[l] & (m << 0) ? 0 : 4))
- + y[l+32] * (s[2] - 32) * (((q[l] >> 2) & 3) - (h[l] & (m << 1) ? 0 : 4))
- + y[l+64] * (s[4] - 32) * (((q[l] >> 4) & 3) - (h[l] & (m << 2) ? 0 : 4))
- + y[l+96] * (s[6] - 32) * (((q[l] >> 6) & 3) - (h[l] & (m << 3) ? 0 : 4));
- sum += y[l+16] * (s[1] - 32) * (((q[l+16] >> 0) & 3) - (h[l+16] & (m << 0) ? 0 : 4))
- + y[l+48] * (s[3] - 32) * (((q[l+16] >> 2) & 3) - (h[l+16] & (m << 1) ? 0 : 4))
- + y[l+80] * (s[5] - 32) * (((q[l+16] >> 4) & 3) - (h[l+16] & (m << 2) ? 0 : 4))
- + y[l+112] * (s[7] - 32) * (((q[l+16] >> 6) & 3) - (h[l+16] & (m << 3) ? 0 : 4));
- }
- tmp += d * sum;
-
- }
-#else
-
- const int tid = item_ct1.get_local_id(2)/(2*K_QUANTS_PER_ITERATION); // 0...15 or 0...7
- const int ix = item_ct1.get_local_id(2)%(2*K_QUANTS_PER_ITERATION); // 0....1 or 0...3
- const int offset = tid * K_QUANTS_PER_ITERATION; // 0...15 or 0...14
- const int in = offset/8; // 0 or 1
- const int im = offset%8; // 0...7
-
- for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + offset;
- const uint8_t * q = x[i].qs + offset;
- const uint8_t * s = x[i].scales;
-
- const float dall = (float)x[i].d;
-
- float sum = 0;
- for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) {
- const uint8_t hl = x[i].hmask[im+l] >> in;
- const uint8_t ql = q[l];
- sum += y[l+ 0] * dall * ((s[0] & 0xF) - 8) * ((int8_t)((ql >> 0) & 3) - ((hl >> 0) & 1 ? 0 : 4))
- + y[l+16] * dall * ((s[0] >> 4) - 8) * ((int8_t)((ql >> 2) & 3) - ((hl >> 2) & 1 ? 0 : 4))
- + y[l+32] * dall * ((s[1] & 0xF) - 8) * ((int8_t)((ql >> 4) & 3) - ((hl >> 4) & 1 ? 0 : 4))
- + y[l+48] * dall * ((s[1] >> 4) - 8) * ((int8_t)((ql >> 6) & 3) - ((hl >> 6) & 1 ? 0 : 4));
- }
- tmp += sum;
- }
-#endif
-
- // sum up partial sums and write back result
-#pragma unroll
- for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (item_ct1.get_local_id(2) == 0) {
- dst[row] = tmp;
- }
-}
-
-/*
-DPCT1110:6: The total declared local variable size in device function
-dequantize_mul_mat_vec_q4_k exceeds 128 bytes and may cause high register
-pressure. Consult with your hardware vendor to find the total register size
-available and adjust the code, or use smaller sub-group size to avoid high
-register pressure.
-*/
-static void dequantize_mul_mat_vec_q4_k(const void *__restrict__ vx,
- const float *__restrict__ yy,
- float *__restrict__ dst,
- const int ncols, int nrows,
- const sycl::nd_item<3> &item_ct1) {
-
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
- if (row > nrows) return;
- const int num_blocks_per_row = ncols / QK_K;
- const int ib0 = row*num_blocks_per_row;
-
- const block_q4_K * x = (const block_q4_K *)vx + ib0;
-
-#if QK_K == 256
- const uint16_t kmask1 = 0x3f3f;
- const uint16_t kmask2 = 0x0f0f;
- const uint16_t kmask3 = 0xc0c0;
-
- const int tid =
- item_ct1.get_local_id(2) / K_QUANTS_PER_ITERATION; // 0...31 or 0...16
- const int ix =
- item_ct1.get_local_id(2) % K_QUANTS_PER_ITERATION; // 0 or 0,1
-
- const int step = 8/K_QUANTS_PER_ITERATION; // 8 or 4
-
- const int il = tid/step; // 0...3
- const int ir = tid - step*il; // 0...7 or 0...3
- const int n = 2 * K_QUANTS_PER_ITERATION; // 2 or 4
-
- const int im = il/2; // 0 or 1. 0 computes 0,32 + 128,160, 1 computes 64,96 + 192,224
- const int in = il%2;
-
- const int l0 = n*(2*ir + in);
- const int q_offset = 32*im + l0;
- const int y_offset = 64*im + l0;
-
- uint16_t aux[4];
- const uint8_t * sc = (const uint8_t *)aux;
-
-#if K_QUANTS_PER_ITERATION == 2
- uint32_t q32[4];
- const uint8_t * q4 = (const uint8_t *)q32;
-#else
- uint16_t q16[4];
- const uint8_t * q4 = (const uint8_t *)q16;
-#endif
-
- float tmp = 0; // partial sum for thread in warp
-
- for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
-
- const float * y1 = yy + i*QK_K + y_offset;
- const float * y2 = y1 + 128;
-
- const float dall = x[i].dm[0];
- const float dmin = x[i].dm[1];
-
- const uint16_t * a = (const uint16_t *)x[i].scales;
- aux[0] = a[im+0] & kmask1;
- aux[1] = a[im+2] & kmask1;
- aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2);
- aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2);
-
-#if K_QUANTS_PER_ITERATION == 2
- const uint32_t * q1 = (const uint32_t *)(x[i].qs + q_offset);
- const uint32_t * q2 = q1 + 16;
-
- q32[0] = q1[0] & 0x0f0f0f0f;
- q32[1] = q1[0] & 0xf0f0f0f0;
- q32[2] = q2[0] & 0x0f0f0f0f;
- q32[3] = q2[0] & 0xf0f0f0f0;
-
- sycl::float4 s = {0.f, 0.f, 0.f, 0.f};
- float smin = 0;
- for (int l = 0; l < 4; ++l) {
- s.x() += y1[l] * q4[l + 0]; s.y() += y1[l + 32] * q4[l + 4];
- s.z() += y2[l] * q4[l + 8]; s.w() += y2[l + 32] * q4[l + 12];
- smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7];
- }
- tmp += dall * (s.x() * sc[0] + s.y() * sc[1] * 1.f / 16.f +
- s.z() * sc[4] + s.w() * sc[5] * 1.f / 16.f) -
- dmin * smin;
-#else
- const uint16_t * q1 = (const uint16_t *)(x[i].qs + q_offset);
- const uint16_t * q2 = q1 + 32;
-
- q16[0] = q1[0] & 0x0f0f;
- q16[1] = q1[0] & 0xf0f0;
- q16[2] = q2[0] & 0x0f0f;
- q16[3] = q2[0] & 0xf0f0;
-
- float4 s = {0.f, 0.f, 0.f, 0.f};
- float smin = 0;
- for (int l = 0; l < 2; ++l) {
- s.x += y1[l] * q4[l+0]; s.y += y1[l+32] * q4[l+2];
- s.z += y2[l] * q4[l+4]; s.w += y2[l+32] * q4[l+6];
- smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7];
- }
- tmp += dall * (s.x * sc[0] + s.y * sc[1] * 1.f/16.f + s.z * sc[4] + s.w * sc[5] * 1.f/16.f) - dmin * smin;
-#endif
-
- }
-#else
- const int tid = item_ct1.get_local_id(2)/(2*K_QUANTS_PER_ITERATION); // 0...15
- const int ix = item_ct1.get_local_id(2)%(2*K_QUANTS_PER_ITERATION);
-
- const int step = tid * K_QUANTS_PER_ITERATION;
-
- uint16_t aux16[2];
- const uint8_t * s = (const uint8_t *)aux16;
-
- float tmp = 0;
-
- for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
- const uint8_t * q = x[i].qs + step;
- const float * y = yy + i*QK_K + step;
- const uint16_t * a = (const uint16_t *)x[i].scales;
- aux16[0] = a[0] & 0x0f0f;
- aux16[1] = (a[0] >> 4) & 0x0f0f;
- const float d = (float)x[i].dm[0];
- const float m = (float)x[i].dm[1];
- float sum = 0.f;
- for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) {
- sum += y[j+ 0] * (d * s[0] * (q[j+ 0] & 0xF) - m * s[2])
- + y[j+16] * (d * s[0] * (q[j+16] & 0xF) - m * s[2])
- + y[j+32] * (d * s[1] * (q[j+ 0] >> 4) - m * s[3])
- + y[j+48] * (d * s[1] * (q[j+16] >> 4) - m * s[3]);
- }
- tmp += sum;
- }
-
-#endif
-
- // sum up partial sums and write back result
-#pragma unroll
- for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (tid == 0) {
- dst[row] = tmp;
- }
-}
-
-/*
-DPCT1110:7: The total declared local variable size in device function
-dequantize_mul_mat_vec_q5_k exceeds 128 bytes and may cause high register
-pressure. Consult with your hardware vendor to find the total register size
-available and adjust the code, or use smaller sub-group size to avoid high
-register pressure.
-*/
-static void dequantize_mul_mat_vec_q5_k(const void *__restrict__ vx,
- const float *__restrict__ yy,
- float *__restrict__ dst,
- const int ncols,
- const sycl::nd_item<3> &item_ct1) {
-
- const int row = item_ct1.get_group(2);
- const int num_blocks_per_row = ncols / QK_K;
- const int ib0 = row*num_blocks_per_row;
-
- const block_q5_K * x = (const block_q5_K *)vx + ib0;
-
- float tmp = 0; // partial sum for thread in warp
-
-#if QK_K == 256
- const uint16_t kmask1 = 0x3f3f;
- const uint16_t kmask2 = 0x0f0f;
- const uint16_t kmask3 = 0xc0c0;
-
- const int tid = item_ct1.get_local_id(2) / 2; // 0...15
- const int ix = item_ct1.get_local_id(2) % 2;
-
- const int il = tid/4; // 0...3
- const int ir = tid - 4*il;// 0...3
- const int n = 2;
-
- const int im = il/2; // 0 or 1. 0 computes 0,32 + 128,160, 1 computes 64,96 + 192,224
- const int in = il%2;
-
- const int l0 = n*(2*ir + in);
- const int q_offset = 32*im + l0;
- const int y_offset = 64*im + l0;
-
- const uint8_t hm1 = 1 << (2*im);
- const uint8_t hm2 = hm1 << 4;
-
- uint16_t aux[4];
- const uint8_t * sc = (const uint8_t *)aux;
-
- uint16_t q16[8];
- const uint8_t * q4 = (const uint8_t *)q16;
-
- for (int i = ix; i < num_blocks_per_row; i += 2) {
-
- const uint8_t * ql1 = x[i].qs + q_offset;
- const uint8_t * qh = x[i].qh + l0;
- const float * y1 = yy + i*QK_K + y_offset;
- const float * y2 = y1 + 128;
-
- const float dall = x[i].dm[0];
- const float dmin = x[i].dm[1];
-
- const uint16_t * a = (const uint16_t *)x[i].scales;
- aux[0] = a[im+0] & kmask1;
- aux[1] = a[im+2] & kmask1;
- aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2);
- aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2);
-
- sycl::float4 sum = {0.f, 0.f, 0.f, 0.f};
- float smin = 0;
- const uint16_t * q1 = (const uint16_t *)ql1;
- const uint16_t * q2 = q1 + 32;
- q16[0] = q1[0] & 0x0f0f;
- q16[1] = q1[8] & 0x0f0f;
- q16[2] = (q1[0] >> 4) & 0x0f0f;
- q16[3] = (q1[8] >> 4) & 0x0f0f;
- q16[4] = q2[0] & 0x0f0f;
- q16[5] = q2[8] & 0x0f0f;
- q16[6] = (q2[0] >> 4) & 0x0f0f;
- q16[7] = (q2[8] >> 4) & 0x0f0f;
- for (int l = 0; l < n; ++l) {
- sum.x() +=
- y1[l + 0] * (q4[l + 0] + (qh[l + 0] & (hm1 << 0) ? 16 : 0)) +
- y1[l + 16] * (q4[l + 2] + (qh[l + 16] & (hm1 << 0) ? 16 : 0));
- sum.y() +=
- y1[l + 32] * (q4[l + 4] + (qh[l + 0] & (hm1 << 1) ? 16 : 0)) +
- y1[l + 48] * (q4[l + 6] + (qh[l + 16] & (hm1 << 1) ? 16 : 0));
- sum.z() +=
- y2[l + 0] * (q4[l + 8] + (qh[l + 0] & (hm2 << 0) ? 16 : 0)) +
- y2[l + 16] * (q4[l + 10] + (qh[l + 16] & (hm2 << 0) ? 16 : 0));
- sum.w() +=
- y2[l + 32] * (q4[l + 12] + (qh[l + 0] & (hm2 << 1) ? 16 : 0)) +
- y2[l + 48] * (q4[l + 14] + (qh[l + 16] & (hm2 << 1) ? 16 : 0));
- smin += (y1[l] + y1[l+16]) * sc[2] + (y1[l+32] + y1[l+48]) * sc[3]
- + (y2[l] + y2[l+16]) * sc[6] + (y2[l+32] + y2[l+48]) * sc[7];
- }
- tmp += dall * (sum.x() * sc[0] + sum.y() * sc[1] + sum.z() * sc[4] +
- sum.w() * sc[5]) -
- dmin * smin;
- }
-
-#else
- const int tid = item_ct1.get_local_id(2)/(2*K_QUANTS_PER_ITERATION); // 0...15
- const int ix = item_ct1.get_local_id(2)%(2*K_QUANTS_PER_ITERATION);
- const int step = tid * K_QUANTS_PER_ITERATION;
- const int im = step/8;
- const int in = step%8;
-
- for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
- const uint8_t * q = x[i].qs + step;
- const int8_t * s = x[i].scales;
- const float * y = yy + i*QK_K + step;
- const float d = x[i].d;
- float sum = 0.f;
- for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) {
- const uint8_t h = x[i].qh[in+j] >> im;
- sum += y[j+ 0] * d * s[0] * ((q[j+ 0] & 0xF) - ((h >> 0) & 1 ? 0 : 16))
- + y[j+16] * d * s[1] * ((q[j+16] & 0xF) - ((h >> 2) & 1 ? 0 : 16))
- + y[j+32] * d * s[2] * ((q[j+ 0] >> 4) - ((h >> 4) & 1 ? 0 : 16))
- + y[j+48] * d * s[3] * ((q[j+16] >> 4) - ((h >> 6) & 1 ? 0 : 16));
- }
- tmp += sum;
- }
-#endif
-
- // sum up partial sums and write back result
-#pragma unroll
- for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (item_ct1.get_local_id(2) == 0) {
- dst[row] = tmp;
- }
-}
-
-static void dequantize_mul_mat_vec_q6_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols, int nrows,
- const sycl::nd_item<3> &item_ct1) {
-
- static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION");
-
- const int row = item_ct1.get_group(2) * item_ct1.get_local_range(1) +
- item_ct1.get_local_id(1);
- if (row > nrows) return;
-
- const int num_blocks_per_row = ncols / QK_K;
- const int ib0 = row*num_blocks_per_row;
-
- const block_q6_K * x = (const block_q6_K *)vx + ib0;
-
-#if QK_K == 256
-
- const int tid =
- item_ct1.get_local_id(2) / K_QUANTS_PER_ITERATION; // 0...31 or 0...16
- const int ix =
- item_ct1.get_local_id(2) % K_QUANTS_PER_ITERATION; // 0 or 0, 1
-
- const int step = 16/K_QUANTS_PER_ITERATION; // 16 or 8
-
- const int im = tid/step; // 0 or 1. 0 computes 0..., 1 computes 128...
- const int in = tid - step*im; // 0...15 or 0...7
-
-#if K_QUANTS_PER_ITERATION == 1
- const int l0 = K_QUANTS_PER_ITERATION*in; // 0...15
- const int is = 0;
-#else
- const int l0 = 4 * in; // 0, 4, 8, ..., 28
- const int is = in / 4;
-#endif
- const int ql_offset = 64*im + l0;
- const int qh_offset = 32*im + l0;
- const int s_offset = 8*im + is;
- const int y_offset = 128*im + l0;
-
- float tmp = 0; // partial sum for thread in warp
-
- for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + y_offset;
- const uint8_t * ql = x[i].ql + ql_offset;
- const uint8_t * qh = x[i].qh + qh_offset;
- const int8_t * s = x[i].scales + s_offset;
-
- const float d = x[i].d;
-
-#if K_QUANTS_PER_ITERATION == 1
- float sum = y[ 0] * s[0] * d * ((int8_t)((ql[ 0] & 0xF) | ((qh[ 0] & 0x03) << 4)) - 32)
- + y[16] * s[1] * d * ((int8_t)((ql[16] & 0xF) | ((qh[16] & 0x03) << 4)) - 32)
- + y[32] * s[2] * d * ((int8_t)((ql[32] & 0xF) | ((qh[ 0] & 0x0c) << 2)) - 32)
- + y[48] * s[3] * d * ((int8_t)((ql[48] & 0xF) | ((qh[16] & 0x0c) << 2)) - 32)
- + y[64] * s[4] * d * ((int8_t)((ql[ 0] >> 4) | ((qh[ 0] & 0x30) >> 0)) - 32)
- + y[80] * s[5] * d * ((int8_t)((ql[16] >> 4) | ((qh[16] & 0x30) >> 0)) - 32)
- + y[96] * s[6] * d * ((int8_t)((ql[32] >> 4) | ((qh[ 0] & 0xc0) >> 2)) - 32)
- +y[112] * s[7] * d * ((int8_t)((ql[48] >> 4) | ((qh[16] & 0xc0) >> 2)) - 32);
- tmp += sum;
-#else
- float sum = 0;
- for (int l = 0; l < 4; ++l) {
- sum += y[l+ 0] * s[0] * d * ((int8_t)((ql[l+ 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32)
- + y[l+32] * s[2] * d * ((int8_t)((ql[l+32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32)
- + y[l+64] * s[4] * d * ((int8_t)((ql[l+ 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32)
- + y[l+96] * s[6] * d * ((int8_t)((ql[l+32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32);
- }
- tmp += sum;
-#endif
-
- }
-
-#else
-
- const int tid = item_ct1.get_local_id(2)/(2*K_QUANTS_PER_ITERATION); // 0...7
- const int ix = item_ct1.get_local_id(2)%(2*K_QUANTS_PER_ITERATION); // 0...3
-
- const int step = tid * K_QUANTS_PER_ITERATION;
-
- float tmp = 0; // partial sum for thread in warp
-
- for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
-
- const float * y = yy + i * QK_K + step;
- const uint8_t * ql = x[i].ql + step;
- const uint8_t * qh = x[i].qh + step;
- const int8_t * s = x[i].scales;
-
- const float d = x[i+0].d;
-
- float sum = 0;
- for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) {
- sum += y[j+ 0] * s[0] * d * ((int8_t)((ql[j+ 0] & 0xF) | ((qh[j] & 0x03) << 4)) - 32)
- + y[j+16] * s[1] * d * ((int8_t)((ql[j+16] & 0xF) | ((qh[j] & 0x0c) << 2)) - 32)
- + y[j+32] * s[2] * d * ((int8_t)((ql[j+ 0] >> 4) | ((qh[j] & 0x30) >> 0)) - 32)
- + y[j+48] * s[3] * d * ((int8_t)((ql[j+16] >> 4) | ((qh[j] & 0xc0) >> 2)) - 32);
- }
- tmp += sum;
-
- }
-
-#endif
-
- // sum up partial sums and write back result
-#pragma unroll
- for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
- tmp +=
- dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
- }
-
- if (tid == 0) {
- dst[row] = tmp;
- }
-}
-
-static void dequantize_mul_mat_vec_q4_0_sycl_reorder(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- // the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec_reorder(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-
-static void dequantize_mul_mat_vec_q4_0_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- // the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-static void dequantize_mul_mat_vec_q4_1_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-static void dequantize_mul_mat_vec_q5_0_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-static void dequantize_mul_mat_vec_q5_1_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-static void dequantize_mul_mat_vec_q8_0_sycl(const void *vx, const dfloat *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % GGML_SYCL_DMMV_X == 0);
- const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1) / GGML_SYCL_MMV_Y;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, GGML_SYCL_MMV_Y, WARP_SIZE);
- {
- dpct::has_capability_or_fail(stream->get_device(),
- {sycl::aspect::fp16});
-
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(WARP_SIZE)]] {
- dequantize_mul_mat_vec(
- vx, y, dst, ncols, nrows, item_ct1);
- });
- }
-}
-
-static void dequantize_mul_mat_vec_q2_K_sycl(const void *vx, const float *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % QK_K == 0);
- const int ny = 2; // very slightly faster than 1 even when K_QUANTS_PER_ITERATION = 2
- const int block_num_y = (nrows + ny - 1) / ny;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, ny, QK_WARP_SIZE);
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(QK_WARP_SIZE)]] {
- dequantize_mul_mat_vec_q2_k(vx, y, dst, ncols, nrows, item_ct1);
- });
-}
-
-static void dequantize_mul_mat_vec_q3_K_sycl(const void *vx, const float *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % QK_K == 0);
- const int ny = 2 / K_QUANTS_PER_ITERATION;
- const int block_num_y = (nrows + ny - 1) / ny;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, ny, QK_WARP_SIZE);
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(QK_WARP_SIZE)]] {
- dequantize_mul_mat_vec_q3_k(vx, y, dst, ncols, nrows, item_ct1);
- });
-}
-
-static void dequantize_mul_mat_vec_q4_K_sycl(const void *vx, const float *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % QK_K == 0);
- const int ny = 2 / K_QUANTS_PER_ITERATION;
- const int block_num_y = (nrows + ny - 1) / ny;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, ny, QK_WARP_SIZE);
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(QK_WARP_SIZE)]] {
- dequantize_mul_mat_vec_q4_k(vx, y, dst, ncols, nrows, item_ct1);
- });
-}
-
-static void dequantize_mul_mat_vec_q5_K_sycl(const void *vx, const float *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % QK_K == 0);
- const sycl::range<3> block_dims(1, 1, QK_WARP_SIZE);
- stream->parallel_for(
- sycl::nd_range<3>(sycl::range<3>(1, 1, nrows) * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(QK_WARP_SIZE)]] {
- dequantize_mul_mat_vec_q5_k(vx, y, dst, ncols, item_ct1);
- });
-}
-
-static void dequantize_mul_mat_vec_q6_K_sycl(const void *vx, const float *y,
- float *dst, const int ncols,
- const int nrows,
- dpct::queue_ptr stream) {
- GGML_ASSERT(ncols % QK_K == 0);
- const int ny = 2 / K_QUANTS_PER_ITERATION;
- const int block_num_y = (nrows + ny - 1) / ny;
- const sycl::range<3> block_nums(1, 1, block_num_y);
- const sycl::range<3> block_dims(1, ny, QK_WARP_SIZE);
- stream->parallel_for(
- sycl::nd_range<3>(block_nums * block_dims, block_dims),
- [=](sycl::nd_item<3> item_ct1) [[sycl::reqd_sub_group_size(QK_WARP_SIZE)]] {
- dequantize_mul_mat_vec_q6_k(vx, y, dst, ncols, nrows, item_ct1);
- });
-}
-
-void ggml_sycl_op_dequantize_mul_mat_vec(
- ggml_backend_sycl_context & ctx,
- const ggml_tensor *src0, const ggml_tensor *src1, ggml_tensor *dst,
- const char *src0_dd_i, const float *src1_ddf_i, const char *src1_ddq_i,
- float *dst_dd_i, const int64_t row_low, const int64_t row_high,
- const int64_t src1_ncols, const int64_t src1_padded_row_size,
- const dpct::queue_ptr &stream) {
-
- const int64_t ne00 = src0->ne[0];
- const int64_t row_diff = row_high - row_low;
- GGML_ASSERT(src1->type == GGML_TYPE_F32);
- // on some GPUs it is faster to convert src1 to half and to use half precision intrinsics
-#ifdef GGML_SYCL_F16
- ggml_sycl_pool_alloc src1_dfloat_a(ctx.pool());
- sycl::half *src1_dfloat = nullptr; // dfloat == half
-
- bool src1_convert_f16 =
- src0->type == GGML_TYPE_Q4_0 || src0->type == GGML_TYPE_Q4_1 ||
- src0->type == GGML_TYPE_Q5_0 || src0->type == GGML_TYPE_Q5_1 ||
- src0->type == GGML_TYPE_Q8_0 || src0->type == GGML_TYPE_F16;
-
- if (src1_convert_f16) {
- src1_dfloat = src1_dfloat_a.alloc(ne00);
- const to_fp16_sycl_t to_fp16_sycl = ggml_get_to_fp16_sycl(src1->type, dst);
- GGML_ASSERT(to_fp16_sycl != nullptr);
- to_fp16_sycl(src1_ddf_i, src1_dfloat, ne00, stream);
- }
-#else
- const dfloat * src1_dfloat = (const dfloat *) src1_ddf_i; // dfloat == float, no conversion
-#endif // GGML_SYCL_F16
-
- switch (src0->type) {
- case GGML_TYPE_Q4_0:
- if ((ggml_tensor_extra_gpu*)dst->src[0]->extra &&
- ((ggml_tensor_extra_gpu*)dst->src[0]->extra)->optimized_feature.reorder) {
- dequantize_mul_mat_vec_q4_0_sycl_reorder(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- } else {
- dequantize_mul_mat_vec_q4_0_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- }
- break;
- case GGML_TYPE_Q4_1:
- dequantize_mul_mat_vec_q4_1_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q5_0:
- dequantize_mul_mat_vec_q5_0_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q5_1:
- dequantize_mul_mat_vec_q5_1_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q8_0:
- dequantize_mul_mat_vec_q8_0_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q2_K:
- dequantize_mul_mat_vec_q2_K_sycl(src0_dd_i, src1_ddf_i, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q3_K:
- dequantize_mul_mat_vec_q3_K_sycl(src0_dd_i, src1_ddf_i, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q4_K:
- dequantize_mul_mat_vec_q4_K_sycl(src0_dd_i, src1_ddf_i, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q5_K:
- dequantize_mul_mat_vec_q5_K_sycl(src0_dd_i, src1_ddf_i, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_Q6_K:
- dequantize_mul_mat_vec_q6_K_sycl(src0_dd_i, src1_ddf_i, dst_dd_i, ne00, row_diff, stream);
- break;
- case GGML_TYPE_F16:
- convert_mul_mat_vec_f16_sycl(src0_dd_i, src1_dfloat, dst_dd_i, ne00, row_diff, stream);
- break;
- default:
- printf("ggml_sycl_op_dequantize_mul_mat_vec unsupported GGML_TYPE %d\n", src0->type);
- GGML_ABORT("fatal error");
- }
-
- GGML_UNUSED(src1);
- GGML_UNUSED(dst);
- GGML_UNUSED(src1_ddq_i);
- GGML_UNUSED(src1_ncols);
- GGML_UNUSED(src1_padded_row_size);
- GGML_UNUSED(ctx);
-}
diff --git a/ggml/src/ggml-sycl/dmmv.hpp b/ggml/src/ggml-sycl/dmmv.hpp
deleted file mode 100644
index bd8373564..000000000
--- a/ggml/src/ggml-sycl/dmmv.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_DMMV_HPP
-#define GGML_SYCL_DMMV_HPP
-
-#include "common.hpp"
-
-
-void ggml_sycl_op_dequantize_mul_mat_vec(
- ggml_backend_sycl_context & ctx,
- const ggml_tensor *src0, const ggml_tensor *src1, ggml_tensor *dst,
- const char *src0_dd_i, const float *src1_ddf_i, const char *src1_ddq_i,
- float *dst_dd_i, const int64_t row_low, const int64_t row_high,
- const int64_t src1_ncols, const int64_t src1_padded_row_size,
- const dpct::queue_ptr &stream);
-
-#endif // GGML_SYCL_DMMV_HPP
diff --git a/ggml/src/ggml-sycl/dpct/helper.hpp b/ggml/src/ggml-sycl/dpct/helper.hpp
deleted file mode 100644
index d538965b0..000000000
--- a/ggml/src/ggml-sycl/dpct/helper.hpp
+++ /dev/null
@@ -1,2957 +0,0 @@
-//
-// MIT license
-// Copyright (C) 2024 Intel Corporation
-// SPDX-License-Identifier: MIT
-//
-
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-
-#ifndef GGML_SYCL_DPCT_HELPER_HPP
-#define GGML_SYCL_DPCT_HELPER_HPP
-
-#include
-#include
-#include
-#include