mirror of
https://github.com/mudler/LocalAI.git
synced 2026-06-28 10:27:30 -04:00
Move ALL paged-attention content out of the stock backend/cpp/llama-cpp backend and into backend/cpp/llama-cpp-localai-paged, so the stock backend is pure upstream llama.cpp and the paged backend owns and applies its own vendored patch series. - Delete the dead early-exploration scaffold backend/cpp/llama-cpp/paged/ (kernel/w4a16 Marlin scaffold, standalone paged_kv_manager, bench/loadgen, its own 0001-0002 patches, dense-era design docs, tests). Zero references repo-wide. - Move backend/cpp/llama-cpp/patches/ (the 28-patch paged series + paged/README + 3 operational docs, plus the kernel/ scaffold patch and the top-level paged README/BENCHMARKS) to backend/cpp/llama-cpp-localai-paged/patches/. The stock backend keeps no patches/ dir; it had no non-paged base patches. - Purify the stock backend: remove the LLAMA_PAGED make variable, the patches/paged apply loop, and the LLAMA_PAGED passthrough to prepare.sh; remove the paged-series handling from prepare.sh. The stock llama.cpp target now only clones the pin and applies its own (currently empty) base patches/ series. The runtime paged option hooks in the shared grpc-server.cpp are untouched (inert without the patches). - The paged backend's Makefile now applies its OWN patches/paged/0*.patch onto each freshly cloned tree via strict git apply (apply-paged-patches), after the copied stock infra clones the pin and applies base patches. - Repoint every reference to the old patches/paged path: the upstream canary workflow + apply script, bump_deps.yaml, gallery/index.yaml, the docs, backend/index.yaml, backend-matrix.yml, the top-level Makefile comments, and the moved PIN_SYNC / README docs. Drop the now-removed LLAMA_PAGED=on build-toggle from comments. Verified: the full 28-patch series applies strict-clean (git apply, exit 0) to a clean ggml-org/llama.cpp checkout at the pinned c299a92c, and the repointed canary apply script resolves and applies the series end to end. Assisted-by: Claude:opus-4.8 [Claude Code] Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
60 lines
2.7 KiB
C++
60 lines
2.7 KiB
C++
// Host-side unit test for the paged-pool burst-reclaim fix (patch 0024).
|
|
// Compiles paged-kv-manager.cpp directly; no ggml / llama / GPU dependency.
|
|
//
|
|
// Fix-1 PagedKVManager::truncate(seq, n_keep) reclaims the trailing blocks
|
|
// beyond ceil(n_keep/bs) (ref-counted), so a partial tail seq_rm no
|
|
// longer strands blocks whose cells were cleared.
|
|
// Fix-2 defrag_free_pool() relinks the free queue into ascending block-id
|
|
// order once the pool is fully idle, undoing a burst's scrambled frees
|
|
// so a later prefill pops physically contiguous blocks again.
|
|
|
|
#include "paged-kv-manager.h"
|
|
#include <cstdio>
|
|
|
|
using paged::PagedKVManager;
|
|
|
|
int main() {
|
|
int rc = 0;
|
|
|
|
// ---- Fix-1: truncate reclaims the trailing block suffix -----------------
|
|
{
|
|
PagedKVManager m(/*num_blocks=*/64, /*block_size=*/16, /*caching=*/true);
|
|
const size_t f0 = m.num_free_blocks(); // 63 (block 0 reserved as null)
|
|
m.allocate(0, 512); // ceil(512/16)=32 blocks
|
|
const size_t f1 = m.num_free_blocks(); // 31
|
|
m.truncate(0, 256); // keep ceil(256/16)=16, free 16
|
|
const size_t f2 = m.num_free_blocks(); // 47
|
|
printf("[unit Fix-1] free=%zu alloc512=%zu truncate256=%zu reclaimed=%zu (expect 16)\n",
|
|
f0, f1, f2, f2 - f1);
|
|
if (f2 - f1 != 16) rc = 1;
|
|
m.truncate(0, 16); // keep 1 block, free 15 more
|
|
const size_t f3 = m.num_free_blocks(); // 62
|
|
printf("[unit Fix-1] truncate16=%zu (expect %zu)\n", f3, f0 - 1);
|
|
if (f3 != f0 - 1) rc = 1;
|
|
m.free(0);
|
|
if (m.num_free_blocks() != f0) { printf("[unit Fix-1] free mismatch\n"); rc = 1; }
|
|
}
|
|
|
|
// ---- Fix-2: defrag restores ascending popleft order ---------------------
|
|
{
|
|
PagedKVManager m(/*num_blocks=*/64, /*block_size=*/16, /*caching=*/false);
|
|
for (int s = 0; s < 8; ++s) m.allocate(s, 16); // pop blocks 1..8
|
|
const int scrambled[8] = {3, 7, 1, 5, 0, 6, 2, 4}; // free out of order
|
|
for (int i = 0; i < 8; ++i) m.free(scrambled[i]);
|
|
m.defrag_free_pool(); // all idle -> compact
|
|
m.allocate(100, 16 * 3); // pop 3 blocks
|
|
const auto bt = m.block_table(100);
|
|
bool asc = true;
|
|
printf("[unit Fix-2] post-defrag block_table:");
|
|
for (size_t i = 0; i < bt.size(); ++i) {
|
|
printf(" %d", bt[i]);
|
|
if (i && bt[i] < bt[i - 1]) asc = false;
|
|
}
|
|
printf(" ascending=%s (expect YES)\n", asc ? "YES" : "NO");
|
|
if (!asc) rc = 1;
|
|
}
|
|
|
|
printf("UNIT %s\n", rc == 0 ? "PASS" : "FAIL");
|
|
return rc;
|
|
}
|