char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
b062ba735
char/aliceai-t5-moe
1// Mamba2 fused SSM scan kernel. One workgroup per ( head , dim , seq ) ; WG size = 2// 64 threads. Each thread owns c_factor = d_state/64 state elements in 3// private registers ; the state stays resident across the n_tokens t-loop 4// 5// References : 6// ggml/src/ggml-cuda/ssm-scan.cu:117 ssm_scan_f32_group 7// ggml/src/ggml-cpu/ops.cpp:9368 ggml_compute_forward_ssm_scan_f32 8 9#pragma OPENCL EXTENSION cl_khr_fp16 : enable 10 11#ifdef cl_khr_subgroups 12#pragma OPENCL EXTENSION cl_khr_subgroups : enable 13#endif 14 15#if defined(cl_qcom_reqd_sub_group_size) 16#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable 17#define REQD_SUBGROUP_SIZE_64 __attribute__((qcom_reqd_sub_group_size("half" ))) 18#else 19#define REQD_SUBGROUP_SIZE_64 20#endif 21 22inline float softplus_f32(float x) { 23 return (x <= 20.0f) ? log(1.0f + exp(x)) : x; 24} 25 26// d_state = 128 (most Mamba-2 models, e.g. mamba2-2.7B, Codestral-Mamba). 27// WG = 64 threads, each holds 2 state elements (tid and tid+64). 28REQD_SUBGROUP_SIZE_64 29kernel void kernel_ssm_scan_f32_mamba2_d128( 30 global const char * src0_base, ulong src0_off, 31 global const char * src1_base, ulong src1_off, 32 global const char * src2_base, ulong src2_off, 33 global const char * src3_base, ulong src3_off, 34 global const char * src4_base, ulong src4_off, 35 global const char * src5_base, ulong src5_off, 36 global const char * src6_base, ulong src6_off, 37 global char * dst_base, ulong dst_off, 38 ulong s0_nb2, ulong s0_nb3, 39 ulong x_nb2, ulong x_nb3, 40 ulong dt_nb1, ulong dt_nb2, 41 ulong A_nb1, 42 ulong B_nb2, ulong B_nb3, 43 ulong C_nb2, ulong C_nb3, 44 ulong s_off_bytes, 45 int head_dim, int n_head, int n_group, int n_tokens 46) { 47 const int d_state = 128; 48 49 const int tid = (int) get_local_id(0); 50 const int wg_x = (int) get_group_id(0); 51 const int seq_id = (int) get_group_id(1); 52 53 const int head_id = wg_x / head_dim; 54 const int dim_id = wg_x - head_id * head_dim; 55 const int g = head_id / (n_head / n_group); 56 57 src0_base += src0_off; 58 src1_base += src1_off; 59 src2_base += src2_off; 60 src3_base += src3_off; 61 src4_base += src4_off; 62 src5_base += src5_off; 63 src6_base += src6_off; 64 dst_base += dst_off; 65 66 const int seq_slot = ((global const int *) src6_base)[seq_id]; 67 68 const ulong state_base_off = (ulong)seq_slot * s0_nb3 + (ulong)head_id * s0_nb2 69 + (ulong)dim_id * d_state * sizeof(float); 70 global const float * s0_warp = (global const float *)(src0_base + state_base_off); 71 const ulong state_out_off = (ulong)seq_id * s0_nb3 + (ulong)head_id * s0_nb2 72 + (ulong)dim_id * d_state * sizeof(float); 73 global float * s_warp = (global float *)(dst_base + s_off_bytes + state_out_off); 74 75 global const char * x_seq = src1_base + (ulong)seq_id * x_nb3; 76 global const char * dt_seq = src2_base + (ulong)seq_id * dt_nb2; 77 global const char * B_seq = src4_base + (ulong)seq_id * B_nb3 + (ulong)g * d_state * sizeof(float); 78 global const char * C_seq = src5_base + (ulong)seq_id * C_nb3 + (ulong)g * d_state * sizeof(float); 79 80 const ulong y_dim_total = (ulong)n_head * head_dim; 81 global float * y_seq = (global float *)dst_base 82 + (ulong)seq_id * (ulong)n_tokens * y_dim_total; 83 84 const float A_val = ((global const float *)src3_base)[(ulong)head_id * A_nb1 / sizeof(float)]; 85 86 // c_factor = 2: each thread owns 2 state elements (tid and tid+64). 87 float state0 = s0_warp[tid]; 88 float state1 = s0_warp[tid + 64]; 89 90 for (int t = 0; t < n_tokens; ++t) { 91 const float dt_h = ((global const float *)(dt_seq + (ulong)t * dt_nb1))[head_id]; 92 const float dt_softplus = softplus_f32(dt_h); 93 const float dA = exp(dt_softplus * A_val); 94 const float x_val = ((global const float *)(x_seq + (ulong)t * x_nb2))[(ulong)head_id * head_dim + dim_id]; 95 const float x_dt = x_val * dt_softplus; 96 97 const float B0 = ((global const float *)(B_seq + (ulong)t * B_nb2))[tid]; 98 const float B1 = ((global const float *)(B_seq + (ulong)t * B_nb2))[tid + 64]; 99 const float C0 = ((global const float *)(C_seq + (ulong)t * C_nb2))[tid]; 100 const float C1 = ((global const float *)(C_seq + (ulong)t * C_nb2))[tid + 64]; 101 102 state0 = state0 * dA + B0 * x_dt; 103 state1 = state1 * dA + B1 * x_dt; 104 const float partial = state0 * C0 + state1 * C1; 105 106 const float sum = sub_group_reduce_add(partial); 107 if (tid == 0) { 108 y_seq[(ulong)t * y_dim_total + (ulong)head_id * head_dim + dim_id] = sum; 109 } 110 } 111 112 s_warp[tid] = state0; 113 s_warp[tid + 64] = state1; 114} 115 116// d_state = 256 (Falcon-H1). WG = 64 threads, each holds 4 state elements. 117REQD_SUBGROUP_SIZE_64 118kernel void kernel_ssm_scan_f32_mamba2_d256( 119 global const char * src0_base, ulong src0_off, 120 global const char * src1_base, ulong src1_off, 121 global const char * src2_base, ulong src2_off, 122 global const char * src3_base, ulong src3_off, 123 global const char * src4_base, ulong src4_off, 124 global const char * src5_base, ulong src5_off, 125 global const char * src6_base, ulong src6_off, 126 global char * dst_base, ulong dst_off, 127 ulong s0_nb2, ulong s0_nb3, 128 ulong x_nb2, ulong x_nb3, 129 ulong dt_nb1, ulong dt_nb2, 130 ulong A_nb1, 131 ulong B_nb2, ulong B_nb3, 132 ulong C_nb2, ulong C_nb3, 133 ulong s_off_bytes, 134 int head_dim, int n_head, int n_group, int n_tokens 135) { 136 const int d_state = 256; 137 138 const int tid = (int) get_local_id(0); 139 const int wg_x = (int) get_group_id(0); 140 const int seq_id = (int) get_group_id(1); 141 142 const int head_id = wg_x / head_dim; 143 const int dim_id = wg_x - head_id * head_dim; 144 const int g = head_id / (n_head / n_group); 145 146 src0_base += src0_off; 147 src1_base += src1_off; 148 src2_base += src2_off; 149 src3_base += src3_off; 150 src4_base += src4_off; 151 src5_base += src5_off; 152 src6_base += src6_off; 153 dst_base += dst_off; 154 155 const int seq_slot = ((global const int *) src6_base)[seq_id]; 156 157 const ulong state_base_off = (ulong)seq_slot * s0_nb3 + (ulong)head_id * s0_nb2 158 + (ulong)dim_id * d_state * sizeof(float); 159 global const float * s0_warp = (global const float *)(src0_base + state_base_off); 160 const ulong state_out_off = (ulong)seq_id * s0_nb3 + (ulong)head_id * s0_nb2 161 + (ulong)dim_id * d_state * sizeof(float); 162 global float * s_warp = (global float *)(dst_base + s_off_bytes + state_out_off); 163 164 global const char * x_seq = src1_base + (ulong)seq_id * x_nb3; 165 global const char * dt_seq = src2_base + (ulong)seq_id * dt_nb2; 166 global const char * B_seq = src4_base + (ulong)seq_id * B_nb3 + (ulong)g * d_state * sizeof(float); 167 global const char * C_seq = src5_base + (ulong)seq_id * C_nb3 + (ulong)g * d_state * sizeof(float); 168 169 const ulong y_dim_total = (ulong)n_head * head_dim; 170 global float * y_seq = (global float *)dst_base 171 + (ulong)seq_id * (ulong)n_tokens * y_dim_total; 172 173 const float A_val = ((global const float *)src3_base)[(ulong)head_id * A_nb1 / sizeof(float)]; 174 175 // c_factor = 4: each thread owns 4 state elements. 176 float state0 = s0_warp[tid]; 177 float state1 = s0_warp[tid + 64]; 178 float state2 = s0_warp[tid + 128]; 179 float state3 = s0_warp[tid + 192]; 180 181 for (int t = 0; t < n_tokens; ++t) { 182 const float dt_h = ((global const float *)(dt_seq + (ulong)t * dt_nb1))[head_id]; 183 const float dt_softplus = softplus_f32(dt_h); 184 const float dA = exp(dt_softplus * A_val); 185 const float x_val = ((global const float *)(x_seq + (ulong)t * x_nb2))[(ulong)head_id * head_dim + dim_id]; 186 const float x_dt = x_val * dt_softplus; 187 188 global const float * B_t = (global const float *)(B_seq + (ulong)t * B_nb2); 189 global const float * C_t = (global const float *)(C_seq + (ulong)t * C_nb2); 190 191 const float B0 = B_t[tid]; 192 const float B1 = B_t[tid + 64]; 193 const float B2 = B_t[tid + 128]; 194 const float B3 = B_t[tid + 192]; 195 const float C0 = C_t[tid]; 196 const float C1 = C_t[tid + 64]; 197 const float C2 = C_t[tid + 128]; 198 const float C3 = C_t[tid + 192]; 199 200 state0 = state0 * dA + B0 * x_dt; 201 state1 = state1 * dA + B1 * x_dt; 202 state2 = state2 * dA + B2 * x_dt; 203 state3 = state3 * dA + B3 * x_dt; 204 const float partial = state0 * C0 + state1 * C1 + state2 * C2 + state3 * C3; 205 206 const float sum = sub_group_reduce_add(partial); 207 if (tid == 0) { 208 y_seq[(ulong)t * y_dim_total + (ulong)head_id * head_dim + dim_id] = sum; 209 } 210 } 211 212 s_warp[tid] = state0; 213 s_warp[tid + 64] = state1; 214 s_warp[tid + 128] = state2; 215 s_warp[tid + 192] = state3; 216}