char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
9c1095486
char/aliceai-t5-moe
1#include "conv3d.hpp" 2 3static inline int64_t ggml_sycl_conv3d_calc_patch_total (const ggml_tensor * dst ,int32_t n ) { 4return (int64_t )n * dst -> ne [0 ]* dst -> ne [1 ]* dst -> ne [2 ]; 5} 6 7static inline int64_t ggml_sycl_conv3d_calc_knl_n_total (const ggml_tensor * src0 ,int32_t c ) { 8return (int64_t )src0 -> ne [0 ]* src0 -> ne [1 ]* src0 -> ne [2 ]* c ; 9} 10 11static inline void ggml_sycl_conv3d_write_output ( 12const ggml_tensor * dst , 13const float * src ,float * dst_data , 14int64_t patch_total ,int64_t oc , 15int64_t dst_w ,int64_t dst_h ,int64_t dst_d , 16 dpct::queue_ptr stream ) { 17const int64_t dst_nb0 = dst -> nb [0 ]; 18const int64_t dst_nb1 = dst -> nb [1 ]; 19const int64_t dst_nb2 = dst -> nb [2 ]; 20const int64_t dst_nb3 = dst -> nb [3 ]; 21const int64_t total = patch_total * oc ; 22const int64_t block_size = 256 ; 23const int64_t num_work_items = ((total + block_size - 1 ) /block_size )* block_size ; 24 25stream -> parallel_for (sycl::range < 1 > (num_work_items ), [= ](sycl::id < 1 > id ) { 26const int64_t i = id [0 ]; 27if (i >=total ) { 28return ; 29 } 30 31const int64_t patch_idx = i /oc ; 32const int64_t out_ch = i %oc ; 33const int64_t p_in_batch = patch_idx % (dst_w * dst_h * dst_d ); 34const int64_t batch_idx = patch_idx / (dst_w * dst_h * dst_d ); 35const int64_t dst_z = p_in_batch / (dst_w * dst_h ); 36const int64_t dst_y = (p_in_batch % (dst_w * dst_h )) /dst_w ; 37const int64_t dst_x = p_in_batch %dst_w ; 38const int64_t ocn_idx = batch_idx * oc + out_ch ; 39 40const int64_t dst_offset = dst_x * dst_nb0 + dst_y * dst_nb1 + dst_z * dst_nb2 + ocn_idx * dst_nb3 ; 41// `src` is a column-major (m x n) GEMM output where m == patch_total, n == oc. 42// GEMM stores element (row, col) at index `row + col*m`, so compute index accordingly. 43const int64_t src_index = patch_idx + out_ch * patch_total ; 44const float value = src [src_index ]; 45* (float * )((char * )dst_data + dst_offset )= value ; 46 }); 47} 48 49void ggml_sycl_op_conv_3d (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 50scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 2 ); 51 52const ggml_tensor * src0 = dst -> src [0 ]; 53const ggml_tensor * src1 = dst -> src [1 ]; 54 55GGML_ASSERT (src0 -> type == GGML_TYPE_F16 || src0 -> type == GGML_TYPE_F32 ); 56GGML_ASSERT (src1 -> type == GGML_TYPE_F32 ); 57GGML_ASSERT (dst -> type == GGML_TYPE_F32 ); 58GGML_ASSERT (ggml_is_contiguous (src0 )); 59GGML_ASSERT (ggml_is_contiguous (src1 )); 60 61const int32_t * opts = (const int32_t * )dst -> op_params ; 62const int32_t s0 = opts [0 ]; 63const int32_t s1 = opts [1 ]; 64const int32_t s2 = opts [2 ]; 65const int32_t p0 = opts [3 ]; 66const int32_t p1 = opts [4 ]; 67const int32_t p2 = opts [5 ]; 68const int32_t d0 = opts [6 ]; 69const int32_t d1 = opts [7 ]; 70const int32_t d2 = opts [8 ]; 71const int32_t c = opts [9 ]; 72const int32_t n = opts [10 ]; 73const int32_t oc = opts [11 ]; 74 75const int64_t knl_w = src0 -> ne [0 ]; 76const int64_t knl_h = src0 -> ne [1 ]; 77const int64_t knl_d = src0 -> ne [2 ]; 78 79const int64_t patch_total = ggml_sycl_conv3d_calc_patch_total (dst ,n ); 80const int64_t knl_n_total = ggml_sycl_conv3d_calc_knl_n_total (src0 ,c ); 81 82const size_t kernel_type_size = ggml_element_size (src0 ); 83 84ggml_sycl_pool_alloc < float > gemm_output (ctx .pool ()); 85gemm_output .alloc ((size_t )patch_total * oc ); 86 87ggml_tensor dst_mat = {}; 88dst_mat .type = GGML_TYPE_F32 ; 89dst_mat .ne [0 ]= patch_total ; 90dst_mat .ne [1 ]= oc ; 91dst_mat .ne [2 ]= 1 ; 92dst_mat .ne [3 ]= 1 ; 93dst_mat .nb [0 ]= sizeof (float ); 94dst_mat .nb [1 ]= dst_mat .nb [0 ]* dst_mat .ne [0 ]; 95dst_mat .nb [2 ]= dst_mat .nb [1 ]; 96dst_mat .nb [3 ]= dst_mat .nb [2 ]; 97dst_mat .data = gemm_output .get (); 98dst_mat .buffer = dst -> buffer ; 99dst_mat .extra = dst -> extra ; 100 101 dpct::queue_ptr stream = ctx .stream (); 102 103// allocate packed arrays: A_packed (k x m), B_packed (k x n) 104ggml_sycl_pool_alloc < float > A_packed_alloc (ctx .pool ()); 105ggml_sycl_pool_alloc < float > B_packed_alloc (ctx .pool ()); 106A_packed_alloc .alloc ((size_t )knl_n_total * patch_total ); 107B_packed_alloc .alloc ((size_t )knl_n_total * oc ); 108 109float * A_packed = A_packed_alloc .get (); 110float * B_packed = B_packed_alloc .get (); 111 112const int m = (int )patch_total ; 113const int n_gemm = (int )oc ; 114const int k = (int )knl_n_total ; 115 116// Combined kernel: im2col -> pack A, and pack B simultaneously 117const char * src1_base = (const char * )src1 -> data ; 118const char * src0_base = (const char * )src0 -> data ; 119const int64_t src1_nb0 = src1 -> nb [0 ]; 120const int64_t src1_nb1 = src1 -> nb [1 ]; 121const int64_t src1_nb2 = src1 -> nb [2 ]; 122const int64_t src1_nb3 = src1 -> nb [3 ]; 123const int64_t src1_w = src1 -> ne [0 ]; 124const int64_t src1_h = src1 -> ne [1 ]; 125const int64_t src1_d = src1 -> ne [2 ]; 126 127const bool src0_is_f32 = (src0 -> type == GGML_TYPE_F32 ); 128 129// Compute correct strides for src0 as (knl_n_total, oc) matrix 130const int64_t src0_packed_nb0 = kernel_type_size ; 131const int64_t src0_packed_nb1 = kernel_type_size * knl_n_total ; 132 133const int64_t KW = knl_w ; 134const int64_t KH = knl_h ; 135const int64_t KD = knl_d ; 136const int64_t PW = dst -> ne [0 ]; 137const int64_t PH = dst -> ne [1 ]; 138const int64_t PD = dst -> ne [2 ]; 139 140// Pack A (with inline im2col): for each (row, col) in k x m matrix 141const int64_t A_total = (int64_t )k * m ; 142const int64_t A_block_size = 256 ; 143const int64_t A_num_work = ((A_total + A_block_size - 1 ) /A_block_size )* A_block_size ; 144 145stream -> parallel_for (sycl::range < 1 > (A_num_work ), [= ](sycl::id < 1 > id ) { 146const int64_t t = id [0 ]; 147if (t >=A_total )return ; 148 149const int64_t row = t %k ; 150const int64_t col = t /k ; 151 152// Inline im2col for this element 153const int64_t k_index = row ; 154const int64_t patch_idx = col ; 155 156const int64_t ic = k_index / (KD * KH * KW ); 157const int64_t rem = k_index - ic * (KD * KH * KW ); 158const int64_t kz = rem / (KH * KW ); 159const int64_t rem2 = rem - kz * (KH * KW ); 160const int64_t ky = rem2 /KW ; 161const int64_t kx = rem2 %KW ; 162 163const int64_t p_in_batch = patch_idx % (PW * PH * PD ); 164const int64_t batch_idx = patch_idx / (PW * PH * PD ); 165const int64_t dst_z = p_in_batch / (PW * PH ); 166const int64_t dst_y = (p_in_batch % (PW * PH )) /PW ; 167const int64_t dst_x = p_in_batch %PW ; 168 169const int64_t sx = dst_x * s0 + kx * d0 - p0 ; 170const int64_t sy = dst_y * s1 + ky * d1 - p1 ; 171const int64_t sz = dst_z * s2 + kz * d2 - p2 ; 172 173float val = 0.0f ; 174if (sx >=0 && sx < src1_w && sy >=0 && sy < src1_h && sz >=0 && sz < src1_d ) { 175const int64_t channel_idx = batch_idx * c + ic ; 176const char * ptr = src1_base + sx * src1_nb0 + sy * src1_nb1 + sz * src1_nb2 + channel_idx * src1_nb3 ; 177val = * (const float * )ptr ; 178 } 179A_packed [row + col * (int64_t )k ]= val ; 180 }); 181 182// Pack B: for each (row, col) in k x n_gemm matrix 183const int64_t B_total = (int64_t )k * n_gemm ; 184const int64_t B_block_size = 256 ; 185const int64_t B_num_work = ((B_total + B_block_size - 1 ) /B_block_size )* B_block_size ; 186 187stream -> parallel_for (sycl::range < 1 > (B_num_work ), [= ](sycl::id < 1 > id ) { 188const int64_t t = id [0 ]; 189if (t >=B_total )return ; 190 191const int64_t row = t %k ; 192const int64_t col = t /k ; 193const char * src_ptr = src0_base + row * src0_packed_nb0 + col * src0_packed_nb1 ; 194float v ; 195if (src0_is_f32 ) { 196v = * (const float * )src_ptr ; 197 }else { 198v = sycl::vec < sycl::half ,1 > (* (const sycl::half * )src_ptr ).convert < float , sycl::rounding_mode::automatic > ()[0 ]; 199 } 200B_packed [row + col * (int64_t )k ]= v ; 201 }); 202 203// GEMM: C = A^T * B where A is (k x m), B is (k x n), C is (m x n) 204const float alpha = 1.0f ; 205const float beta = 0.0f ; 206const int lda = k ; 207const int ldb = k ; 208const int ldc = m ; 209 210SYCL_CHECK (CHECK_TRY_ERROR (oneapi::mkl::blas::column_major::gemm ( 211* stream , oneapi::mkl::transpose::trans , oneapi::mkl::transpose::nontrans , 212m ,n_gemm ,k , 213 dpct::get_value (& alpha ,* stream ), 214 (const float * )A_packed ,lda , 215 (const float * )B_packed ,ldb , 216 dpct::get_value (& beta ,* stream ), 217 (float * )dst_mat .data ,ldc ))); 218 219const float * gemm_data = (const float * )dst_mat .data ; 220float * dst_data = (float * )dst -> data ; 221 222ggml_sycl_conv3d_write_output (dst ,gemm_data ,dst_data ,patch_total ,oc , 223dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],stream ); 224}