JIRA-2258 review aid: Tsavorite-only diff vs upstream 1f368f354 (side-by-side)
gemma4-validation-logs.zip
posix-validation-logs.zip
tsisim-validation-logs.zip
This PR diffs against upstream-1f368f354-baseline, a branch pointing at the exact
upstream commit (1f368f354d9edcfea9fd6a1e0989b3e7335a050f) that
consolidated-patch.patch is generated against. Since both branches share that same
upstream tree, this diff shows only the ~92 files this sync actually changes: the
Tsavorite backend (ggml/src/ggml-tsavorite/), build config (tsi-pkg-build.sh,
tsavorite-model-deployment.yaml, CMake wiring), new regression tests, and the
JIRA-2258 validation docs/logs. Companion branch jira-2258-llama-cpp-sync (PR #162)
carries the same content against origin/master directly, which is why that PR shows
~3150 changed files instead — almost all of it is upstream's own already-reviewed
commit history landing via the version bump, not new content.
Why this sync, and why now
origin/master last touched upstream at 51abc96bdc (2025-09-16). This sync's target,
1f368f354 (2026-08-13), is ~11 months of upstream ggml-org/llama.cpp history later.
That gap — not a preference for a different branch or approach — is why this lands as
one large, version-bump-style sync consolidating every Tsavorite-specific change
accumulated since 2025-09-16 into one patch file (consolidated-patch.patch), rather
than as a normal incremental PR. The stated core motivation was Gemma 4 architecture
support, which didn't exist at all on the pre-sync fork — see the Gemma 4 findings in
docs/jira-2258/gemma4-validation-logs/GEMMA4-VALIDATION-SUMMARY.md.
cubic-dev-ai review remediation (2026-08-26)
All 54 cubic-dev-ai comments across two review passes replied to and resolved
(40 in the first pass, 14 more in a second pass triggered by pushing the first round's
fixes — cubic re-reviews on every push).
- ~40 fixed directly: CMake unquoted-
STREQUAL/$ENV{}bugs (the kind that break
the wholecmakeconfigure, not just the guarded branch), missingGGML_APIon
ggml_backend_cleanup(), an inverted log-level filter inggml_log_internal(), a
NaN/Inf-vs-tolerance check that silently passed bad kernel output, backend-cleanup
ordering fixed via aBackendCleanupGuardRAII pattern (tools/cli/cli.cpp,
tools/completion/completion.cpp,tools/server/server.cpp), the.profile
backend callback missing itsbackendparameter,api_versionnever set for
non-OLLAMAGGML_BACKEND_DLbuilds, a duplicate perf-summary print in
common_perf_print(), a regex inmodel-rerun.pymatching the wrong log line,
LLAMA_OPENSSLsilently defaulting OFF,ggml-tsavorite.hshipping a public header
that depended on an uninstalled private header, plus several doc fixes (missing
SDK_VERSIONexports, a nonexistentTSI-VERSIONsetting, missing
UPSTREAM_BASE_COMMITfrom the review-scope doc). - 1 false positive: a
.gitmodules/ggml-tsi-kernelgitlink flagged as
mismatched — confirmed valid viagit ls-tree HEAD, no fix needed. - 3 real bugs found while verifying the fixes above, not flagged by cubic directly:
llama-cli/llama-serverwere never built at all underGGML_TSAVORITE=ON,
in posix or FPGA, since this sync landed — a nesting bug intools/CMakeLists.txt
(the old fork builtmain,cli's pre-refactor name, outside the Tsavorite
exclusion guard; this sync's port put the newcli/serversubdirectories
inside it by accident). This silently brokemodel-rerun.py(added in this
same PR), which callsbuild-posix/bin/llama-cli. Fixed by movingui/cli/
server/mtmdout from under the exclusion, and fixing the FPGA.tzpackaging
step (it only knew to copyllama-completion) to include the newly-buildable
binaries too.CMAKE_FIND_ROOT_PATHis a 4-entry CMake list (the ARM toolchain's own sysroot
search path), not a scalar. The first attempt at a cubic-suggested rpath-link fix
used it as one anyway, which corrupted the FPGA link
(ld: ... Is a directory) — caught by actually rebuilding, not just trusting a
greencmake configure. Fixed by moving the rpath-link flags to a single
add_link_options()call in the top-levelCMakeLists.txt, so it applies to
every target viatsi-pkg-build.shor the manualcmake -B build-fpga ...
flow documented in the README/docs/build.md.llama-clihung forever on any non-interactive invocation (piped/redirected
output, no controlling TTY — exactly howmodel-rerun.py, added in this same PR,
invokes it viasubprocess.check_output()).cli-context.cpp's main loop, once
the initial-pprompt is consumed, callsread_input()for the next turn and
treats an empty returned buffer as "blank line, keep waiting" — correct for a real
interactive TTY session, but on a non-TTY stdingetwchar()hits EOF instantly and
forever, so the loop spins at ~100% CPU rewriting the>prompt indefinitely,
never terminating. This is pure upstream code (cli-context.cppisn't part of the
Tsavorite patch) that was simply never exercised before tonight, sincellama-cli
was never buildable under Tsavorite until bug 1 above was fixed. Caught by actually
running the freshly-built binary non-interactively, not just confirming it linked.
Fixed by checkingfeof(stdin)before deciding to continue vs. break out of the
loop — distinguishes genuine end-of-input from an interactively-submitted blank
line, which were previously indistinguishable from the loop's point of view.
- A separate, more serious bug caught in the second review pass: an earlier fix
had added a globalset -etotsi-pkg-build.shto make a narrow error-propagation
gap more reliable. cubic correctly flagged that as worse than the problem it solved —
verified empirically: sourcing this script withset -eactive and hitting any
failing command (not just insidedie()) terminates the calling shell, not just
this script, and skips the cleanup trap entirely. Reverted; the narrower gap it was
trying to close is left as a documented follow-up instead. - 3 real findings deliberately left unfixed (real, but risky enough that a
drive-by fix without dedicated regression testing would be reckless — flagged in the
GitHub replies for a deliberate follow-up decision, not silently dropped):ggml_backend_igained new callbacks (PR #158, already merged, ollama's
split-binary boundary depends on it) without bumpingGGML_BACKEND_API_VERSION
(still2) — a real ABI risk for any old dynamically-loaded backend.so.ggml-backend.cpp's view-op scheduling forcing both a view node and its source
onto the CPU backend is not a new bug — it's the deliberate fix from #120 (the
revert of the graph-split optimization that crashed Qwen and hid OPU usage, #118).struct ggml_tensor's size/layout changing underGGML_PERF/GGML_PERF_RELEASE/
GGML_PERF_DETAIL(also from #158) is safe inside this repo's own build, but a
real hazard for external consumers of the installed publicggml.h+
libggml.sothat don't define the same flag.
Full rebuild verification after every round: posix + FPGA both clean (0 errors),
llama-cli/llama-server/llama-completion all present and packaged into
tsi-ggml-0.4.24.tz.
Posix re-validation (2026-08-26, post-remediation)
None of the fixes above touch compute kernels, but re-ran the full model set anyway
since real bugs were found and fixed along the way:
| Model | Result | Duration | Generated text |
|---|---|---|---|
tinyllama-vo-5m-para.gguf | ✅ 0 warnings | 5s | My cat's name is Tim. He |
Gemma3-270M-F32.gguf | ✅ 0 warnings | 33s | My cat's name is "Cat" |
Tiny-Llama-v0.3-FP32-1.1B-F32.gguf | ✅ 0 warnings | 3m55s | My cat's name is Luna. |
Llama3.2:1B-1.2B-F32.gguf | ✅ 0 warnings | 3m59s | My cat's name is "Bella" |
qwen2-0_5b-instruct-q5_k_m.gguf | ✅ 0 warnings | 1m30s | My cat's name is Muffy. She |
Qwen2.5-0.5B-Q4_K_M.gguf | ✅ 0 warnings | 1m25s | My cat's name is Zane. He |
Gemma4-e2b-5.1B-Q4_K_M.gguf | ⚠️ known upstream bug, not a regression -- fails to load (wrong number of tensors), independently confirmed against ggml-org/llama.cpp#27349 | 4s | (fails to load) |
Gemma4-12b-Q4_K_M.gguf | ✅ 0 warnings | 29m18s | My cat's name is **"Luna0 (matches the already-documented Tsavorite-vs-CPU formatting divergence, not corruption) |
7/8 models pass cleanly with zero warnings; the 8th (Gemma4-e2b) fails identically to before this PR's changes, a pre-existing upstream loading bug unrelated to the Tsavorite backend (see the Gemma 4 investigation this PR already contains for detail).
Raw logs gzipped and attached to this PR description rather than committed to the
repo tree. llama-cli smoke-tested end to end for the first time (it was never
buildable under Tsavorite before this fix): clean run, user_dram_size_gb=16 correctly read, generated "I'm, exited cleanly in 6s (previously spun forever on any non-interactive invocation -- see the cli-context.cpp fix above).
Review this PR's file-by-file diff for the actual code review of the ~92 files that
matter. Once approved here, the same content lands via #162.
Summary by cubic
Review-only branch for JIRA-2258 that diffs against the exact upstream baseline consolidated-patch.patch is generated from, exposing only the ~93 files this sync actually changes instead of the ~3150-file diff against master. Do not merge this branch; the real merge is jira-2258-llama-cpp-sync.
What changed
- Carries the full Tsavorite delta as
consolidated-patch.patch, withUPSTREAM_BASE_COMMITpinning its regeneration base. - Adds the backend (
ggml/src/ggml-tsavorite/), build tooling (tsi-pkg-build.sh,tsavorite-model-deployment.yaml, CMake wiring), repro tools underexamples/simple/, and amodel-rerun.pyvalidation harness. - Fixes llama-cli and llama-server building under
GGML_TSAVORITE(they previously never built). - Makes FPGA rpath-link a single global
add_link_options()call and routesTOOLBOX_DIRoverrides (normalized to an absolute path) through oneTSAVORITE_TOOLBOX_ROOTfor both include and link roots. - Removes
set -efromtsi-pkg-build.sh; sourcing it could kill the caller's shell. - Fixes llama-cli's 100% CPU spin on piped, non-TTY input by tracking EOF separately from blank lines via a
bool* eofout-param; the loop breaks on genuine EOF (getline failure/Ctrl+D/WEOF), and the earlierisatty()heuristic that exited early on embedded blank lines is removed. - Makes
ggml_backend_cleanup()explicit(void)to fix an upstream-Werror=strict-prototypesCI failure. - Fixes validation findings: non-128-byte-aligned broadcast chunking, 2D scalar broadcast, and unaligned-memory warnings.
- Adds
GGML_PERF-guarded op profiling with a dedicated Tsavorite summary, aGGML_LOG_LEVEL_TSAVORITElog level, and backend profile/cleanup hooks. - Skips upstream examples and tests that don't build on Tsavorite via
GGML_TSAVORITECMake guards. - Raises the
user_dram_size_gbdeployment default from 8 to 16. - Keeps posix, gemma4, and tsisim validation summaries under
docs/jira-2258/: 4/4 posix models are byte-identical old vs new and Gemma 4 12b loads; raw per-run logs are attached to this PR instead of committed.