char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ad0922465
char/aliceai-t5-moe
1#include "cumsum.hpp" 2#include "common.hpp" 3 4#include <algorithm> 5 6#define SYCL_CUMSUM_BLOCK_SIZE 256 7 8static __dpct_inline__ float warp_prefix_inclusive_sum_f32 (float x ,const sycl::nd_item < 3 > & item ) { 9return sycl::inclusive_scan_over_group (item .get_sub_group (),x , sycl::plus < float > ()); 10} 11 12static void cumsum_f32_kernel ( 13const float * __restrict__src ,float * __restrict__dst , 14const int64_t ne00 ,const int64_t ne01 ,const int64_t ne02 ,const int64_t ne03 , 15const int64_t s01 ,const int64_t s02 ,const int64_t s03 , 16const int64_t d1 ,const int64_t d2 ,const int64_t d3 , 17const sycl::nd_item < 3 > & item ,float * smem ) { 18 19const int tid = item .get_local_id (2 ); 20const int block_size = item .get_local_range (2 ); 21const int lane = tid %WARP_SIZE ; 22const int warp = tid /WARP_SIZE ; 23const int warps_per_block = block_size /WARP_SIZE ; 24 25float * s_vals = smem ; 26float * s_warp_sums = smem + block_size ; 27float * s_carry = smem + block_size + warps_per_block ; 28 29if (tid == 0 ) { 30s_carry [0 ]= 0.0f ; 31 } 32item .barrier (sycl::access::fence_space::local_space ); 33 34const int64_t i3 = item .get_group (0 ); 35const int64_t i2 = item .get_group (1 ); 36const int64_t i1 = item .get_group (2 ); 37if (i3 >=ne03 || i2 >=ne02 || i1 >=ne01 ) { 38return ; 39 } 40 41const float * src_row = src + i1 * s01 + i2 * s02 + i3 * s03 ; 42float * dst_row = dst + i1 * d1 + i2 * d2 + i3 * d3 ; 43 44constexpr int num_unroll = 4 ; 45float temp [num_unroll ]; 46 47for (int64_t i = 0 ;i < ne00 ;i += num_unroll * block_size ) { 48int64_t idx = i + tid * num_unroll ; 49 50temp [0 ]= (idx < ne00 ?src_row [idx ] :0.0f ); 51#pragma unroll 52for (int j = 1 ;j < num_unroll ;j ++ ) { 53temp [j ]= temp [j - 1 ]; 54if (idx + j < ne00 ) { 55temp [j ]+= src_row [idx + j ]; 56 } 57 } 58 59float val = (idx < ne00 ) ?temp [num_unroll - 1 ] :0.0f ; 60 61val = warp_prefix_inclusive_sum_f32 (val ,item ); 62s_vals [tid ]= val ; 63 64if (lane == WARP_SIZE - 1 ) { 65s_warp_sums [warp ]= val ; 66 } 67item .barrier (sycl::access::fence_space::local_space ); 68 69if (warp == 0 ) { 70float w = (tid < warps_per_block ) ?s_warp_sums [tid ] :0.0f ; 71float inc = warp_prefix_inclusive_sum_f32 (w ,item ); 72if (tid < warps_per_block ) { 73s_warp_sums [tid ]= inc - w ; 74 } 75if (tid == warps_per_block - 1 ) { 76s_carry [1 ]= inc ; 77 } 78 } 79item .barrier (sycl::access::fence_space::local_space ); 80 81float carry = s_carry [0 ]; 82float final_offset = s_vals [tid ]+ s_warp_sums [warp ]+ carry - temp [num_unroll - 1 ]; 83 84#pragma unroll 85for (int j = 0 ;j < num_unroll ;j ++ ) { 86if (idx + j < ne00 ) { 87dst_row [idx + j ]= temp [j ]+ final_offset ; 88 } 89 } 90 91item .barrier (sycl::access::fence_space::local_space ); 92 93if (tid == 0 ) { 94s_carry [0 ]+= s_carry [1 ]; 95 } 96 } 97} 98 99inline void ggml_sycl_op_cumsum (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 100const ggml_tensor * src0 = dst -> src [0 ]; 101 102GGML_ASSERT (src0 -> type == GGML_TYPE_F32 ); 103GGML_ASSERT (dst -> type == GGML_TYPE_F32 ); 104 105 dpct::queue_ptr stream = ctx .stream (); 106SYCL_CHECK (ggml_sycl_set_device (ctx .device )); 107 108const float * src_d = static_cast < const float *> (src0 -> data ); 109float * dst_d = static_cast < float *> (dst -> data ); 110 111const int64_t ne00 = src0 -> ne [0 ]; 112const int64_t ne01 = src0 -> ne [1 ]; 113const int64_t ne02 = src0 -> ne [2 ]; 114const int64_t ne03 = src0 -> ne [3 ]; 115 116const size_t ts = sizeof (float ); 117const int64_t s01 = src0 -> nb [1 ] /ts ; 118const int64_t s02 = src0 -> nb [2 ] /ts ; 119const int64_t s03 = src0 -> nb [3 ] /ts ; 120const int64_t d1 = dst -> nb [1 ] /ts ; 121const int64_t d2 = dst -> nb [2 ] /ts ; 122const int64_t d3 = dst -> nb [3 ] /ts ; 123 124const int num_warps = (ne00 + WARP_SIZE - 1 ) /WARP_SIZE ; 125int block_size = num_warps * WARP_SIZE ; 126block_size = std::min (block_size ,SYCL_CUMSUM_BLOCK_SIZE ); 127const int warps_per_block = block_size /WARP_SIZE ; 128const int smem_size = block_size + warps_per_block + 2 ; 129 130const sycl::range < 3 > grid (ne03 ,ne02 ,ne01 ); 131const sycl::range < 3 > block (1 ,1 ,block_size ); 132 133stream -> submit ([& ](sycl::handler & cgh ) { 134 sycl::local_accessor < float ,1 > smem_acc (sycl::range < 1 > (smem_size ),cgh ); 135cgh .parallel_for ( 136 sycl::nd_range < 3 > (grid * block ,block ), 137 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 138cumsum_f32_kernel (src_d ,dst_d ,ne00 ,ne01 ,ne02 ,ne03 , 139s01 ,s02 ,s03 ,d1 ,d2 ,d3 , 140item ,get_pointer (smem_acc )); 141 }); 142 }); 143} 144 145void ggml_sycl_cumsum (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 146scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 1 ); 147ggml_sycl_op_cumsum (ctx ,dst ); 148}