@FIR-2216 - llama.cpp: expose ggml perf-summary symbols across ollama's split-binary backend boundary
Summary
Ollama statically links llama-context.cpp into its Go binary via cgo, while the ggml core (ggml.c) and the Tsavorite backend are built into separately dlopen'd shared libraries (libggml-base.so, libggml-tsavorite.so). Several symbols the "GGML Perf Summary" table depends on are defined in ggml.c and were link-time unreachable from llama-context.cpp in that configuration:
ggml_perf_accumulate— undefined reference at link time (table never printed at all).ggml_perf_log_open,ggml_perf_write_detailed_csv,ggml_backend_type— same issue, only surfaced once the detailed (Target/TSI_KERNEL-RUNcolumn) table variant was exercised.
Also, ggml-tsavorite.cpp's existing #ifdef OLLAMA backend struct literal already references .profile, .graph_reserve, .buffer_size, .reset, but ggml-backend-impl.h didn't yet define those ggml_backend_i fields, and ggml_backend_log_profile_info() (declared in ggml-backend.h) had no definition — both needed for that file to even compile under -DOLLAMA.
Changes
include/llama.h,src/llama.cpp: addllama_backend_log_profile(); restore theggml_backend_free(TSAVORITE)call inllama_backend_free().ggml/include/ggml-backend.h,ggml/src/ggml-backend.cpp: addggml_backend_log_profile_info().ggml/src/ggml-backend-impl.h: addgraph_reserve,buffer_size,reset,profilefields tostruct ggml_backend_i.ggml/src/ggml-tsavorite/ggml-tsavorite.cpp: exposeggml_perf_accumulate,ggml_perf_log_open,ggml_perf_write_detailed_csv,ggml_backend_typeviaggml_backend_tsavorite_get_proc_address().src/llama-context.cpp: add a sharedllama_resolve_ggml_proc_address()helper plus#ifdef OLLAMA-gated wrappers (llama_perf_ggml_accumulate,llama_perf_ggml_log_open,llama_perf_ggml_write_detailed_csv,llama_perf_ggml_backend_type) that resolve these symbols dynamically at runtime through the backend registry. Native (non-OLLAMA) builds keep the original direct calls, unchanged.
Scope is intentionally llama.cpp-only. Ollama picks this up via a separate Makefile.sync commit-id bump once this merges -- no ollama-side changes in this PR.
Also included (found while investigating a separate, still-open multi_thread_enable:true intermittent crash in ollama, unrelated to the perf-symbol work above but touching the same file):
- Fix a real data race in
tsi_init_per_txe_state_once(): unsynchronizedstd::vectormutation (packed_args,device_free) on first use from concurrent callers. - Harden
call_triton_matmul_full_packed(): its static descriptor buffers were populated with no synchronization before reaching thetsi_pack_mutex-protected dispatch call.
These are real, standalone concurrency fixes, but do not fully resolve the intermittent multi_thread_enable:true SIGSEGV in the Triton MAT_MUL dispatch path (still under investigation, tracked separately).
Validation
Tested in ollama (posix build, SDK_VERSION=0.4.24), via a temporary local sync pointed at this branch:
- Native llama.cpp posix debug build compiles and links cleanly with all changes (sanity check independent of ollama).
- Ollama posix debug build (
GGML_PERF_DETAIL) — full detail table prints correctly, matching llama.cpp's owntsi-pkg-build.shdev output format:
Verified via=== GGML Perf Summary === Op Target Runs TSI_KERNEL-RUN Total us Avg us ADD OPU 480 30496556 677744 1411.97 MUL OPU 490 30847744 653504 1333.68 RMS_NORM OPU 10 970154 14996 1499.60 MUL_MAT OPU 165 51087589 63340037 383879.01 CONT OPU 240 15149184 16538 68.91 GET_ROWS OPU 30 2201664 2113 70.43 SOFT_MAX OPU 240 15096192 27038 112.66 GLU OPU 240 15274774 696186 2900.78qwen:0.5b, HTTP 200, no crash. - Ollama posix release build (
GGML_PERF_RELEASE) — plain customer-safe table prints correctly, no CPU/OPU breakdown:
Verified via=== GGML Perf Summary === Op Runs Total us Avg us ADD 144 287062 1993.49 MUL 147 558433 3798.86 RMS_NORM 3 37089 12363.00 MUL_MAT 165 61081193 370189.05 CONT 72 16335 226.88 GET_ROWS 9 2070 230.00 SOFT_MAX 72 24200 336.11 GLU 72 545814 7580.75qwen:0.5b, HTTP 200, no crash. - Both tested with
multi_thread_enable:false(the known-stable path);multi_thread_enable:trueremains separately tracked as an open, intermittent issue unrelated to this fix.
Summary by cubic
Restores GGML perf-summary tables in ollama split-binary builds and adds a backend profile hook. Previously llama-context.cpp could not reach ggml_perf_*/ggml_backend_type and printed no tables; now runtime resolution restores detailed and release tables, and exports for detailed CSV are correctly guarded to prevent release build link errors. Addresses FIR-2216.
- Dynamic perf symbols for
ollama:ggml-tsavorite.cppexposesggml_perf_accumulateandggml_backend_typein all perf modes, and exposesggml_perf_log_open/ggml_perf_write_detailed_csvonly underGGML_PERF_DETAIL;src/llama-context.cppadds OLLAMA-only wrappers that resolve these at runtime with atomic caches and retry after late backend registration; nativellama.cppbuilds keep direct calls. - Backend profiling: adds
ggml_backend_log_profile_info()and optionalgraph_reserve,buffer_size,reset,profileinstruct ggml_backend_i. Introducesllama_backend_log_profile()and caches a singleTSAVORITEbackend; tracks when the profile hook finalizes the runtime to avoid double teardown inllama_backend_free(). - Concurrency hardening in
ggml-tsavorite: serializes first-use lazy init intsi_init_per_txe_state_once()via an atomic flag plus mutex; serializescall_triton_matmul_full_packed()descriptor populate+dispatch; on all teardown paths, clearspacked_argsand allscalar_*per‑TXE vectors and resets the init flag to force clean reallocation on the next init. - Rollout: no migration required;
ollamawill pick this via Makefile sync.