metal : per-device tuned (Q, NE) for flash-attn vec (#26570)
* metal : per-device tuned (Q, NE) for flash-attn vec (#25750) * rebase Q-generic FA vec body from 01dc93607 (#23114) * add 53 f16 (Q,NE) flash-attn vec instantiations (vec 80 -> 133) * add FA vec (Q,NE) tuning table + dispatch wiring + SMEM cap fallback * add FA vec (Q,NE) perf sweep * fill tuning result * fold family table into a per-family representative SKU * refactor tuning result format * extend FA vec tuning to quantized KV caches * sync fa vec tuner bucketing with runtime, use pointwise tuning regret * update tuned table * format and cleanup * prefix fa_vec tuning procs with ggml_backend_metal_tuning_, drop unused fa_vec_override_active * add device id -> token lookup for the offline tuning tool * add ggml-metal-tuning skeleton * add op-agnostic perf cell + median timing for the tuner * add FA-vec graph build + tensor init to the tuner * tools : add FA-vec (Q,NE) sweep, compression and table emit * cool down and re-measure the dirty window on thermal drift * test-backend-ops : replace the FA vec tune mode with a bounded (Q,NE) slice * tools : document the Metal tuner, point the table comment at it * abort on unknown KV type, single-source fa_vec_legal_ne * cleanup * honor -o in the FA vec (Q,NE) slice * retune FA-vec (Q, NE) under a pointwise no-harm gate * cont : add fa-vec tunings for M1 Pro, M2 Ultra, M5 Max --------- Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
This commit is contained in:
co-authored by
Georgi Gerganov
parent
b615f5b4bd
commit
f280b26983
@@ -11,6 +11,7 @@ ggml_add_backend_library(ggml-metal
|
|||||||
ggml-metal-common.cpp
|
ggml-metal-common.cpp
|
||||||
ggml-metal-context.m
|
ggml-metal-context.m
|
||||||
ggml-metal-ops.cpp
|
ggml-metal-ops.cpp
|
||||||
|
ggml-metal-tuning.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(ggml-metal PRIVATE
|
target_link_libraries(ggml-metal PRIVATE
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "ggml-metal-device.h"
|
#include "ggml-metal-device.h"
|
||||||
|
|
||||||
#include "ggml-metal-impl.h"
|
#include "ggml-metal-impl.h"
|
||||||
|
#include "ggml-metal-tuning.h"
|
||||||
|
|
||||||
#include "ggml-impl.h"
|
#include "ggml-impl.h"
|
||||||
|
|
||||||
@@ -1544,6 +1545,8 @@ ggml_metal_pipeline_with_params ggml_metal_library_get_pipeline_flash_attn_ext_v
|
|||||||
bool has_bias,
|
bool has_bias,
|
||||||
bool has_scap,
|
bool has_scap,
|
||||||
bool has_kvpad,
|
bool has_kvpad,
|
||||||
|
int32_t nqpsg,
|
||||||
|
int32_t ne,
|
||||||
int32_t nsg,
|
int32_t nsg,
|
||||||
int32_t nwg,
|
int32_t nwg,
|
||||||
bool use_kv_f16,
|
bool use_kv_f16,
|
||||||
@@ -1559,11 +1562,17 @@ ggml_metal_pipeline_with_params ggml_metal_library_get_pipeline_flash_attn_ext_v
|
|||||||
|
|
||||||
const char * type = use_kv_f16 ? "f16" : ggml_type_name(op->src[1]->type);
|
const char * type = use_kv_f16 ? "f16" : ggml_type_name(op->src[1]->type);
|
||||||
|
|
||||||
snprintf(base, 256, "kernel_%s_%s_dk%d_dv%d",
|
char qne_suffix[16] = {0};
|
||||||
|
if (!(nqpsg == 1 && ne == ggml_metal_tuning::fa_vec_baseline_ne(dk, dv))) {
|
||||||
|
snprintf(qne_suffix, sizeof(qne_suffix), "_q%d_ne%d", nqpsg, ne);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(base, 256, "kernel_%s_%s_dk%d_dv%d%s",
|
||||||
"flash_attn_ext_vec",
|
"flash_attn_ext_vec",
|
||||||
type,
|
type,
|
||||||
dk,
|
dk,
|
||||||
dv);
|
dv,
|
||||||
|
qne_suffix);
|
||||||
|
|
||||||
snprintf(name, 256, "%s_mask=%d_sink=%d_bias=%d_scap=%d_kvpad=%d_ns10=%d_ns20=%d_nsg=%d_nwg=%d",
|
snprintf(name, 256, "%s_mask=%d_sink=%d_bias=%d_scap=%d_kvpad=%d_ns10=%d_ns20=%d_nsg=%d_nwg=%d",
|
||||||
base,
|
base,
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ struct ggml_metal_pipeline_with_params ggml_metal_library_get_pipeline_flash_att
|
|||||||
bool has_bias,
|
bool has_bias,
|
||||||
bool has_scap,
|
bool has_scap,
|
||||||
bool has_kvpad,
|
bool has_kvpad,
|
||||||
|
int32_t nqpsg,
|
||||||
|
int32_t ne,
|
||||||
int32_t nsg,
|
int32_t nsg,
|
||||||
int32_t nwg,
|
int32_t nwg,
|
||||||
bool use_kv_f16,
|
bool use_kv_f16,
|
||||||
@@ -257,6 +259,8 @@ enum ggml_metal_device_id {
|
|||||||
GGML_METAL_DEVICE_M5_ULTRA,
|
GGML_METAL_DEVICE_M5_ULTRA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char * ggml_metal_device_id_token(enum ggml_metal_device_id id);
|
||||||
|
|
||||||
struct ggml_metal_device_props {
|
struct ggml_metal_device_props {
|
||||||
int device;
|
int device;
|
||||||
int device_phys;
|
int device_phys;
|
||||||
@@ -279,6 +283,7 @@ struct ggml_metal_device_props {
|
|||||||
bool supports_gpu_family_apple7;
|
bool supports_gpu_family_apple7;
|
||||||
|
|
||||||
enum ggml_metal_device_id device_id;
|
enum ggml_metal_device_id device_id;
|
||||||
|
int gpu_family;
|
||||||
|
|
||||||
int op_offload_min_batch_size;
|
int op_offload_min_batch_size;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -962,6 +962,34 @@ void ggml_metal_rsets_free(ggml_metal_rsets_t rsets) {
|
|||||||
free(rsets);
|
free(rsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char * name;
|
||||||
|
const char * token;
|
||||||
|
enum ggml_metal_device_id id;
|
||||||
|
} k_metal_devices[] = {
|
||||||
|
#define DEV(name, id) { name, #id, id }
|
||||||
|
DEV("M1", GGML_METAL_DEVICE_M1),
|
||||||
|
DEV("M1 Pro", GGML_METAL_DEVICE_M1_PRO),
|
||||||
|
DEV("M1 Max", GGML_METAL_DEVICE_M1_MAX),
|
||||||
|
DEV("M1 Ultra", GGML_METAL_DEVICE_M1_ULTRA),
|
||||||
|
DEV("M2", GGML_METAL_DEVICE_M2),
|
||||||
|
DEV("M2 Pro", GGML_METAL_DEVICE_M2_PRO),
|
||||||
|
DEV("M2 Max", GGML_METAL_DEVICE_M2_MAX),
|
||||||
|
DEV("M2 Ultra", GGML_METAL_DEVICE_M2_ULTRA),
|
||||||
|
DEV("M3", GGML_METAL_DEVICE_M3),
|
||||||
|
DEV("M3 Pro", GGML_METAL_DEVICE_M3_PRO),
|
||||||
|
DEV("M3 Max", GGML_METAL_DEVICE_M3_MAX),
|
||||||
|
DEV("M3 Ultra", GGML_METAL_DEVICE_M3_ULTRA),
|
||||||
|
DEV("M4", GGML_METAL_DEVICE_M4),
|
||||||
|
DEV("M4 Pro", GGML_METAL_DEVICE_M4_PRO),
|
||||||
|
DEV("M4 Max", GGML_METAL_DEVICE_M4_MAX),
|
||||||
|
DEV("M5", GGML_METAL_DEVICE_M5),
|
||||||
|
DEV("M5 Pro", GGML_METAL_DEVICE_M5_PRO),
|
||||||
|
DEV("M5 Max", GGML_METAL_DEVICE_M5_MAX),
|
||||||
|
DEV("M5 Ultra", GGML_METAL_DEVICE_M5_ULTRA),
|
||||||
|
#undef DEV
|
||||||
|
};
|
||||||
|
|
||||||
static enum ggml_metal_device_id ggml_metal_device_id_parse(const char * name) {
|
static enum ggml_metal_device_id ggml_metal_device_id_parse(const char * name) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return GGML_METAL_DEVICE_GENERIC;
|
return GGML_METAL_DEVICE_GENERIC;
|
||||||
@@ -973,39 +1001,23 @@ static enum ggml_metal_device_id ggml_metal_device_id_parse(const char * name) {
|
|||||||
}
|
}
|
||||||
const char * suffix = name + sizeof(prefix) - 1;
|
const char * suffix = name + sizeof(prefix) - 1;
|
||||||
|
|
||||||
static const struct {
|
for (size_t i = 0; i < sizeof(k_metal_devices)/sizeof(k_metal_devices[0]); ++i) {
|
||||||
const char * name;
|
if (strcmp(suffix, k_metal_devices[i].name) == 0) {
|
||||||
enum ggml_metal_device_id id;
|
return k_metal_devices[i].id;
|
||||||
} table[] = {
|
|
||||||
{"M1", GGML_METAL_DEVICE_M1},
|
|
||||||
{"M1 Pro", GGML_METAL_DEVICE_M1_PRO},
|
|
||||||
{"M1 Max", GGML_METAL_DEVICE_M1_MAX},
|
|
||||||
{"M1 Ultra", GGML_METAL_DEVICE_M1_ULTRA},
|
|
||||||
{"M2", GGML_METAL_DEVICE_M2},
|
|
||||||
{"M2 Pro", GGML_METAL_DEVICE_M2_PRO},
|
|
||||||
{"M2 Max", GGML_METAL_DEVICE_M2_MAX},
|
|
||||||
{"M2 Ultra", GGML_METAL_DEVICE_M2_ULTRA},
|
|
||||||
{"M3", GGML_METAL_DEVICE_M3},
|
|
||||||
{"M3 Pro", GGML_METAL_DEVICE_M3_PRO},
|
|
||||||
{"M3 Max", GGML_METAL_DEVICE_M3_MAX},
|
|
||||||
{"M3 Ultra", GGML_METAL_DEVICE_M3_ULTRA},
|
|
||||||
{"M4", GGML_METAL_DEVICE_M4},
|
|
||||||
{"M4 Pro", GGML_METAL_DEVICE_M4_PRO},
|
|
||||||
{"M4 Max", GGML_METAL_DEVICE_M4_MAX},
|
|
||||||
{"M5", GGML_METAL_DEVICE_M5},
|
|
||||||
{"M5 Pro", GGML_METAL_DEVICE_M5_PRO},
|
|
||||||
{"M5 Max", GGML_METAL_DEVICE_M5_MAX},
|
|
||||||
{"M5 Ultra", GGML_METAL_DEVICE_M5_ULTRA},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
|
|
||||||
if (strcmp(suffix, table[i].name) == 0) {
|
|
||||||
return table[i].id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GGML_METAL_DEVICE_GENERIC;
|
return GGML_METAL_DEVICE_GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * ggml_metal_device_id_token(enum ggml_metal_device_id id) {
|
||||||
|
for (size_t i = 0; i < sizeof(k_metal_devices)/sizeof(k_metal_devices[0]); ++i) {
|
||||||
|
if (k_metal_devices[i].id == id) {
|
||||||
|
return k_metal_devices[i].token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "GGML_METAL_DEVICE_GENERIC";
|
||||||
|
}
|
||||||
|
|
||||||
ggml_metal_device_t ggml_metal_device_init(int device, int n_devices) {
|
ggml_metal_device_t ggml_metal_device_init(int device, int n_devices) {
|
||||||
ggml_metal_device_t dev = calloc(1, sizeof(struct ggml_metal_device));
|
ggml_metal_device_t dev = calloc(1, sizeof(struct ggml_metal_device));
|
||||||
|
|
||||||
@@ -1220,7 +1232,8 @@ ggml_metal_device_t ggml_metal_device_init(int device, int n_devices) {
|
|||||||
{
|
{
|
||||||
for (int i = MTLGPUFamilyApple1 + 20; i >= MTLGPUFamilyApple1; --i) {
|
for (int i = MTLGPUFamilyApple1 + 20; i >= MTLGPUFamilyApple1; --i) {
|
||||||
if ([dev->mtl_device supportsFamily:i]) {
|
if ([dev->mtl_device supportsFamily:i]) {
|
||||||
GGML_LOG_INFO("%s: GPU family: MTLGPUFamilyApple%d (%d)\n", __func__, i - (int) MTLGPUFamilyApple1 + 1, i);
|
dev->props.gpu_family = i - (int) MTLGPUFamilyApple1 + 1;
|
||||||
|
GGML_LOG_INFO("%s: GPU family: MTLGPUFamilyApple%d (%d)\n", __func__, dev->props.gpu_family, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "ggml-metal-impl.h"
|
#include "ggml-metal-impl.h"
|
||||||
#include "ggml-metal-common.h"
|
#include "ggml-metal-common.h"
|
||||||
#include "ggml-metal-device.h"
|
#include "ggml-metal-device.h"
|
||||||
|
#include "ggml-metal-tuning.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -3346,12 +3347,18 @@ int ggml_metal_op_flash_attn_ext(ggml_metal_op_t ctx, int idx) {
|
|||||||
#undef FATTN_SMEM
|
#undef FATTN_SMEM
|
||||||
} else {
|
} else {
|
||||||
// half4x4 kernel
|
// half4x4 kernel
|
||||||
const int nqptg = OP_FLASH_ATTN_EXT_VEC_NQPSG; // queries per threadgroup
|
auto cfg = ggml_metal_tuning::fa_vec_pick(
|
||||||
|
props_dev->device_id,
|
||||||
|
props_dev->gpu_family,
|
||||||
|
(int) op->src[1]->type,
|
||||||
|
(int) ne00, (int) ne20, // dk, dv (ne00 == dk for FA)
|
||||||
|
ne11, ne01);
|
||||||
|
int nqptg = cfg.Q; // queries per threadgroup
|
||||||
const int ncpsg = OP_FLASH_ATTN_EXT_VEC_NCPSG; // cache values per simdgroup !! sync with kernel template arguments !!
|
const int ncpsg = OP_FLASH_ATTN_EXT_VEC_NCPSG; // cache values per simdgroup !! sync with kernel template arguments !!
|
||||||
const int nhptg = 1; // heads per threadgroup
|
const int nhptg = 1; // heads per threadgroup
|
||||||
|
|
||||||
GGML_ASSERT(nqptg <= 32);
|
GGML_ASSERT(nqptg <= 32);
|
||||||
GGML_ASSERT(nqptg % 1 == 0);
|
GGML_ASSERT(nqptg == 1 || nqptg == 2 || nqptg == 4); // only instantiated Q values
|
||||||
GGML_ASSERT(ncpsg % 32 == 0);
|
GGML_ASSERT(ncpsg % 32 == 0);
|
||||||
|
|
||||||
bool need_sync = false;
|
bool need_sync = false;
|
||||||
@@ -3410,7 +3417,7 @@ int ggml_metal_op_flash_attn_ext(ggml_metal_op_t ctx, int idx) {
|
|||||||
// ne20*(nsg)
|
// ne20*(nsg)
|
||||||
// each simdgroup has a full f32 head vector in shared mem to accumulate results
|
// each simdgroup has a full f32 head vector in shared mem to accumulate results
|
||||||
//
|
//
|
||||||
#define FATTN_SMEM(nsg) (GGML_PAD(((GGML_PAD(ne00, 128) + 4*ncpsg + 2*GGML_PAD(ne20, 128))*(nsg))*(sizeof(float)/2), 16))
|
#define FATTN_SMEM(nsg) (GGML_PAD(((GGML_PAD(ne00, 128) + 4*ncpsg + 2*GGML_PAD(ne20, 128))*(nsg)*nqptg)*(sizeof(float)/2), 16))
|
||||||
|
|
||||||
int64_t nsg = 1;
|
int64_t nsg = 1;
|
||||||
|
|
||||||
@@ -3430,6 +3437,12 @@ int ggml_metal_op_flash_attn_ext(ggml_metal_op_t ctx, int idx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fall back to baseline (Q=1) if the tuned config exceeds threadgroup memory
|
||||||
|
if ((size_t) FATTN_SMEM(nsg) > props_dev->max_theadgroup_memory_size) {
|
||||||
|
cfg = ggml_metal_tuning::fa_vec_baseline_cfg((int) ne00, (int) ne20);
|
||||||
|
nqptg = cfg.Q; // = 1
|
||||||
|
}
|
||||||
|
|
||||||
const int32_t ns10 = nb11_attn/nb10_attn;
|
const int32_t ns10 = nb11_attn/nb10_attn;
|
||||||
const int32_t ns20 = nb21_attn/nb20_attn;
|
const int32_t ns20 = nb21_attn/nb20_attn;
|
||||||
|
|
||||||
@@ -3468,7 +3481,7 @@ int ggml_metal_op_flash_attn_ext(ggml_metal_op_t ctx, int idx) {
|
|||||||
/*.logit_softcap =*/ logit_softcap,
|
/*.logit_softcap =*/ logit_softcap,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto pipeline = ggml_metal_library_get_pipeline_flash_attn_ext_vec(lib, op, has_mask, has_sinks, has_bias, has_scap, has_kvpad, nsg, nwg, use_kv_f16, ns10, ns20);
|
auto pipeline = ggml_metal_library_get_pipeline_flash_attn_ext_vec(lib, op, has_mask, has_sinks, has_bias, has_scap, has_kvpad, nqptg, cfg.NE, nsg, nwg, use_kv_f16, ns10, ns20);
|
||||||
|
|
||||||
GGML_ASSERT(nsg*32 <= ggml_metal_pipeline_max_theads_per_threadgroup(pipeline));
|
GGML_ASSERT(nsg*32 <= ggml_metal_pipeline_max_theads_per_threadgroup(pipeline));
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ggml-metal-device.h" // enum ggml_metal_device_id
|
||||||
|
#include "ggml.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ggml_metal_tuning {
|
||||||
|
|
||||||
|
// FA vec selection buckets. ne01 (query rows) splits decode (==1) from batch (>=2), the
|
||||||
|
// batch side refined into {2,3,4,5}: Q>1 reuses one K/V load across rows, so it only pays
|
||||||
|
// off once ne01 aligns with Q. ne11 (KV length) is bucketed too, as the Q>1 crossover is
|
||||||
|
// head-size dependent (small dk crosses late, large dk wins even at short KV).
|
||||||
|
constexpr int FA_VEC_NE11_BUCKETS[] = { 1024, 4096, 16384 };
|
||||||
|
constexpr int FA_VEC_NE01_BUCKETS[] = { 2, 3, 4, 5 };
|
||||||
|
|
||||||
|
int fa_vec_ne11_bucket(int64_t ne11);
|
||||||
|
int fa_vec_ne01_bucket(int64_t ne01);
|
||||||
|
|
||||||
|
// NE baked into each (dk,dv) baseline instantiation in kernels/fa.metal.
|
||||||
|
// Hand-maintained mirror; keep in sync with those instantiations.
|
||||||
|
// The Metal test slice covers every legal config for dk=128 and dk=576.
|
||||||
|
int fa_vec_baseline_ne(int dk, int dv);
|
||||||
|
|
||||||
|
// Tuned table has two row kinds. Exact rows key a (ne11_b, ne01_b) bucket. Default rows
|
||||||
|
// collapse ne11 over one ne01 domain: ne11_b == FA_VEC_NE11_DEFAULT and ne01_b holds the
|
||||||
|
// domain. fa_vec_pick tries exact bucket -> domain default -> baseline; short KV
|
||||||
|
// (ne11 < FA_VEC_NE11_BUCKETS[0]) always uses baseline.
|
||||||
|
constexpr int8_t FA_VEC_NE11_DEFAULT = -1;
|
||||||
|
constexpr int8_t FA_VEC_DOMAIN_DECODE = 0; // ne01 == 1
|
||||||
|
constexpr int8_t FA_VEC_DOMAIN_BATCH = 1; // ne01 >= 2
|
||||||
|
|
||||||
|
struct fa_vec_key_t {
|
||||||
|
int8_t device_id;
|
||||||
|
int8_t dtype;
|
||||||
|
int16_t dk;
|
||||||
|
int16_t dv;
|
||||||
|
int8_t ne11_b;
|
||||||
|
int8_t ne01_b;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(fa_vec_key_t) == 8, "fa_vec_key_t must be tightly packed for memcmp");
|
||||||
|
|
||||||
|
struct fa_vec_cfg_t {
|
||||||
|
int8_t Q;
|
||||||
|
int8_t NE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fa_vec_entry_t {
|
||||||
|
fa_vec_key_t key;
|
||||||
|
fa_vec_cfg_t cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
// legal NE values for a (dk,dv): NL = 32/NE, require (dk/4)%NL==0 && (dv/4)%NL==0.
|
||||||
|
// single source shared by the offline tuner and test-backend-ops.
|
||||||
|
inline std::vector<int> fa_vec_legal_ne(int dk, int dv) {
|
||||||
|
std::vector<int> r;
|
||||||
|
for (int ne : { 1, 2, 4 }) {
|
||||||
|
const int nl = 32 / ne;
|
||||||
|
if ((dk / 4) % nl == 0 && (dv / 4) % nl == 0) {
|
||||||
|
r.push_back(ne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test/tune-only override; when set, fa_vec_pick returns it directly.
|
||||||
|
void fa_vec_set_override(fa_vec_cfg_t cfg);
|
||||||
|
void fa_vec_clear_override();
|
||||||
|
fa_vec_cfg_t fa_vec_baseline_cfg(int dk, int dv);
|
||||||
|
|
||||||
|
// device_id selects a per-SKU row; on a miss, gpu_family (0 if unknown) maps to a representative
|
||||||
|
// SKU and the table is retried. No match -> baseline.
|
||||||
|
fa_vec_cfg_t fa_vec_pick(enum ggml_metal_device_id device_id, int gpu_family, int dtype, int dk, int dv, int64_t ne11, int64_t ne01);
|
||||||
|
|
||||||
|
} // namespace ggml_metal_tuning
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "ggml-metal-device.h"
|
#include "ggml-metal-device.h"
|
||||||
#include "ggml-metal-context.h"
|
#include "ggml-metal-context.h"
|
||||||
#include "ggml-metal-ops.h"
|
#include "ggml-metal-ops.h"
|
||||||
|
#include "ggml-metal-tuning.h"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -870,10 +871,55 @@ static ggml_backend_feature * ggml_backend_metal_get_features(ggml_backend_reg_t
|
|||||||
GGML_UNUSED(reg);
|
GGML_UNUSED(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test/tune-only override for the FA vec (Q, NE) selection, reached via proc_address.
|
||||||
|
static void ggml_backend_metal_tuning_set_fa_vec_override(int Q, int NE) {
|
||||||
|
ggml_metal_tuning::fa_vec_set_override({ (int8_t) Q, (int8_t) NE });
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ggml_backend_metal_tuning_clear_fa_vec_override(void) {
|
||||||
|
ggml_metal_tuning::fa_vec_clear_override();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ggml_backend_metal_tuning_fa_vec_ne11_bucket(int64_t ne11) {
|
||||||
|
return ggml_metal_tuning::fa_vec_ne11_bucket(ne11);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ggml_backend_metal_tuning_fa_vec_ne01_bucket(int64_t ne01) {
|
||||||
|
return ggml_metal_tuning::fa_vec_ne01_bucket(ne01);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ggml_backend_metal_tuning_fa_vec_baseline_ne(int dk, int dv) {
|
||||||
|
return ggml_metal_tuning::fa_vec_baseline_ne(dk, dv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * ggml_backend_metal_tuning_device_token(ggml_backend_dev_t dev) {
|
||||||
|
ggml_metal_device_t ctx_dev = (ggml_metal_device_t)dev->context;
|
||||||
|
|
||||||
|
return ggml_metal_device_id_token(ggml_metal_device_get_props(ctx_dev)->device_id);
|
||||||
|
}
|
||||||
|
|
||||||
static void * ggml_backend_metal_get_proc_address(ggml_backend_reg_t reg, const char * name) {
|
static void * ggml_backend_metal_get_proc_address(ggml_backend_reg_t reg, const char * name) {
|
||||||
if (strcmp(name, "ggml_backend_get_features") == 0) {
|
if (strcmp(name, "ggml_backend_get_features") == 0) {
|
||||||
return (void *)ggml_backend_metal_get_features;
|
return (void *)ggml_backend_metal_get_features;
|
||||||
}
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_set_fa_vec_override") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_set_fa_vec_override;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_clear_fa_vec_override") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_clear_fa_vec_override;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_fa_vec_ne11_bucket") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_fa_vec_ne11_bucket;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_fa_vec_ne01_bucket") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_fa_vec_ne01_bucket;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_fa_vec_baseline_ne") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_fa_vec_baseline_ne;
|
||||||
|
}
|
||||||
|
if (strcmp(name, "ggml_backend_metal_tuning_device_token") == 0) {
|
||||||
|
return (void *)ggml_backend_metal_tuning_device_token;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -1130,7 +1130,7 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
constexpr short NW = N_SIMDWIDTH;
|
constexpr short NW = N_SIMDWIDTH;
|
||||||
constexpr short NL = NW/NE; // note: this can be adjusted to support different head sizes and simdgroup work loads
|
constexpr short NL = NW/NE; // note: this can be adjusted to support different head sizes and simdgroup work loads
|
||||||
constexpr short SH = 4*C; // shared memory per simdgroup
|
constexpr short SH = 4*Q*C; // shared memory per simdgroup
|
||||||
|
|
||||||
static_assert(DK4 % NL == 0, "DK4 must be divisible by NL");
|
static_assert(DK4 % NL == 0, "DK4 must be divisible by NL");
|
||||||
static_assert(DV4 % NL == 0, "DV4 must be divisible by NL");
|
static_assert(DV4 % NL == 0, "DV4 must be divisible by NL");
|
||||||
@@ -1139,16 +1139,16 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
//threadgroup q_t * sq = (threadgroup q_t *) (shmem_f16 + 0*PK); // holds the query data
|
//threadgroup q_t * sq = (threadgroup q_t *) (shmem_f16 + 0*PK); // holds the query data
|
||||||
threadgroup q4_t * sq4 = (threadgroup q4_t *) (shmem_f16 + 0*PK); // same as above but in q4_t
|
threadgroup q4_t * sq4 = (threadgroup q4_t *) (shmem_f16 + 0*PK); // same as above but in q4_t
|
||||||
threadgroup s_t * ss = (threadgroup s_t *) (shmem_f16 + sgitg*SH + NSG*PK); // scratch buffer for attention
|
threadgroup s_t * ss = (threadgroup s_t *) (shmem_f16 + sgitg*SH + Q*NSG*PK); // scratch buffer for attention
|
||||||
threadgroup s4_t * ss4 = (threadgroup s4_t *) (shmem_f16 + sgitg*SH + NSG*PK); // same as above but in s4_t
|
threadgroup s4_t * ss4 = (threadgroup s4_t *) (shmem_f16 + sgitg*SH + Q*NSG*PK); // same as above but in s4_t
|
||||||
threadgroup half * sm = (threadgroup half *) (shmem_f16 + sgitg*SH + 2*C + NSG*PK); // scratch buffer for mask
|
threadgroup half * sm = (threadgroup half *) (shmem_f16 + sgitg*SH + 2*Q*C + Q*NSG*PK); // scratch buffer for mask
|
||||||
threadgroup o4_t * so4 = (threadgroup o4_t *) (shmem_f16 + 2*sgitg*PV + NSG*PK + NSG*SH); // scratch buffer for the results
|
threadgroup o4_t * so4 = (threadgroup o4_t *) (shmem_f16 + 2*sgitg*Q*PV + Q*NSG*PK + NSG*SH); // scratch buffer for the results
|
||||||
|
|
||||||
// store the result for all queries in shared memory (the O matrix from the paper)
|
// store the result for all queries in shared memory (the O matrix from the paper)
|
||||||
so4 += tiisg;
|
so4 += tiisg;
|
||||||
|
|
||||||
{
|
{
|
||||||
q += iq1*args.nb01 + iq2*args.nb02 + iq3*args.nb03;
|
q += iq1*Q*args.nb01 + iq2*args.nb02 + iq3*args.nb03;
|
||||||
|
|
||||||
const short ikv2 = iq2/(args.ne02/args.ne_12_2);
|
const short ikv2 = iq2/(args.ne02/args.ne_12_2);
|
||||||
const short ikv3 = iq3/(args.ne03/args.ne_12_3);
|
const short ikv3 = iq3/(args.ne03/args.ne_12_3);
|
||||||
@@ -1157,22 +1157,32 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
v += ikv2*args.nb22 + ikv3*args.nb23;
|
v += ikv2*args.nb22 + ikv3*args.nb23;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load heads from Q to shared memory
|
// load Q query rows to shared memory
|
||||||
device const float4 * q4 = (device const float4 *) ((device const char *) q);
|
{
|
||||||
|
for (short qq = 0; qq < Q; ++qq) {
|
||||||
if (iq1 < args.ne01) {
|
const int iq1_q = iq1*Q + qq;
|
||||||
|
device const float4 * q4 = (device const float4 *) ((device const char *) q + qq*args.nb01);
|
||||||
|
if (iq1_q < args.ne01) {
|
||||||
for (short i = tiisg; i < PK4; i += NW) {
|
for (short i = tiisg; i < PK4; i += NW) {
|
||||||
if (i < DK4) {
|
if (i < DK4) {
|
||||||
sq4[i] = (q4_t) q4[i];
|
sq4[qq*PK4 + i] = (q4_t) q4[i];
|
||||||
} else {
|
} else {
|
||||||
sq4[i] = (q4_t) 0.0f;
|
sq4[qq*PK4 + i] = (q4_t) 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (short i = tiisg; i < PK4; i += NW) {
|
||||||
|
sq4[qq*PK4 + i] = (q4_t) 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero out so
|
// zero out so
|
||||||
|
for (short qq = 0; qq < Q; ++qq) {
|
||||||
for (short i = 0; i < DV4/NL; ++i) {
|
for (short i = 0; i < DV4/NL; ++i) {
|
||||||
so4[i*NL] = (o4_t) 0.0f;
|
so4[qq*DV4 + i*NL] = (o4_t) 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero out shared memory SH
|
// zero out shared memory SH
|
||||||
@@ -1183,15 +1193,19 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
threadgroup_barrier(mem_flags::mem_threadgroup);
|
threadgroup_barrier(mem_flags::mem_threadgroup);
|
||||||
|
|
||||||
{
|
{
|
||||||
float S = 0.0f;
|
float S[Q];
|
||||||
float M = -FLT_MAX/2;
|
float M[Q];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
S[qq] = 0.0f;
|
||||||
|
M[qq] = -FLT_MAX/2;
|
||||||
|
}
|
||||||
|
|
||||||
// thread indices inside the simdgroup
|
// thread indices inside the simdgroup
|
||||||
const short tx = tiisg%NL;
|
const short tx = tiisg%NL;
|
||||||
const short ty = tiisg/NL;
|
const short ty = tiisg/NL;
|
||||||
|
|
||||||
// pointer to the mask
|
// pointer to the mask
|
||||||
device const half * pm = (device const half *) (mask + iq1*args.nb31 + (iq2%args.ne32)*args.nb32 + (iq3%args.ne33)*args.nb33);
|
device const half * pm_base = (device const half *) (mask + iq1*Q*args.nb31 + (iq2%args.ne32)*args.nb32 + (iq3%args.ne33)*args.nb33);
|
||||||
|
|
||||||
float slope = 1.0f;
|
float slope = 1.0f;
|
||||||
|
|
||||||
@@ -1213,6 +1227,13 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device const half * pm[Q];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
// padded query rows clamp to row 0 of the mask to avoid OOB; their scores
|
||||||
|
// are forced to -inf below, so the values never affect the result.
|
||||||
|
pm[qq] = pm_base + ((iq1*Q + qq) < args.ne01 ? qq*(args.nb31/sizeof(half)) : -iq1*Q*(args.nb31/sizeof(half)));
|
||||||
|
}
|
||||||
|
|
||||||
// the last partial chunk uses the pad buffer as source
|
// the last partial chunk uses the pad buffer as source
|
||||||
if (FC_flash_attn_ext_vec_has_kvpad && ic + C > args.ne11) {
|
if (FC_flash_attn_ext_vec_has_kvpad && ic + C > args.ne11) {
|
||||||
k = pad;
|
k = pad;
|
||||||
@@ -1226,43 +1247,72 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
v += (ikv2 + ikv3*args.ne_12_2)*args.nb21*C;
|
v += (ikv2 + ikv3*args.ne_12_2)*args.nb21*C;
|
||||||
|
|
||||||
if (!FC_flash_attn_ext_vec_has_mask) {
|
if (!FC_flash_attn_ext_vec_has_mask) {
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
if (ic + tiisg >= args.ne11) {
|
if (ic + tiisg >= args.ne11) {
|
||||||
sm[tiisg] = -MAXHALF;
|
sm[qq*C + tiisg] = -MAXHALF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pm = (device const half *) (mask) +
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
iq1*C +
|
pm[qq] = (device const half *) (mask) +
|
||||||
|
(iq1*Q + qq)*C +
|
||||||
(iq2%args.ne32)*(C*args.ne31) +
|
(iq2%args.ne32)*(C*args.ne31) +
|
||||||
(iq3%args.ne33)*(C*args.ne31*args.ne32);
|
(iq3%args.ne33)*(C*args.ne31*args.ne32);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ic = 0;
|
ic = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FC_flash_attn_ext_vec_has_mask) {
|
if (FC_flash_attn_ext_vec_has_mask) {
|
||||||
sm[tiisg] = pm[ic + tiisg];
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
if ((iq1*Q + qq) < args.ne01) {
|
||||||
|
sm[qq*C + tiisg] = pm[qq][ic + tiisg];
|
||||||
|
} else {
|
||||||
|
sm[qq*C + tiisg] = -MAXHALF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
if ((iq1*Q + qq) >= args.ne01) {
|
||||||
|
sm[qq*C + tiisg] = -MAXHALF;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip -INF blocks
|
{
|
||||||
if (simd_max(sm[tiisg]) <= -MAXHALF) {
|
bool any_finite = false;
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
if (simd_max(sm[qq*C + tiisg]) > -MAXHALF) {
|
||||||
|
any_finite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!any_finite) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Q*K^T
|
// Q*K^T
|
||||||
{
|
{
|
||||||
device const k4_t * pk4 = (device const k4_t *) (k + ic*args.nb11);
|
device const k4_t * pk4 = (device const k4_t *) (k + ic*args.nb11);
|
||||||
threadgroup const q4_t * pq4 = sq4;
|
|
||||||
|
|
||||||
pk4 += ty*NS10/4 + tx;
|
pk4 += ty*NS10/4 + tx;
|
||||||
pq4 += tx;
|
|
||||||
|
|
||||||
qk_t mqk[C/NE] = { [ 0 ... C/NE - 1] = 0.0f };
|
qk_t mqk[Q][C/NE];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
FOR_UNROLL (short cc = 0; cc < C/NE; ++cc) {
|
||||||
|
mqk[qq][cc] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// each simdgroup processes 1 query and NE (NW/NL) cache elements
|
// each simdgroup processes Q queries and NE (NW/NL) cache elements
|
||||||
FOR_UNROLL (short cc = 0; cc < C/NE; ++cc) {
|
FOR_UNROLL (short cc = 0; cc < C/NE; ++cc) {
|
||||||
if (is_same<kd4_t, k4_t>::value) {
|
if (is_same<kd4_t, k4_t>::value) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DK4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DK4/NL; ++ii) {
|
||||||
mqk[cc] += dot((float4) pk4[cc*NE*NS10/4 + ii*NL], (float4) pq4[ii*NL]);
|
const k4_t k_elem = pk4[cc*NE*NS10/4 + ii*NL];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
mqk[qq][cc] += dot((float4) k_elem, (float4) sq4[qq*PK4 + ii*NL + tx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
device const kd4_t * pk = (device const kd4_t *) (k + ((ic + NE*cc + ty)*args.nb11));
|
device const kd4_t * pk = (device const kd4_t *) (k + ((ic + NE*cc + ty)*args.nb11));
|
||||||
@@ -1274,12 +1324,15 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
deq_k_t4(pk + i/nl_k, i%nl_k, mk);
|
deq_k_t4(pk + i/nl_k, i%nl_k, mk);
|
||||||
|
|
||||||
mqk[cc] += dot((float4) mk, (float4) sq4[i]);
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
mqk[qq][cc] += dot((float4) mk, (float4) sq4[qq*PK4 + i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
if (NE == 1) {
|
if (NE == 1) {
|
||||||
mqk[cc] = simd_sum(mqk[cc]);
|
mqk[qq][cc] = simd_sum(mqk[qq][cc]);
|
||||||
} else {
|
} else {
|
||||||
// simdgroup reduce (NE = 4)
|
// simdgroup reduce (NE = 4)
|
||||||
// [ 0 .. 7] -> [ 0]
|
// [ 0 .. 7] -> [ 0]
|
||||||
@@ -1287,44 +1340,47 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
// [16 .. 23] -> [16]
|
// [16 .. 23] -> [16]
|
||||||
// [24 .. 31] -> [24]
|
// [24 .. 31] -> [24]
|
||||||
if (NE <= 1) {
|
if (NE <= 1) {
|
||||||
mqk[cc] += simd_shuffle_down(mqk[cc], 16);
|
mqk[qq][cc] += simd_shuffle_down(mqk[qq][cc], 16);
|
||||||
}
|
}
|
||||||
if (NE <= 2) {
|
if (NE <= 2) {
|
||||||
mqk[cc] += simd_shuffle_down(mqk[cc], 8);
|
mqk[qq][cc] += simd_shuffle_down(mqk[qq][cc], 8);
|
||||||
}
|
}
|
||||||
if (NE <= 4) {
|
if (NE <= 4) {
|
||||||
mqk[cc] += simd_shuffle_down(mqk[cc], 4);
|
mqk[qq][cc] += simd_shuffle_down(mqk[qq][cc], 4);
|
||||||
}
|
}
|
||||||
if (NE <= 8) {
|
if (NE <= 8) {
|
||||||
mqk[cc] += simd_shuffle_down(mqk[cc], 2);
|
mqk[qq][cc] += simd_shuffle_down(mqk[qq][cc], 2);
|
||||||
}
|
}
|
||||||
if (NE <= 16) {
|
if (NE <= 16) {
|
||||||
mqk[cc] += simd_shuffle_down(mqk[cc], 1);
|
mqk[qq][cc] += simd_shuffle_down(mqk[qq][cc], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// broadcast
|
// broadcast
|
||||||
mqk[cc] = simd_shuffle(mqk[cc], NL*ty);
|
mqk[qq][cc] = simd_shuffle(mqk[qq][cc], NL*ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
if (FC_flash_attn_ext_vec_has_mask &&
|
if (FC_flash_attn_ext_vec_has_mask &&
|
||||||
!FC_flash_attn_ext_vec_has_scap &&
|
!FC_flash_attn_ext_vec_has_scap &&
|
||||||
!FC_flash_attn_ext_vec_has_bias) {
|
!FC_flash_attn_ext_vec_has_bias) {
|
||||||
ss[NE*tx + ty] = fma(mqk[tx], args.scale, (qk_t) sm[NE*tx + ty]);
|
ss[qq*C + NE*tx + ty] = fma(mqk[qq][tx], args.scale, (qk_t) sm[qq*C + NE*tx + ty]);
|
||||||
} else {
|
} else {
|
||||||
mqk[tx] *= args.scale;
|
mqk[qq][tx] *= args.scale;
|
||||||
|
|
||||||
if (FC_flash_attn_ext_vec_has_scap) {
|
if (FC_flash_attn_ext_vec_has_scap) {
|
||||||
mqk[tx] = args.logit_softcap*precise::tanh(mqk[tx]);
|
mqk[qq][tx] = args.logit_softcap*precise::tanh(mqk[qq][tx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FC_flash_attn_ext_vec_has_bias) {
|
if (FC_flash_attn_ext_vec_has_bias) {
|
||||||
mqk[tx] += (qk_t) sm[NE*tx + ty]*slope;
|
mqk[qq][tx] += (qk_t) sm[qq*C + NE*tx + ty]*slope;
|
||||||
} else {
|
} else {
|
||||||
mqk[tx] += (qk_t) sm[NE*tx + ty];
|
mqk[qq][tx] += (qk_t) sm[qq*C + NE*tx + ty];
|
||||||
}
|
}
|
||||||
|
|
||||||
ss[NE*tx + ty] = mqk[tx];
|
ss[qq*C + NE*tx + ty] = mqk[qq][tx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1332,23 +1388,25 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
// online softmax
|
// online softmax
|
||||||
{
|
{
|
||||||
const float m = M;
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
const float s = ss[tiisg];
|
const float m = M[qq];
|
||||||
|
const float s = ss[qq*C + tiisg];
|
||||||
|
|
||||||
M = simd_max(max(M, s));
|
M[qq] = simd_max(max(M[qq], s));
|
||||||
|
|
||||||
const float ms = exp(m - M);
|
const float ms = exp(m - M[qq]);
|
||||||
const float vs = exp(s - M);
|
const float vs = exp(s - M[qq]);
|
||||||
|
|
||||||
S = S*ms + simd_sum(vs);
|
S[qq] = S[qq]*ms + simd_sum(vs);
|
||||||
|
|
||||||
// the P matrix from the paper (Q rows, C columns)
|
// the P matrix from the paper (Q rows, C columns)
|
||||||
ss[tiisg] = vs;
|
ss[qq*C + tiisg] = vs;
|
||||||
|
|
||||||
// O = diag(ms)*O
|
// O = diag(ms)*O
|
||||||
if ((DV4/NL % NW == 0) || ty == 0) {
|
if ((DV4/NL % NW == 0) || ty == 0) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
so4[ii*NL] *= ms;
|
so4[qq*DV4 + ii*NL] *= ms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1357,9 +1415,11 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
// O = O + (Q*K^T)*V
|
// O = O + (Q*K^T)*V
|
||||||
{
|
{
|
||||||
o4_t lo[DV4/NL];
|
o4_t lo[Q][DV4/NL];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
lo[ii] = 0.0f;
|
lo[qq][ii] = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_same<vd4_t, v4_t>::value) {
|
if (is_same<vd4_t, v4_t>::value) {
|
||||||
@@ -1367,11 +1427,12 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
|
|
||||||
pv4 += ty*NS20/4 + tx;
|
pv4 += ty*NS20/4 + tx;
|
||||||
|
|
||||||
const auto sst = ss + ty;
|
|
||||||
|
|
||||||
FOR_UNROLL (short cc = 0; cc < C/NE; ++cc) {
|
FOR_UNROLL (short cc = 0; cc < C/NE; ++cc) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
lo[ii] += o4_t(float4(pv4[cc*NE*NS20/4 + ii*NL])*float4(sst[cc*NE]));
|
const v4_t v_elem = pv4[cc*NE*NS20/4 + ii*NL];
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
lo[qq][ii] += o4_t(float4(v_elem)*float4(ss[qq*C + cc*NE + ty]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1384,78 +1445,88 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
v4_t mv;
|
v4_t mv;
|
||||||
deq_v_t4(pv4 + i/nl_v, i%nl_v, mv);
|
deq_v_t4(pv4 + i/nl_v, i%nl_v, mv);
|
||||||
|
|
||||||
lo[ii] += o4_t(float4(mv)*float4(ss[NE*cc + ty]));
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
lo[qq][ii] += o4_t(float4(mv)*float4(ss[qq*C + NE*cc + ty]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
if (NE > 1) {
|
if (NE > 1) {
|
||||||
lo[ii][0] += simd_shuffle_down(lo[ii][0], 16);
|
lo[qq][ii][0] += simd_shuffle_down(lo[qq][ii][0], 16);
|
||||||
lo[ii][1] += simd_shuffle_down(lo[ii][1], 16);
|
lo[qq][ii][1] += simd_shuffle_down(lo[qq][ii][1], 16);
|
||||||
lo[ii][2] += simd_shuffle_down(lo[ii][2], 16);
|
lo[qq][ii][2] += simd_shuffle_down(lo[qq][ii][2], 16);
|
||||||
lo[ii][3] += simd_shuffle_down(lo[ii][3], 16);
|
lo[qq][ii][3] += simd_shuffle_down(lo[qq][ii][3], 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NE > 2) {
|
if (NE > 2) {
|
||||||
lo[ii][0] += simd_shuffle_down(lo[ii][0], 8);
|
lo[qq][ii][0] += simd_shuffle_down(lo[qq][ii][0], 8);
|
||||||
lo[ii][1] += simd_shuffle_down(lo[ii][1], 8);
|
lo[qq][ii][1] += simd_shuffle_down(lo[qq][ii][1], 8);
|
||||||
lo[ii][2] += simd_shuffle_down(lo[ii][2], 8);
|
lo[qq][ii][2] += simd_shuffle_down(lo[qq][ii][2], 8);
|
||||||
lo[ii][3] += simd_shuffle_down(lo[ii][3], 8);
|
lo[qq][ii][3] += simd_shuffle_down(lo[qq][ii][3], 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NE > 4) {
|
if (NE > 4) {
|
||||||
lo[ii][0] += simd_shuffle_down(lo[ii][0], 4);
|
lo[qq][ii][0] += simd_shuffle_down(lo[qq][ii][0], 4);
|
||||||
lo[ii][1] += simd_shuffle_down(lo[ii][1], 4);
|
lo[qq][ii][1] += simd_shuffle_down(lo[qq][ii][1], 4);
|
||||||
lo[ii][2] += simd_shuffle_down(lo[ii][2], 4);
|
lo[qq][ii][2] += simd_shuffle_down(lo[qq][ii][2], 4);
|
||||||
lo[ii][3] += simd_shuffle_down(lo[ii][3], 4);
|
lo[qq][ii][3] += simd_shuffle_down(lo[qq][ii][3], 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NE > 8) {
|
if (NE > 8) {
|
||||||
lo[ii][0] += simd_shuffle_down(lo[ii][0], 2);
|
lo[qq][ii][0] += simd_shuffle_down(lo[qq][ii][0], 2);
|
||||||
lo[ii][1] += simd_shuffle_down(lo[ii][1], 2);
|
lo[qq][ii][1] += simd_shuffle_down(lo[qq][ii][1], 2);
|
||||||
lo[ii][2] += simd_shuffle_down(lo[ii][2], 2);
|
lo[qq][ii][2] += simd_shuffle_down(lo[qq][ii][2], 2);
|
||||||
lo[ii][3] += simd_shuffle_down(lo[ii][3], 2);
|
lo[qq][ii][3] += simd_shuffle_down(lo[qq][ii][3], 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NE > 16) {
|
if (NE > 16) {
|
||||||
lo[ii][0] += simd_shuffle_down(lo[ii][0], 1);
|
lo[qq][ii][0] += simd_shuffle_down(lo[qq][ii][0], 1);
|
||||||
lo[ii][1] += simd_shuffle_down(lo[ii][1], 1);
|
lo[qq][ii][1] += simd_shuffle_down(lo[qq][ii][1], 1);
|
||||||
lo[ii][2] += simd_shuffle_down(lo[ii][2], 1);
|
lo[qq][ii][2] += simd_shuffle_down(lo[qq][ii][2], 1);
|
||||||
lo[ii][3] += simd_shuffle_down(lo[ii][3], 1);
|
lo[qq][ii][3] += simd_shuffle_down(lo[qq][ii][3], 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((DV4/NL % NW == 0) || ty == 0) {
|
if ((DV4/NL % NW == 0) || ty == 0) {
|
||||||
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
so4[ii*NL] += lo[ii];
|
so4[qq*DV4 + ii*NL] += lo[qq][ii];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FC_flash_attn_ext_vec_has_sinks && sgitg == 0 && iwg == 0) {
|
if (FC_flash_attn_ext_vec_has_sinks && sgitg == 0 && iwg == 0) {
|
||||||
const float m = M;
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
const float m = M[qq];
|
||||||
const float s = tiisg == 0 ? ((device const float *) sinks)[iq2] : -FLT_MAX/2;
|
const float s = tiisg == 0 ? ((device const float *) sinks)[iq2] : -FLT_MAX/2;
|
||||||
|
|
||||||
M = simd_max(max(M, s));
|
M[qq] = simd_max(max(M[qq], s));
|
||||||
|
|
||||||
const float ms = exp(m - M);
|
const float ms = exp(m - M[qq]);
|
||||||
const float vs = exp(s - M);
|
const float vs = exp(s - M[qq]);
|
||||||
|
|
||||||
S = S*ms + simd_sum(vs);
|
S[qq] = S[qq]*ms + simd_sum(vs);
|
||||||
|
|
||||||
if ((DV4/NL % NW == 0) || ty == 0) {
|
if ((DV4/NL % NW == 0) || ty == 0) {
|
||||||
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
FOR_UNROLL (short ii = 0; ii < DV4/NL; ++ii) {
|
||||||
so4[ii*NL] *= ms;
|
so4[qq*DV4 + ii*NL] *= ms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are needed for reducing the results from the simdgroups (reuse the ss buffer)
|
// these are needed for reducing the results from the simdgroups (reuse the ss buffer)
|
||||||
if (tiisg == 0) {
|
if (tiisg == 0) {
|
||||||
ss[0] = (s_t) S;
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
ss[1] = (s_t) M;
|
ss[2*qq + 0] = (s_t) S[qq];
|
||||||
|
ss[2*qq + 1] = (s_t) M[qq];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1466,27 +1537,29 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
// parallel reduce
|
// parallel reduce
|
||||||
for (short r = NSG/2; r > 0; r >>= 1) {
|
for (short r = NSG/2; r > 0; r >>= 1) {
|
||||||
if (sgitg < r) {
|
if (sgitg < r) {
|
||||||
const float S0 = ss[ 0];
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
const float S1 = ss[r*(SH/2) + 0];
|
const float S0 = ss[ 2*qq + 0];
|
||||||
|
const float S1 = ss[r*(SH/2) + 2*qq + 0];
|
||||||
|
|
||||||
const float M0 = ss[ 1];
|
const float M0 = ss[ 2*qq + 1];
|
||||||
const float M1 = ss[r*(SH/2) + 1];
|
const float M1 = ss[r*(SH/2) + 2*qq + 1];
|
||||||
|
|
||||||
const float M = max(M0, M1);
|
const float Mx = max(M0, M1);
|
||||||
|
|
||||||
const float ms0 = exp(M0 - M);
|
const float ms0 = exp(M0 - Mx);
|
||||||
const float ms1 = exp(M1 - M);
|
const float ms1 = exp(M1 - Mx);
|
||||||
|
|
||||||
const float S = S0*ms0 + S1*ms1;
|
const float Sx = S0*ms0 + S1*ms1;
|
||||||
|
|
||||||
if (tiisg == 0) {
|
if (tiisg == 0) {
|
||||||
ss[0] = S;
|
ss[2*qq + 0] = Sx;
|
||||||
ss[1] = M;
|
ss[2*qq + 1] = Mx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// O_0 = diag(ms0)*O_0 + diag(ms1)*O_1
|
// O_0 = diag(ms0)*O_0 + diag(ms1)*O_1
|
||||||
for (short i = tiisg; i < DV4; i += NW) {
|
for (short i = tiisg; i < DV4; i += NW) {
|
||||||
so4[i] = so4[i]*ms0 + so4[i + r*PV4]*ms1;
|
so4[qq*DV4 + i] = so4[qq*DV4 + i]*ms0 + so4[qq*DV4 + i + r*Q*PV4]*ms1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1496,23 +1569,31 @@ kernel void kernel_flash_attn_ext_vec(
|
|||||||
// final rescale with 1/S and store to global memory
|
// final rescale with 1/S and store to global memory
|
||||||
if (sgitg == 0) {
|
if (sgitg == 0) {
|
||||||
const int64_t nrows = args.ne3*args.ne2*args.ne1;
|
const int64_t nrows = args.ne3*args.ne2*args.ne1;
|
||||||
const int64_t rid = iq3*args.ne2*args.ne1 + iq2 + iq1*args.ne1;
|
|
||||||
|
|
||||||
device float4 * dst4 = (device float4 *) dst;
|
device float4 * dst4 = (device float4 *) dst;
|
||||||
device float * dst1 = (device float *) dst + nrows*DV*NWG; // the S and M are stored after the results
|
device float * dst1 = (device float *) dst + nrows*DV*NWG; // the S and M are stored after the results
|
||||||
|
|
||||||
const float S = NWG == 1 ? (ss[0] == 0.0f ? 0.0f : 1.0f/ss[0]) : 1.0f;
|
FOR_UNROLL (short qq = 0; qq < Q; ++qq) {
|
||||||
|
const int iq1_q = iq1*Q + qq;
|
||||||
|
if (iq1_q >= args.ne01) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t rid = iq3*args.ne2*args.ne1 + iq2 + iq1_q*args.ne1;
|
||||||
|
|
||||||
|
const float Sval = NWG == 1 ? (ss[2*qq + 0] == 0.0f ? 0.0f : 1.0f/ss[2*qq + 0]) : 1.0f;
|
||||||
|
|
||||||
// interleave the workgroup data
|
// interleave the workgroup data
|
||||||
for (short i = tiisg; i < DV4; i += NW) {
|
for (short i = tiisg; i < DV4; i += NW) {
|
||||||
dst4[rid*DV4*NWG + NWG*i + iwg] = (float4) so4[i]*S;
|
dst4[rid*DV4*NWG + NWG*i + iwg] = (float4) so4[qq*DV4 + i]*Sval;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store S and M
|
// store S and M
|
||||||
if (NWG > 1) {
|
if (NWG > 1) {
|
||||||
if (tiisg == 0) {
|
if (tiisg == 0) {
|
||||||
dst1[rid*(2*NWG) + 2*iwg + 0] = ss[0];
|
dst1[rid*(2*NWG) + 2*iwg + 0] = ss[2*qq + 0];
|
||||||
dst1[rid*(2*NWG) + 2*iwg + 1] = ss[1];
|
dst1[rid*(2*NWG) + 2*iwg + 1] = ss[2*qq + 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1546,113 +1627,432 @@ typedef decltype(kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4
|
|||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 32, 32, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 32, 32, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 32, 32, 4>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 32, 32, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 32, 32, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 32, 32, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 32, 32, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 32, 32, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk32_dv32")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 32, 32, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk32_dv32_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 32, 32, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk32_dv32_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 32, 32, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 64, 64, 2>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 64, 64, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 64, 64, 2>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 64, 64, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 64, 64, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 64, 64, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 64, 64, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk64_dv64_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 64, 64, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 96, 96, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 96, 96, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 96, 96, 4>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 96, 96, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 96, 96, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 96, 96, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 96, 96, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 96, 96, 4>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk96_dv96")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 96, 96, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk96_dv96_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 96, 96, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk96_dv96_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 96, 96, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 128, 128, 1>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 128, 128, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 128, 128, 1>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 128, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 128, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 128, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 128, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk128_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 128, 128, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 192, 192, 2>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 192, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 192, 192, 2>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 192, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 192, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 192, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 192, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv192_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 192, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 192, 128, 2>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 192, 128, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 192, 128, 2>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 192, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 192, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 192, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 192, 128, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk192_dv128_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 192, 128, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 256, 256, 1>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 256, 256, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 256, 256, 1>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 256, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 256, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 256, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 256, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk256_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 256, 256, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 320, 256, 2>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 320, 256, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 320, 256, 2>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 320, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 320, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 320, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 320, 256, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk320_dv256_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 320, 256, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 512, 512, 1>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 512, 512, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 512, 512, 1>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 512, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 512, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 512, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 512, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 1>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q1_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 2, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q2_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 1, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q4_ne1")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 1, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk512_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 512, 512, 4, 4>;
|
||||||
|
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f32_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f32_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES_F32, float4, 1, dequantize_f32_t4, float4, 1, dequantize_f32_t4, 576, 512, 2>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_f16_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, half4, 1, dequantize_f16_t4, half4, 1, dequantize_f16_t4, 576, 512, 4, 4>;
|
||||||
#if defined(GGML_METAL_HAS_BF16)
|
#if defined(GGML_METAL_HAS_BF16)
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_bf16_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, bfloat4, 1, dequantize_bf16_t4, bfloat4, 1, dequantize_bf16_t4, 576, 512, 2>;
|
||||||
#endif
|
#endif
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_0_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_0, 8, dequantize_q4_0_t4, block_q4_0, 8, dequantize_q4_0_t4, 576, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q4_1_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q4_1, 8, dequantize_q4_1_t4, block_q4_1, 8, dequantize_q4_1_t4, 576, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_0_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_0, 8, dequantize_q5_0_t4, block_q5_0, 8, dequantize_q5_0_t4, 576, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q5_1_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q5_1, 8, dequantize_q5_1_t4, block_q5_1, 8, dequantize_q5_1_t4, 576, 512, 4, 4>;
|
||||||
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 2>;
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512_q1_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 4, 1>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512_q2_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 2, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512_q2_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 4, 2>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512_q4_ne2")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 2, 4>;
|
||||||
|
template [[host_name("kernel_flash_attn_ext_vec_q8_0_dk576_dv512_q4_ne4")]] kernel flash_attn_ext_vec_t kernel_flash_attn_ext_vec<FA_TYPES, block_q8_0, 8, dequantize_q8_0_t4, block_q8_0, 8, dequantize_q8_0_t4, 576, 512, 4, 4>;
|
||||||
|
|
||||||
|
|
||||||
#undef FA_TYPES
|
#undef FA_TYPES
|
||||||
#undef FA_TYPES_F32
|
#undef FA_TYPES_F32
|
||||||
|
|||||||
@@ -10573,6 +10573,101 @@ static std::vector<std::unique_ptr<test_case>> make_test_cases_from_file(const c
|
|||||||
return test_cases;
|
return test_cases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- FA vec (Q,NE): forced-config numerical slice (Metal only) ----
|
||||||
|
using set_fa_vec_override_t = void (*)(int, int);
|
||||||
|
using clear_fa_vec_override_t = void (*)(void);
|
||||||
|
|
||||||
|
// NL = 32/NE must divide both dk/4 and dv/4.
|
||||||
|
static std::vector<int> fa_vec_legal_ne(int dk, int dv) {
|
||||||
|
std::vector<int> r;
|
||||||
|
for (int ne : {1, 2, 4}) {
|
||||||
|
const int nl = 32 / ne;
|
||||||
|
if ((dk/4) % nl == 0 && (dv/4) % nl == 0) {
|
||||||
|
r.push_back(ne);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool op_names_filter_selects(const char * op_names_filter, const char * op_name) {
|
||||||
|
if (!op_names_filter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::string_view filter(op_names_filter);
|
||||||
|
while (!filter.empty()) {
|
||||||
|
auto comma_pos = filter.find_first_of(',');
|
||||||
|
const auto lparen_pos = filter.find_first_of('(');
|
||||||
|
std::string_view entry;
|
||||||
|
if (lparen_pos < comma_pos) {
|
||||||
|
const auto rparen_pos = filter.find_first_of(')');
|
||||||
|
comma_pos = filter.find_first_of(',', rparen_pos);
|
||||||
|
entry = filter.substr(0, lparen_pos);
|
||||||
|
} else {
|
||||||
|
entry = filter.substr(0, comma_pos);
|
||||||
|
}
|
||||||
|
if (entry == op_name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
filter = comma_pos != std::string_view::npos ? filter.substr(comma_pos + 1) : "";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Covers padded rows, sinks, kvpad, multi-SIMDgroup reduction, quantized K/V, and MLA views.
|
||||||
|
// The override is backend-global, so this runs after all parallel workers have joined.
|
||||||
|
static bool run_fa_vec_slice(ggml_backend_t backend, ggml_backend_t backend_cpu, const char * op_names_filter) {
|
||||||
|
if (!op_names_filter_selects(op_names_filter, "FLASH_ATTN_EXT")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto * reg = ggml_backend_dev_backend_reg(ggml_backend_get_device(backend));
|
||||||
|
|
||||||
|
auto set_ov = (set_fa_vec_override_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_set_fa_vec_override");
|
||||||
|
auto clear_ov = (clear_fa_vec_override_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_clear_fa_vec_override");
|
||||||
|
if (!set_ov || !clear_ov) {
|
||||||
|
return true; // not the Metal backend: nothing to force
|
||||||
|
}
|
||||||
|
|
||||||
|
struct shape_t { int dk, dv; };
|
||||||
|
const shape_t shapes[] = { { 128, 128 }, { 576, 512 } }; // mainstream head size + MLA shared K/V view
|
||||||
|
const int ne01_pts[] = { 1, 3 }; // decode, and padded rows for Q=2 and Q=4
|
||||||
|
const int ne11_pts[] = { 512, 4097 }; // nsg=1, and nsg>=2 together with kvpad
|
||||||
|
const ggml_type types[] = { GGML_TYPE_F16, GGML_TYPE_Q4_0 };
|
||||||
|
|
||||||
|
int n_run = 0, n_fail = 0;
|
||||||
|
for (auto s : shapes) {
|
||||||
|
for (int ne : fa_vec_legal_ne(s.dk, s.dv)) {
|
||||||
|
for (int Q : { 1, 2, 4 }) {
|
||||||
|
for (ggml_type type_kv : types) {
|
||||||
|
for (bool sinks : { false, true }) {
|
||||||
|
for (int ne01 : ne01_pts) {
|
||||||
|
for (int ne11 : ne11_pts) {
|
||||||
|
set_ov(Q, ne);
|
||||||
|
test_flash_attn_ext tc(s.dk, s.dv, /*nh=*/4, { 1, 1 }, /*kv=*/ne11, /*nb=*/ne01,
|
||||||
|
/*mask=*/true, sinks, 0.0f, 0.0f, GGML_PREC_F32,
|
||||||
|
type_kv, type_kv);
|
||||||
|
auto st = tc.eval(backend, backend_cpu, "FLASH_ATTN_EXT", nullptr);
|
||||||
|
clear_ov();
|
||||||
|
|
||||||
|
if (st == test_status_t::FAIL) {
|
||||||
|
printf(" FAIL fa_vec slice: dk=%d dv=%d Q=%d ne=%d type=%s ne01=%d ne11=%d sinks=%d\n",
|
||||||
|
s.dk, s.dv, Q, ne, ggml_type_name(type_kv), ne01, ne11, (int) sinks);
|
||||||
|
n_fail++;
|
||||||
|
}
|
||||||
|
n_run++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" fa_vec (Q,NE) slice: %d cases run, %d failed\n", n_run, n_fail);
|
||||||
|
|
||||||
|
return n_fail == 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool test_backend(ggml_backend_t backend, ggml_backend_dev_t dev, test_mode mode, const char * op_names_filter, const char * params_filter,
|
static bool test_backend(ggml_backend_t backend, ggml_backend_dev_t dev, test_mode mode, const char * op_names_filter, const char * params_filter,
|
||||||
printer * output_printer, const char * test_file_path, int parallel_workers) {
|
printer * output_printer, const char * test_file_path, int parallel_workers) {
|
||||||
auto filter_test_cases = [](std::vector<std::unique_ptr<test_case>> & test_cases, const char * params_filter) {
|
auto filter_test_cases = [](std::vector<std::unique_ptr<test_case>> & test_cases, const char * params_filter) {
|
||||||
@@ -10710,7 +10805,9 @@ static bool test_backend(ggml_backend_t backend, ggml_backend_dev_t dev, test_mo
|
|||||||
output_printer->print_summary(test_summary_info(n_ok, tests_run, false));
|
output_printer->print_summary(test_summary_info(n_ok, tests_run, false));
|
||||||
output_printer->print_failed_tests(failed_tests);
|
output_printer->print_failed_tests(failed_tests);
|
||||||
|
|
||||||
return n_ok == tests_run;
|
const bool slice_ok = run_fa_vec_slice(backend, backend_cpu.get(), op_names_filter);
|
||||||
|
|
||||||
|
return n_ok == tests_run && slice_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == MODE_GRAD) {
|
if (mode == MODE_GRAD) {
|
||||||
|
|||||||
@@ -38,5 +38,8 @@ else()
|
|||||||
add_subdirectory(export-lora)
|
add_subdirectory(export-lora)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(fit-params)
|
add_subdirectory(fit-params)
|
||||||
|
if (GGML_METAL)
|
||||||
|
add_subdirectory(tuning)
|
||||||
|
endif()
|
||||||
add_subdirectory(results)
|
add_subdirectory(results)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
set(TARGET ggml-metal-tuning)
|
||||||
|
|
||||||
|
add_executable(${TARGET} main.cpp bench.cpp fa-vec.cpp)
|
||||||
|
target_link_libraries(${TARGET} PRIVATE ggml ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||||
|
target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}/ggml/src/ggml-metal)
|
||||||
|
|
||||||
|
if(LLAMA_TOOLS_INSTALL)
|
||||||
|
install(TARGETS ${TARGET} RUNTIME)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# ggml-metal-tuning
|
||||||
|
|
||||||
|
Offline kernel tuner for the Metal backend.
|
||||||
|
It sweeps a kernel's config grid on the machine it runs on and prints pasteable table rows for `ggml/src/ggml-metal/ggml-metal-tuning.cpp`.
|
||||||
|
|
||||||
|
This is not a test: it never reports pass/fail on performance.
|
||||||
|
A non-zero exit code means bad arguments or a wrong environment (no Metal device, missing proc bridges), never a perf result.
|
||||||
|
|
||||||
|
| tuner | tunes | table |
|
||||||
|
|---|---|---|
|
||||||
|
| `fa-vec` | flash-attn vec `(Q, NE)` per `(dtype, head size, KV depth, batch width)` | `fa_vec_tuned_table` |
|
||||||
|
|
||||||
|
## Adding a device to the FA-vec table
|
||||||
|
|
||||||
|
Build on the target machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -B build -DGGML_METAL=ON
|
||||||
|
cmake --build build --target ggml-metal-tuning -j
|
||||||
|
cmake --build build --target test-backend-ops -j
|
||||||
|
```
|
||||||
|
|
||||||
|
Sweep the grid (6 dtypes x 10 head sizes x 4 KV depths x 9 batch widths; a few hours):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build/bin/ggml-metal-tuning fa-vec > fa_vec_rows.txt 2> fa_vec_sweep.log
|
||||||
|
```
|
||||||
|
|
||||||
|
`fa_vec_rows.txt` holds nothing but table rows, ready to paste into `fa_vec_tuned_table`: the min-max-regret target, the aggregate benefit gate, the short-KV drop and the pointwise compression are already applied.
|
||||||
|
A config represents a bucket only if it is no slower than the baseline config at every point that bucket covers, so a config that wins on average but loses at one batch width leaves its bucket at baseline.
|
||||||
|
`fa_vec_sweep.log` holds the per-cell timings, bucket coverage, noise floor, any cooldown activity, and every config the no-harm rule refused together with the point that refused it.
|
||||||
|
Post both: the log is what makes the rows reviewable.
|
||||||
|
|
||||||
|
Long sweeps can be split.
|
||||||
|
`--dtype f16,q4_0` and `--dk 128,192` restrict the grid, and the emitted rows for one `(dtype, head size)` do not depend on the others.
|
||||||
|
Concatenating the shard outputs in the order the full grid would visit them gives the same rows a single run prints.
|
||||||
|
|
||||||
|
Then validate the numerics, where Metal is compared against the CPU reference:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build/bin/test-backend-ops test -o FLASH_ATTN_EXT -b MTL0
|
||||||
|
```
|
||||||
|
|
||||||
|
This forces every legal `(Q, NE)` on `dk=128` and `dk=576`.
|
||||||
|
The tuner itself does no numerical checks, so the other head sizes have no automated numerical coverage.
|
||||||
|
|
||||||
|
If the device is not in `enum ggml_metal_device_id` yet, register it in `ggml/src/ggml-metal/ggml-metal-device.{h,m}` first.
|
||||||
|
The tuner emits whatever token the runtime reports for the machine, so an unregistered device emits `GGML_METAL_DEVICE_GENERIC` and its rows would apply to every unknown device.
|
||||||
|
|
||||||
|
## Thermal throttling
|
||||||
|
|
||||||
|
Long sweeps heat the GPU, and a throttled measurement is indistinguishable from a slow kernel.
|
||||||
|
The tuner re-measures a fixed baseline config every four candidates as an anchor.
|
||||||
|
When the anchor drifts more than `--cool-drift` (10% by default) from the coolest anchor seen in that cell, the tuner:
|
||||||
|
|
||||||
|
1. discards every candidate measured since the last clean anchor,
|
||||||
|
2. sleeps with exponential backoff until the anchor comes back within `--cool-eps` (3%),
|
||||||
|
3. re-measures the discarded candidates.
|
||||||
|
|
||||||
|
If it cannot cool down within `--cool-max-wait` seconds, or a cell needs more than `--cool-max-retry` rounds, that cell is dropped from the table and reported on stderr.
|
||||||
|
|
||||||
|
`--no-cooldown` only warns on drift and keeps the measurement.
|
||||||
|
Use it to reproduce a sweep taken without cooling.
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
#include "bench.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
perf_cell build_perf_cell(ggml_backend_t backend,
|
||||||
|
const build_graph_fn & build,
|
||||||
|
const init_tensors_fn & init,
|
||||||
|
const op_flops_fn & flops) {
|
||||||
|
perf_cell cell;
|
||||||
|
|
||||||
|
const size_t graph_nodes = 1024;
|
||||||
|
|
||||||
|
ggml_init_params params = {
|
||||||
|
/* .mem_size = */ ggml_tensor_overhead() * 128 + ggml_graph_overhead_custom(graph_nodes, false),
|
||||||
|
/* .mem_base = */ NULL,
|
||||||
|
/* .no_alloc = */ true,
|
||||||
|
};
|
||||||
|
|
||||||
|
cell.ctx.reset(ggml_init(params));
|
||||||
|
GGML_ASSERT(cell.ctx);
|
||||||
|
|
||||||
|
ggml_tensor * out = build(cell.ctx.get());
|
||||||
|
if (!out || !ggml_backend_supports_op(backend, out)) {
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell.buf.reset(ggml_backend_alloc_ctx_tensors(cell.ctx.get(), backend));
|
||||||
|
if (!cell.buf) {
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
init(cell.ctx.get());
|
||||||
|
|
||||||
|
cell.gf = ggml_new_graph_custom(cell.ctx.get(), graph_nodes, false);
|
||||||
|
ggml_build_forward_expand(cell.gf, out);
|
||||||
|
|
||||||
|
// replicate the op to amortize overhead (target ~50 GFLOP/compute, capped to bound graph size)
|
||||||
|
cell.n_runs = 1;
|
||||||
|
const uint64_t n_flops = flops(out);
|
||||||
|
if (n_flops > 0) {
|
||||||
|
const uint64_t target_flops = 50ULL * 1000 * 1000 * 1000;
|
||||||
|
const int cap = 512;
|
||||||
|
const int by_flops = (int) std::min<int64_t>(cap, (int64_t) (target_flops / n_flops));
|
||||||
|
cell.n_runs =
|
||||||
|
std::max(1, std::min<int>(by_flops, (int) (ggml_graph_size(cell.gf) - ggml_graph_n_nodes(cell.gf))));
|
||||||
|
}
|
||||||
|
for (int i = 1; i < cell.n_runs; ++i) {
|
||||||
|
ggml_graph_add_node(cell.gf, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
double time_cell_median(ggml_backend_t backend, const perf_cell & cell, int reps) {
|
||||||
|
if (cell.gf == nullptr) {
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ggml_backend_graph_compute(backend, cell.gf); // warmup (compiles the pipeline for this config)
|
||||||
|
ggml_backend_synchronize(backend);
|
||||||
|
|
||||||
|
std::vector<double> samples;
|
||||||
|
samples.reserve(reps);
|
||||||
|
for (int r = 0; r < reps; ++r) {
|
||||||
|
const int64_t t0 = ggml_time_us();
|
||||||
|
ggml_backend_graph_compute(backend, cell.gf);
|
||||||
|
ggml_backend_synchronize(backend);
|
||||||
|
samples.push_back((double) (ggml_time_us() - t0));
|
||||||
|
}
|
||||||
|
std::nth_element(samples.begin(), samples.begin() + samples.size() / 2, samples.end());
|
||||||
|
|
||||||
|
return samples[samples.size() / 2] / cell.n_runs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double measure_one(ggml_backend_t backend,
|
||||||
|
const perf_cell & cell,
|
||||||
|
int reps,
|
||||||
|
const set_candidate_fn & set_cand,
|
||||||
|
const clear_candidate_fn & clear_cand,
|
||||||
|
int cand) {
|
||||||
|
set_cand(cand);
|
||||||
|
const double t = time_cell_median(backend, cell, reps);
|
||||||
|
clear_cand();
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// waits for the anchor to come back within eps of anchor_ref, with exponential backoff.
|
||||||
|
// returns the converged anchor, or -1 if it never converged within max_wait.
|
||||||
|
static double cool_until_steady(ggml_backend_t backend,
|
||||||
|
const perf_cell & cell,
|
||||||
|
int reps,
|
||||||
|
const set_candidate_fn & set_cand,
|
||||||
|
const clear_candidate_fn & clear_cand,
|
||||||
|
int baseline_cand,
|
||||||
|
double & anchor_ref,
|
||||||
|
const cooldown_opts & cool,
|
||||||
|
const char * cell_label) {
|
||||||
|
int total_wait = 0;
|
||||||
|
|
||||||
|
for (int sleep_s = 2; total_wait < cool.max_wait; sleep_s = std::min(sleep_s * 2, 32)) {
|
||||||
|
const int this_wait = std::min(sleep_s, cool.max_wait - total_wait);
|
||||||
|
|
||||||
|
fprintf(stderr, "# COOL sleeping %ds (%ds/%ds) %s\n", this_wait, total_wait + this_wait, cool.max_wait,
|
||||||
|
cell_label);
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(this_wait));
|
||||||
|
total_wait += this_wait;
|
||||||
|
|
||||||
|
const double a = measure_one(backend, cell, reps, set_cand, clear_cand, baseline_cand);
|
||||||
|
if (a <= 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// a faster anchor means the machine got cooler than anything seen so far: adopt it
|
||||||
|
if (a < anchor_ref) {
|
||||||
|
anchor_ref = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a <= anchor_ref * (1.0 + cool.eps)) {
|
||||||
|
fprintf(stderr, "# COOL steady after %ds %s\n", total_wait, cell_label);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "# COOL gave up after %ds %s\n", total_wait, cell_label);
|
||||||
|
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_result measure_cell(ggml_backend_t backend,
|
||||||
|
const perf_cell & cell,
|
||||||
|
int reps,
|
||||||
|
const std::vector<int> & order,
|
||||||
|
const set_candidate_fn & set_cand,
|
||||||
|
const clear_candidate_fn & clear_cand,
|
||||||
|
int baseline_cand,
|
||||||
|
const cooldown_opts & cool,
|
||||||
|
const char * cell_label) {
|
||||||
|
cell_result res;
|
||||||
|
res.t.assign(order.size(), 0.0);
|
||||||
|
|
||||||
|
double anchor_ref = 0.0;
|
||||||
|
|
||||||
|
// anchors accepted as clean, as (value, position in order[]). the dirty window starts
|
||||||
|
// at the position of the last anchor still within eps of anchor_ref, so a downward
|
||||||
|
// drift (anchor_ref dropping) naturally widens the window to the whole cell.
|
||||||
|
std::vector<std::pair<double, size_t>> anchors;
|
||||||
|
|
||||||
|
auto window_start = [&]() -> size_t {
|
||||||
|
for (size_t i = anchors.size(); i-- > 0;) {
|
||||||
|
if (anchors[i].first <= anchor_ref * (1.0 + cool.eps)) {
|
||||||
|
return anchors[i].second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // no clean anchor left -> the whole cell is suspect
|
||||||
|
};
|
||||||
|
|
||||||
|
int retries_left = cool.max_retry;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < order.size(); ++i) {
|
||||||
|
res.t[order[i]] = measure_one(backend, cell, reps, set_cand, clear_cand, order[i]);
|
||||||
|
|
||||||
|
if (i % 4 != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double a = measure_one(backend, cell, reps, set_cand, clear_cand, baseline_cand);
|
||||||
|
if (a <= 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.anchor_min = res.anchor_min > 0.0 ? std::min(res.anchor_min, a) : a;
|
||||||
|
res.anchor_max = std::max(res.anchor_max, a);
|
||||||
|
|
||||||
|
if (anchor_ref == 0.0) {
|
||||||
|
anchor_ref = a;
|
||||||
|
anchors.push_back({ a, i });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double drift = std::fabs(a - anchor_ref) / anchor_ref;
|
||||||
|
|
||||||
|
// a cooler anchor than any so far becomes the reference: whatever was measured
|
||||||
|
// before it was measured on a hotter machine
|
||||||
|
if (a < anchor_ref) {
|
||||||
|
anchor_ref = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drift <= cool.drift) {
|
||||||
|
anchors.push_back({ a, i });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "# WARN throttling? anchor drift %.1f%% %s\n", 100.0 * drift, cell_label);
|
||||||
|
|
||||||
|
if (!cool.enabled) {
|
||||||
|
anchors.push_back({ a, i });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retries_left <= 0) {
|
||||||
|
fprintf(stderr, "# DIRTY retries exhausted %s\n", cell_label);
|
||||||
|
res.trusted = false;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t dirty_from = window_start();
|
||||||
|
|
||||||
|
const double a_cool =
|
||||||
|
cool_until_steady(backend, cell, reps, set_cand, clear_cand, baseline_cand, anchor_ref, cool, cell_label);
|
||||||
|
if (a_cool <= 0.0) {
|
||||||
|
res.trusted = false;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the converged anchor is the only clean one now; re-measure the dirty window from it
|
||||||
|
anchors.clear();
|
||||||
|
anchors.push_back({ a_cool, dirty_from });
|
||||||
|
|
||||||
|
retries_left--;
|
||||||
|
|
||||||
|
fprintf(stderr, "# REDO candidates %zu..%zu %s\n", dirty_from, i, cell_label);
|
||||||
|
for (size_t j = dirty_from; j <= i; ++j) {
|
||||||
|
res.t[order[j]] = measure_one(backend, cell, reps, set_cand, clear_cand, order[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ggml-backend.h"
|
||||||
|
#include "ggml-cpp.h"
|
||||||
|
#include "ggml.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// A prebuilt graph replicated to amortize dispatch and synchronization overhead.
|
||||||
|
struct perf_cell {
|
||||||
|
ggml_context_ptr ctx;
|
||||||
|
ggml_backend_buffer_ptr buf;
|
||||||
|
ggml_cgraph * gf = nullptr;
|
||||||
|
int n_runs = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
using build_graph_fn = std::function<ggml_tensor *(ggml_context *)>;
|
||||||
|
using init_tensors_fn = std::function<void(ggml_context *)>;
|
||||||
|
using op_flops_fn = std::function<uint64_t(ggml_tensor *)>;
|
||||||
|
|
||||||
|
perf_cell build_perf_cell(ggml_backend_t backend,
|
||||||
|
const build_graph_fn & build,
|
||||||
|
const init_tensors_fn & init,
|
||||||
|
const op_flops_fn & flops);
|
||||||
|
|
||||||
|
double time_cell_median(ggml_backend_t backend, const perf_cell & cell, int reps);
|
||||||
|
|
||||||
|
struct cooldown_opts {
|
||||||
|
bool enabled = true;
|
||||||
|
double drift = 0.10; // anchor drift that triggers a cooldown
|
||||||
|
double eps = 0.03; // anchor tolerance to call the GPU cool again
|
||||||
|
int max_wait = 120; // seconds of cooling per cell before giving up
|
||||||
|
int max_retry = 2; // re-measure rounds per cell before giving up
|
||||||
|
};
|
||||||
|
|
||||||
|
using set_candidate_fn = std::function<void(int)>;
|
||||||
|
using clear_candidate_fn = std::function<void()>;
|
||||||
|
|
||||||
|
struct cell_result {
|
||||||
|
std::vector<double> t;
|
||||||
|
bool trusted = true;
|
||||||
|
double anchor_min = 0.0;
|
||||||
|
double anchor_max = 0.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Times candidates in order while using baseline_cand as a thermal-drift anchor.
|
||||||
|
cell_result measure_cell(ggml_backend_t backend,
|
||||||
|
const perf_cell & cell,
|
||||||
|
int reps,
|
||||||
|
const std::vector<int> & order,
|
||||||
|
const set_candidate_fn & set_cand,
|
||||||
|
const clear_candidate_fn & clear_cand,
|
||||||
|
int baseline_cand,
|
||||||
|
const cooldown_opts & cool,
|
||||||
|
const char * cell_label);
|
||||||
@@ -0,0 +1,641 @@
|
|||||||
|
#include "fa-vec.h"
|
||||||
|
|
||||||
|
#include "bench.h"
|
||||||
|
#include "ggml-backend.h"
|
||||||
|
#include "ggml-metal-tuning.h"
|
||||||
|
#include "ggml.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <random>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// GQA spec-decode shape: enough query heads to keep the GPU busy so the Q>1 K/V-reuse
|
||||||
|
// benefit is visible. nh KV heads, nr2 query heads each, nr3 batches.
|
||||||
|
static const int FA_NH = 4;
|
||||||
|
static const int FA_NR2 = 8;
|
||||||
|
static const int FA_NR3 = 1;
|
||||||
|
|
||||||
|
struct fa_shape {
|
||||||
|
int dk;
|
||||||
|
int dv;
|
||||||
|
int ne01; // query rows
|
||||||
|
int ne11; // KV length
|
||||||
|
ggml_type type_kv;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mirrors test_flash_attn_ext::build_graph for the subset this tuner sweeps
|
||||||
|
// (mask=true, sinks=false, prec=F32, type_K==type_V, no permute)
|
||||||
|
static ggml_tensor * fa_build_graph(ggml_context * ctx, const fa_shape & s) {
|
||||||
|
const int64_t dk_padded = GGML_PAD(s.dk, ggml_blck_size(s.type_kv));
|
||||||
|
const int64_t dv_padded = GGML_PAD(s.dv, ggml_blck_size(s.type_kv));
|
||||||
|
|
||||||
|
ggml_tensor * q = ggml_new_tensor_4d(ctx, GGML_TYPE_F32, dk_padded, s.ne01, FA_NH * FA_NR2, FA_NR3);
|
||||||
|
ggml_set_name(q, "q");
|
||||||
|
|
||||||
|
// K/V are views of a 2x-tall parent, as they are of the KV cache in production
|
||||||
|
ggml_tensor * k0 = ggml_new_tensor_4d(ctx, s.type_kv, dk_padded, 2 * s.ne11, FA_NH, FA_NR3);
|
||||||
|
ggml_tensor * k = ggml_view_4d(ctx, k0, dk_padded, s.ne11, FA_NH, FA_NR3, k0->nb[1], k0->nb[2], k0->nb[3], 0);
|
||||||
|
ggml_set_name(k, "k");
|
||||||
|
|
||||||
|
ggml_tensor * v = nullptr;
|
||||||
|
if (dk_padded == 576 && dv_padded == 512) {
|
||||||
|
// MLA: the V cache is a sub-view of the K cache
|
||||||
|
v = ggml_view_4d(ctx, k, dv_padded, s.ne11, FA_NH, FA_NR3, k->nb[1], k->nb[2], k->nb[3], 0);
|
||||||
|
} else {
|
||||||
|
ggml_tensor * v0 = ggml_new_tensor_4d(ctx, s.type_kv, dv_padded, 2 * s.ne11, FA_NH, FA_NR3);
|
||||||
|
v = ggml_view_4d(ctx, v0, dv_padded, s.ne11, FA_NH, FA_NR3, v0->nb[1], v0->nb[2], v0->nb[3], 0);
|
||||||
|
}
|
||||||
|
ggml_set_name(v, "v");
|
||||||
|
|
||||||
|
ggml_tensor * m = ggml_new_tensor_4d(ctx, GGML_TYPE_F16, s.ne11, s.ne01, 1, FA_NR3);
|
||||||
|
ggml_set_name(m, "m");
|
||||||
|
|
||||||
|
ggml_tensor * out = ggml_flash_attn_ext(ctx, q, k, v, m, 1.0f / sqrtf((float) s.dk), 0.0f, 0.0f);
|
||||||
|
ggml_flash_attn_ext_set_prec(out, GGML_PREC_F32);
|
||||||
|
ggml_set_name(out, "out");
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t fa_op_flops(const fa_shape & s) {
|
||||||
|
// Q*K^T is ne01 x dk x ne11, P*V is ne01 x ne11 x dv, per head
|
||||||
|
return (uint64_t) 2 * FA_NH * FA_NR2 * s.ne01 * (s.dk + s.dv) * s.ne11 * FA_NR3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fa_init_uniform(ggml_tensor * t, std::mt19937 & rng, float min, float max) {
|
||||||
|
const size_t nels = ggml_nelements(t);
|
||||||
|
|
||||||
|
std::vector<float> data(nels);
|
||||||
|
std::uniform_real_distribution<float> dist(min, max);
|
||||||
|
for (size_t i = 0; i < nels; i++) {
|
||||||
|
data[i] = dist(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->type == GGML_TYPE_F32) {
|
||||||
|
ggml_backend_tensor_set(t, data.data(), 0, nels * sizeof(float));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GGML_ASSERT(ggml_is_quantized(t->type) || t->type == GGML_TYPE_F16 || t->type == GGML_TYPE_BF16);
|
||||||
|
GGML_ASSERT(nels % ggml_blck_size(t->type) == 0);
|
||||||
|
|
||||||
|
std::vector<float> imatrix(t->ne[0], 1.0f);
|
||||||
|
const float * im = imatrix.data();
|
||||||
|
if (!ggml_quantize_requires_imatrix(t->type)) {
|
||||||
|
// when the imatrix is optional, exercise both paths; pick via one of the random numbers
|
||||||
|
if (data[0] > 0.5f * (min + max)) {
|
||||||
|
im = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t blck_size = ggml_blck_size(t->type);
|
||||||
|
const size_t n_blocks = nels / blck_size;
|
||||||
|
|
||||||
|
std::vector<uint8_t> dataq(ggml_row_size(t->type, nels));
|
||||||
|
ggml_quantize_chunk(t->type, data.data(), dataq.data(), 0, n_blocks, blck_size, im);
|
||||||
|
|
||||||
|
ggml_backend_tensor_set(t, dataq.data(), 0, dataq.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// mirrors init_tensor_kq_mask: f16 mask with ~20% of its blocks set to -INF or zero.
|
||||||
|
// the -INF blocks are what drives the kernel's skip-INF path, so this pattern is
|
||||||
|
// load-bearing for the timings, not just for numerics.
|
||||||
|
static void fa_init_kq_mask(ggml_tensor * t, std::mt19937 & rng, float min, float max) {
|
||||||
|
GGML_ASSERT(t->type == GGML_TYPE_F16);
|
||||||
|
|
||||||
|
const int32_t ne0 = (int32_t) t->ne[0];
|
||||||
|
const int32_t ne1 = (int32_t) t->ne[1];
|
||||||
|
const int32_t ne2 = (int32_t) t->ne[2];
|
||||||
|
const int32_t ne3 = (int32_t) t->ne[3];
|
||||||
|
|
||||||
|
std::vector<float> data_f32(size_t(ne0) * ne1 * ne2 * ne3);
|
||||||
|
std::vector<ggml_fp16_t> data_f16(size_t(ne0) * ne1 * ne2 * ne3);
|
||||||
|
|
||||||
|
std::uniform_real_distribution<float> dis(min, max);
|
||||||
|
for (size_t i = 0; i < data_f32.size(); i++) {
|
||||||
|
data_f32[i] = dis(rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int blck0 = 128;
|
||||||
|
const int blck1 = 64;
|
||||||
|
|
||||||
|
const int n_inf_zero_blocks = 0.2 * (ne0 * ne1 * ne2 * ne3) / (blck0 * blck1);
|
||||||
|
|
||||||
|
for (int b = 0; b < n_inf_zero_blocks; b++) {
|
||||||
|
const int p3 = (int) (rng() % ne3);
|
||||||
|
const int p2 = (int) (rng() % ne2);
|
||||||
|
const int p1 = (int) (rng() % ne1);
|
||||||
|
const int p0 = (int) (rng() % ne0);
|
||||||
|
|
||||||
|
const bool inf = rng() & 1;
|
||||||
|
|
||||||
|
for (int i1 = 0; i1 < blck1 && p1 + i1 < ne1; i1++) {
|
||||||
|
const int idx = p3 * ne2 * ne1 * ne0 + p2 * ne1 * ne0 + (p1 + i1) * ne0 + p0;
|
||||||
|
|
||||||
|
for (int i0 = 0; i0 < blck0 && p0 + i0 < ne0; i0++) {
|
||||||
|
data_f32[idx + i0] = inf ? -INFINITY : 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ggml_fp32_to_fp16_row(data_f32.data(), data_f16.data(), ne0 * ne1 * ne2 * ne3);
|
||||||
|
|
||||||
|
ggml_backend_tensor_set(t, data_f16.data(), 0, data_f16.size() * sizeof(ggml_fp16_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned fa_cell_seed(const fa_shape & s, unsigned base) {
|
||||||
|
unsigned h = base;
|
||||||
|
for (int v : { s.dk, s.dv, s.ne01, s.ne11, (int) s.type_kv }) {
|
||||||
|
h = h * 1000003u + (unsigned) v;
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fa_init_tensors(ggml_context * ctx, const fa_shape & s, unsigned base_seed) {
|
||||||
|
std::mt19937 rng(fa_cell_seed(s, base_seed));
|
||||||
|
|
||||||
|
for (ggml_tensor * t = ggml_get_first_tensor(ctx); t != NULL; t = ggml_get_next_tensor(ctx, t)) {
|
||||||
|
if (t->view_src != NULL) {
|
||||||
|
continue; // views share their parent's data
|
||||||
|
}
|
||||||
|
if (strcmp(t->name, "m") == 0) {
|
||||||
|
fa_init_kq_mask(t, rng, -1.0f, 1.0f);
|
||||||
|
} else {
|
||||||
|
fa_init_uniform(t, rng, -1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using set_override_t = void (*)(int, int);
|
||||||
|
using clear_override_t = void (*)(void);
|
||||||
|
using bucket_t = int (*)(int64_t);
|
||||||
|
using baseline_ne_t = int (*)(int, int);
|
||||||
|
using device_token_t = const char * (*) (ggml_backend_dev_t);
|
||||||
|
|
||||||
|
struct fa_procs {
|
||||||
|
set_override_t set_ov = nullptr;
|
||||||
|
clear_override_t clr_ov = nullptr;
|
||||||
|
bucket_t ne11_bucket = nullptr;
|
||||||
|
bucket_t ne01_bucket = nullptr;
|
||||||
|
baseline_ne_t baseline_ne = nullptr;
|
||||||
|
device_token_t dev_token = nullptr;
|
||||||
|
|
||||||
|
bool ok() const { return set_ov && clr_ov && ne11_bucket && ne01_bucket && baseline_ne && dev_token; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static fa_procs fa_resolve_procs(ggml_backend_dev_t dev) {
|
||||||
|
ggml_backend_reg_t reg = ggml_backend_dev_backend_reg(dev);
|
||||||
|
|
||||||
|
fa_procs p;
|
||||||
|
p.set_ov = (set_override_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_set_fa_vec_override");
|
||||||
|
p.clr_ov =
|
||||||
|
(clear_override_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_clear_fa_vec_override");
|
||||||
|
p.ne11_bucket = (bucket_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_fa_vec_ne11_bucket");
|
||||||
|
p.ne01_bucket = (bucket_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_fa_vec_ne01_bucket");
|
||||||
|
p.baseline_ne =
|
||||||
|
(baseline_ne_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_fa_vec_baseline_ne");
|
||||||
|
p.dev_token = (device_token_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_metal_tuning_device_token");
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fa_filter_has(const char * filter, const char * name) {
|
||||||
|
if (!filter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string f = std::string(",") + filter + ",";
|
||||||
|
|
||||||
|
return f.find(std::string(",") + name + ",") != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct fa_cand {
|
||||||
|
int Q, NE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fa_point {
|
||||||
|
int dk, dv, ne11, ne01;
|
||||||
|
std::vector<double> t;
|
||||||
|
};
|
||||||
|
|
||||||
|
// base_i identifies the (Q=1, baseline NE) anchor configuration.
|
||||||
|
static std::vector<fa_cand> fa_build_cands(const fa_procs & procs, int dk, int dv, int & base_i) {
|
||||||
|
const int base_ne = procs.baseline_ne(dk, dv);
|
||||||
|
|
||||||
|
std::vector<fa_cand> cands;
|
||||||
|
base_i = -1;
|
||||||
|
for (int ne : ggml_metal_tuning::fa_vec_legal_ne(dk, dv)) {
|
||||||
|
for (int Q : { 1, 2, 4 }) {
|
||||||
|
if (Q == 1 && ne == base_ne) {
|
||||||
|
base_i = (int) cands.size();
|
||||||
|
}
|
||||||
|
cands.push_back({ Q, ne });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GGML_ASSERT(base_i >= 0);
|
||||||
|
|
||||||
|
return cands;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tuner_fa_vec_run(ggml_backend_t backend, ggml_backend_dev_t dev, const tuner_opts & opts) {
|
||||||
|
const fa_procs procs = fa_resolve_procs(dev);
|
||||||
|
if (!procs.ok()) {
|
||||||
|
fprintf(stderr, "error: metal fa_vec tuning procs unavailable\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * dev_token = procs.dev_token(dev);
|
||||||
|
|
||||||
|
struct shape_t {
|
||||||
|
int dk, dv;
|
||||||
|
};
|
||||||
|
|
||||||
|
const shape_t shapes[] = {
|
||||||
|
{ 32, 32 },
|
||||||
|
{ 64, 64 },
|
||||||
|
{ 96, 96 },
|
||||||
|
{ 128, 128 },
|
||||||
|
{ 192, 192 },
|
||||||
|
{ 192, 128 },
|
||||||
|
{ 256, 256 },
|
||||||
|
{ 320, 256 },
|
||||||
|
{ 512, 512 },
|
||||||
|
{ 576, 512 }
|
||||||
|
};
|
||||||
|
// nsg is a pipeline specialization constant (1 up to ne11=2048, 2 up to 4096, 4 above), so ne11
|
||||||
|
// bucket 1 takes two samples to cover both of its regimes. Bucket 0 is not sampled at all: the
|
||||||
|
// runtime leaves short KV at baseline, so no measurement there can reach the table.
|
||||||
|
const int ne11_rep[] = { 2048, 3072, 8192, 32768 };
|
||||||
|
const int ne01_rep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 16 }; // point buckets (1-4) + tail mod-4 cycle + anchor
|
||||||
|
|
||||||
|
struct dtype_t {
|
||||||
|
ggml_type type;
|
||||||
|
const char * token;
|
||||||
|
};
|
||||||
|
|
||||||
|
const dtype_t dtypes[] = {
|
||||||
|
{ GGML_TYPE_F16, "GGML_TYPE_F16" },
|
||||||
|
{ GGML_TYPE_Q4_0, "GGML_TYPE_Q4_0" },
|
||||||
|
{ GGML_TYPE_Q4_1, "GGML_TYPE_Q4_1" },
|
||||||
|
{ GGML_TYPE_Q5_0, "GGML_TYPE_Q5_0" },
|
||||||
|
{ GGML_TYPE_Q5_1, "GGML_TYPE_Q5_1" },
|
||||||
|
{ GGML_TYPE_Q8_0, "GGML_TYPE_Q8_0" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const double TUNE_TAU = 0.05; // max POINTWISE regret to ride a domain default
|
||||||
|
const double TUNE_THETA = 1.05; // min AGGREGATE bucket speedup vs baseline to tune at all
|
||||||
|
|
||||||
|
const cooldown_opts cool = {
|
||||||
|
opts.cooldown, opts.cool_drift, opts.cool_eps, opts.cool_max_wait, opts.cool_max_retry,
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr, "seed=%u reps=%d cooldown=%s (drift=%.2f eps=%.2f max_wait=%ds max_retry=%d)\n", opts.seed,
|
||||||
|
opts.reps, cool.enabled ? "on" : "off", cool.drift, cool.eps, cool.max_wait, cool.max_retry);
|
||||||
|
fprintf(stderr, "device token: %s\n", dev_token);
|
||||||
|
|
||||||
|
int n_untrusted = 0;
|
||||||
|
|
||||||
|
// stdout carries nothing but table rows, so the whole stream pastes into fa_vec_tuned_table
|
||||||
|
for (const auto & dtype : dtypes) {
|
||||||
|
const ggml_type type_kv = dtype.type;
|
||||||
|
if (!fa_filter_has(opts.dtype_filter, ggml_type_name(type_kv))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "\n### dtype=%s\n", ggml_type_name(type_kv));
|
||||||
|
|
||||||
|
std::vector<fa_point> pts;
|
||||||
|
|
||||||
|
for (auto s : shapes) {
|
||||||
|
if (!fa_filter_has(opts.dk_filter, std::to_string(s.dk).c_str())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_i = 0;
|
||||||
|
std::vector<fa_cand> cands = fa_build_cands(procs, s.dk, s.dv, base_i);
|
||||||
|
|
||||||
|
for (int ne11 : ne11_rep) {
|
||||||
|
for (int ne01 : ne01_rep) {
|
||||||
|
const fa_shape sh = { s.dk, s.dv, ne01, ne11, type_kv };
|
||||||
|
|
||||||
|
perf_cell cell = build_perf_cell(
|
||||||
|
backend, [&](ggml_context * ctx) { return fa_build_graph(ctx, sh); },
|
||||||
|
[&](ggml_context * ctx) { fa_init_tensors(ctx, sh, opts.seed); },
|
||||||
|
[&](ggml_tensor *) { return fa_op_flops(sh); });
|
||||||
|
|
||||||
|
if (cell.gf == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// randomize candidate order to decorrelate thermal drift across the cell
|
||||||
|
std::vector<int> order((size_t) cands.size());
|
||||||
|
for (size_t i = 0; i < order.size(); ++i) {
|
||||||
|
order[i] = (int) i;
|
||||||
|
}
|
||||||
|
std::shuffle(order.begin(), order.end(), std::mt19937(fa_cell_seed(sh, opts.seed)));
|
||||||
|
|
||||||
|
char label[128];
|
||||||
|
snprintf(label, sizeof(label), "dk=%d ne11=%d", s.dk, ne11);
|
||||||
|
|
||||||
|
cell_result r = measure_cell(
|
||||||
|
backend, cell, opts.reps, order, [&](int i) { procs.set_ov(cands[i].Q, cands[i].NE); },
|
||||||
|
[&]() { procs.clr_ov(); }, base_i, cool, label);
|
||||||
|
|
||||||
|
if (r.anchor_min > 0.0) {
|
||||||
|
fprintf(stderr, "# noise dk=%d dv=%d ne11=%d ne01=%d spread=%.1f%%\n", s.dk, s.dv, ne11, ne01,
|
||||||
|
100.0 * (r.anchor_max - r.anchor_min) / r.anchor_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!r.trusted) {
|
||||||
|
n_untrusted++;
|
||||||
|
fprintf(stderr, "# DROP untrusted cell dk=%d dv=%d ne11=%d ne01=%d\n", s.dk, s.dv, ne11, ne01);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int best_i = -1;
|
||||||
|
for (size_t i = 0; i < cands.size(); ++i) {
|
||||||
|
if (r.t[i] > 0.0 && (best_i < 0 || r.t[i] < r.t[best_i])) {
|
||||||
|
best_i = (int) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const double base_t = r.t[base_i];
|
||||||
|
const bool keep = best_i >= 0 && base_t > 0.0 && r.t[best_i] < base_t * 0.98;
|
||||||
|
|
||||||
|
fprintf(stderr, "# dtype=%s dk=%d dv=%d ne11=%d ne01=%d:", ggml_type_name(type_kv), s.dk, s.dv,
|
||||||
|
ne11, ne01);
|
||||||
|
for (size_t i = 0; i < cands.size(); ++i) {
|
||||||
|
fprintf(stderr, " Q%dNE%d=%.1f%s", cands[i].Q, cands[i].NE, r.t[i],
|
||||||
|
(int) i == best_i ? "*" : "");
|
||||||
|
}
|
||||||
|
if (keep) {
|
||||||
|
fprintf(stderr, " => Q%d,NE%d %.2fx\n", cands[best_i].Q, cands[best_i].NE,
|
||||||
|
base_t / r.t[best_i]);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " => baseline\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
pts.push_back({ s.dk, s.dv, ne11, ne01, r.t });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compress into pasteable rows. per (dk,dv) and ne01 domain {decode==1, batch>=2},
|
||||||
|
// emit one ne11-collapsed default cfg (ne11_b=-1) plus a per-bucket exception wherever the
|
||||||
|
// default's pointwise regret vs the bucket target exceeds TUNE_TAU, or the default is not
|
||||||
|
// admissible for that bucket (see never_slower / admissible below).
|
||||||
|
std::vector<std::string> rows_out;
|
||||||
|
char rbuf[192];
|
||||||
|
|
||||||
|
for (auto s : shapes) {
|
||||||
|
if (!fa_filter_has(opts.dk_filter, std::to_string(s.dk).c_str())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_i = 0;
|
||||||
|
std::vector<fa_cand> cands = fa_build_cands(procs, s.dk, s.dv, base_i);
|
||||||
|
|
||||||
|
struct bkt_t {
|
||||||
|
int b11, b01, Ti;
|
||||||
|
std::vector<double> agg;
|
||||||
|
std::vector<const fa_point *> bp;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A config may represent a bucket only if it is no slower than baseline at every point that
|
||||||
|
// bucket covers. The aggregate gate below sums absolute times, so it can pass on the aligned
|
||||||
|
// and deep points while a misaligned ne01 pays the mod-Q padding. Nothing measured, nothing
|
||||||
|
// proven: a bucket with no surviving sample admits baseline only.
|
||||||
|
auto never_slower = [&](const std::vector<const fa_point *> & bp, int i) {
|
||||||
|
if (i == base_i) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bp.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const auto * p : bp) {
|
||||||
|
if (p->t[i] <= 0.0 || p->t[base_i] <= 0.0 || p->t[i] > p->t[base_i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The padded-row waste ceil(n/Q)*Q/n is largest at the smallest ne01 of each residue class
|
||||||
|
// mod Q, so one of a bucket's first Q values carries the worst padding it can ever see, and
|
||||||
|
// that value has to be sampled. Otherwise the bucket bounds nothing: a config picked on the
|
||||||
|
// aligned ne01=8,16 says nothing about ne01=9. This covers the padding term only - the
|
||||||
|
// per-row cost varies with ne01 too - so it is a floor on the evidence, not a proof.
|
||||||
|
auto admissible = [&](const std::vector<const fa_point *> & bp, int b01, int i) {
|
||||||
|
if (!never_slower(bp, i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const int Q = cands[i].Q;
|
||||||
|
if (Q == 1) {
|
||||||
|
return true; // one row per threadgroup, no padding to witness
|
||||||
|
}
|
||||||
|
int lo = bp[0]->ne01;
|
||||||
|
for (const auto * p : bp) {
|
||||||
|
lo = std::min(lo, p->ne01);
|
||||||
|
}
|
||||||
|
while (lo > 1 && procs.ne01_bucket(lo - 1) == b01) {
|
||||||
|
lo--; // walk down to where this bucket's runtime domain starts
|
||||||
|
}
|
||||||
|
int wit = lo;
|
||||||
|
double wmax = 0.0;
|
||||||
|
for (int n = lo; n < lo + Q && procs.ne01_bucket(n) == b01; ++n) {
|
||||||
|
const int padded = ((n + Q - 1) / Q) * Q;
|
||||||
|
const double w = (double) padded / n;
|
||||||
|
if (w > wmax) {
|
||||||
|
wmax = w;
|
||||||
|
wit = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto * p : bp) {
|
||||||
|
if (p->ne01 == wit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::set<std::pair<int, int>> buckets;
|
||||||
|
for (int ne11 : ne11_rep) {
|
||||||
|
const int b11 = procs.ne11_bucket(ne11);
|
||||||
|
if (b11 == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int ne01 : ne01_rep) {
|
||||||
|
buckets.insert({ b11, procs.ne01_bucket(ne01) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bkt_t> bks;
|
||||||
|
for (const auto & bb : buckets) {
|
||||||
|
const int b11 = bb.first, b01 = bb.second;
|
||||||
|
|
||||||
|
std::vector<const fa_point *> bp;
|
||||||
|
for (const auto & p : pts) {
|
||||||
|
if (p.dk == s.dk && p.dv == s.dv && procs.ne11_bucket(p.ne11) == b11 &&
|
||||||
|
procs.ne01_bucket(p.ne01) == b01) {
|
||||||
|
bp.push_back(&p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "# bucket dk=%d dv=%d ne11_b=%d ne01_b=%d samples=%zu\n", s.dk, s.dv, b11, b01,
|
||||||
|
bp.size());
|
||||||
|
if (bp.empty()) {
|
||||||
|
// nothing to check a config against, so pin the bucket to baseline instead of
|
||||||
|
// letting the ne11-collapsed domain default ride in unmeasured
|
||||||
|
fprintf(stderr, "# WARN empty bucket dk=%d dv=%d ne11_b=%d ne01_b=%d -> baseline\n", s.dk, s.dv,
|
||||||
|
b11, b01);
|
||||||
|
bks.push_back({ b11, b01, base_i, std::vector<double>(cands.size(), 0.0), {} });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> agg(cands.size(), 0.0), worst(cands.size(), 0.0);
|
||||||
|
for (const auto * p : bp) {
|
||||||
|
double bestt = 0.0;
|
||||||
|
for (size_t i = 0; i < cands.size(); ++i) {
|
||||||
|
if (p->t[i] > 0.0 && (bestt == 0.0 || p->t[i] < bestt)) {
|
||||||
|
bestt = p->t[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < cands.size(); ++i) {
|
||||||
|
agg[i] += p->t[i];
|
||||||
|
if (p->t[i] > 0.0 && bestt > 0.0) {
|
||||||
|
worst[i] = std::max(worst[i], p->t[i] / bestt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int robust = -1, oracle_pick = -1;
|
||||||
|
for (size_t i = 0; i < cands.size(); ++i) {
|
||||||
|
auto tighter = [&](int j) {
|
||||||
|
return j < 0 || worst[i] < worst[j] ||
|
||||||
|
(worst[i] == worst[j] && (cands[i].Q < cands[j].Q ||
|
||||||
|
(cands[i].Q == cands[j].Q && cands[i].NE < cands[j].NE)));
|
||||||
|
};
|
||||||
|
if (tighter(oracle_pick)) {
|
||||||
|
oracle_pick = (int) i;
|
||||||
|
}
|
||||||
|
if (admissible(bp, b01, (int) i) && tighter(robust)) {
|
||||||
|
robust = (int) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool tune = robust != base_i && agg[base_i] > 0.0 && agg[robust] > 0.0 &&
|
||||||
|
agg[base_i] / agg[robust] >= TUNE_THETA;
|
||||||
|
|
||||||
|
// report what the no-harm rule cost this bucket, but only when it changed the outcome:
|
||||||
|
// a sweep on another machine then shows where the winner loses, instead of just
|
||||||
|
// emitting a smaller table
|
||||||
|
const bool refused = oracle_pick != robust && oracle_pick != base_i && agg[base_i] > 0.0 &&
|
||||||
|
agg[oracle_pick] > 0.0 && agg[base_i] / agg[oracle_pick] >= TUNE_THETA;
|
||||||
|
if (refused) {
|
||||||
|
double over = 0.0;
|
||||||
|
int at11 = 0, at01 = 0;
|
||||||
|
for (const auto * p : bp) {
|
||||||
|
if (p->t[base_i] > 0.0 && p->t[oracle_pick] / p->t[base_i] - 1.0 > over) {
|
||||||
|
over = p->t[oracle_pick] / p->t[base_i] - 1.0;
|
||||||
|
at11 = p->ne11;
|
||||||
|
at01 = p->ne01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (over > 0.0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"# reject dk=%d dv=%d ne11_b=%d ne01_b=%d Q%dNE%d: +%.2f%% vs baseline at "
|
||||||
|
"ne11=%d ne01=%d\n",
|
||||||
|
s.dk, s.dv, b11, b01, cands[oracle_pick].Q, cands[oracle_pick].NE, 100.0 * over, at11,
|
||||||
|
at01);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "# reject dk=%d dv=%d ne11_b=%d ne01_b=%d Q%dNE%d: no padding witness\n", s.dk,
|
||||||
|
s.dv, b11, b01, cands[oracle_pick].Q, cands[oracle_pick].NE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bks.push_back({ b11, b01, tune ? robust : base_i, agg, bp });
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointwise regret of default cfg d vs the bucket target: a ratio-of-sums lets a
|
||||||
|
// default that wins on aligned ne01 hide a large penalty on a misaligned point
|
||||||
|
auto reg_pointwise = [&](const bkt_t * b, int d) {
|
||||||
|
double r = 0.0;
|
||||||
|
for (const auto * p : b->bp) {
|
||||||
|
const double td = p->t[d], tT = p->t[b->Ti];
|
||||||
|
if (td > 0.0 && tT > 0.0) {
|
||||||
|
r = std::max(r, td / tT - 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int dom = 0; dom <= 1; ++dom) { // 0 = decode (ne01==1), 1 = batch (ne01>=2)
|
||||||
|
std::vector<const bkt_t *> db;
|
||||||
|
for (const auto & b : bks) {
|
||||||
|
if ((dom == 0) == (b.b01 == 0)) {
|
||||||
|
db.push_back(&b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (db.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default cfg = the one minimizing (#rows, total achieved time, Q, NE)
|
||||||
|
int bestD = -1, bestRows = 1 << 30;
|
||||||
|
double bestTot = 0.0;
|
||||||
|
for (size_t d = 0; d < cands.size(); ++d) {
|
||||||
|
int rows = ((int) d != base_i) ? 1 : 0;
|
||||||
|
double tot = 0.0;
|
||||||
|
for (const auto * b : db) {
|
||||||
|
if (reg_pointwise(b, (int) d) > TUNE_TAU || !admissible(b->bp, b->b01, (int) d)) {
|
||||||
|
rows++;
|
||||||
|
tot += b->agg[b->Ti];
|
||||||
|
} else {
|
||||||
|
tot += b->agg[d];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bool better =
|
||||||
|
bestD < 0 || rows < bestRows ||
|
||||||
|
(rows == bestRows &&
|
||||||
|
(tot < bestTot ||
|
||||||
|
(tot == bestTot && (cands[d].Q < cands[bestD].Q ||
|
||||||
|
(cands[d].Q == cands[bestD].Q && cands[d].NE < cands[bestD].NE)))));
|
||||||
|
if (better) {
|
||||||
|
bestD = (int) d;
|
||||||
|
bestRows = rows;
|
||||||
|
bestTot = tot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestD != base_i) {
|
||||||
|
snprintf(rbuf, sizeof(rbuf), " { { %s, %s, %d, %d, -1, %d }, { %d, %d } },", dev_token,
|
||||||
|
dtype.token, s.dk, s.dv, dom, cands[bestD].Q, cands[bestD].NE);
|
||||||
|
rows_out.emplace_back(rbuf);
|
||||||
|
}
|
||||||
|
for (const auto * b : db) {
|
||||||
|
if (reg_pointwise(b, bestD) <= TUNE_TAU && admissible(b->bp, b->b01, bestD)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snprintf(rbuf, sizeof(rbuf), " { { %s, %s, %d, %d, %d, %d }, { %d, %d } },", dev_token,
|
||||||
|
dtype.token, s.dk, s.dv, b->b11, b->b01, cands[b->Ti].Q, cands[b->Ti].NE);
|
||||||
|
rows_out.emplace_back(rbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto & r : rows_out) {
|
||||||
|
printf("%s\n", r.c_str());
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_untrusted > 0) {
|
||||||
|
fprintf(stderr, "\n%d cells excluded as untrusted (see DROP lines above)\n", n_untrusted);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ggml-backend.h"
|
||||||
|
|
||||||
|
struct tuner_opts {
|
||||||
|
const char * dtype_filter = nullptr; // comma-separated, e.g. "f16,q4_0"; null = all
|
||||||
|
const char * dk_filter = nullptr; // comma-separated dk values, e.g. "128,192"; null = all
|
||||||
|
int reps = 7;
|
||||||
|
unsigned seed = 1234;
|
||||||
|
bool cooldown = true;
|
||||||
|
double cool_drift = 0.10;
|
||||||
|
double cool_eps = 0.03;
|
||||||
|
int cool_max_wait = 120;
|
||||||
|
int cool_max_retry = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns false only when the required Metal proc bridges are unavailable.
|
||||||
|
bool tuner_fa_vec_run(ggml_backend_t backend, ggml_backend_dev_t dev, const tuner_opts & opts);
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
#include "fa-vec.h"
|
||||||
|
#include "ggml-backend.h"
|
||||||
|
#include "ggml.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
struct tuner_def {
|
||||||
|
const char * name;
|
||||||
|
bool (*run)(ggml_backend_t, ggml_backend_dev_t, const tuner_opts &);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const tuner_def k_tuners[] = {
|
||||||
|
{ "fa-vec", tuner_fa_vec_run },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(const char * argv0) {
|
||||||
|
printf("usage: %s <tuner> [options]\n", argv0);
|
||||||
|
printf("\n");
|
||||||
|
printf(" offline kernel tuner for the Metal backend: sweeps a kernel's config grid and\n");
|
||||||
|
printf(" prints pasteable table rows for the machine it runs on. never a pass/fail test.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" tuners:\n");
|
||||||
|
printf(" fa-vec flash-attn vec (Q,NE) for ggml-metal-tuning.cpp\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" options:\n");
|
||||||
|
printf(" -b <name> backend device (default: first Metal device)\n");
|
||||||
|
printf(" --dtype <list> restrict KV dtypes, e.g. f16,q4_0 (default: all)\n");
|
||||||
|
printf(" --dk <list> restrict head sizes, e.g. 128,192 (default: all)\n");
|
||||||
|
printf(" --reps <n> timed reps per candidate, odd for an exact median (default: 7)\n");
|
||||||
|
printf(" --seed <n> RNG seed; per-cell seeds mix it with the shape (default: 1234)\n");
|
||||||
|
printf(" --no-cooldown do not pause/re-measure on thermal drift, only warn\n");
|
||||||
|
printf(" --cool-drift <f> anchor drift that triggers a cooldown (default: 0.10)\n");
|
||||||
|
printf(" --cool-eps <f> anchor tolerance to consider the GPU cool again (default: 0.03)\n");
|
||||||
|
printf(" --cool-max-wait <s> give up cooling a cell after this many seconds (default: 120)\n");
|
||||||
|
printf(" --cool-max-retry <n> re-measure rounds per cell before giving up (default: 2)\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" the table goes to stdout, all diagnostics to stderr:\n");
|
||||||
|
printf(" %s fa-vec > rows.txt 2> sweep.log\n", argv0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char ** argv) {
|
||||||
|
const char * tuner = nullptr;
|
||||||
|
const char * bname = nullptr;
|
||||||
|
tuner_opts opts;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
const char * a = argv[i];
|
||||||
|
if (strcmp(a, "-h") == 0 || strcmp(a, "--help") == 0) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
} else if (strcmp(a, "-b") == 0 && i + 1 < argc) {
|
||||||
|
bname = argv[++i];
|
||||||
|
} else if (strcmp(a, "--dtype") == 0 && i + 1 < argc) {
|
||||||
|
opts.dtype_filter = argv[++i];
|
||||||
|
} else if (strcmp(a, "--dk") == 0 && i + 1 < argc) {
|
||||||
|
opts.dk_filter = argv[++i];
|
||||||
|
} else if (strcmp(a, "--reps") == 0 && i + 1 < argc) {
|
||||||
|
opts.reps = atoi(argv[++i]);
|
||||||
|
} else if (strcmp(a, "--seed") == 0 && i + 1 < argc) {
|
||||||
|
opts.seed = (unsigned) strtoul(argv[++i], nullptr, 10);
|
||||||
|
} else if (strcmp(a, "--no-cooldown") == 0) {
|
||||||
|
opts.cooldown = false;
|
||||||
|
} else if (strcmp(a, "--cool-drift") == 0 && i + 1 < argc) {
|
||||||
|
opts.cool_drift = atof(argv[++i]);
|
||||||
|
} else if (strcmp(a, "--cool-eps") == 0 && i + 1 < argc) {
|
||||||
|
opts.cool_eps = atof(argv[++i]);
|
||||||
|
} else if (strcmp(a, "--cool-max-wait") == 0 && i + 1 < argc) {
|
||||||
|
opts.cool_max_wait = atoi(argv[++i]);
|
||||||
|
} else if (strcmp(a, "--cool-max-retry") == 0 && i + 1 < argc) {
|
||||||
|
opts.cool_max_retry = atoi(argv[++i]);
|
||||||
|
} else if (a[0] != '-' && tuner == nullptr) {
|
||||||
|
tuner = a;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "error: unrecognized or incomplete argument: %s\n\n", a);
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tuner == nullptr) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (opts.reps < 1) {
|
||||||
|
fprintf(stderr, "error: --reps must be >= 1\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tuner_def * t = nullptr;
|
||||||
|
for (const auto & cand : k_tuners) {
|
||||||
|
if (strcmp(tuner, cand.name) == 0) {
|
||||||
|
t = &cand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t == nullptr) {
|
||||||
|
fprintf(stderr, "error: unknown tuner: %s\n\n", tuner);
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ggml_backend_load_all();
|
||||||
|
|
||||||
|
ggml_backend_dev_t dev = nullptr;
|
||||||
|
for (size_t i = 0; i < ggml_backend_dev_count(); i++) {
|
||||||
|
ggml_backend_dev_t d = ggml_backend_dev_get(i);
|
||||||
|
if (bname) {
|
||||||
|
if (strcmp(ggml_backend_dev_name(d), bname) == 0) {
|
||||||
|
dev = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (strncmp(ggml_backend_dev_name(d), "MTL", 3) == 0) {
|
||||||
|
dev = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev == nullptr) {
|
||||||
|
fprintf(stderr, "error: no %s device found\n", bname ? bname : "Metal");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ggml_backend_t backend = ggml_backend_dev_init(dev, nullptr);
|
||||||
|
if (backend == nullptr) {
|
||||||
|
fprintf(stderr, "error: failed to init backend %s\n", ggml_backend_dev_name(dev));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "device: %s (%s)\n", ggml_backend_dev_name(dev), ggml_backend_dev_description(dev));
|
||||||
|
|
||||||
|
const bool ok = t->run(backend, dev, opts);
|
||||||
|
|
||||||
|
ggml_backend_free(backend);
|
||||||
|
ggml_quantize_free();
|
||||||
|
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user