char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ad0922465
char/aliceai-t5-moe
1#include "solve_tri.hpp" 2#include "common.hpp" 3#include <oneapi/mkl/blas.hpp> 4 5template < int n_template ,int k_template > 6static void solve_tri_f32_fast (const float * __restrict__A , 7const float * __restrict__B , 8float * __restrict__X , 9const int64_t ne02 , [[maybe_unused ]]const int64_t ne03 , 10const int64_t nb02 ,const int64_t nb03 , 11const int64_t nb12 ,const int64_t nb13 , 12const int64_t nb2 ,const int64_t nb3 , 13const int n_arg ,const int k_arg , 14const sycl::nd_item < 2 > & item ,float * sA ) { 15 16const int n = n_template == 0 ?n_arg :n_template ; 17const int k = k_template == 0 ?k_arg :k_template ; 18 19const int batch_idx = item .get_group (1 ); 20const int lane = item .get_local_id (1 ) %WARP_SIZE ; 21const int col_idx = item .get_local_id (0 ); 22 23if (col_idx >=k ) { 24return ; 25 } 26 27const int64_t i03 = batch_idx /ne02 ; 28const int64_t i02 = batch_idx %ne02 ; 29 30const float * A_batch = (const float * ) ((const char * )A + i02 * nb02 + i03 * nb03 ); 31const float * B_batch = (const float * ) ((const char * )B + i02 * nb12 + i03 * nb13 ); 32float * X_batch = (float * ) ((char * )X + i02 * nb2 + i03 * nb3 ); 33 34const int offset = item .get_local_id (1 )+ item .get_local_id (0 )* item .get_local_range (1 ); 35 36#pragma unroll 37for (int i = 0 ;i < n * n ;i += k * WARP_SIZE ) { 38const int i0 = i + offset ; 39if (i0 < n * n ) { 40sA [i0 ]= A_batch [i0 ]; 41 } 42 } 43 44item .barrier (sycl::access::fence_space::local_space ); 45 46float x_low = (lane < n ) ?B_batch [lane * k + col_idx ] :0.0f ; 47float x_high = (WARP_SIZE + lane < n ) ?B_batch [(WARP_SIZE + lane )* k + col_idx ] :0.0f ; 48 49const int half = WARP_SIZE ; 50const int nrows_low = (n < half ) ?n :half ; 51 52#pragma unroll 53for (int row = 0 ;row < nrows_low ;++ row ) { 54float sum = 0.0f ; 55if (lane < row ) { 56sum += sA [row * n + lane ]* x_low ; 57 } 58sum = warp_reduce_sum < WARP_SIZE > (sum ); 59if (lane == row ) { 60x_low = (x_low - sum ) /sA [row * n + row ]; 61 } 62 } 63 64#pragma unroll 65for (int row = half ;row < n ;++ row ) { 66float sum = sA [row * n + lane ]* x_low ; 67const int j = half + lane ; 68if (j < row ) { 69sum += sA [row * n + j ]* x_high ; 70 } 71sum = warp_reduce_sum < WARP_SIZE > (sum ); 72if (lane == row - half ) { 73x_high = (x_high - sum ) /sA [row * n + row ]; 74 } 75 } 76 77#pragma unroll 78for (int rr = 0 ;rr < 2 ;++ rr ) { 79const int row = rr * WARP_SIZE + lane ; 80if (row < n ) { 81const float val = (row < half ) ?x_low :x_high ; 82X_batch [row * k + col_idx ]= val ; 83 } 84 } 85} 86 87static void solve_tri_f32_mkl (dpct::queue_ptr stream , 88const float * A ,float * X , 89int n ,int k , 90int64_t ne02 , [[maybe_unused ]]int64_t ne03 , 91int64_t nb02 , [[maybe_unused ]]int64_t nb03 , 92int64_t nb2 , [[maybe_unused ]]int64_t nb3 ) { 93const float alpha = 1.0f ; 94const int64_t total_batches = ne02 * ne03 ; 95if (total_batches == 0 ) { 96return ; 97 } 98 99const int64_t stride_a = nb02 /sizeof (float ); 100const int64_t stride_x = nb2 /sizeof (float ); 101 102 oneapi::mkl::blas::trsm_batch ( 103* stream , 104 oneapi::mkl::side::right , 105 oneapi::mkl::uplo::upper , 106 oneapi::mkl::transpose::nontrans , 107 oneapi::mkl::diag::nonunit , 108k ,n ,alpha , 109A ,n ,stride_a , 110X ,k ,stride_x , 111total_batches ); 112} 113 114inline void ggml_sycl_op_solve_tri (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 115const ggml_tensor * src0 = dst -> src [0 ]; 116const ggml_tensor * src1 = dst -> src [1 ]; 117 118GGML_ASSERT (ggml_is_contiguous (src0 )); 119GGML_ASSERT (ggml_is_contiguous (src1 )); 120GGML_ASSERT (src0 -> type == GGML_TYPE_F32 ); 121 122 dpct::queue_ptr stream = ctx .stream (); 123SYCL_CHECK (ggml_sycl_set_device (ctx .device )); 124 125const int n = src0 -> ne [0 ]; 126const int k = src1 -> ne [0 ]; 127const int64_t ne02 = src0 -> ne [2 ]; 128const int64_t ne03 = src0 -> ne [3 ]; 129 130GGML_ASSERT (n <=SYCL_SOLVE_TRI_MAX_N && k <=SYCL_SOLVE_TRI_MAX_K ); 131 132const float * A_d = static_cast < const float *> (src0 -> data ); 133const float * B_d = static_cast < const float *> (src1 -> data ); 134float * X_d = static_cast < float *> (dst -> data ); 135 136if (X_d != B_d ) { 137const int64_t total_elements = (int64_t )n * k * ne02 * ne03 ; 138stream -> memcpy (X_d ,B_d ,total_elements * sizeof (float )); 139 } 140 141const int64_t nb02 = src0 -> nb [2 ]; 142const int64_t nb03 = src0 -> nb [3 ]; 143const int64_t nb12 = src1 -> nb [2 ]; 144const int64_t nb13 = src1 -> nb [3 ]; 145const int64_t nb2 = dst -> nb [2 ]; 146const int64_t nb3 = dst -> nb [3 ]; 147 148const int64_t total_batches = ne02 * ne03 ; 149 150if (n <=2 * WARP_SIZE && k <=32 ) { 151const int smem_size = 2 * WARP_SIZE * 2 * WARP_SIZE ; 152const sycl::range < 2 > grid (1 ,total_batches ); 153const sycl::range < 2 > block (k ,WARP_SIZE ); 154stream -> submit ([& ](sycl::handler & cgh ) { 155 sycl::local_accessor < float ,1 > smem_acc (sycl::range < 1 > (smem_size ),cgh ); 156cgh .parallel_for ( 157 sycl::nd_range < 2 > (grid * block ,block ), 158 [= ](sycl::nd_item < 2 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 159solve_tri_f32_fast < 0 ,0 > (A_d ,B_d ,X_d ,ne02 ,ne03 , 160nb02 ,nb03 ,nb12 ,nb13 ,nb2 ,nb3 , 161n ,k ,item ,get_pointer (smem_acc )); 162 }); 163 }); 164 }else { 165solve_tri_f32_mkl (stream ,A_d ,X_d ,n ,k ,ne02 ,ne03 ,nb02 ,nb03 ,nb2 ,nb3 ); 166 } 167} 168 169void ggml_sycl_solve_tri (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 170scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 2 ); 171ggml_sycl_op_solve_tri (ctx ,dst ); 172}