char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
f9f09f02c
char/aliceai-t5-moe
1// 2// MIT license 3// Copyright (C) 2025 Intel Corporation 4// SPDX-License-Identifier: MIT 5// 6 7// 8// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 9// See https://llvm.org/LICENSE.txt for license information. 10// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 11// 12 13 14#include <sycl/sycl.hpp> 15#include "dpct/helper.hpp" 16#include "common.hpp" 17#include "fattn-common.hpp" 18#include "fattn-tile.hpp" 19#include "fattn-vec.hpp" 20#include "fattn.hpp" 21#include "fattn-onednn.hpp" 22 23 24#define FATTN_VEC_CASE (D ,type_K ,type_V ) \ 25 { \ 26 const bool type_K_okay = K->type == (type_K) || (K->type == GGML_TYPE_F32 && (type_K) == GGML_TYPE_F16); \ 27 const bool type_V_okay = V->type == (type_V) || (V->type == GGML_TYPE_F32 && (type_V) == GGML_TYPE_F16); \ 28 if (Q->ne[0] == (D) && type_K_okay && type_V_okay) { \ 29 ggml_sycl_flash_attn_ext_vec_case<D, type_K, type_V>(ctx, dst); \ 30 return; \ 31 } \ 32 } \ 33 34#define FATTN_VEC_CASES_ALL_D (type_K ,type_V ) \ 35 FATTN_VEC_CASE( 64, type_K, type_V) \ 36 FATTN_VEC_CASE(128, type_K, type_V) \ 37 FATTN_VEC_CASE(256, type_K, type_V) \ 38 FATTN_VEC_CASE(512, type_K, type_V) \ 39 40static void ggml_sycl_flash_attn_ext_vec (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 41ggml_tensor * Q = dst -> src [0 ]; 42ggml_tensor * K = dst -> src [1 ]; 43ggml_tensor * V = dst -> src [2 ]; 44 45#ifdef GGML_SYCL_FA_ALL_QUANTS 46FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_F16 ) 47FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_F16 ) 48FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_F16 ) 49FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_F16 ) 50FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_F16 ) 51FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_F16 ) 52 53FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_Q4_0 ) 54FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q4_0 ) 55FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_Q4_0 ) 56FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_Q4_0 ) 57FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_Q4_0 ) 58FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q4_0 ) 59 60FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_Q4_1 ) 61FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q4_1 ) 62FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_Q4_1 ) 63FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_Q4_1 ) 64FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_Q4_1 ) 65FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q4_1 ) 66 67FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_Q5_0 ) 68FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q5_0 ) 69FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_Q5_0 ) 70FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_Q5_0 ) 71FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_Q5_0 ) 72FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q5_0 ) 73 74FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_Q5_1 ) 75FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q5_1 ) 76FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_Q5_1 ) 77FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_Q5_1 ) 78FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_Q5_1 ) 79FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q5_1 ) 80 81FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_Q8_0 ) 82FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q8_0 ) 83FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_1 ,GGML_TYPE_Q8_0 ) 84FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_0 ,GGML_TYPE_Q8_0 ) 85FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q5_1 ,GGML_TYPE_Q8_0 ) 86FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q8_0 ) 87#else 88FATTN_VEC_CASES_ALL_D (GGML_TYPE_F16 ,GGML_TYPE_F16 ) 89FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q4_0 ,GGML_TYPE_Q4_0 ) 90FATTN_VEC_CASES_ALL_D (GGML_TYPE_Q8_0 ,GGML_TYPE_Q8_0 ) 91#endif // GGML_SYCL_FA_ALL_QUANTS 92 93GGML_ABORT ("Not match KV type in vec" ); 94} 95 96// Best FlashAttention kernel for a specific GPU: 97enum best_fattn_kernel { 98BEST_FATTN_KERNEL_NONE = 0 , 99BEST_FATTN_KERNEL_VEC = 100 , 100BEST_FATTN_KERNEL_ONEDNN = 150 ,// oneDNN SDPA: native F16 (PR #25222) 101BEST_FATTN_KERNEL_TILE = 200 , 102BEST_FATTN_KERNEL_MKL = 300 , 103}; 104 105 106static best_fattn_kernel ggml_sycl_get_best_fattn_kernel (const int device ,const ggml_tensor * dst ) { 107#ifndef SYCL_FLASH_ATTN 108GGML_UNUSED (dst ); 109return BEST_FATTN_KERNEL_NONE ; 110#endif // SYCL_FLASH_ATTN 111 112if (!g_ggml_sycl_enable_flash_attention )return BEST_FATTN_KERNEL_NONE ; 113 114const ggml_tensor * KQV = dst ; 115const ggml_tensor * Q = dst -> src [0 ]; 116const ggml_tensor * K = dst -> src [1 ]; 117const ggml_tensor * V = dst -> src [2 ]; 118const ggml_tensor * mask = dst -> src [3 ]; 119const ggml_tensor * sinks = dst -> src [4 ]; 120 121const int gqa_ratio = Q -> ne [2 ] /K -> ne [2 ]; 122GGML_ASSERT (Q -> ne [2 ] %K -> ne [2 ]== 0 ); 123 124float max_bias = 0.0f ; 125memcpy (& max_bias , (const float * )KQV -> op_params + 1 ,sizeof (float )); 126 127float logit_softcap = 0.0f ; 128memcpy (& logit_softcap , (const float * )KQV -> op_params + 2 ,sizeof (float )); 129 130bool gqa_opt_applies = gqa_ratio >=2 && mask && max_bias == 0.0f && K -> ne [1 ] %FATTN_KQ_STRIDE == 0 ; 131 132// XMX-accelerated path: oneDNN SDPA (native F16 and dequant+non-F16). 133// ONEDNN requires min 32 query tokens — short-circuit decode to avoid 134// calling _supported() on every decode FA call. 135if (Q -> ne [1 ] >=32 136&& ggml_sycl_flash_attn_ext_onednn_supported (dst )) { 137return BEST_FATTN_KERNEL_ONEDNN ; 138 } 139 140// MKL path: XMX-accelerated GEMM for prompt processing (all KV cache types). 141// The MKL kernel converts non-F16 K/V to F16 via to_fp16_sycl before GEMM, 142// so quantized, F16, BF16, and F32 caches all benefit from XMX acceleration. 143// Activates automatically when flash-attn is enabled (--flash-attn on or -fa) 144// and n_kv >= 1024. Falls through to TILE/VEC for ALiBi, logit softcap, 145// and mismatched batch dimensions (unsupported by the MKL kernel). 146// Set GGML_SYCL_ENABLE_MKL_FA=0 to force TILE/VEC path for A/B testing. 147// Example: GGML_SYCL_ENABLE_MKL_FA=0 llama-cli -m model.gguf -fa -ngl 99 ... 148// Note: MKL GEMM calls are incompatible with SYCL graph capture replay. 149// MKL is validated for the mainstream GQA envelope: grouped-query 150// (gqa_ratio >= 2), head_dim a multiple of 64 in [64,512] with matching 151// K/V head size, mask, no sinks/ALiBi/softcap. Gemma's global layers use 152// head_dim 512, so the cap must include it. Head sizes not a multiple of 153// 64 (72/80/96), MHA (gqa_ratio == 1), and MLA (DKQ != DV, e.g. 576/512) 154// fall through to TILE/VEC; see follow-up work. 155if (g_ggml_sycl_enable_mkl_fa == 1 && mask && !sinks && gqa_ratio >=2 && 156Q -> ne [0 ] >=64 && Q -> ne [0 ] <=512 && Q -> ne [0 ] %64 == 0 && 157Q -> ne [0 ]== V -> ne [0 ]&& 158Q -> ne [1 ] >=32 && K -> ne [1 ] >=1024 && 159max_bias == 0.0f && logit_softcap == 0.0f && 160 (Q -> ne [3 ]== K -> ne [3 ]|| K -> ne [3 ]== 1 )) { 161// F16 K/V strides must be a multiple of ne[0]*2 (the natural row size 162// in bytes). This passes both dense (nb1 == ne0*2) and interleaved 163// (nb1 == H * ne0*2). Only pathological test strides like nb1=32 or 164// nb1=75 for ne0=40 fall through to TILE. 165bool kv_strides_ok = true; 166for (const ggml_tensor * t : {K ,V }) { 167if (t -> type == GGML_TYPE_F16 && t -> nb [1 ] % (t -> ne [0 ]* 2 )!= 0 ) { 168kv_strides_ok = false; 169break ; 170 } 171 } 172if (kv_strides_ok ) { 173return BEST_FATTN_KERNEL_MKL ; 174 } 175 } 176for (const ggml_tensor * t : {Q ,K ,V ,mask }) { 177if (t == nullptr || ggml_is_quantized (t -> type )) { 178continue ; 179 } 180for (size_t i = 1 ;i < GGML_MAX_DIMS ;++ i ) { 181if (t -> nb [i ] %16 != 0 ) { 182gqa_opt_applies = false; 183break ; 184 } 185 } 186 } 187 188switch (K -> ne [0 ]) { 189case 40 : 190case 64 : 191case 72 : 192case 80 : 193case 96 : 194case 128 : 195case 112 : 196case 256 : 197case 512 : 198if (V -> ne [0 ]!= K -> ne [0 ]) { 199return BEST_FATTN_KERNEL_NONE ; 200 } 201break ; 202case 576 : 203if (V -> ne [0 ]!= 512 ) { 204return BEST_FATTN_KERNEL_NONE ; 205 } 206if (!gqa_opt_applies ) { 207return BEST_FATTN_KERNEL_NONE ; 208 } 209break ; 210default : 211return BEST_FATTN_KERNEL_NONE ; 212 } 213 214#ifndef GGML_SYCL_FA_ALL_QUANTS 215if (K -> type != V -> type ) { 216return BEST_FATTN_KERNEL_NONE ; 217 } 218#endif // GGML_SYCL_FA_ALL_QUANTS 219 220switch (K -> type ) { 221case GGML_TYPE_F32 : 222case GGML_TYPE_F16 : 223case GGML_TYPE_BF16 : 224break ; 225case GGML_TYPE_Q4_1 : 226case GGML_TYPE_Q5_0 : 227case GGML_TYPE_Q5_1 : 228#ifndef GGML_SYCL_FA_ALL_QUANTS 229return BEST_FATTN_KERNEL_NONE ; 230#endif // GGML_SYCL_FA_ALL_QUANTS 231case GGML_TYPE_Q4_0 : 232case GGML_TYPE_Q8_0 : 233break ; 234default : 235return BEST_FATTN_KERNEL_NONE ; 236 } 237 238if (mask && mask -> ne [2 ]!= 1 ) { 239return BEST_FATTN_KERNEL_NONE ; 240 } 241 242// For small batch sizes the vector kernel may be preferable over the kernels optimized for large batch sizes. 243// BF16 is excluded: the VEC kernel has no BF16 template (it needs GGML_SYCL_FA_ALL_QUANTS for non-F16/Q4_0/Q8_0). 244const bool has_bf16 = (K -> type == GGML_TYPE_BF16 || V -> type == GGML_TYPE_BF16 ); 245const bool can_use_vector_kernel = Q -> ne [0 ] <=512 && Q -> ne [0 ] %64 == 0 && K -> ne [1 ] %FATTN_KQ_STRIDE == 0 246&& !has_bf16 ; 247 248// Fused-XMX path: oneDNN Graph SDPA (flash attention). Strictly 249// additive -- taken only when statically supported, otherwise falls through to VEC/TILE below. 250if (ggml_sycl_flash_attn_ext_onednn_supported (dst )) { 251return BEST_FATTN_KERNEL_ONEDNN ; 252 } 253 254// If there are no tensor cores available, use the generic tile kernel: 255if (can_use_vector_kernel ) { 256if (!ggml_is_quantized (K -> type )&& !ggml_is_quantized (V -> type )) { 257if (Q -> ne [1 ]== 1 ) { 258if (!gqa_opt_applies ) { 259return BEST_FATTN_KERNEL_VEC ; 260 } 261 } 262 }else { 263if (Q -> ne [1 ] <=2 ) { 264// TILE is faster for quantized KV decode on Xe2 (BMG); keep VEC on untested archs 265const gpu_arch arch = ggml_sycl_info ().devices [device ].hw_info .arch ; 266if (arch == gpu_arch::intel_gpu_bmg_g21 || arch == gpu_arch::intel_gpu_bmg_g31 ) { 267return BEST_FATTN_KERNEL_TILE ; 268 } 269return BEST_FATTN_KERNEL_VEC ; 270 } 271 } 272 } 273return BEST_FATTN_KERNEL_TILE ; 274} 275 276void ggml_sycl_flash_attn_ext (ggml_backend_sycl_context & ctx ,ggml_tensor * dst ) { 277ggml_sycl_set_device (ctx .device ); 278 279// n_kv watchdog: log when n_kv differs from the last FA call with 280// the same D — helps detect cache-truncation issues. 281static int nkv_debug = ggml_sycl_get_env ("GGML_SYCL_MKL_FA_DEBUG" ,0 ); 282if (nkv_debug == 1 ) { 283const ggml_tensor * K_dbg = dst -> src [1 ]; 284const ggml_tensor * V_dbg = dst -> src [2 ]; 285static int64_t last_nkv_d256 = 0 ,last_nkv_d512 = 0 ; 286static int fa_call_seq = 0 ; 287fa_call_seq ++ ; 288int64_t cur_nkv = K_dbg -> ne [1 ]; 289int Dk = (int )K_dbg -> ne [0 ]; 290const char * kname = "TILE" ; 291best_fattn_kernel k = ggml_sycl_get_best_fattn_kernel (ctx .device ,dst ); 292if (k == BEST_FATTN_KERNEL_MKL )kname = "MKL" ; 293if (k == BEST_FATTN_KERNEL_ONEDNN )kname = "ONEDNN" ; 294if (k == BEST_FATTN_KERNEL_VEC )kname = "VEC" ; 295int64_t delta = 0 ; 296if (Dk == 256 ) { 297delta = cur_nkv - last_nkv_d256 ; 298last_nkv_d256 = cur_nkv ; 299 }else if (Dk == 512 ) { 300delta = cur_nkv - last_nkv_d512 ; 301last_nkv_d512 = cur_nkv ; 302 } 303GGML_LOG_INFO ("[FA-DISP] #%d %s D=%d n_kv=%lld delta=%lld " 304"V_ne1=%lld\n" , 305fa_call_seq ,kname ,Dk , 306 (long long )cur_nkv , (long long )delta , 307 (long long )V_dbg -> ne [1 ]); 308 } 309 310const best_fattn_kernel fk = ggml_sycl_get_best_fattn_kernel (ggml_sycl_get_device (),dst ); 311switch (fk ) { 312case BEST_FATTN_KERNEL_NONE : 313GGML_ABORT ("Not support Flash-Attention" ); 314case BEST_FATTN_KERNEL_ONEDNN : 315// guarded: ggml_sycl_flash_attn_ext_onednn() is only defined under GGML_SYCL_DNNL; 316// the reference must be compiled out here or the GGML_SYCL_DNNL=0 build fails to link. 317#if GGML_SYCL_DNNL 318ggml_sycl_flash_attn_ext_onednn (ctx ,dst ); 319#endif 320break ; 321case BEST_FATTN_KERNEL_TILE : 322ggml_sycl_flash_attn_ext_tile (ctx ,dst ); 323break ; 324case BEST_FATTN_KERNEL_VEC : 325ggml_sycl_flash_attn_ext_vec (ctx ,dst ); 326break ; 327case BEST_FATTN_KERNEL_MKL : 328ggml_sycl_flash_attn_ext_mkl (ctx ,dst ); 329break ; 330 } 331 332// --- Output fingerprint (GGML_SYCL_MKL_FA_DIAG=1) --- 333// Copy first 64 float output values to host for fingerprinting. 334// Compare MKL vs TILE (GGML_SYCL_ENABLE_MKL_FA=0) to detect divergence. 335// Only fingerprints the first 6 FA calls with n_kv >= 1024. 336static int fa_diag = ggml_sycl_get_env ("GGML_SYCL_MKL_FA_DIAG" ,0 ); 337static int fa_diag_count = 0 ; 338if (fa_diag == 1 && fa_diag_count < 6 ) { 339const ggml_tensor * K_diag = dst -> src [1 ]; 340const ggml_tensor * V_diag = dst -> src [2 ]; 341const ggml_tensor * Q_diag = dst -> src [0 ]; 342if (K_diag -> ne [1 ] >=1024 ) { 343fa_diag_count ++ ; 344float diag_buf [64 ]; 345 dpct::queue_ptr q = ctx .stream (); 346q -> memcpy (diag_buf ,dst -> data ,64 * sizeof (float )); 347q -> wait (); 348const char * kname = "???" ; 349best_fattn_kernel kb = ggml_sycl_get_best_fattn_kernel (ctx .device ,dst ); 350if (kb == BEST_FATTN_KERNEL_ONEDNN )kname = "ONEDNN" ; 351if (kb == BEST_FATTN_KERNEL_MKL )kname = "MKL" ; 352if (kb == BEST_FATTN_KERNEL_TILE )kname = "TILE" ; 353if (kb == BEST_FATTN_KERNEL_VEC )kname = "VEC" ; 354GGML_LOG_INFO ("[FA-DIAG] #%d %s D=%d n_kv=%lld n_q=%lld " 355"n_qh=%lld n_kvh=%lld K=%s V=%s " 356"nb1=%zu nb2=%zu first 64 floats:\n" , 357fa_diag_count ,kname , 358 (int )K_diag -> ne [0 ], (long long )K_diag -> ne [1 ], 359 (long long )Q_diag -> ne [1 ], 360 (long long )Q_diag -> ne [2 ], (long long )K_diag -> ne [2 ], 361ggml_type_name (K_diag -> type ), 362ggml_type_name (V_diag -> type ), 363K_diag -> nb [1 ],K_diag -> nb [2 ]); 364for (int i = 0 ;i < 64 ;i += 8 ) { 365GGML_LOG_INFO (" [%2d] %08x %08x %08x %08x %08x %08x %08x %08x\n" , 366i , 367* (unsigned * )& diag_buf [i + 0 ],* (unsigned * )& diag_buf [i + 1 ], 368* (unsigned * )& diag_buf [i + 2 ],* (unsigned * )& diag_buf [i + 3 ], 369* (unsigned * )& diag_buf [i + 4 ],* (unsigned * )& diag_buf [i + 5 ], 370* (unsigned * )& diag_buf [i + 6 ],* (unsigned * )& diag_buf [i + 7 ]); 371 } 372 } 373 } 374 375} 376 377bool ggml_sycl_flash_attn_ext_supported (int device ,const ggml_tensor * dst ) { 378return ggml_sycl_get_best_fattn_kernel (device ,dst )!= BEST_FATTN_KERNEL_NONE ; 379} 380 381static uintptr_t ggml_sycl_fattn_reserve_halves (ggml_sycl_fattn_extra & extra ,size_t n_halves ) { 382if (n_halves == 0 ) { 383return 0 ; 384 } 385extra .end = GGML_PAD (extra .end ,SYCL_BUFFER_ALIGNMENT ); 386const uintptr_t block = extra .end ; 387extra .end += n_halves * sizeof (sycl::half ); 388return block ; 389} 390 391ggml_sycl_fattn_extra ggml_sycl_fattn_get_extra (const ggml_tensor * dst ) { 392ggml_sycl_fattn_extra extra ; 393 394extra .end = (uintptr_t )dst -> data + ggml_nbytes (dst ); 395 396if (dst -> op != GGML_OP_FLASH_ATTN_EXT ) { 397return extra ; 398 } 399 400const ggml_tensor * Q = dst -> src [0 ]; 401const ggml_tensor * K = dst -> src [1 ]; 402const ggml_tensor * V = dst -> src [2 ]; 403if (!Q || !K || !V ) { 404return extra ; 405 } 406 407const int64_t d = K -> ne [0 ]; 408const int64_t H = Q -> ne [2 ]; 409const int64_t q = Q -> ne [1 ]; 410 411// calculate the worst-case memory consumption across all kernels 412const bool onednn_supported = ggml_sycl_flash_attn_ext_onednn_supported (dst ,/* use_shape_limit */ false); 413 414const bool tile_needs_K = K -> type != GGML_TYPE_F16 ; 415const bool tile_needs_V = V -> type != GGML_TYPE_F16 ; 416 417const bool V_is_K_view = V -> view_src && 418 (V -> view_src == K || (V -> view_src == K -> view_src && V -> view_offs == K -> view_offs )); 419 420size_t need_K = 0 ,need_V = 0 ,need_Q = 0 ,need_out = 0 ,need_scale = 0 ; 421if (onednn_supported ) { 422need_Q = (size_t )H * q * d ; 423need_out = (size_t )H * q * d ; 424need_scale = 1 ; 425// an f16 cache is bound in place, so it needs no staging copy 426if (!ggml_sycl_fattn_onednn_binds_kv (K ,V )) { 427need_K = (size_t )ggml_nelements (K ); 428need_V = (size_t )ggml_nelements (V ); 429 } 430 } 431if (tile_needs_K ) { 432need_K = std::max (need_K , (size_t )ggml_nelements (K )); 433 } 434if (tile_needs_V ) { 435need_V = std::max (need_V , (size_t )ggml_nelements (V )); 436 } 437 438extra .Q_buffer_ptr = ggml_sycl_fattn_reserve_halves (extra ,need_Q ); 439extra .K_buffer_ptr = ggml_sycl_fattn_reserve_halves (extra ,need_K ); 440extra .V_buffer_ptr = (V_is_K_view && !onednn_supported && need_V ) 441 ?extra .K_buffer_ptr 442 :ggml_sycl_fattn_reserve_halves (extra ,need_V ); 443extra .scale_buffer_ptr = ggml_sycl_fattn_reserve_halves (extra ,need_scale ); 444extra .out_buffer_ptr = ggml_sycl_fattn_reserve_halves (extra ,need_out ); 445 446return extra ; 447} 448 449size_t ggml_sycl_flash_attn_ext_get_alloc_size (const ggml_tensor * dst ) { 450const ggml_sycl_fattn_extra extra = ggml_sycl_fattn_get_extra (dst ); 451return (size_t ) (extra .end - (uintptr_t )dst -> data ); 452}