char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
55edb2de4
char/aliceai-t5-moe
1#include "cross_entropy_loss.hpp" 2 3#include <cstdint> 4#include <cmath> 5 6template < bool has_shared > 7static __dpct_inline__ void cross_entropy_loss_f32_kernel ( 8const float * __restrict__logits , 9const float * __restrict__labels , 10float * __restrict__row_loss , 11const int nclasses , 12const int nrows , 13float * __restrict__smem , 14const sycl::nd_item < 3 > & item ) { 15 16const int row = item .get_group (2 ); 17const int tid = item .get_local_id (2 ); 18 19logits += (int64_t )row * nclasses ; 20labels += (int64_t )row * nclasses ; 21 22float max_logit = - INFINITY ; 23for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 24const float v = logits [i ]; 25max_logit = sycl::fmax (max_logit ,v ); 26if (has_shared ) { 27smem [i ]= v ; 28 } 29 } 30max_logit = warp_reduce_max < WARP_SIZE > (max_logit ); 31 32float sum_exp = 0.0f ; 33for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 34const float v = has_shared ?smem [i ] :logits [i ]; 35sum_exp += sycl::exp (v - max_logit ); 36 } 37sum_exp = warp_reduce_sum < WARP_SIZE > (sum_exp ); 38const float log_sum = sycl::log (sum_exp ); 39 40float loss = 0.0f ; 41for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 42const float v = has_shared ?smem [i ] :logits [i ]; 43loss += (v - max_logit - log_sum )* labels [i ]; 44 } 45loss = - warp_reduce_sum < WARP_SIZE > (loss ) / (float )nrows ; 46 47if (tid == 0 ) { 48row_loss [row ]= loss ; 49 } 50} 51 52template < bool has_shared > 53static __dpct_inline__ void cross_entropy_loss_back_f32_kernel ( 54const float * __restrict__grad , 55const float * __restrict__logits , 56const float * __restrict__labels , 57float * __restrict__dst , 58const int nclasses , 59const int nrows , 60float * __restrict__smem , 61const sycl::nd_item < 3 > & item ) { 62 63const int row = item .get_group (2 ); 64const int tid = item .get_local_id (2 ); 65 66logits += (int64_t )row * nclasses ; 67labels += (int64_t )row * nclasses ; 68dst += (int64_t )row * nclasses ; 69 70float max_logit = - INFINITY ; 71for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 72const float v = logits [i ]; 73max_logit = sycl::fmax (max_logit ,v ); 74if (has_shared ) { 75smem [i ]= v ; 76 } 77 } 78max_logit = warp_reduce_max < WARP_SIZE > (max_logit ); 79 80float sum_exp = 0.0f ; 81for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 82const float v = sycl::exp ((has_shared ?smem [i ] :logits [i ])- max_logit ); 83sum_exp += v ; 84if (has_shared ) { 85smem [i ]= v ; 86 }else { 87dst [i ]= v ; 88 } 89 } 90sum_exp = warp_reduce_sum < WARP_SIZE > (sum_exp ); 91const float inv_sum = 1.0f /sum_exp ; 92 93const float d_by_nrows = grad [0 ] / (float )nrows ; 94for (int i = tid ;i < nclasses ;i += WARP_SIZE ) { 95const float sm_num = has_shared ?smem [i ] :dst [i ]; 96dst [i ]= (sm_num * inv_sum - labels [i ])* d_by_nrows ; 97 } 98} 99 100static void cross_entropy_reduce_rows ( 101ggml_backend_sycl_context & ctx , 102const float * row_loss , 103float * dst , 104const int64_t nrows ) { 105if (nrows == 1 ) { 106SYCL_CHECK (CHECK_TRY_ERROR ( 107ctx .stream ()-> memcpy (dst ,row_loss ,sizeof (float )))); 108return ; 109 } 110 111ggml_sycl_pool_alloc < float > tmp_alloc (ctx .pool (),nrows ); 112float * tmp = tmp_alloc .get (); 113SYCL_CHECK (CHECK_TRY_ERROR ( 114ctx .stream ()-> memcpy (tmp ,row_loss ,nrows * sizeof (float )))); 115 116int64_t cur = nrows ; 117while (cur > 1 ) { 118const int64_t out = (cur + WARP_SIZE - 1 ) /WARP_SIZE ; 119const sycl::range < 3 > block (1 ,1 ,WARP_SIZE ); 120const sycl::range < 3 > grid (1 ,1 ,out ); 121ctx .stream ()-> parallel_for ( 122 sycl::nd_range < 3 > (grid * block ,block ), 123 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 124const int row = item .get_group (2 ); 125const int tid = item .get_local_id (2 ); 126const int64_t i = (int64_t )row * WARP_SIZE + tid ; 127float v = i < cur ?tmp [i ] :0.0f ; 128v = warp_reduce_sum < WARP_SIZE > (v ); 129if (tid == 0 ) { 130tmp [row ]= v ; 131 } 132 }); 133cur = out ; 134 } 135 136SYCL_CHECK (CHECK_TRY_ERROR ( 137ctx .stream ()-> memcpy (dst ,tmp ,sizeof (float )))); 138} 139 140void ggml_sycl_cross_entropy_loss (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 141scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 2 ); 142 143const ggml_tensor * src0 = dst -> src [0 ]; 144const ggml_tensor * src1 = dst -> src [1 ]; 145 146GGML_ASSERT (src0 -> type == GGML_TYPE_F32 ); 147GGML_ASSERT (src1 -> type == GGML_TYPE_F32 ); 148GGML_ASSERT (dst -> type == GGML_TYPE_F32 ); 149GGML_ASSERT (ggml_is_contiguous (src0 )); 150GGML_ASSERT (ggml_is_contiguous (src1 )); 151GGML_ASSERT (ggml_is_contiguous (dst )); 152GGML_ASSERT (ggml_are_same_shape (src0 ,src1 )); 153GGML_ASSERT (ggml_is_scalar (dst )); 154 155SYCL_CHECK (ggml_sycl_set_device (ctx .device )); 156 157const int64_t nclasses = src0 -> ne [0 ]; 158const int64_t nrows = ggml_nrows (src0 ); 159 160const float * logits_d = (const float * )src0 -> data ; 161const float * labels_d = (const float * )src1 -> data ; 162float * dst_d = (float * )dst -> data ; 163 164ggml_sycl_pool_alloc < float > row_loss_alloc (ctx .pool (),nrows ); 165float * row_loss = row_loss_alloc .get (); 166 167const sycl::range < 3 > block (1 ,1 ,WARP_SIZE ); 168const sycl::range < 3 > grid (1 ,1 ,nrows ); 169const size_t nbytes_shared = (size_t )nclasses * sizeof (float ); 170const size_t smpbo = ggml_sycl_info ().devices [ctx .device ].smpbo ; 171 172if (nbytes_shared <=smpbo ) { 173ctx .stream ()-> submit ([& ](sycl::handler & cgh ) { 174 sycl::local_accessor < float ,1 > smem (sycl::range < 1 > (nclasses ),cgh ); 175cgh .parallel_for ( 176 sycl::nd_range < 3 > (grid * block ,block ), 177 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 178cross_entropy_loss_f32_kernel < true> ( 179logits_d ,labels_d ,row_loss , 180 (int )nclasses , (int )nrows , 181get_pointer (smem ),item ); 182 }); 183 }); 184 }else { 185ctx .stream ()-> parallel_for ( 186 sycl::nd_range < 3 > (grid * block ,block ), 187 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 188cross_entropy_loss_f32_kernel < false> ( 189logits_d ,labels_d ,row_loss , 190 (int )nclasses , (int )nrows , 191nullptr ,item ); 192 }); 193 } 194 195cross_entropy_reduce_rows (ctx ,row_loss ,dst_d ,nrows ); 196} 197 198void ggml_sycl_cross_entropy_loss_back (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 199scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 3 ); 200 201const ggml_tensor * grad = dst -> src [0 ]; 202const ggml_tensor * src0f = dst -> src [1 ]; 203const ggml_tensor * src1f = dst -> src [2 ]; 204 205GGML_ASSERT (grad -> type == GGML_TYPE_F32 ); 206GGML_ASSERT (src0f -> type == GGML_TYPE_F32 ); 207GGML_ASSERT (src1f -> type == GGML_TYPE_F32 ); 208GGML_ASSERT (dst -> type == GGML_TYPE_F32 ); 209 210GGML_ASSERT (ggml_is_scalar (grad )); 211GGML_ASSERT (ggml_is_contiguous (grad )); 212GGML_ASSERT (ggml_is_contiguous (src0f )); 213GGML_ASSERT (ggml_is_contiguous (src1f )); 214GGML_ASSERT (ggml_is_contiguous (dst )); 215GGML_ASSERT (ggml_are_same_shape (src0f ,src1f )); 216GGML_ASSERT (ggml_are_same_shape (src0f ,dst )); 217 218SYCL_CHECK (ggml_sycl_set_device (ctx .device )); 219 220const int64_t nclasses = src0f -> ne [0 ]; 221const int64_t nrows = ggml_nrows (src0f ); 222 223const float * grad_d = (const float * )grad -> data ; 224const float * logits_d = (const float * )src0f -> data ; 225const float * labels_d = (const float * )src1f -> data ; 226float * dst_d = (float * )dst -> data ; 227 228const sycl::range < 3 > block (1 ,1 ,WARP_SIZE ); 229const sycl::range < 3 > grid (1 ,1 ,nrows ); 230const size_t nbytes_shared = (size_t )nclasses * sizeof (float ); 231const size_t smpbo = ggml_sycl_info ().devices [ctx .device ].smpbo ; 232 233if (nbytes_shared <=smpbo ) { 234ctx .stream ()-> submit ([& ](sycl::handler & cgh ) { 235 sycl::local_accessor < float ,1 > smem (sycl::range < 1 > (nclasses ),cgh ); 236cgh .parallel_for ( 237 sycl::nd_range < 3 > (grid * block ,block ), 238 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 239cross_entropy_loss_back_f32_kernel < true> ( 240grad_d ,logits_d ,labels_d ,dst_d , 241 (int )nclasses , (int )nrows , 242get_pointer (smem ),item ); 243 }); 244 }); 245 }else { 246ctx .stream ()-> parallel_for ( 247 sycl::nd_range < 3 > (grid * block ,block ), 248 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 249cross_entropy_loss_back_f32_kernel < false> ( 250grad_d ,logits_d ,labels_d ,dst_d , 251 (int )nclasses , (int )nrows , 252nullptr ,item ); 253 }); 254 } 255}