char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ae9291e16
char/aliceai-t5-moe
1#include "conv2d-dw.hpp" 2 3struct conv2d_dw_params { 4int in_w ,in_h ; 5int out_w ,out_h ; 6int kernel_w ,kernel_h ; 7int stride_x ,stride_y ; 8int padding_x ,padding_y ; 9int dilation_x ,dilation_y ; 10int channels ,batches ; 11}; 12 13struct conv2d_dw_kernel_bounds { 14int y_min ,y_max ; 15int x_min ,x_max ; 16}; 17 18static inline conv2d_dw_kernel_bounds dw_calculate_kernel_bounds (int out_x ,int out_y , 19const conv2d_dw_params & p ) { 20conv2d_dw_kernel_bounds bounds ; 21bounds .y_min = sycl::max (0 , (p .padding_y - out_y * p .stride_y + p .dilation_y - 1 ) /p .dilation_y ); 22bounds .y_max = sycl::min (p .kernel_h , 23 (p .in_h + p .padding_y - out_y * p .stride_y + p .dilation_y - 1 ) /p .dilation_y ); 24bounds .x_min = sycl::max (0 , (p .padding_x - out_x * p .stride_x + p .dilation_x - 1 ) /p .dilation_x ); 25bounds .x_max = sycl::min (p .kernel_w , 26 (p .in_w + p .padding_x - out_x * p .stride_x + p .dilation_x - 1 ) /p .dilation_x ); 27return bounds ; 28} 29 30static inline int dw_calculate_input_coord (int out_coord ,int kern_coord ,int stride ,int dilation ,int padding ) { 31return out_coord * stride + kern_coord * dilation - padding ; 32} 33 34// whcn layout: input/output stored as [N, C, H, W] 35struct dw_whcn_layout { 36static int input_index (int n ,int c ,int y ,int x ,const conv2d_dw_params & p ) { 37return n * (p .channels * p .in_w * p .in_h )+ c * p .in_w * p .in_h + y * p .in_w + x ; 38 } 39static int kernel_index (int c ,int ky ,int kx ,const conv2d_dw_params & p ) { 40return c * p .kernel_h * p .kernel_w + ky * p .kernel_w + kx ; 41 } 42static int output_index (int n ,int c ,int y ,int x ,const conv2d_dw_params & p ) { 43return n * (p .channels * p .out_w * p .out_h )+ c * p .out_w * p .out_h + y * p .out_w + x ; 44 } 45static void unpack_indices (int global_idx ,const conv2d_dw_params & p , 46int & n ,int & c ,int & out_y ,int & out_x ) { 47out_x = global_idx %p .out_w ; 48out_y = (global_idx /p .out_w ) %p .out_h ; 49c = (global_idx / (p .out_w * p .out_h )) %p .channels ; 50n = global_idx / (p .out_w * p .out_h * p .channels ); 51 } 52}; 53 54// cwhn layout: input/output stored as [N, H, W, C] 55struct dw_cwhn_layout { 56static int input_index (int n ,int c ,int y ,int x ,const conv2d_dw_params & p ) { 57return n * (p .channels * p .in_w * p .in_h )+ (y * p .in_w + x )* p .channels + c ; 58 } 59static int kernel_index (int c ,int ky ,int kx ,const conv2d_dw_params & p ) { 60return (ky * p .kernel_w + kx )* p .channels + c ; 61 } 62static int output_index (int n ,int c ,int y ,int x ,const conv2d_dw_params & p ) { 63return n * (p .channels * p .out_w * p .out_h )+ y * (p .out_w * p .channels )+ x * p .channels + c ; 64 } 65static void unpack_indices (int global_idx ,const conv2d_dw_params & p , 66int & n ,int & c ,int & out_y ,int & out_x ) { 67c = global_idx %p .channels ; 68out_x = (global_idx /p .channels ) %p .out_w ; 69out_y = (global_idx / (p .channels * p .out_w )) %p .out_h ; 70n = global_idx / (p .channels * p .out_w * p .out_h ); 71 } 72}; 73 74template < typename KernelT ,typename Layout > 75static void conv2d_dw_kernel (const float * input ,const KernelT * kernel ,float * output , 76const conv2d_dw_params p ,const sycl::nd_item < 3 > & item_ct1 ) { 77const int global_idx = item_ct1 .get_local_id (2 )+ 78item_ct1 .get_group (2 )* item_ct1 .get_local_range (2 ); 79const int total_elements = p .batches * p .channels * p .out_h * p .out_w ; 80 81if (global_idx >=total_elements ) { 82return ; 83 } 84 85int n ,c ,out_y ,out_x ; 86Layout ::unpack_indices (global_idx ,p ,n ,c ,out_y ,out_x ); 87 88float acc = 0.0f ; 89const conv2d_dw_kernel_bounds bounds = dw_calculate_kernel_bounds (out_x ,out_y ,p ); 90 91for (int ky = bounds .y_min ;ky < bounds .y_max ;++ ky ) { 92const int in_y = dw_calculate_input_coord (out_y ,ky ,p .stride_y ,p .dilation_y ,p .padding_y ); 93for (int kx = bounds .x_min ;kx < bounds .x_max ;++ kx ) { 94const int in_x = dw_calculate_input_coord (out_x ,kx ,p .stride_x ,p .dilation_x ,p .padding_x ); 95acc += input [Layout ::input_index (n ,c ,in_y ,in_x ,p )]* 96static_cast < float > (kernel [Layout ::kernel_index (c ,ky ,kx ,p )]); 97 } 98 } 99 100output [Layout ::output_index (n ,c ,out_y ,out_x ,p )]= acc ; 101} 102 103template < typename KernelT ,typename Layout > 104static void conv2d_dw_sycl (const float * x_d ,const KernelT * w_d ,float * y_d , 105const conv2d_dw_params p ,const queue_ptr & stream ) { 106const int total = p .batches * p .channels * p .out_h * p .out_w ; 107const int num_blocks = (total + SYCL_CONV2D_DW_BLOCK_SIZE - 1 ) /SYCL_CONV2D_DW_BLOCK_SIZE ; 108const sycl::range < 3 > block_dims (1 ,1 ,SYCL_CONV2D_DW_BLOCK_SIZE ); 109const sycl::range < 3 > block_nums (1 ,1 ,num_blocks ); 110stream -> parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 111 [= ](sycl::nd_item < 3 > item_ct1 ) { 112conv2d_dw_kernel < KernelT ,Layout > (x_d ,w_d ,y_d ,p ,item_ct1 ); 113 }); 114} 115 116void ggml_sycl_op_conv2d_dw (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 117scope_op_debug_print scope_dbg_print (__func__ ,dst ,/*num_src=*/ 2 ); 118 119const ggml_tensor * kernel = dst -> src [0 ]; 120const ggml_tensor * input = dst -> src [1 ]; 121 122GGML_ASSERT ((kernel -> type == GGML_TYPE_F32 || kernel -> type == GGML_TYPE_F16 )&& 123input -> type == GGML_TYPE_F32 && dst -> type == GGML_TYPE_F32 ); 124 125const float * x_d = (const float * )input -> data ; 126float * y_d = (float * )dst -> data ; 127 128const int32_t * p = (const int32_t * )dst -> op_params ; 129const int stride_x = p [0 ]; 130const int stride_y = p [1 ]; 131const int padding_x = p [2 ]; 132const int padding_y = p [3 ]; 133const int dilation_x = p [4 ]; 134const int dilation_y = p [5 ]; 135 136const int in_w = input -> ne [0 ]; 137const int in_h = input -> ne [1 ]; 138const int kernel_w = kernel -> ne [0 ]; 139const int kernel_h = kernel -> ne [1 ]; 140const int out_w = dst -> ne [0 ]; 141const int out_h = dst -> ne [1 ]; 142const int channels = dst -> ne [2 ]; 143const int batches = dst -> ne [3 ]; 144 145const conv2d_dw_params params = {in_w ,in_h ,out_w ,out_h ,kernel_w ,kernel_h , 146stride_x ,stride_y ,padding_x ,padding_y , 147dilation_x ,dilation_y ,channels ,batches }; 148 149const queue_ptr stream = ctx .stream (); 150 151if (kernel -> type == GGML_TYPE_F16 ) { 152const sycl::half * w_d = (const sycl::half * )kernel -> data ; 153if (ggml_is_contiguous (input )) { 154conv2d_dw_sycl < sycl::half ,dw_whcn_layout > (x_d ,w_d ,y_d ,params ,stream ); 155 }else if (ggml_is_contiguous_channels (input )) { 156conv2d_dw_sycl < sycl::half ,dw_cwhn_layout > (x_d ,w_d ,y_d ,params ,stream ); 157 }else { 158GGML_ABORT ("Unsupported memory layout for conv2d_dw" ); 159 } 160 }else { 161const float * w_d = (const float * )kernel -> data ; 162if (ggml_is_contiguous (input )) { 163conv2d_dw_sycl < float ,dw_whcn_layout > (x_d ,w_d ,y_d ,params ,stream ); 164 }else if (ggml_is_contiguous_channels (input )) { 165conv2d_dw_sycl < float ,dw_cwhn_layout > (x_d ,w_d ,y_d ,params ,stream ); 166 }else { 167GGML_ABORT ("Unsupported memory layout for conv2d_dw" ); 168 } 169 } 170}