engram: batch-cosine Adapter/Strategy/Factory over ggml, supersedes hand-rolled PR #114
El SDK CI - dev / build-and-test (pull_request) Failing after 4m29s
El SDK CI - dev / build-and-test (pull_request) Failing after 4m29s
Stop hand-rolling GPU kernels for batch cosine similarity — use ggml (the MIT-licensed compute library underneath llama.cpp, installed standalone via Homebrew) as the preferred backend, without ripping out PR #114's carefully-verified hand-rolled Metal shader. Structure: one stable public adapter (eg_cosine_batch.h, zero #ifdef at call sites) backed by three selectable concrete Strategies behind an internal vtable (eg_cosine_batch_strategy.h) chosen by a Factory (eg_cosine_batch.c): - eg_cosine_batch_strategy_ggml.c — NEW. ggml + dynamically-loaded Metal backend plugin (ggml_backend_load_all_from_path + ggml_mul_mat for the batched dot product), gather/scatter around the -2.0 sentinel contract. - eg_cosine_batch_strategy_metal_hand.m — PR #114's original hand-rolled Metal shader bridge, preserved almost verbatim, now one strategy among several rather than the only option. eg_cosine_batch.metal kept byte-identical to the original. - eg_cosine_batch_strategy_cpu.c — universal always-false fallback (direct descendant of PR #114's eg_metal_cosine_stub.c). Selection: EL_COSINE_BATCH_STRATEGY=ggml|metal|cpu|auto (default: ggml first, then hand-rolled Metal, then CPU — first available wins), plus back-compat EL_METAL_COSINE=0 to disable every GPU-backed strategy. build_vindex_bench.sh compiles all three strategies on Darwin, CPU-fallback-only elsewhere. vindex_bench.c now reports BRUTE-GGML and BRUTE-METAL side by side against the same CPU oracle, on the same dataset, in one run (real numbers vs. real store snapshot in the PR body).
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/* eg_cosine_batch_strategy_cpu.c — plain-C, zero-dependency universal
|
||||
* fallback strategy. Always returns false / unavailable. Direct descendant
|
||||
* of PR #114's eg_metal_cosine_stub.c, generalized from "the Metal stub" to
|
||||
* "the strategy vtable's universal fallback entry" now that multiple real
|
||||
* strategies can exist.
|
||||
*
|
||||
* Always compiled, on every platform. On Darwin builds it is the last-resort
|
||||
* strategy the factory falls back to when neither ggml nor the hand-rolled
|
||||
* Metal strategy is available at runtime (no device, compile failure, ...).
|
||||
* On non-Darwin builds it is the ONLY strategy compiled in at all — no
|
||||
* Objective-C, no Metal frameworks, no ggml/Metal backend plugin — so
|
||||
* eg_cosine_batch()/eg_cosine_batch_multi() always return false there and
|
||||
* every call site's existing CPU fallback runs unconditionally, exactly as
|
||||
* before this PR.
|
||||
*/
|
||||
#include "eg_cosine_batch_strategy.h"
|
||||
|
||||
static bool cpu_available(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cpu_batch(const float* query, int32_t qdim,
|
||||
const float* const* node_ptrs, const int32_t* node_dims,
|
||||
int32_t n, double* out_scores) {
|
||||
(void)query; (void)qdim; (void)node_ptrs; (void)node_dims; (void)n; (void)out_scores;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cpu_batch_multi(const float* queries, int32_t qdim, int32_t nq,
|
||||
const float* const* node_ptrs, const int32_t* node_dims,
|
||||
int32_t n, double* out_scores) {
|
||||
(void)queries; (void)qdim; (void)nq; (void)node_ptrs; (void)node_dims; (void)n; (void)out_scores;
|
||||
return false;
|
||||
}
|
||||
|
||||
static const EgCosineBatchStrategy g_cpu_strategy = {
|
||||
.name = "cpu-fallback",
|
||||
.available = cpu_available,
|
||||
.batch = cpu_batch,
|
||||
.batch_multi = cpu_batch_multi,
|
||||
};
|
||||
|
||||
const EgCosineBatchStrategy* eg_cosine_batch_strategy_cpu(void) {
|
||||
return &g_cpu_strategy;
|
||||
}
|
||||
Reference in New Issue
Block a user