Results and Metrics
mace.metrics records every loop run in a SQLite database.
examples/mace_end_to_end.py writes to runs/mace_end_to_end.db, mace shell to runs/mace_cli.db, and examples/generic_integrate.py to runs/generic_integrate.db; all accept --db-path.
The one-shot baseline prints its result and records nothing.
Git ignores runs/ and *.db.
Tables
Every insert except into llm_calls uses INSERT OR REPLACE on the table’s primary key, so recording the same row again overwrites it.
llm_calls rows are appended with the next seq.
Table |
Primary key |
Other columns |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
run_idis 12 hex digits.runs.methodnames what ran:macefor a plain loop run, or the baseline or ablation an evaluation run was.runs.task,runs.repeat, andruns.seedidentify the evaluation task and repeat, andruns.metaholds the run’s environment as JSON. A database written before these columns existed gets them empty.iterations.wall_sruns from the start of the planner call to the end of the iteration’s last task, and excludes triage.iterations.usdis the cost of the iteration’s planner, task, and triage calls; see LLM Backends.tasks.build_sandtasks.run_sare the build time and the summed simulation time, andtasks.wall_sis their sum; a reused build counts as 0.tasks.programslists each gate workload run with its verdict, as JSON.tasks.cachesholds the build configuration’s cache map as JSON, andtasks.config_rtlits sorted RTL defines as a JSON list.tasks.rtl_editsholds the unified diff of the RTL edits the build carried, or nothing.tasks.modulenames the module of aunit_testtask.tasks.evidenceholds, for a task that did not pass, the text triage reads: the build flags and their changes from the defaults, then the build’s errors and output tail or the failing simulation’s transcript tail and status log, then the diff of any RTL edits the build carried. It stays after an evaluation job’s cache clear removes the logs.plan_checksholds one row for each look the plan check took at an iteration’s plan that found a problem or removed a define, and for each retry’s look.attemptcounts the plans the iteration asked for,actionisrejected,accepted,kept, orunusable(a planner reply with no plan), andproblemsandstrippedare JSON lists.probesholds one row per narrowing probe, tied to the task whose failure it examined byfailed_task;undonelists the changes the probe put back as JSON, andverdictrepeats the narrowing’s verdict on every row. Probes stay out oftasks.fast_pathshas a row for each iteration whose plan ran as one task:keptis that task anddroppedthe ids of the tasks it replaced, as JSON.directed_testsholds each test atesttask wrote, with its verdict on the design the task built, andtest_checksthe evaluation’s mutation check of each test (see Directed Tests and Directed-Test Evaluation). Inevaluations,hart_cyclesholds an RTL-parameter design’s per-hart cycle counts as JSON,storage_bitsthe flip-flop bits it adds per tile, andnotethe bottleneck line of the MACE proposer that chose it (see RTL-Parameter Searches).llm_callsholds one row per LLM call, numbered in the order the calls finished.phaseisplan,plan_retry(a plan asked for again after the plan check rejected one),task,triage, orpost_mortemfor the loop,agentfor the retry-agent baseline, andproposefor the co-design LLM proposer; a post-mortem call has no iteration.okis 0 for a call that failed; such a call records no tokens.replyholds the reply’s text, such as a plan’sTASK:lines or a triage diagnosis.failures.diagnosisis free text. The triage prompt suggeststest_bug,config_error,timeout,maxcycles,rtl_suspect, andtestbench_mismatch. The loop recordsunknownwhen the reply has noDIAGNOSIS:line, andconfig_changewhen narrowing decided the diagnosis without a triage call. When a run passes after earlier failures, all of its failures are markedrecovered.The post-mortem prompt asks for the assessment
fixable_config,likely_hardware_limitation, orinconclusive.
Run statuses
Status |
Meaning |
|---|---|
|
The run started and has not finished. A killed process leaves its run in this state. |
|
Every task of one iteration passed, or one task’s design passed every gate workload. |
|
|
|
The planner’s reply held no valid task DAG, and the two retries the plan check allows gave none either. |
|
An iteration produced no task results. |
|
A C program in |
|
The generic tile cannot run the core descriptor’s core, or the checkout lacks its files; nothing ran. |
|
An exception stopped the run. |
A run that ends failed or budget_exceeded after at least one iteration gets a post-mortem, unless the LLM’s reply cannot be parsed.
The five metrics
mace.metrics.summary(db, run_id) returns:
Key |
Computed as |
|---|---|
|
Count of |
|
Count of |
|
Count of |
|
Sum of |
|
Sum of |
from mace.metrics import DBReader, all_runs
db = DBReader("runs/mace_end_to_end.db")
for run in all_runs(db):
print(run["run_id"], run["status"], run["successful_tasks"], run["execution_time_s"])
DBReader reads the database with Python’s sqlite3 and starts no Ray. It adds the columns that an older database lacks, such as caches, config_rtl, and reply, then refuses writes.
The loop writes through open_db(path), a CHIA SQLiteNode; the first call on one starts Ray, because CHIA’s profiler looks up its collector actor.
all_runs(db) returns every run, newest first, with its summary merged in.
trace_run(db, run_id) gives one run’s iterations with their tasks and failures.
failure_taxonomy(db, run_id) counts failures by diagnosis.
module_status(db, run_id) gives the latest status of each unit_test module.
get_post_mortem(db, run_id) returns the post-mortem.
mace results
mace results reads the database through DBReader, so it needs no shell session and starts no Ray. It exits with an error when the file does not exist.
Its --db-path default is runs/mace_cli.db, so name the loop script’s database explicitly:
mace results --db-path runs/mace_end_to_end.db
mace results --db-path runs/mace_end_to_end.db --run-id <run_id>
mace results --db-path runs/mace_end_to_end.db --run-id <run_id> --trace
With no other option, it prints one row per run (run_id, core, mesh, status, tasks, iterations, wall_s, usd) and a line with the pass count, total execution time, and total cost.
The tasks column counts passed tasks.
--run-id prints that run’s failure taxonomy.
--trace with --run-id prints the run as a tree: one branch per iteration, the tasks its plan dispatched with their build result and verdict, and a TRIAGE branch when a failure was diagnosed.
--trace without --run-id is an error.
SQL
You can also query the tables directly:
SELECT iteration, task_id, kind, build_success, run_verdict, wall_s
FROM tasks
WHERE run_id = '<run_id>'
ORDER BY iteration, rowid;