char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
788e07dc9
char/aliceai-t5-moe
1#version 450 2 3#extension GL_EXT_shader_explicit_arithmetic_types_int32 : require 4#extension GL_EXT_integer_dot_product : require 5 6#define MMQ 7#define NEEDS_IQ1S_GRID_GPU 8#define B_TYPE block_q8_1_x4 9 10#include "mul_mat_vec_base.glsl" 11 12layout(local_size_x_id = 0, local_size_y = 1, local_size_z = 1) in; 13 14#if defined(DATA_A_Q2_0) || defined(DATA_A_QUANT_K) 15#define K_PER_ITER 16 16#elif defined(DATA_A_QUANT_LEGACY) || defined(DATA_A_MXFP4) 17#define K_PER_ITER 8 18#elif defined(DATA_A_IQ1_S) || defined(DATA_A_IQ1_M) 19#define K_PER_ITER 32 20#else 21#error unimplemented 22#endif 23 24uint a_offset, b_offset, d_offset; 25 26int32_t cache_b_qs[K_PER_ITER / 4]; 27vec2 cache_b_ds; 28 29#include "mul_mat_vecq_funcs.glsl" 30 31void iter(inout FLOAT_TYPE temp[NUM_COLS][NUM_ROWS], const uint first_row, const uint num_rows, const uint col, const uint b_qs_idx) { 32 [[unroll]] for (uint j = 0; j < NUM_COLS; ++j) { 33 // Preload data_b block 34 const uint b_block_idx = (j*p.batch_stride_b + col) / QUANT_K_Q8_1 + b_offset; 35 const uint b_block_idx_outer = b_block_idx / 4; 36 const uint b_block_idx_inner = b_block_idx % 4; 37 cache_b_ds = vec2(data_b[b_block_idx_outer].ds[b_block_idx_inner]); 38 39#if QUANT_R == 2 40 // Assumes K_PER_ITER == 8 41 cache_b_qs[0] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx]; 42 cache_b_qs[1] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx + 4]; 43#else 44#if K_PER_ITER == 8 45 cache_b_qs[0] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 2]; 46 cache_b_qs[1] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 2 + 1]; 47#elif K_PER_ITER == 16 48 cache_b_qs[0] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 4 ]; 49 cache_b_qs[1] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 4 + 1]; 50 cache_b_qs[2] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 4 + 2]; 51 cache_b_qs[3] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + b_qs_idx * 4 + 3]; 52#elif K_PER_ITER == 32 53 cache_b_qs[0] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 ]; 54 cache_b_qs[1] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 1]; 55 cache_b_qs[2] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 2]; 56 cache_b_qs[3] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 3]; 57 cache_b_qs[4] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 4]; 58 cache_b_qs[5] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 5]; 59 cache_b_qs[6] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 6]; 60 cache_b_qs[7] = data_b[b_block_idx_outer].qs[b_block_idx_inner * 8 + 7]; 61#else 62#error unimplemented 63#endif 64#endif 65 66 uint ibi = first_row*p.ncols; 67 [[unroll]] for (uint n = 0; n < num_rows; ++n) { 68 const uint a_block_idx = (ibi + col)/QUANT_K_Q8_1 + a_offset; 69 ibi += p.ncols; 70 71 temp[j][n] += mmvq_dot_product(a_block_idx, b_qs_idx); 72 } 73 } 74} 75 76void compute_outputs(const uint32_t first_row, const uint32_t num_rows) { 77 const uint tid = gl_LocalInvocationID.x; 78 79 get_offsets(a_offset, b_offset, d_offset); 80 a_offset *= QUANT_K / QUANT_K_Q8_1; 81 b_offset /= QUANT_K_Q8_1; 82 83 FLOAT_TYPE temp[NUM_COLS][NUM_ROWS]; 84 85 [[unroll]] for (uint j = 0; j < NUM_COLS; ++j) { 86 [[unroll]] for (uint n = 0; n < num_rows; ++n) { 87 temp[j][n] = FLOAT_TYPE(0.0f); 88 } 89 } 90 91 const uint col_stride = K_PER_ITER * BLOCK_SIZE; 92 uint num_iters = p.ncols / col_stride; 93 if (num_iters * col_stride + K_PER_ITER * tid < p.ncols) { 94 num_iters++; 95 } 96 97 const uint b_qs_idx = tid % (32 / K_PER_ITER); 98 uint col = tid * K_PER_ITER; 99 while (num_iters >= 4) { 100 // Manually partially unroll the loop 101 [[unroll]] for (uint k = 0; k < 4; ++k) { 102 iter(temp, first_row, num_rows, col, b_qs_idx); 103 col += col_stride; 104 } 105 106 num_iters -= 4; 107 } 108 109 if (num_iters >= 2) { 110 // Manually partially unroll the loop 111 iter(temp, first_row, num_rows, col, b_qs_idx); 112 col += col_stride; 113 iter(temp, first_row, num_rows, col, b_qs_idx); 114 col += col_stride; 115 num_iters -= 2; 116 } 117 118 if (num_iters > 0) { 119 iter(temp, first_row, num_rows, col, b_qs_idx); 120 } 121 122 reduce_result(temp, d_offset, first_row, num_rows, tid); 123} 124 125void main() { 126 const uint first_row = NUM_ROWS * (gl_WorkGroupID.x + gl_NumWorkGroups.x * gl_WorkGroupID.z); 127 128#ifdef NEEDS_INIT_IQ_SHMEM 129 init_iq_shmem(gl_WorkGroupSize); 130#endif 131 132 // do NUM_ROWS at a time, unless there aren't enough remaining rows 133 if (first_row + NUM_ROWS <= p.stride_d) { 134 compute_outputs(first_row, NUM_ROWS); 135 } else { 136 if (first_row >= p.stride_d) { 137 return; 138 } 139 compute_outputs(first_row, p.stride_d - first_row); 140 } 141}