--- name: ocannl-debug-tracing description: How to get debug output out of OCANNL: kernel/routine runtime logs, generated code artifacts, and ppx_minidebug tracing of library internals such as the shape/row solver. Use when debugging a wrong-value or wrong-shape result and you need to see generated code, per-kernel logs, or the solver's decisions. --- # Debugging and Logging - Set `debug_log_from_routines=true` in config for kernel/routine-level debugging - Use `log_level=2` for verbose ppx_minidebug output - CUDA debugging requires `Utils.capture_stdout_logs` wrapper - Debug files generated in `log_files//` (this process's subdirectory is cleaned on startup by default) - Runtime logs from kernel execution are written to `--.log` (e.g., `cuda-0-0.log`) inside that subdirectory - Generated code files in `build_files//` show high-level `.cd`, intermediate `.ll`, and backend-specific `.c`/`.cu` files See the `Important Debug Settings` list in `AGENTS.md` for the config keys that enable these artifacts. ## Tracing library internals with ppx_minidebug (e.g. the shape/row solver) - High-level `%debug5_sexp`/`%track5_sexp` etc. log statements are stripped at COMPILE time; each module has its own gate env var: `[%%global_debug_log_level_from_env_var "OCANNL_LOG_LEVEL_ROW"]` at the top of `row.ml`, similarly `..._SHAPE`, `..._TNODE`, `..._ASSIGNMENTS`, `..._CC_BACKEND`, etc. (grep for `global_debug_log_level_from_env_var`) - Every gate is declared as a `preprocessor_deps` `(env_var ...)` of the library whose modules read it (gh-ocannl-628), so setting one re-preprocesses those modules by itself: `OCANNL_LOG_LEVEL_ROW=9 OCANNL_LOG_LEVEL_SHAPE=9 dune build ...`. Adding a gate to a module means adding it to that library's `preprocessor_deps` too, which `test/operations/env_var_deps` checks - At runtime, pass `--ocannl_log_level=9` and run from a directory with an `ocannl_config` on its ancestor path (e.g. `test/config/`); logs land in `log_files/` - Backend choice: the default `debug_backend=db` writes a database supporting structured queries (e.g. print a subtree containing two given terms); `--ocannl_debug_backend=flushing` writes greppable flat text to `log_files/debug.log` and survives crashes mid-trace - Useful flat-text queries: `stage = StageN` lines segment `finish_inference`'s solver passes; track a variable by grepping `Row_var N` / `(id N)` for its transition to `Solved_row`/`Solved_dim`, then inspect the surrounding `unify_row`/`solve_dim_ineq` scope