char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
1692f9e50
char/aliceai-t5-moe
1#include "ssm_scan.hpp" 2#include "common.hpp" 3 4template < int c_factor ,int d_state > 5static void ssm_scan_f32_group ( 6const float * __restrict__src0 ,const float * __restrict__src1 ,const float * __restrict__src2 , 7const float * __restrict__src3 ,const float * __restrict__src4 ,const float * __restrict__src5 , 8const int32_t * __restrict__src6 ,float * __restrict__dst , 9const int src0_nb2 ,const int src0_nb3 ,const int src1_nb2 ,const int src1_nb3 , 10const int src2_nb1 ,const int src2_nb2 ,const int src3_nb1 , 11const int src4_nb2 ,const int src4_nb3 ,const int src5_nb2 ,const int src5_nb3 , 12const int64_t s_off ,const int64_t n_head ,const int64_t d_head ,const int64_t n_group ,const int64_t n_tok , 13const int64_t K , 14const sycl::nd_item < 2 > & item ) { 15 16const int lane = item .get_local_id (1 ) %WARP_SIZE ; 17const int warp = item .get_local_id (1 ) /WARP_SIZE ; 18const int warp_idx = item .get_group (1 )* c_factor + warp ; 19const int seq_idx = item .get_group (0 ); 20 21const int head_idx = warp_idx /d_head ; 22const int head_off = (warp_idx %d_head )* sizeof (float ); 23const int group_off = (head_idx / (n_head /n_group ))* d_state * sizeof (float ); 24 25const float * s0_warp = (const float * ) ((const char * )src0 + src6 [seq_idx ]* src0_nb3 + head_idx * src0_nb2 + head_off * d_state ); 26const float * x_warp = (const float * ) ((const char * )src1 + (seq_idx * src1_nb3 )+ (warp_idx * sizeof (float ))); 27const float * dt_warp = (const float * ) ((const char * )src2 + (seq_idx * src2_nb2 )+ head_idx * sizeof (float )); 28const float * A_warp = (const float * ) ((const char * )src3 + head_idx * src3_nb1 ); 29const float * B_warp = (const float * ) ((const char * )src4 + (seq_idx * src4_nb3 )+ (group_off )); 30const float * C_warp = (const float * ) ((const char * )src5 + (seq_idx * src5_nb3 )+ (group_off )); 31float * y_warp = dst + (seq_idx * n_tok * n_head * d_head )+ warp_idx ; 32float * s_warp = (float * ) ((char * )dst + s_off + seq_idx * src0_nb3 + head_idx * src0_nb2 + head_off * d_state ); 33 34const int stride_x = src1_nb2 /sizeof (float ); 35const int stride_dt = src2_nb1 /sizeof (float ); 36const int stride_B = src4_nb2 /sizeof (float ); 37const int stride_C = src5_nb2 /sizeof (float ); 38const int stride_y = n_head * d_head ; 39 40float state [c_factor ]; 41float state_sum = 0.0f ; 42 43#pragma unroll 44for (int j = 0 ;j < c_factor ;j ++ ) { 45state [j ]= s0_warp [WARP_SIZE * j + lane ]; 46 } 47 48for (int64_t i = 0 ;i < n_tok ;i ++ ) { 49const float dt_val = dt_warp [i * stride_dt ]; 50const float dt_soft_plus = (dt_val <=20.0f ? sycl::log1p (sycl::exp (dt_val )) :dt_val ); 51 52state_sum = 0.0f ; 53const float dA = sycl::exp (dt_soft_plus * A_warp [0 ]); 54const float x_dt = x_warp [i * stride_x ]* dt_soft_plus ; 55#pragma unroll 56for (int j = 0 ;j < c_factor ;j ++ ) { 57const float B_val = B_warp [i * stride_B + WARP_SIZE * j + lane ]; 58const float C_val = C_warp [i * stride_C + WARP_SIZE * j + lane ]; 59state [j ]= (state [j ]* dA )+ (B_val * x_dt ); 60state_sum += state [j ]* C_val ; 61 } 62 63state_sum = warp_reduce_sum < WARP_SIZE > (state_sum ); 64 65if (lane == 0 ) { 66y_warp [i * stride_y ]= state_sum ; 67 } 68 69const int64_t slot = n_tok - 1 - i ; 70if (K > 1 && slot > 0 && slot < K ) { 71float * s_snapshot_warp = (float * ) ((char * )dst + s_off + (slot * item .get_group_range (0 )+ seq_idx )* src0_nb3 + head_idx * src0_nb2 + head_off * d_state ); 72#pragma unroll 73for (int j = 0 ;j < c_factor ;j ++ ) { 74s_snapshot_warp [WARP_SIZE * j + lane ]= state [j ]; 75 } 76 } 77 } 78 79#pragma unroll 80for (int j = 0 ;j < c_factor ;j ++ ) { 81s_warp [WARP_SIZE * j + lane ]= state [j ]; 82 } 83} 84 85static void ssm_scan_f32_sycl ( 86const float * src0 ,const float * src1 ,const float * src2 ,const float * src3 , 87const float * src4 ,const float * src5 ,const int32_t * src6 ,float * dst , 88const int src0_nb2 ,const int src0_nb3 ,const int src1_nb2 ,const int src1_nb3 ,const int src2_nb1 , 89const int src2_nb2 ,const int src3_nb1 ,const int src4_nb2 ,const int src4_nb3 ,const int src5_nb2 , 90const int src5_nb3 ,const int64_t s_off ,const int64_t d_state ,const int64_t head_dim , 91const int64_t n_head ,const int64_t n_group ,const int64_t n_tok ,const int64_t n_seq , 92const int64_t K , 93 dpct::queue_ptr stream ) { 94 95// NOTE: if you change conditions here, be sure to update the corresponding supports_op condition! 96GGML_ASSERT (src3_nb1 == sizeof (float )); 97if (d_state == 128 ) { 98constexpr int threads = 128 ; 99constexpr int num_warps = threads /WARP_SIZE ; 100const sycl::range < 2 > grid (n_seq , (n_head * head_dim + num_warps - 1 ) /num_warps ); 101const sycl::range < 2 > block (1 ,threads ); 102stream -> parallel_for ( 103 sycl::nd_range < 2 > (grid * block ,block ), 104 [= ](sycl::nd_item < 2 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 105ssm_scan_f32_group < 128 /WARP_SIZE ,128 > ( 106src0 ,src1 ,src2 ,src3 ,src4 ,src5 ,src6 ,dst , 107src0_nb2 ,src0_nb3 ,src1_nb2 ,src1_nb3 ,src2_nb1 ,src2_nb2 ,src3_nb1 , 108src4_nb2 ,src4_nb3 ,src5_nb2 ,src5_nb3 ,s_off ,n_head ,head_dim ,n_group ,n_tok ,K ,item ); 109 }); 110 }else if (d_state == 256 ) { 111constexpr int threads = 256 ; 112constexpr int num_warps = threads /WARP_SIZE ; 113const sycl::range < 2 > grid (n_seq , (n_head * head_dim + num_warps - 1 ) /num_warps ); 114const sycl::range < 2 > block (1 ,threads ); 115stream -> parallel_for ( 116 sycl::nd_range < 2 > (grid * block ,block ), 117 [= ](sycl::nd_item < 2 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 118ssm_scan_f32_group < 256 /WARP_SIZE ,256 > ( 119src0 ,src1 ,src2 ,src3 ,src4 ,src5 ,src6 ,dst , 120src0_nb2 ,src0_nb3 ,src1_nb2 ,src1_nb3 ,src2_nb1 ,src2_nb2 ,src3_nb1 , 121src4_nb2 ,src4_nb3 ,src5_nb2 ,src5_nb3 ,s_off ,n_head ,head_dim ,n_group ,n_tok ,K ,item ); 122 }); 123 }else { 124GGML_ABORT ("ssm_scan: unsupported d_state (must be 128 or 256)" ); 125 } 126} 127 128inline void ggml_sycl_op_ssm_scan (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 129const ggml_tensor * src0 = dst -> src [0 ]; 130const ggml_tensor * src1 = dst -> src [1 ]; 131const ggml_tensor * src2 = dst -> src [2 ]; 132const ggml_tensor * src3 = dst -> src [3 ]; 133const ggml_tensor * src4 = dst -> src [4 ]; 134const ggml_tensor * src5 = dst -> src [5 ]; 135const ggml_tensor * src6 = dst -> src [6 ]; 136 137GGML_ASSERT (src0 -> type == GGML_TYPE_F32 ); 138GGML_ASSERT (src6 -> type == GGML_TYPE_I32 ); 139GGML_ASSERT (dst -> type == GGML_TYPE_F32 ); 140 141const int64_t nc = src0 -> ne [0 ]; 142const int64_t nr = src0 -> ne [1 ]; 143const int64_t nh = src1 -> ne [1 ]; 144const int64_t ng = src4 -> ne [1 ]; 145const int64_t n_t = src1 -> ne [2 ]; 146const int64_t n_s = src1 -> ne [3 ]; 147const int64_t K = ggml_get_op_params_i32 (dst ,0 ); 148const int64_t s_off = ggml_nelements (src1 )* sizeof (float ); 149 150GGML_ASSERT (K >=1 ); 151GGML_ASSERT (ggml_nelements (src1 )+ K * nc * nr * nh * n_s == ggml_nelements (dst )); 152GGML_ASSERT (src3 -> ne [0 ]== 1 || K == 1 ); 153 154 dpct::queue_ptr stream = ctx .stream (); 155SYCL_CHECK (ggml_sycl_set_device (ctx .device )); 156 157ssm_scan_f32_sycl ( 158static_cast < const float *> (src0 -> data ),static_cast < const float *> (src1 -> data ), 159static_cast < const float *> (src2 -> data ),static_cast < const float *> (src3 -> data ), 160static_cast < const float *> (src4 -> data ),static_cast < const float *> (src5 -> data ), 161static_cast < const int32_t *> (src6 -> data ),static_cast < float *> (dst -> data ), 162src0 -> nb [2 ],src0 -> nb [3 ],src1 -> nb [2 ],src1 -> nb [3 ],src2 -> nb [1 ],src2 -> nb [2 ], 163src3 -> nb [1 ],src4 -> nb [2 ],src4 -> nb [3 ],src5 -> nb [2 ],src5 -> nb [3 ], 164s_off ,nc ,nr ,nh ,ng ,n_t ,n_s ,K ,stream ); 165} 166 167void ggml_sycl_ssm_scan (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 168scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 7 ); 169ggml_sycl_op_ssm_scan (ctx ,dst ); 170}