Understanding results#
Every kernel KernelFoundry generates, including the failures, is recorded in the results database along with its prompt, the model’s full answer, the measured runtimes and the evaluation log. That record is the main tool for working out why a run went the way it did.
Browse it in the web UI:
kernelfoundry-gui # needs the ui extra: pip install 'kernelfoundry[ui]'
python start_gui.py # equivalent, from a clone
It serves http://localhost:8885. Find your run by the task_name and job_name you set in
config.yaml.
The generation graph#
The central view is a graph of one job, where every circle is a generated kernel:
Colour is how far the candidate got:
Colour
Meaning
Green
Correct and faster than the reference
Blue
Correct, but no faster than the reference
Orange
Compiled, but failed a correctness test
Yellow
Compiled, but the tests timed out
Red
Did not compile
Pink
The build itself timed out
White, black outline
The best kernel of the job
The green/blue split is the one to read first: blue means the model is producing valid kernels and simply not beating the baseline, which is a very different problem from red.
Size is speed: bigger is faster.
Arrows point from parent to child. The kernel at the base of an arrow was included in the prompt as inspiration for the one it points to.
Labels read
i<N>-b<M>: iteration N, branch M. Soi0-b0throughi0-b3are the four branches generated in the first iteration.
Reading the shape of the graph tells you a lot quickly. A wall of red means the model cannot
compile against your build setup. Green but small circles mean it is producing correct kernels
that aren’t faster. A single lineage with no branching means branches_per_iteration is 1.
Per-kernel fields#
Clicking a circle opens everything recorded for that candidate.
Kernel info: task and job name, the iteration it came from, the model that produced it, and the hardware it was benchmarked on.
Runtime stats: computed from the benchmark test in your task.py, not from the profiler
(see Writing tests). Alongside the usual statistics it shows the number of
trials, which varies because fast kernels are benchmarked more times, and the speedup over the
reference measured the same way.
Prompt: what was actually sent to the model. This is the field to check when a run behaves oddly: it shows whether your reference and user instructions really made it into the prompt. The standard structure is intro, user instructions, reference implementation, best kernel so far, parent kernel, language-specific instructions, optimization strategies.
Input code: the reference from your task.
Answer: the model’s complete response, including its reasoning about previous attempts and what it planned to change. Useful for understanding whether it correctly diagnosed the last failure.
Output code: the kernel extracted from the answer. Extraction expects a fenced code block, so a malformed answer shows up as an empty or truncated output here.
Evaluation log: build errors if it did not compile, correctness test output, and the profiling summary. This log is fed back into later prompts when this kernel is sampled as a parent, which is how profiler evidence reaches the next generation.
Where the data lives#
Results are stored in SQLite at runs/kernels.sqlite3, relative to where you started the run.
Change the location with paths.kernels_db_path.
Note
When the MCP server runs in local execution mode from an editor, the database is written relative to your home directory, because that is where the editor launches the server from.
What to do with what you see#
Symptom in the graph |
Likely cause |
Where to look |
|---|---|---|
All red |
Build environment or missing includes |
Evaluation log, build errors |
Compiles, never correct |
Reference mismatch, or tolerances too tight |
Correctness output, |
Correct but no speedup |
Reference is already well optimized, or the benchmark shape is too small to show a difference |
Runtime stats, benchmark shapes |
No profiler data |
Timed trials not inside |
|
One lineage, no branches |
|