Safetensors
GGUF
Turkish
llama
Llama-3
instruct
finetune
chatml
gpt4
synthetic data
distillation
function calling
json mode
axolotl
roleplaying
chat
Instructions to use tda45/TdAI with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use tda45/TdAI with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="tda45/TdAI", filename="llama.cpp/models/ggml-vocab-aquila.gguf", )
output = llm( "Once upon a time,", max_tokens=512, echo=True ) print(output)
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use tda45/TdAI with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf tda45/TdAI # Run inference directly in the terminal: llama cli -hf tda45/TdAI
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./llama-cli -hf tda45/TdAI
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf tda45/TdAI # Run inference directly in the terminal: ./build/bin/llama-cli -hf tda45/TdAI
Use Docker
docker model run hf.co/tda45/TdAI
- LM Studio
- Jan
- Ollama
How to use tda45/TdAI with Ollama:
ollama run hf.co/tda45/TdAI
- Unsloth Studio
How to use tda45/TdAI with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for tda45/TdAI to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for tda45/TdAI to start chatting
- Atomic Chat new
- Docker Model Runner
How to use tda45/TdAI with Docker Model Runner:
docker model run hf.co/tda45/TdAI
- Lemonade
How to use tda45/TdAI with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull tda45/TdAI
Run and chat with the model
lemonade run user.TdAI-{{QUANT_TAG}}List all available models
lemonade list
| //------------------------------------------------------------------------------ | |
| // This file is contains kernels for data conversion. | |
| // These kernels are used when loading the model, so its performance is less | |
| // important. | |
| //------------------------------------------------------------------------------ | |
| 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_q1_0 | |
| //------------------------------------------------------------------------------ | |
| typedef struct { | |
| half d; // delta | |
| uchar qs[QK1_0/8]; // 1-bit signs (16 bytes) | |
| } block_q1_0; | |
| //------------------------------------------------------------------------------ | |
| // block_q4_0 | |
| //------------------------------------------------------------------------------ | |
| struct block_q4_0 | |
| { | |
| half d; | |
| uint8_t qs[QK4_0 / 2]; | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q4_1 | |
| //------------------------------------------------------------------------------ | |
| struct block_q4_1 { | |
| half d; // delta | |
| half m; // min | |
| uchar qs[QK4_1 / 2]; // nibbles / quants | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q5_0 | |
| //------------------------------------------------------------------------------ | |
| struct block_q5_0 { | |
| half d; // delta | |
| uchar qh[4]; // 5-th bit of quants | |
| uchar qs[QK5_0 / 2]; // nibbles / quants | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q5_1 | |
| //------------------------------------------------------------------------------ | |
| struct block_q5_1 { | |
| half d; // delta | |
| half m; // min | |
| uchar qh[4]; // 5-th bit of quants | |
| uchar qs[QK5_1 / 2]; // nibbles / quants | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q4_k | |
| //------------------------------------------------------------------------------ | |
| struct block_q4_K { | |
| half d; // delta | |
| half dm; // min | |
| uchar s[K_SCALE_SIZE]; | |
| uchar q[QK_K / 2]; // nibbles / quants | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q5_k | |
| //------------------------------------------------------------------------------ | |
| struct block_q5_K { | |
| half d; // delta | |
| half dm; // min | |
| uchar s[K_SCALE_SIZE]; | |
| uchar qh[QK_K / 8]; | |
| uchar qs[QK_K / 2]; // nibbles / quants | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // block_q6_K | |
| //------------------------------------------------------------------------------ | |
| struct block_q6_K { | |
| 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_iq4_nl | |
| //------------------------------------------------------------------------------ | |
| struct block_iq4_nl | |
| { | |
| half d; | |
| uint8_t qs[QK4_NL / 2]; | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // bf16 to f16 | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_bf16_to_f16( | |
| global const ushort * src, | |
| global half * dst, | |
| ulong off_dst, | |
| ulong n | |
| ) { | |
| uint i = get_global_id(0); | |
| if (i >= n) { | |
| return; | |
| } | |
| dst[i + off_dst] = (half) as_float((uint) src[i] << 16); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // f16 to bf16 | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_f16_to_bf16( | |
| global const half * src, | |
| ulong off_src, | |
| global ushort * dst, | |
| ulong n | |
| ) { | |
| uint i = get_global_id(0); | |
| if (i >= n) { | |
| return; | |
| } | |
| float f = (float) src[i + off_src]; | |
| uint bits = as_uint(f); | |
| if ((bits & 0x7fffffffu) > 0x7f800000u) { | |
| // nan to quiet nan | |
| dst[i] = (ushort)((bits >> 16) | 0x40u); | |
| } else { | |
| uint rounded = bits + 0x7fffu + ((bits >> 16) & 1u); | |
| dst[i] = (ushort)(rounded >> 16); | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q1_0 | |
| // Convert block_q1_0 (AOS) to 2 separate arrays (SOA): quant bytes + scales. | |
| // q1_0 bits are stored in natural order (bit j of byte i -> weight 8*i + j) | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q1_0( | |
| global block_q1_0 * src0, | |
| global uchar * dst_q, | |
| global half * dst_d | |
| ) { | |
| global block_q1_0 * b = (global block_q1_0 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + (QK1_0/8)*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| for (int i = 0; i < QK1_0/8; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q1_0( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global block_q1_0 * dst | |
| ) { | |
| global block_q1_0 * b = (global block_q1_0 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + (QK1_0/8)*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| b->d = *d; | |
| for (int i = 0; i < QK1_0/8; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // 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); | |
| // 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)); | |
| } | |
| } | |
| } | |
| kernel void kernel_restore_block_q4_0_noshuffle( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global struct block_q4_0 * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| 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/4; ++i) { | |
| uchar x0 = q[i + 0 ] ; | |
| uchar x1 = q[i + QK4_0/4]; | |
| b->qs[2*i + 0] = convert_uchar((x0 & mask_0F) | ((x1 & mask_0F) << 4)); | |
| b->qs[2*i + 1] = convert_uchar(((x0 & mask_F0) >> 4) | (x1 & mask_F0)); | |
| } | |
| } | |
| kernel void kernel_convert_block_q4_0_trans4_ns( | |
| global struct block_q4_0 * src0, | |
| __global uint * dst_q, | |
| __global half * dst_d, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK4_0; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_q4_0 * b = src0 + src_blk_offset; | |
| dst_d[dst_blk_offset] = b->d; | |
| // extract quantization and unshuffle | |
| ushort8 pre_block = ((global ushort8 *)(&(b->qs[0])))[0]; | |
| ushort8 post_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK4_0 / 4; ++i) { | |
| uchar x0 = pre_block_ptr[2*i + 0]; | |
| uchar x1 = pre_block_ptr[2*i + 1]; | |
| post_block_ptr[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| post_block_ptr[i + QK4_0 / 4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| uint4 q_block = as_uint4(post_block); | |
| uint offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| dst_q[offset] = q_block.x; | |
| dst_q[offset + ne01] = q_block.y; | |
| dst_q[offset + ne01 * 2] = q_block.z; | |
| dst_q[offset + ne01 * 3] = q_block.w; | |
| } | |
| kernel void kernel_restore_block_q4_0_trans4_ns( | |
| __global uint * src_q, | |
| __global half * src_d, | |
| __global struct block_q4_0 * dst0, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK4_0; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint src_d_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q4_0 * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_d_offset]; | |
| // collect transposed quantization parts for a block | |
| uint src_q_offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| uint4 q_block; | |
| q_block.x = src_q[src_q_offset]; | |
| q_block.y = src_q[src_q_offset + ne01]; | |
| q_block.z = src_q[src_q_offset + ne01 * 2]; | |
| q_block.w = src_q[src_q_offset + ne01 * 3]; | |
| ushort8 post_block = as_ushort8(q_block); | |
| ushort8 pre_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK4_0 / 4; ++i) { | |
| uchar x0 = post_block_ptr[i + 0]; | |
| uchar x1 = post_block_ptr[i + QK4_0 / 4]; | |
| pre_block_ptr[2 * i + 0] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| pre_block_ptr[2 * i + 1] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| ((__global ushort8 *)(&(b->qs[0])))[0] = pre_block; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q4_1 | |
| // Convert the block_q4_1 format to 2 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q4_1( | |
| global struct block_q4_1 * src0, | |
| global uchar * dst_q, | |
| global half * dst_d, | |
| global half * dst_m | |
| ) { | |
| global struct block_q4_1 * b = (global struct block_q4_1 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK4_1/2*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * m = (global half *) dst_m + get_global_id(0); | |
| *d = b->d; | |
| *m = b->m; | |
| for (int i = 0; i < QK4_1/2; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q4_1( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global half * src_m, | |
| global struct block_q4_1 * dst | |
| ) { | |
| global struct block_q4_1 * b = (global struct block_q4_1 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK4_1/2*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * m = (global half *) src_m + get_global_id(0); | |
| b->d = *d; | |
| b->m = *m; | |
| for (int i = 0; i < QK4_1/2; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q4_1_noshuffle( | |
| global struct block_q4_1 * src0, | |
| global uchar * dst_q, | |
| global half * dst_d, | |
| global half * dst_m | |
| ) { | |
| global struct block_q4_1 * b = (global struct block_q4_1 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK4_1/2*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * m = (global half *) dst_m + get_global_id(0); | |
| *d = b->d; | |
| *m = b->m; | |
| for (int i = 0; i < QK4_1/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_1/4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| if (get_global_id(0) == 65536*4096) { | |
| printf("%04x - %02x\n", *(global ushort*)d, ((x0 & 0xF0) >> 4) | (x1 & 0xF0)); | |
| } | |
| } | |
| } | |
| kernel void kernel_restore_block_q4_1_noshuffle( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global half * src_m, | |
| global struct block_q4_1 * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q4_1 * b = (global struct block_q4_1 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK4_1/2*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * m = (global half *) src_m + get_global_id(0); | |
| b->d = *d; | |
| b->m = *m; | |
| for (int i = 0; i < QK4_1/4; ++i) { | |
| uchar x0 = q[i + 0 ] ; | |
| uchar x1 = q[i + QK4_1/4]; | |
| b->qs[2*i + 0] = convert_uchar((x0 & mask_0F) | ((x1 & mask_0F) << 4)); | |
| b->qs[2*i + 1] = convert_uchar(((x0 & mask_F0) >> 4) | (x1 & mask_F0)); | |
| } | |
| } | |
| kernel void kernel_convert_block_q4_1_trans4_ns( | |
| __global struct block_q4_1 * src0, | |
| __global uint * dst_q, | |
| __global half * dst_d, | |
| __global half * dst_m, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK4_1; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_q4_1 * b = src0 + src_blk_offset; | |
| dst_d[dst_blk_offset] = b->d; | |
| dst_m[dst_blk_offset] = b->m; | |
| // extract quantization and unshuffle | |
| ushort8 pre_block = ((global ushort8 *)(&(b->qs[0])))[0]; | |
| ushort8 post_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK4_1 / 4; ++i) { | |
| uchar x0 = pre_block_ptr[2*i + 0]; | |
| uchar x1 = pre_block_ptr[2*i + 1]; | |
| post_block_ptr[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| post_block_ptr[i + QK4_1 / 4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| uint4 q_block = as_uint4(post_block); | |
| uint offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| dst_q[offset] = q_block.x; | |
| dst_q[offset + ne01] = q_block.y; | |
| dst_q[offset + ne01 * 2] = q_block.z; | |
| dst_q[offset + ne01 * 3] = q_block.w; | |
| } | |
| kernel void kernel_restore_block_q4_1_trans4_ns( | |
| __global uint * src_q, | |
| __global half * src_d, | |
| __global half * src_m, | |
| __global struct block_q4_1 * dst0, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| int i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK4_1; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint src_dm_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q4_1 * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_dm_offset]; | |
| b->m = src_m[src_dm_offset]; | |
| // collect transposed quantization parts for a block | |
| uint src_q_offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| uint4 q_block; | |
| q_block.x = src_q[src_q_offset]; | |
| q_block.y = src_q[src_q_offset + ne01]; | |
| q_block.z = src_q[src_q_offset + ne01 * 2]; | |
| q_block.w = src_q[src_q_offset + ne01 * 3]; | |
| ushort8 post_block = as_ushort8(q_block); | |
| ushort8 pre_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK4_0 / 4; ++i) { | |
| uchar x0 = post_block_ptr[i + 0]; | |
| uchar x1 = post_block_ptr[i + QK4_0 / 4]; | |
| pre_block_ptr[2 * i + 0] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| pre_block_ptr[2 * i + 1] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| ((__global ushort8 *)(&(b->qs[0])))[0] = pre_block; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q5_0 | |
| // Convert the block_q5_0 format to 3 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q5_0( | |
| global struct block_q5_0 * src0, | |
| global uchar * dst_qs, | |
| global uint * dst_qh, | |
| global half * dst_d, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q5_0 * b = (global struct block_q5_0 *) src0 + get_global_id(0); | |
| global uchar * qs = (global uchar *) dst_qs + (QK5_0/2)*get_global_id(0); | |
| global uint * qh = (global uint *) dst_qh + get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| *qh = *((global uint *)(b->qh)); | |
| for (int i = 0; i < QK5_0/2; ++i) { | |
| qs[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_0( | |
| global uchar * src_qs, | |
| global uint * src_qh, | |
| global half * src_d, | |
| global struct block_q5_0 * dst | |
| ) { | |
| global struct block_q5_0 * b = (global struct block_q5_0 *) dst + get_global_id(0); | |
| global uchar * qs = (global uchar *) src_qs + (QK5_0/2)*get_global_id(0); | |
| global uint * qh = (global uint *) src_qh + get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| b->d = *d; | |
| *((global uint *)(b->qh)) = *qh; | |
| for (int i = 0; i < QK5_0/2; ++i) { | |
| b->qs[i] = qs[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_0_noshuffle( | |
| global struct block_q5_0 * src0, | |
| global uchar * dst_q, | |
| global uint * dst_qh, | |
| global half * dst_d | |
| ) { | |
| global struct block_q5_0 * b = (global struct block_q5_0 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK5_0/2*get_global_id(0); | |
| global uint * qh = (global uint *) dst_qh + get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| *qh = *((global uint *)(b->qh)); | |
| for (int i = 0; i < QK5_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 + QK5_0/4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| if (get_global_id(0) == 65536*4096) { | |
| printf("%04x - %02x\n", *(global ushort*)d, ((x0 & 0xF0) >> 4) | (x1 & 0xF0)); | |
| } | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_0_noshuffle( | |
| global uchar * src_q, | |
| global uint * src_qh, | |
| global half * src_d, | |
| global struct block_q5_0 * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_0 * b = (global struct block_q5_0 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK5_0/2*get_global_id(0); | |
| global uint * qh = (global uint *) src_qh + get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| b->d = *d; | |
| *((global uint *)(b->qh)) = *qh; | |
| for (int i = 0; i < QK5_0/4; ++i) { | |
| uchar x0 = q[i + 0 ]; | |
| uchar x1 = q[i + QK5_0/4]; | |
| b->qs[2*i + 0] = convert_uchar((x0 & mask_0F) | ((x1 & mask_0F) << 4)); | |
| b->qs[2*i + 1] = convert_uchar(((x0 & mask_F0) >> 4) | (x1 & mask_F0)); | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_0_trans4_ns( | |
| __global struct block_q5_0 * src0, | |
| __global uint * dst_qs, | |
| __global uint * dst_qh, | |
| __global half * dst_d, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK5_0; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_q5_0 * b = src0 + src_blk_offset; | |
| dst_d[dst_blk_offset] = b->d; | |
| dst_qh[dst_blk_offset] = ((global uint *)(&(b->qh[0])))[0]; | |
| // extract quantization and unshuffle | |
| ushort8 pre_block = ((global ushort8 *)(&(b->qs[0])))[0]; | |
| ushort8 post_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK5_0 / 4; ++i) { | |
| uchar x0 = pre_block_ptr[2*i + 0]; | |
| uchar x1 = pre_block_ptr[2*i + 1]; | |
| post_block_ptr[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| post_block_ptr[i + QK5_0 / 4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| uint4 q_block = as_uint4(post_block); | |
| uint offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| dst_qs[offset] = q_block.x; | |
| dst_qs[offset + ne01] = q_block.y; | |
| dst_qs[offset + ne01 * 2] = q_block.z; | |
| dst_qs[offset + ne01 * 3] = q_block.w; | |
| } | |
| kernel void kernel_restore_block_q5_0_trans4_ns( | |
| __global uint * src_qs, | |
| __global uint * src_qh, | |
| __global half * src_d, | |
| __global struct block_q5_0 * dst0, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| int i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK5_0; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q5_0 * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_blk_offset]; | |
| ((__global uint *)(&(b->qh[0])))[0] = src_qh[src_blk_offset]; | |
| // collect transposed quantization parts for a block | |
| uint src_q_offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| uint4 q_block; | |
| q_block.x = src_qs[src_q_offset]; | |
| q_block.y = src_qs[src_q_offset + ne01]; | |
| q_block.z = src_qs[src_q_offset + ne01 * 2]; | |
| q_block.w = src_qs[src_q_offset + ne01 * 3]; | |
| ushort8 post_block = as_ushort8(q_block); | |
| ushort8 pre_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK5_0 / 4; ++i) { | |
| uchar x0 = post_block_ptr[i + 0]; | |
| uchar x1 = post_block_ptr[i + QK5_0 / 4]; | |
| pre_block_ptr[2 * i + 0] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| pre_block_ptr[2 * i + 1] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| ((__global ushort8 *)(&(b->qs[0])))[0] = pre_block; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q5_1 | |
| // Convert the block_q5_1 format to 4 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q5_1( | |
| global struct block_q5_1 * src0, | |
| global uchar * dst_qs, | |
| global uint * dst_qh, | |
| global half * dst_d, | |
| global half * dst_m, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q5_1 * b = (global struct block_q5_1 *) src0 + get_global_id(0); | |
| global uchar * qs = (global uchar *) dst_qs + (QK5_1/2)*get_global_id(0); | |
| global uint * qh = (global uint *) dst_qh + get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * m = (global half *) dst_m + get_global_id(0); | |
| *d = b->d; | |
| *m = b->m; | |
| *qh = *((global uint *)(b->qh)); | |
| for (int i = 0; i < QK5_1/2; ++i) { | |
| qs[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_1( | |
| global uchar * src_qs, | |
| global uint * src_qh, | |
| global half * src_d, | |
| global half * src_m, | |
| global struct block_q5_1 * dst | |
| ) { | |
| global struct block_q5_1 * b = (global struct block_q5_1 *) dst + get_global_id(0); | |
| global uchar * qs = (global uchar *) src_qs + (QK5_1/2)*get_global_id(0); | |
| global uint * qh = (global uint *) src_qh + get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * m = (global half *) src_m + get_global_id(0); | |
| b->d = *d; | |
| b->m = *m; | |
| *((global uint *)(b->qh)) = *qh; | |
| for (int i = 0; i < QK5_1/2; ++i) { | |
| b->qs[i] = qs[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_1_noshuffle( | |
| global struct block_q5_1 * src0, | |
| global uchar * dst_q, | |
| global uint * dst_qh, | |
| global half * dst_d, | |
| global half * dst_m | |
| ) { | |
| global struct block_q5_1 * b = (global struct block_q5_1 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK5_1/2*get_global_id(0); | |
| global uint * qh = (global uint *) dst_qh + get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * m = (global half *) dst_m + get_global_id(0); | |
| *d = b->d; | |
| *m = b->m; | |
| *qh = *((global uint *)(b->qh)); | |
| for (int i = 0; i < QK5_1/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 + QK5_1/4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| if (get_global_id(0) == 65536*4096) { | |
| printf("%04x - %02x\n", *(global ushort*)d, ((x0 & 0xF0) >> 4) | (x1 & 0xF0)); | |
| } | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_1_noshuffle( | |
| global uchar * src_q, | |
| global uint * src_qh, | |
| global half * src_d, | |
| global half * src_m, | |
| global struct block_q5_1 * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_1 * b = (global struct block_q5_1 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK5_1/2*get_global_id(0); | |
| global uint * qh = (global uint *) src_qh + get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * m = (global half *) src_m + get_global_id(0); | |
| b->d = *d; | |
| b->m = *m; | |
| *((global uint *)(b->qh)) = *qh; | |
| for (int i = 0; i < QK5_1/4; ++i) { | |
| uchar x0 = q[i + 0 ]; | |
| uchar x1 = q[i + QK5_1/4]; | |
| b->qs[2*i + 0] = convert_uchar((x0 & mask_0F) | ((x1 & mask_0F) << 4)); | |
| b->qs[2*i + 1] = convert_uchar(((x0 & mask_F0) >> 4) | (x1 & mask_F0)); | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_1_trans4_ns( | |
| __global struct block_q5_1 * src0, | |
| __global uint * dst_qs, | |
| __global uint * dst_qh, | |
| __global half * dst_d, | |
| __global half * dst_m, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK5_1; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_q5_1 * b = src0 + src_blk_offset; | |
| dst_d[dst_blk_offset] = b->d; | |
| dst_m[dst_blk_offset] = b->m; | |
| dst_qh[dst_blk_offset] = ((global uint *)(&(b->qh[0])))[0]; | |
| // extract quantization and unshuffle | |
| ushort8 pre_block = ((global ushort8 *)(&(b->qs[0])))[0]; | |
| ushort8 post_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK5_1 / 4; ++i) { | |
| uchar x0 = pre_block_ptr[2*i + 0]; | |
| uchar x1 = pre_block_ptr[2*i + 1]; | |
| post_block_ptr[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| post_block_ptr[i + QK5_1 / 4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| uint4 q_block = as_uint4(post_block); | |
| uint offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| dst_qs[offset] = q_block.x; | |
| dst_qs[offset + ne01] = q_block.y; | |
| dst_qs[offset + ne01 * 2] = q_block.z; | |
| dst_qs[offset + ne01 * 3] = q_block.w; | |
| } | |
| kernel void kernel_restore_block_q5_1_trans4_ns( | |
| __global uint * src_qs, | |
| __global uint * src_qh, | |
| __global half * src_d, | |
| __global half * src_m, | |
| __global struct block_q5_1 * dst0, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| int i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK5_1; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q5_1 * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_blk_offset]; | |
| b->m = src_m[src_blk_offset]; | |
| ((__global uint *)(&(b->qh[0])))[0] = src_qh[src_blk_offset]; | |
| // collect transposed quantization parts for a block | |
| uint src_q_offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| uint4 q_block; | |
| q_block.x = src_qs[src_q_offset]; | |
| q_block.y = src_qs[src_q_offset + ne01]; | |
| q_block.z = src_qs[src_q_offset + ne01 * 2]; | |
| q_block.w = src_qs[src_q_offset + ne01 * 3]; | |
| ushort8 post_block = as_ushort8(q_block); | |
| ushort8 pre_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK5_1 / 4; ++i) { | |
| uchar x0 = post_block_ptr[i + 0]; | |
| uchar x1 = post_block_ptr[i + QK5_1 / 4]; | |
| pre_block_ptr[2 * i + 0] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| pre_block_ptr[2 * i + 1] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| ((__global ushort8 *)(&(b->qs[0])))[0] = pre_block; | |
| } | |
| kernel void kernel_convert_block_q4_k_trans4_ns( | |
| __global struct block_q4_K * src0, | |
| __global uint * dst_q, | |
| __global half * dst_d, | |
| __global half * dst_dm, | |
| __global uchar * dst_s, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q4_K * b = src0 + src_blk_offset; | |
| dst_d [dst_blk_offset] = b->d; | |
| dst_dm[dst_blk_offset] = b->dm; | |
| uint4 qv[8]; | |
| uchar * qv_bytes = (uchar *)qv; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar x0 = b->q[i*32 + 2*j]; | |
| uchar x1 = b->q[i*32 + 2*j + 1]; | |
| qv_bytes[i*32 + j ] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| qv_bytes[i*32 + j + 16] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| } | |
| } | |
| uint base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| for (int p = 0; p < 8; ++p) { | |
| uint4 v = qv[p]; | |
| dst_q[base + (p * 4 + 0) * ne01] = v.x; | |
| dst_q[base + (p * 4 + 1) * ne01] = v.y; | |
| dst_q[base + (p * 4 + 2) * ne01] = v.z; | |
| dst_q[base + (p * 4 + 3) * ne01] = v.w; | |
| } | |
| __global uchar * s_dst = dst_s + (i02 * ne01 + i01) * ne00_blk * K_SCALE_SIZE + i00 * K_SCALE_SIZE; | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s_dst[i] = b->s[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q4_k_trans4_ns( | |
| __global uint * src_q, | |
| __global half * src_d, | |
| __global half * src_dm, | |
| __global uchar * src_s, | |
| __global struct block_q4_K * dst0, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); // block index along K | |
| uint i01 = get_global_id(0); // row index | |
| uint i02 = get_global_id(2); // batch index | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| __global struct block_q4_K * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_blk_offset]; | |
| b->dm = src_dm[src_blk_offset]; | |
| __global uchar * s_src = src_s + (i02 * ne01 + i01) * ne00_blk * K_SCALE_SIZE + i00 * K_SCALE_SIZE; | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s_src[i]; | |
| } | |
| uint base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| uint4 qv[8]; | |
| for (int p = 0; p < 8; ++p) { | |
| qv[p].x = src_q[base + (p * 4 + 0) * ne01]; | |
| qv[p].y = src_q[base + (p * 4 + 1) * ne01]; | |
| qv[p].z = src_q[base + (p * 4 + 2) * ne01]; | |
| qv[p].w = src_q[base + (p * 4 + 3) * ne01]; | |
| } | |
| uchar * qv_bytes = (uchar *)qv; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar lo = qv_bytes[i*32 + j]; | |
| uchar hi = qv_bytes[i*32 + j + 16]; | |
| b->q[i*32 + 2*j] = convert_uchar((lo & mask_0F) | ((hi & mask_0F) << 4)); | |
| b->q[i*32 + 2*j + 1] = convert_uchar(((lo & mask_F0) >> 4) | (hi & mask_F0)); | |
| } | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_k_trans4_ns( | |
| __global struct block_q5_K * src0, | |
| __global uint * dst_qs, | |
| __global uint * dst_qh, | |
| __global half * dst_d, | |
| __global half * dst_dm, | |
| __global uchar * dst_s, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q5_K * b = src0 + src_blk_offset; | |
| dst_d [dst_blk_offset] = b->d; | |
| dst_dm[dst_blk_offset] = b->dm; | |
| for (int k = 0; k < 8; k++) { | |
| uchar b0 = 0, b1 = 0, b2 = 0, b3 = 0; | |
| for (int bit = 0; bit < 8; bit++) { | |
| b0 |= (uchar)(((b->qh[bit] >> k) & 1) << bit); | |
| b1 |= (uchar)(((b->qh[8 + bit] >> k) & 1) << bit); | |
| b2 |= (uchar)(((b->qh[16 + bit] >> k) & 1) << bit); | |
| b3 |= (uchar)(((b->qh[24 + bit] >> k) & 1) << bit); | |
| } | |
| uint packed = (uint)b0 | ((uint)b1 << 8) | ((uint)b2 << 16) | ((uint)b3 << 24); | |
| dst_qh[i01 + (i00 * 8 + k) * ne01 + i02 * ne00_blk * 8 * ne01] = packed; | |
| } | |
| uint4 qv[8]; | |
| uchar * qv_bytes = (uchar *)qv; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar x0 = b->qs[i*32 + 2*j]; | |
| uchar x1 = b->qs[i*32 + 2*j + 1]; | |
| qv_bytes[i*32 + j ] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| qv_bytes[i*32 + j + 16] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| } | |
| } | |
| uint base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| for (int p = 0; p < 8; ++p) { | |
| uint4 v = qv[p]; | |
| dst_qs[base + (p * 4 + 0) * ne01] = v.x; | |
| dst_qs[base + (p * 4 + 1) * ne01] = v.y; | |
| dst_qs[base + (p * 4 + 2) * ne01] = v.z; | |
| dst_qs[base + (p * 4 + 3) * ne01] = v.w; | |
| } | |
| __global uchar * s_dst = dst_s + (i02 * ne01 + i01) * ne00_blk * K_SCALE_SIZE + i00 * K_SCALE_SIZE; | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s_dst[i] = b->s[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_k_trans4_ns( | |
| __global uint * src_qs, | |
| __global uint * src_qh, | |
| __global half * src_d, | |
| __global half * src_dm, | |
| __global uchar * src_s, | |
| __global struct block_q5_K * dst0, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); // block index along K | |
| uint i01 = get_global_id(0); // row index | |
| uint i02 = get_global_id(2); // batch index | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| __global struct block_q5_K * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_blk_offset]; | |
| b->dm = src_dm[src_blk_offset]; | |
| for (int j = 0; j < 32; j++) b->qh[j] = 0; | |
| for (int k = 0; k < 8; k++) { | |
| uint packed = src_qh[i01 + (i00 * 8 + k) * ne01 + i02 * ne00_blk * 8 * ne01]; | |
| uchar b0 = (uchar)(packed & 0xFF); | |
| uchar b1 = (uchar)((packed >> 8) & 0xFF); | |
| uchar b2 = (uchar)((packed >> 16) & 0xFF); | |
| uchar b3 = (uchar)((packed >> 24) & 0xFF); | |
| for (int bit = 0; bit < 8; bit++) { | |
| b->qh[bit] |= (uchar)(((b0 >> bit) & 1) << k); | |
| b->qh[8 + bit] |= (uchar)(((b1 >> bit) & 1) << k); | |
| b->qh[16 + bit] |= (uchar)(((b2 >> bit) & 1) << k); | |
| b->qh[24 + bit] |= (uchar)(((b3 >> bit) & 1) << k); | |
| } | |
| } | |
| __global uchar * s_src = src_s + (i02 * ne01 + i01) * ne00_blk * K_SCALE_SIZE + i00 * K_SCALE_SIZE; | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s_src[i]; | |
| } | |
| uint base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| uint4 qv[8]; | |
| for (int p = 0; p < 8; ++p) { | |
| qv[p].x = src_qs[base + (p * 4 + 0) * ne01]; | |
| qv[p].y = src_qs[base + (p * 4 + 1) * ne01]; | |
| qv[p].z = src_qs[base + (p * 4 + 2) * ne01]; | |
| qv[p].w = src_qs[base + (p * 4 + 3) * ne01]; | |
| } | |
| uchar * qv_bytes = (uchar *)qv; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar lo = qv_bytes[i*32 + j]; | |
| uchar hi = qv_bytes[i*32 + j + 16]; | |
| b->qs[i*32 + 2*j] = convert_uchar((lo & mask_0F) | ((hi & mask_0F) << 4)); | |
| b->qs[i*32 + 2*j + 1] = convert_uchar(((lo & mask_F0) >> 4) | (hi & mask_F0)); | |
| } | |
| } | |
| } | |
| kernel void kernel_convert_block_q6_k_trans4_ns( | |
| __global struct block_q6_K * src0, | |
| __global uint * dst_ql, | |
| __global uint * dst_qh, | |
| __global half * dst_d, | |
| __global char * dst_s, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_q6_K * b = src0 + src_blk_offset; | |
| dst_d[dst_blk_offset] = b->d; | |
| uint4 qlv[8]; | |
| uchar * qlv_bytes = (uchar *)qlv; | |
| for (int i = 0; i < 2; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar x0 = b->ql[i*64 + 2*j]; | |
| uchar x1 = b->ql[i*64 + 2*j + 1]; | |
| uchar x2 = b->ql[i*64 + 32 + 2*j]; | |
| uchar x3 = b->ql[i*64 + 32 + 2*j + 1]; | |
| qlv_bytes[i*64 + j ] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| qlv_bytes[i*64 + j + 16] = convert_uchar(x2 & mask_0F) | convert_uchar((x3 & mask_0F) << 4); | |
| qlv_bytes[i*64 + j + 32] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| qlv_bytes[i*64 + j + 48] = convert_uchar((x2 & mask_F0) >> 4) | convert_uchar(x3 & mask_F0); | |
| } | |
| } | |
| uint ql_base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| for (int p = 0; p < 8; ++p) { | |
| uint4 v = qlv[p]; | |
| dst_ql[ql_base + (p * 4 + 0) * ne01] = v.x; | |
| dst_ql[ql_base + (p * 4 + 1) * ne01] = v.y; | |
| dst_ql[ql_base + (p * 4 + 2) * ne01] = v.z; | |
| dst_ql[ql_base + (p * 4 + 3) * ne01] = v.w; | |
| } | |
| uint qhv[16] = {0}; | |
| for (int n = 0; n < 2; ++n) { | |
| for (int l = 0; l < 32; ++l) { | |
| uchar h = b->qh[n*32 + l]; | |
| int u = l / 16; | |
| int bit_pos = (l % 16) * 2; | |
| qhv[(n*4 + 0)*2 + u] |= ((uint)((h >> 0) & 0x03)) << bit_pos; | |
| qhv[(n*4 + 1)*2 + u] |= ((uint)((h >> 2) & 0x03)) << bit_pos; | |
| qhv[(n*4 + 2)*2 + u] |= ((uint)((h >> 4) & 0x03)) << bit_pos; | |
| qhv[(n*4 + 3)*2 + u] |= ((uint)((h >> 6) & 0x03)) << bit_pos; | |
| } | |
| } | |
| uint qh_base = i02 * ne00_blk * ne01 * 16 + i00 * ne01 * 16 + i01; | |
| for (int p = 0; p < 16; ++p) { | |
| dst_qh[qh_base + p * ne01] = qhv[p]; | |
| } | |
| __global char * s_dst = dst_s + (i02 * ne01 + i01) * ne00_blk * 16 + i00 * 16; | |
| for (int i = 0; i < 16; ++i) { | |
| s_dst[i] = b->scales[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q6_k_trans4_ns( | |
| __global uint * src_ql, | |
| __global uint * src_qh, | |
| __global half * src_d, | |
| __global char * src_s, | |
| __global struct block_q6_K * dst0, | |
| uint ne00, | |
| uint ne01, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| uint i00 = get_global_id(1); // block index along K | |
| uint i01 = get_global_id(0); // row index | |
| uint i02 = get_global_id(2); // batch index | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_K; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| __global struct block_q6_K * b = dst0 + dst_blk_offset; | |
| b->d = src_d[src_blk_offset]; | |
| uint ql_base = i02 * ne00_blk * ne01 * 32 + i00 * ne01 * 32 + i01; | |
| uint4 qlv[8]; | |
| for (int p = 0; p < 8; ++p) { | |
| qlv[p].x = src_ql[ql_base + (p * 4 + 0) * ne01]; | |
| qlv[p].y = src_ql[ql_base + (p * 4 + 1) * ne01]; | |
| qlv[p].z = src_ql[ql_base + (p * 4 + 2) * ne01]; | |
| qlv[p].w = src_ql[ql_base + (p * 4 + 3) * ne01]; | |
| } | |
| uchar * qlv_bytes = (uchar *)qlv; | |
| for (int i = 0; i < 2; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar lo_02 = qlv_bytes[i*64 + j]; | |
| uchar lo_13 = qlv_bytes[i*64 + j + 16]; | |
| uchar hi_02 = qlv_bytes[i*64 + j + 32]; | |
| uchar hi_13 = qlv_bytes[i*64 + j + 48]; | |
| b->ql[i*64 + 2*j] = convert_uchar((lo_02 & mask_0F) | ((hi_02 & mask_0F) << 4)); | |
| b->ql[i*64 + 2*j + 1] = convert_uchar(((lo_02 & mask_F0) >> 4) | (hi_02 & mask_F0)); | |
| b->ql[i*64 + 32 + 2*j] = convert_uchar((lo_13 & mask_0F) | ((hi_13 & mask_0F) << 4)); | |
| b->ql[i*64 + 32 + 2*j + 1] = convert_uchar(((lo_13 & mask_F0) >> 4) | (hi_13 & mask_F0)); | |
| } | |
| } | |
| uint qh_base = i02 * ne00_blk * ne01 * 16 + i00 * ne01 * 16 + i01; | |
| uint qhv[16]; | |
| for (int p = 0; p < 16; ++p) { | |
| qhv[p] = src_qh[qh_base + p * ne01]; | |
| } | |
| for (int n = 0; n < 2; ++n) { | |
| for (int l = 0; l < 32; ++l) { | |
| int u = l / 16; | |
| int bit_pos = (l % 16) * 2; | |
| uchar v0 = (uchar)((qhv[(n*4 + 0)*2 + u] >> bit_pos) & 0x03); | |
| uchar v1 = (uchar)((qhv[(n*4 + 1)*2 + u] >> bit_pos) & 0x03); | |
| uchar v2 = (uchar)((qhv[(n*4 + 2)*2 + u] >> bit_pos) & 0x03); | |
| uchar v3 = (uchar)((qhv[(n*4 + 3)*2 + u] >> bit_pos) & 0x03); | |
| b->qh[n*32 + l] = v0 | (v1 << 2) | (v2 << 4) | (v3 << 6); | |
| } | |
| } | |
| __global char * s_src = src_s + (i02 * ne01 + i01) * ne00_blk * 16 + i00 * 16; | |
| for (int i = 0; i < 16; ++i) { | |
| b->scales[i] = s_src[i]; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // block_mxfp4 | |
| //------------------------------------------------------------------------------ | |
| struct block_mxfp4 { | |
| uchar e; // E8M0 | |
| uchar qs[QK_MXFP4 / 2]; | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_mxfp4 | |
| // Convert the block_mxfp4 format to 2 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_mxfp4( | |
| global struct block_mxfp4 * src0, | |
| global uchar * dst_q, | |
| global uchar * dst_e | |
| ) { | |
| global struct block_mxfp4 * b = (global struct block_mxfp4 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK_MXFP4 / 2 * get_global_id(0); | |
| global uchar * e = (global uchar *) dst_e + get_global_id(0); | |
| *e = b->e; | |
| for (int i = 0; i < QK_MXFP4 / 2; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_mxfp4_trans( | |
| global struct block_mxfp4 * src0, | |
| __global uint4 * dst_q, | |
| __global uchar * dst_e, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| int i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| uint ne00_blk = ne00 / QK_MXFP4; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_mxfp4 * b = src0 + src_blk_offset; | |
| dst_q[dst_blk_offset] = ((global uint4 *)(&(b->qs[0])))[0]; | |
| dst_e[dst_blk_offset] = b->e; | |
| } | |
| kernel void kernel_restore_block_mxfp4( | |
| global uchar * src_q, | |
| global half * src_e, | |
| global struct block_mxfp4 * dst | |
| ) { | |
| global struct block_mxfp4 * b = (global struct block_mxfp4 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK_MXFP4 / 2 * get_global_id(0); | |
| global uchar * e = (global uchar *) src_e + get_global_id(0); | |
| b->e = *e; | |
| for (int i = 0; i < QK_MXFP4 / 2; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_mxfp4_trans( | |
| __global uint4 * src_q, | |
| __global uchar * src_e, | |
| global struct block_mxfp4 * dst, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| int i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| uint ne00_blk = ne00 / QK_MXFP4; | |
| uint src_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| global struct block_mxfp4 * b = dst + dst_blk_offset; | |
| ((global uint4 *)(&(b->qs[0])))[0] = src_q[src_blk_offset]; | |
| b->e = src_e[src_blk_offset]; | |
| } | |
| kernel void kernel_convert_block_mxfp4_trans4_ns( | |
| global struct block_mxfp4 * src0, | |
| __global uint * dst_q, | |
| __global uchar * dst_e, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_MXFP4; | |
| uint src_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint dst_blk_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| global struct block_mxfp4 * b = src0 + src_blk_offset; | |
| dst_e[dst_blk_offset] = b->e; | |
| // extract quantization and unshuffle | |
| ushort8 pre_block = ((global ushort8 *)(&(b->qs[0])))[0]; | |
| ushort8 post_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK_MXFP4 / 4; ++i) { | |
| uchar x0 = pre_block_ptr[2*i + 0]; | |
| uchar x1 = pre_block_ptr[2*i + 1]; | |
| post_block_ptr[i + 0 ] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| post_block_ptr[i + QK_MXFP4 / 4] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| uint4 q_block = as_uint4(post_block); | |
| uint offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| dst_q[offset] = q_block.x; | |
| dst_q[offset + ne01] = q_block.y; | |
| dst_q[offset + ne01 * 2] = q_block.z; | |
| dst_q[offset + ne01 * 3] = q_block.w; | |
| } | |
| kernel void kernel_restore_block_mxfp4_trans4_ns( | |
| __global uint * src_q, | |
| __global uchar * src_e, | |
| __global struct block_mxfp4 * dst0, | |
| uint ne00, | |
| uint ne01 | |
| ) { | |
| uint i00 = get_global_id(1); | |
| uint i01 = get_global_id(0); | |
| uint i02 = get_global_id(2); | |
| if (i01 >= ne01) { | |
| return; | |
| } | |
| uint ne00_blk = ne00 / QK_MXFP4; | |
| uint dst_blk_offset = i00 + i01 * ne00_blk + i02 * ne00_blk * ne01; | |
| uint src_d_offset = i01 + i00 * ne01 + i02 * ne00_blk * ne01; | |
| __global struct block_mxfp4 * b = dst0 + dst_blk_offset; | |
| b->e = src_e[src_d_offset]; | |
| // collect transposed quantization parts for a block | |
| uint src_q_offset = i02 * ne00_blk * ne01 * 4 + i00 * ne01 * 4 + i01; | |
| uint4 q_block; | |
| q_block.x = src_q[src_q_offset]; | |
| q_block.y = src_q[src_q_offset + ne01]; | |
| q_block.z = src_q[src_q_offset + ne01 * 2]; | |
| q_block.w = src_q[src_q_offset + ne01 * 3]; | |
| ushort8 post_block = as_ushort8(q_block); | |
| ushort8 pre_block = (ushort8)(0); | |
| uchar * pre_block_ptr = (uchar *)(&pre_block); | |
| uchar * post_block_ptr = (uchar *)(&post_block); | |
| for (int i = 0; i < QK_MXFP4 / 4; ++i) { | |
| uchar x0 = post_block_ptr[i + 0]; | |
| uchar x1 = post_block_ptr[i + QK_MXFP4 / 4]; | |
| pre_block_ptr[2 * i + 0] = convert_uchar(x0 & 0x0F) | convert_uchar((x1 & 0x0F) << 4); | |
| pre_block_ptr[2 * i + 1] = convert_uchar((x0 & 0xF0) >> 4) | convert_uchar(x1 & 0xF0); | |
| } | |
| ((__global ushort8 *)(&(b->qs[0])))[0] = pre_block; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // block_q8_0 | |
| //------------------------------------------------------------------------------ | |
| typedef struct { | |
| half d; // delta | |
| char qs[QK8_0]; // quants | |
| } block_q8_0; | |
| kernel void kernel_convert_block_q8_0( | |
| global block_q8_0 * src0, | |
| global uchar * dst_q, | |
| global half * dst_d | |
| ) { | |
| global block_q8_0 * b = (global block_q8_0 *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK8_0*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| for (int i = 0; i < QK8_0; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q8_0( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global block_q8_0 * dst | |
| ) { | |
| global block_q8_0 * b = (global block_q8_0 *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK8_0*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| b->d = *d; | |
| for (int i = 0; i < QK8_0; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| } | |
| // View-aware AoS q8_0 -> f32 dequant (f32/f32 FA path). | |
| kernel void kernel_dequant_q8_0_f32_view_aos( | |
| global char * src, | |
| ulong src_offset, | |
| ulong src_nb1, | |
| ulong src_nb2, | |
| ulong src_nb3, | |
| int nblk0, | |
| int ne1, | |
| int ne2, | |
| int ne3, | |
| global float * dst | |
| ) { | |
| int blk_i0 = get_global_id(0); | |
| int i1 = get_global_id(1); | |
| int batch = get_global_id(2); | |
| if (blk_i0 >= nblk0) return; | |
| if (i1 >= ne1) return; | |
| int i2 = batch % ne2; | |
| int i3 = batch / ne2; | |
| if (i3 >= ne3) return; | |
| global char * block = src + src_offset + (ulong)i3*src_nb3 + (ulong)i2*src_nb2 + (ulong)i1*src_nb1 + (ulong)blk_i0 * (2 + QK8_0); | |
| float d = vload_half(0, (global half *)block); | |
| global char * qs = block + 2; | |
| ulong dst_row_base = ((ulong)i3 * ne2 * ne1 + (ulong)i2 * ne1 + (ulong)i1) * nblk0; | |
| global float * out = dst + (dst_row_base + blk_i0) * QK8_0; | |
| for (int i = 0; i < QK8_0; ++i) { | |
| out[i] = d * (float)qs[i]; | |
| } | |
| } | |
| // View-aware AoS q8_0 -> f16 dequant. Rows tight, batch strides may be gapped. | |
| kernel void kernel_dequant_q8_0_f16_view_aos( | |
| global char * src, | |
| ulong src_offset, | |
| ulong src_nb1, | |
| ulong src_nb2, | |
| ulong src_nb3, | |
| int nblk0, | |
| int ne1, | |
| int ne2, | |
| int ne3, | |
| global half * dst | |
| ) { | |
| int blk_i0 = get_global_id(0); | |
| int i1 = get_global_id(1); | |
| int batch = get_global_id(2); | |
| if (blk_i0 >= nblk0) return; | |
| if (i1 >= ne1) return; | |
| int i2 = batch % ne2; | |
| int i3 = batch / ne2; | |
| if (i3 >= ne3) return; | |
| global char * block = src + src_offset + (ulong)i3*src_nb3 + (ulong)i2*src_nb2 + (ulong)i1*src_nb1 + (ulong)blk_i0 * (2 + QK8_0); | |
| float d = vload_half(0, (global half *)block); | |
| global char * qs = block + 2; | |
| ulong dst_row_base = ((ulong)i3 * ne2 * ne1 + (ulong)i2 * ne1 + (ulong)i1) * nblk0; | |
| global half * out = dst + (dst_row_base + blk_i0) * QK8_0; | |
| for (int i = 0; i < QK8_0; ++i) { | |
| out[i] = (half)(d * (float)qs[i]); | |
| } | |
| } | |
| // View-aware AoS q4_0 -> f32 dequant (mirrors the q8_0 view variant). | |
| kernel void kernel_dequant_q4_0_f32_view_aos( | |
| global char * src, | |
| ulong src_offset, | |
| ulong src_nb1, | |
| ulong src_nb2, | |
| ulong src_nb3, | |
| int nblk0, | |
| int ne1, | |
| int ne2, | |
| int ne3, | |
| global float * dst | |
| ) { | |
| int blk_i0 = get_global_id(0); | |
| int i1 = get_global_id(1); | |
| int batch = get_global_id(2); | |
| if (blk_i0 >= nblk0) return; | |
| if (i1 >= ne1) return; | |
| int i2 = batch % ne2; | |
| int i3 = batch / ne2; | |
| if (i3 >= ne3) return; | |
| global char * block = src + src_offset + (ulong)i3*src_nb3 + (ulong)i2*src_nb2 + (ulong)i1*src_nb1 + (ulong)blk_i0 * (2 + QK4_0/2); | |
| float d = vload_half(0, (global half *)block); | |
| global uchar * qs = (global uchar *)(block + 2); | |
| ulong dst_row_base = ((ulong)i3 * ne2 * ne1 + (ulong)i2 * ne1 + (ulong)i1) * nblk0; | |
| global float * out = dst + (dst_row_base + blk_i0) * QK4_0; | |
| for (int i = 0; i < QK4_0/2; ++i) { | |
| uchar byte = qs[i]; | |
| int q0 = (int)(byte & 0x0F) - 8; | |
| int q1 = (int)(byte >> 4) - 8; | |
| out[i] = d * (float)q0; | |
| out[i + QK4_0/2] = d * (float)q1; | |
| } | |
| } | |
| // View-aware AoS q4_0 -> f16 dequant (mirrors the q8_0 view variant). | |
| kernel void kernel_dequant_q4_0_f16_view_aos( | |
| global char * src, | |
| ulong src_offset, | |
| ulong src_nb1, | |
| ulong src_nb2, | |
| ulong src_nb3, | |
| int nblk0, | |
| int ne1, | |
| int ne2, | |
| int ne3, | |
| global half * dst | |
| ) { | |
| int blk_i0 = get_global_id(0); | |
| int i1 = get_global_id(1); | |
| int batch = get_global_id(2); | |
| if (blk_i0 >= nblk0) return; | |
| if (i1 >= ne1) return; | |
| int i2 = batch % ne2; | |
| int i3 = batch / ne2; | |
| if (i3 >= ne3) return; | |
| global char * block = src + src_offset + (ulong)i3*src_nb3 + (ulong)i2*src_nb2 + (ulong)i1*src_nb1 + (ulong)blk_i0 * (2 + QK4_0/2); | |
| float d = vload_half(0, (global half *)block); | |
| global uchar * qs = (global uchar *)(block + 2); | |
| ulong dst_row_base = ((ulong)i3 * ne2 * ne1 + (ulong)i2 * ne1 + (ulong)i1) * nblk0; | |
| global half * out = dst + (dst_row_base + blk_i0) * QK4_0; | |
| for (int i = 0; i < QK4_0/2; ++i) { | |
| uchar byte = qs[i]; | |
| int q0 = (int)(byte & 0x0F) - 8; | |
| int q1 = (int)(byte >> 4) - 8; | |
| out[i] = (half)(d * (float)q0); | |
| out[i + QK4_0/2] = (half)(d * (float)q1); | |
| } | |
| } | |
| kernel void kernel_restore_block_q8_0_trans( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global block_q8_0 * dst, | |
| uint ne00, | |
| uint ne01 | |
| ){ | |
| uint num_blk_per_row = ne00 / QK8_0; | |
| global block_q8_0 * b = (global block_q8_0 *) dst + get_global_id(0) * num_blk_per_row; | |
| global uchar * q = (global uchar *) src_q + get_global_id(0) * 4; // 4 8-bit packed | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| for (uint blk = 0; blk < num_blk_per_row; blk++) { | |
| b->d = *d; | |
| for (uint i = 0; i < QK8_0; i+=4) { | |
| b->qs[i] = q[0]; | |
| b->qs[i+1] = q[1]; | |
| b->qs[i+2] = q[2]; | |
| b->qs[i+3] = q[3]; | |
| q += 4 * ne01; // M stride | |
| } | |
| d += ne01; | |
| b++; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q4_K | |
| // Convert the block_q4_K format to 4 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| // Each thread processes a super block. | |
| // Mask args are just to keep the signature consistent with the no-shuffle | |
| // version and they are not used in this kernel. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q4_K( | |
| global struct block_q4_K * src0, | |
| global uchar * dst_q, | |
| global uchar * dst_s, | |
| global half * dst_d, | |
| global half * dst_dm, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q4_K * b = (global struct block_q4_K *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK_K/2*get_global_id(0); | |
| global uchar * s = (global uchar *) dst_s + K_SCALE_SIZE*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * dm = (global half *) dst_dm + get_global_id(0); | |
| *d = b->d; | |
| *dm = b->dm; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| q[i] = b->q[i]; | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s[i] = b->s[i]; | |
| } | |
| } | |
| // Restore block_q4_K from flattened arrays. | |
| // Each thread processes a super block. | |
| // Mask args are just to keep the signature consistent with the no-shuffle ones. | |
| kernel void kernel_restore_block_q4_K( | |
| global uchar * src_q, | |
| global uchar * src_s, | |
| global half * src_d, | |
| global half * src_dm, | |
| global struct block_q4_K * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q4_K * b = (global struct block_q4_K *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK_K/2*get_global_id(0); | |
| global uchar * s = (global uchar *) src_s + K_SCALE_SIZE*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * dm = (global half *) src_dm + get_global_id(0); | |
| b->d = *d; | |
| b->dm = *dm; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| b->q[i] = q[i]; | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q4_K_noshuffle( | |
| global struct block_q4_K * src0, | |
| global uchar * dst_q, | |
| global uchar * dst_s, | |
| global half * dst_d, | |
| global half * dst_dm, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q4_K * b = (global struct block_q4_K *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK_K/2 * get_global_id(0); | |
| global uchar * s = (global uchar *) dst_s + K_SCALE_SIZE * get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * dm = (global half *) dst_dm + get_global_id(0); | |
| *d = b->d; | |
| *dm = b->dm; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar x0 = b->q[i*32 + 2*j]; | |
| uchar x1 = b->q[i*32 + 2*j + 1]; | |
| q[i*32 + j] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| q[i*32 + j + 16] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| } | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s[i] = b->s[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q4_K_noshuffle( | |
| global uchar * src_q, | |
| global uchar * src_s, | |
| global half * src_d, | |
| global half * src_dm, | |
| global struct block_q4_K * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q4_K * b = (global struct block_q4_K *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK_K/2 * get_global_id(0); | |
| global uchar * s = (global uchar *) src_s + K_SCALE_SIZE * get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * dm = (global half *) src_dm + get_global_id(0); | |
| b->d = *d; | |
| b->dm = *dm; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar lo = q[i*32 + j]; | |
| uchar hi = q[i*32 + j + 16]; | |
| b->q[i*32 + 2*j] = convert_uchar((lo & mask_0F) | ((hi & mask_0F) << 4)); | |
| b->q[i*32 + 2*j + 1] = convert_uchar(((lo & mask_F0) >> 4) | (hi & mask_F0)); | |
| } | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s[i]; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q5_K | |
| // Convert the block_q5_K format to 5 separate arrays (AOS -> SOA). | |
| // Each thread processes a super block. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q5_K( | |
| global struct block_q5_K * src0, | |
| global uchar * dst_q, | |
| global uchar * dst_qh, | |
| global uchar * dst_s, | |
| global half * dst_d, | |
| global half * dst_dm, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_K * b = (global struct block_q5_K *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) dst_qh + QK_K/8*get_global_id(0); | |
| global uchar * s = (global uchar *) dst_s + K_SCALE_SIZE*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * dm = (global half *) dst_dm + get_global_id(0); | |
| *d = b->d; | |
| *dm = b->dm; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| for (int i = 0; i < QK_K/8; ++i) { | |
| qh[i] = b->qh[i]; | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s[i] = b->s[i]; | |
| } | |
| } | |
| // Restore block_q5_K from flattened arrays. | |
| // Each thread processes a super block. | |
| kernel void kernel_restore_block_q5_K( | |
| global uchar * src_q, | |
| global uchar * src_qh, | |
| global uchar * src_s, | |
| global half * src_d, | |
| global half * src_dm, | |
| global struct block_q5_K * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_K * b = (global struct block_q5_K *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) src_qh + QK_K/8*get_global_id(0); | |
| global uchar * s = (global uchar *) src_s + K_SCALE_SIZE*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * dm = (global half *) src_dm + get_global_id(0); | |
| b->d = *d; | |
| b->dm = *dm; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| for (int i = 0; i < QK_K/8; ++i) { | |
| b->qh[i] = qh[i]; | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q5_K_noshuffle( | |
| global struct block_q5_K * src0, | |
| global uchar * dst_q, | |
| global uchar * dst_qh, | |
| global uchar * dst_s, | |
| global half * dst_d, | |
| global half * dst_dm, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_K * b = (global struct block_q5_K *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK_K/2 * get_global_id(0); | |
| global uchar * qh = (global uchar *) dst_qh + QK_K/8 * get_global_id(0); | |
| global uchar * s = (global uchar *) dst_s + K_SCALE_SIZE * get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| global half * dm = (global half *) dst_dm + get_global_id(0); | |
| *d = b->d; | |
| *dm = b->dm; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar x0 = b->qs[i*32 + 2*j]; | |
| uchar x1 = b->qs[i*32 + 2*j + 1]; | |
| q[i*32 + j] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| q[i*32 + j + 16] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| } | |
| } | |
| for (int l = 0; l < QK_K/8; ++l) { | |
| uchar x0 = 0; | |
| for (int i = 0; i < 8; ++i) { | |
| x0 |= ((b->qh[(l%4)*8+i] >> (l/4)) & 0x01) << i; | |
| } | |
| qh[l] = x0; | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| s[i] = b->s[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q5_K_noshuffle( | |
| global uchar * src_q, | |
| global uchar * src_qh, | |
| global uchar * src_s, | |
| global half * src_d, | |
| global half * src_dm, | |
| global struct block_q5_K * dst, | |
| uchar mask_0F, | |
| uchar mask_F0 | |
| ) { | |
| global struct block_q5_K * b = (global struct block_q5_K *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK_K/2 * get_global_id(0); | |
| global uchar * qh = (global uchar *) src_qh + QK_K/8 * get_global_id(0); | |
| global uchar * s = (global uchar *) src_s + K_SCALE_SIZE * get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| global half * dm = (global half *) src_dm + get_global_id(0); | |
| b->d = *d; | |
| b->dm = *dm; | |
| for (int i = 0; i < QK_K / 64; ++i) { | |
| for (int j = 0; j < 16; ++j) { | |
| uchar lo = q[i*32 + j]; | |
| uchar hi = q[i*32 + j + 16]; | |
| b->qs[i*32 + 2*j] = convert_uchar((lo & mask_0F) | ((hi & mask_0F) << 4)); | |
| b->qs[i*32 + 2*j + 1] = convert_uchar(((lo & mask_F0) >> 4) | (hi & mask_F0)); | |
| } | |
| } | |
| for (int g = 0; g < 4; ++g) { | |
| for (int i = 0; i < 8; ++i) { | |
| uchar x0 = 0; | |
| for (int k = 0; k < 8; ++k) { | |
| x0 |= ((qh[4*k+g] >> i) & 0x01) << k; | |
| } | |
| b->qh[g*8+i] = x0; | |
| } | |
| } | |
| for (int i = 0; i < K_SCALE_SIZE; ++i) { | |
| b->s[i] = s[i]; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_q6_K | |
| // Convert the block_q6_K format to 3 separate arrays (AOS -> SOA). | |
| // This kernel does not deshuffle the bits. | |
| // Each thread processes a super block. | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_q6_K( | |
| global struct block_q6_K * src0, | |
| global uchar * dst_ql, | |
| global uchar * dst_qh, | |
| global char * dst_s, | |
| global half * dst_d, | |
| uchar mask_lsb_8, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q6_K * b = (global struct block_q6_K *) src0 + get_global_id(0); | |
| global uchar * ql = (global uchar *) dst_ql + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) dst_qh + QK_K/4*get_global_id(0); | |
| global char * s = (global char *) dst_s + QK_K/16*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| ql[i] = b->ql[i]; | |
| } | |
| for (int i = 0; i < QK_K/4; ++i) { | |
| qh[i] = b->qh[i]; | |
| } | |
| for (int i = 0; i < QK_K/16; ++i) { | |
| s[i] = b->scales[i]; | |
| } | |
| } | |
| // Restore block_q6_K from flattened arrays. | |
| // Each thread processes a super block. | |
| kernel void kernel_restore_block_q6_K( | |
| global uchar * dst_ql, | |
| global uchar * dst_qh, | |
| global char * dst_s, | |
| global half * dst_d, | |
| global struct block_q6_K * dst, | |
| uchar mask_lsb_8, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q6_K * b = (global struct block_q6_K *) dst + get_global_id(0); | |
| global uchar * ql = (global uchar *) dst_ql + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) dst_qh + QK_K/4*get_global_id(0); | |
| global char * s = (global char *) dst_s + QK_K/16*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| b->d = *d; | |
| for (int i = 0; i < QK_K/2; ++i) { | |
| b->ql[i] = ql[i]; | |
| } | |
| for (int i = 0; i < QK_K/4; ++i) { | |
| b->qh[i] = qh[i]; | |
| } | |
| for (int i = 0; i < QK_K/16; ++i) { | |
| b->scales[i] = s[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_q6_K_noshuffle( | |
| global struct block_q6_K * src0, | |
| global uchar * dst_ql, | |
| global uchar * dst_qh, | |
| global char * dst_s, | |
| global half * dst_d, | |
| uchar mask_lsb_8, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q6_K * b = (global struct block_q6_K *) src0 + get_global_id(0); | |
| global uchar * ql = (global uchar *) dst_ql + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) dst_qh + QK_K/4*get_global_id(0); | |
| global char * s = (global char *) dst_s + QK_K/16*get_global_id(0); | |
| global half * d = (global half *) dst_d + get_global_id(0); | |
| *d = b->d; | |
| for (int i = 0; i < QK_K/2/4; ++i) { | |
| uchar x0 = b->ql[i*2 + 0] & mask_lsb_8; | |
| uchar x1 = b->ql[i*2 + 1] & mask_lsb_8; | |
| ql[i + 0] = (x0 & 0x0F) | ((x1 & 0x0F) << 4); | |
| ql[i + 32] = ((x0 & 0xF0) >> 4) | (x1 & 0xF0); | |
| uchar x2 = b->ql[i*2 + 0 + 64] & mask_lsb_8; | |
| uchar x3 = b->ql[i*2 + 1 + 64] & mask_lsb_8; | |
| ql[i + 64] = (x2 & 0x0F) | ((x3 & 0x0F) << 4); | |
| ql[i + 96] = ((x2 & 0xF0) >> 4) | (x3 & 0xF0); | |
| } | |
| for (int i = 0; i < QK_K/4/8; ++i) { | |
| uchar x0 = b->qh[i*4 + 0] & mask_lsb_8; | |
| uchar x1 = b->qh[i*4 + 1] & mask_lsb_8; | |
| uchar x2 = b->qh[i*4 + 2] & mask_lsb_8; | |
| uchar x3 = b->qh[i*4 + 3] & mask_lsb_8; | |
| qh[i + 0] = (x0 & 0x03) | ((x1 & 0x03) << 2) | ((x2 & 0x03) << 4) | ((x3 & 0x03) << 6); | |
| qh[i + 8] = ((x0 & 0x0C) >> 2) | (x1 & 0x0C) | ((x2 & 0x0C) << 2) | ((x3 & 0x0C) << 4); | |
| qh[i + 16] = ((x0 & 0x30) >> 4) | ((x1 & 0x30) >> 2) | (x2 & 0x30) | ((x3 & 0x30) << 2); | |
| qh[i + 24] = ((x0 & 0xC0) >> 6) | ((x1 & 0xC0) >> 4) | ((x2 & 0xC0) >> 2) | (x3 & 0xC0); | |
| uchar x4 = b->qh[i*4 + 0 + 32] & mask_lsb_8; | |
| uchar x5 = b->qh[i*4 + 1 + 32] & mask_lsb_8; | |
| uchar x6 = b->qh[i*4 + 2 + 32] & mask_lsb_8; | |
| uchar x7 = b->qh[i*4 + 3 + 32] & mask_lsb_8; | |
| qh[i + 32] = (x4 & 0x03) | ((x5 & 0x03) << 2) | ((x6 & 0x03) << 4) | ((x7 & 0x03) << 6); | |
| qh[i + 40] = ((x4 & 0x0C) >> 2) | (x5 & 0x0C) | ((x6 & 0x0C) << 2) | ((x7 & 0x0C) << 4); | |
| qh[i + 48] = ((x4 & 0x30) >> 4) | ((x5 & 0x30) >> 2) | (x6 & 0x30) | ((x7 & 0x30) << 2); | |
| qh[i + 56] = ((x4 & 0xC0) >> 6) | ((x5 & 0xC0) >> 4) | ((x6 & 0xC0) >> 2) | (x7 & 0xC0); | |
| } | |
| for (int i = 0; i < QK_K/16; ++i) { | |
| s[i] = b->scales[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_q6_K_noshuffle( | |
| global uchar * src_ql, | |
| global uchar * src_qh, | |
| global char * src_s, | |
| global half * src_d, | |
| global struct block_q6_K * dst, | |
| uchar mask_lsb_8, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_q6_K * b = (global struct block_q6_K *) dst + get_global_id(0); | |
| global uchar * ql = (global uchar *) src_ql + QK_K/2*get_global_id(0); | |
| global uchar * qh = (global uchar *) src_qh + QK_K/4*get_global_id(0); | |
| global char * s = (global char *) src_s + QK_K/16*get_global_id(0); | |
| global half * d = (global half *) src_d + get_global_id(0); | |
| b->d = *d; | |
| for (int i = 0; i < QK_K/2/4; ++i) { | |
| uchar x0 = ql[i + 0] & mask_lsb_8; | |
| uchar x1 = ql[i + 32] & mask_lsb_8; | |
| b->ql[i*2 + 0] = (x0 & 0x0F) | ((x1 & 0x0F) << 4); | |
| b->ql[i*2 + 1] = ((x0 & 0xF0) >> 4) | (x1 & 0xF0); | |
| uchar x2 = ql[i + 64] & mask_lsb_8; | |
| uchar x3 = ql[i + 96] & mask_lsb_8; | |
| b->ql[i*2 + 0 + 64] = (x2 & 0x0F) | ((x3 & 0x0F) << 4); | |
| b->ql[i*2 + 1 + 64] = ((x2 & 0xF0) >> 4) | (x3 & 0xF0); | |
| } | |
| for (int i = 0; i < QK_K/4/8; ++i) { | |
| uchar x0 = qh[i + 0] & mask_lsb_8; | |
| uchar x1 = qh[i + 8] & mask_lsb_8; | |
| uchar x2 = qh[i + 16] & mask_lsb_8; | |
| uchar x3 = qh[i + 24] & mask_lsb_8; | |
| b->qh[i*4 + 0] = (x0 & 0x03) | ((x1 & 0x03) << 2) | ((x2 & 0x03) << 4) | ((x3 & 0x03) << 6); | |
| b->qh[i*4 + 1] = ((x0 & 0x0C) >> 2) | (x1 & 0x0C) | ((x2 & 0x0C) << 2) | ((x3 & 0x0C) << 4); | |
| b->qh[i*4 + 2] = ((x0 & 0x30) >> 4) | ((x1 & 0x30) >> 2) | (x2 & 0x30) | ((x3 & 0x30) << 2); | |
| b->qh[i*4 + 3] = ((x0 & 0xC0) >> 6) | ((x1 & 0xC0) >> 4) | ((x2 & 0xC0) >> 2) | (x3 & 0xC0); | |
| uchar x4 = qh[i + 0 + 32] & mask_lsb_8; | |
| uchar x5 = qh[i + 8 + 32] & mask_lsb_8; | |
| uchar x6 = qh[i + 16 + 32] & mask_lsb_8; | |
| uchar x7 = qh[i + 24 + 32] & mask_lsb_8; | |
| b->qh[i*4 + 0 + 32] = (x4 & 0x03) | ((x5 & 0x03) << 2) | ((x6 & 0x03) << 4) | ((x7 & 0x03) << 6); | |
| b->qh[i*4 + 1 + 32] = ((x4 & 0x0C) >> 2) | (x5 & 0x0C) | ((x6 & 0x0C) << 2) | ((x7 & 0x0C) << 4); | |
| b->qh[i*4 + 2 + 32] = ((x4 & 0x30) >> 4) | ((x5 & 0x30) >> 2) | (x6 & 0x30) | ((x7 & 0x30) << 2); | |
| b->qh[i*4 + 3 + 32] = ((x4 & 0xC0) >> 6) | ((x5 & 0xC0) >> 4) | ((x6 & 0xC0) >> 2) | (x7 & 0xC0); | |
| } | |
| for (int i = 0; i < QK_K/16; ++i) { | |
| b->scales[i] = s[i]; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // kernel_convert_block_iq4_nl | |
| // Convert the block_iq4_nl format to 2 separate arrays (AOS -> SOA). | |
| //------------------------------------------------------------------------------ | |
| kernel void kernel_convert_block_iq4_nl( | |
| global struct block_iq4_nl * src0, | |
| global uchar * dst_q, | |
| global half * dst_d, | |
| uchar mask_0F, | |
| uchar mask_F0, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_iq4_nl * b = (global struct block_iq4_nl *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK4_NL/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_NL/2; ++i) { | |
| q[i] = b->qs[i]; | |
| } | |
| } | |
| kernel void kernel_restore_block_iq4_nl( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global struct block_iq4_nl * dst, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_iq4_nl * b = (global struct block_iq4_nl *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK4_NL/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_NL/2; ++i) { | |
| b->qs[i] = q[i]; | |
| } | |
| } | |
| kernel void kernel_convert_block_iq4_nl_noshuffle( | |
| global struct block_iq4_nl * src0, | |
| global uchar * dst_q, | |
| global half * dst_d, | |
| uchar mask_0F, | |
| uchar mask_F0, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_iq4_nl * b = (global struct block_iq4_nl *) src0 + get_global_id(0); | |
| global uchar * q = (global uchar *) dst_q + QK4_NL/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_NL/4; ++i) { | |
| uchar x0 = b->qs[2*i + 0]; | |
| uchar x1 = b->qs[2*i + 1]; | |
| q[i + 0 ] = convert_uchar(x0 & mask_0F) | convert_uchar((x1 & mask_0F) << 4); | |
| q[i + QK4_NL/4] = convert_uchar((x0 & mask_F0) >> 4) | convert_uchar(x1 & mask_F0); | |
| } | |
| } | |
| kernel void kernel_restore_block_iq4_nl_noshuffle( | |
| global uchar * src_q, | |
| global half * src_d, | |
| global struct block_iq4_nl * dst, | |
| uchar mask_0F, | |
| uchar mask_F0, | |
| ulong n_blk | |
| ) { | |
| if (get_global_id(0) >= n_blk) { | |
| return; | |
| } | |
| global struct block_iq4_nl * b = (global struct block_iq4_nl *) dst + get_global_id(0); | |
| global uchar * q = (global uchar *) src_q + QK4_NL/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_NL/4; ++i) { | |
| uchar x0 = q[i + 0 ]; | |
| uchar x1 = q[i + QK4_NL/4]; | |
| b->qs[2*i + 0] = convert_uchar((x0 & mask_0F) | ((x1 & mask_0F) << 4)); | |
| b->qs[2*i + 1] = convert_uchar(((x0 & mask_F0) >> 4) | (x1 & mask_F0)); | |
| } | |
| } | |