Repository navigation
refactor(rocm): move the rocm model catalog renderer out of examine_report_text.rs - #892
Conversation
…eport_text.rs examine_report_text.rs held two unrelated halves: the `rocm examine` report plus the engine-inventory listing, and the `rocm model` catalog renderer. The two do not call each other, and the file was one line under the planned module-size gate. Move the catalog half into model_catalog_text.rs: the two renderers, their `append_model_*` writers, the fit and manual-alternative helpers, `format_bytes` and `format_gib`, and `once_per_call`. This is a pure move; the `rocm model` output is byte-identical. main.rs imports the renderers and `format_bytes` from the new module, so chat.rs, storage.rs and automations.rs keep reaching them as `crate::...`. `model_registry_adapter_availability_note` becomes `pub(crate)` only because the engine-status test that stays in examine_report_text.rs calls it. `missing_packaged_engine_reason` is used by both halves and stays at the crate root, imported by each. The 18 tests whose subject is the catalog moved with it under their existing names. proptest finds saved cases by the test's source file, so the `format_bytes` seed moves from proptest-regressions/main.txt to model_catalog_text.txt; a deliberately unparsable line appended to the moved file was reported by proptest at that path, then removed. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
… module docs Add the model_catalog_text.rs entry to docs/architecture.md, rewrite the examine_report_text.rs entry and its module doc to list only what it still owns, and update the model_fit.rs and model_readiness.rs mentions that named examine_report_text.rs as the reader of the platform gate and the verbose fit labels. The architecture entry also records that the format_bytes proptest seed file is keyed by the test's source file. Comments and documentation only; no code changes. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
…catalog module The architecture entry cited the format_bytes proptest seed file as a bare path; make it a relative link. model_catalog_text.rs imports PlatformRuleOut and engine_ruled_out_by_platform_with, not engine_ruled_out_by_platform, so say so in the model_fit.rs doc and its architecture entry, re-wrap an over-wide comment line there, and fix the count of crate-root items named in the examine_report_text.rs doc (four, not three). Comments and documentation only; no code changes. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for the catalog-renderer module extraction.
No open issues 🎉
What changed in this PR
Separates the rocm model catalog renderer from examine and engine-inventory reporting, reducing module size without changing CLI behavior.
Changes:
- Moves catalog rendering, formatting helpers, and 18 existing tests into
model_catalog_text.rs. - Updates crate-root imports and relocates the proptest regression seed to match the moved test.
- Refreshes module comments and architecture documentation to describe the new boundaries.
| File | Description |
|---|---|
docs/architecture.md |
Documents the catalog module and updated dependencies. |
apps/rocm/src/model_fit.rs |
Updates comments to name both platform-gate consumers. |
apps/rocm/src/model_catalog_text.rs |
Houses the relocated catalog renderer, helpers, and tests. |
apps/rocm/src/main.rs |
Registers the new module and redirects imports. |
apps/rocm/src/examine_report_text.rs |
Removes catalog code while retaining examine and engine reporting. |
apps/rocm/proptest-regressions/model_catalog_text.txt |
Preserves the saved failure seed at the moved test’s expected path. |
Review effort: Balanced
juhovainio
left a comment
There was a problem hiding this comment.
I compared the removed lines in examine_report_text.rs against the added lines in model_catalog_text.rs. The function bodies, doc comments and all 18 tests are identical. The only differences are the module docs, imports, the license header and test scaffolding, and the visibility change below. This is a diff-only read: I didn't build or run anything locally, and I'm relying on CI plus your byte-identical rocm model output capture.
No blocking issues. Two small notes, neither needs to hold the merge:
model_registry_adapter_availability_noteis widened topub(crate)only becauselinux_only_engine_runtime_status_is_explicit_on_native_windowsstays behind. You already call this out. Moving that test's second assertion in a follow-up would let the function go private again.- The
docs/architecture.mdline saying the catalog "shares onlyrecipe_display_ref" frommodel_readinessis loosely true. The moved file keeps its own privaterecipe_display_refwrapper that delegates to it. This was already the case before the PR, so a wording tweak is optional.
FYI: renaming the proptest seed file means proptest now actually replays bytes = 1048525 for format_bytes_renders_a_size_in_its_own_unit. It passes in CI, so it's a positive change, just worth knowing about.
On CI, the only failure I saw is the Strix Halo E2E at bench.feature:71 (GPU not drained after 120s), which looks like a runner problem rather than anything in this move. The MI300X and W7900 E2E jobs were still pending when I looked.
Signed-off-by: Jussi Elo <jussi.elo@amd.com> # Conflicts: # docs/architecture.md
…readiness The architecture entry said the catalog renderer "shares only" curated_alternatives and recipe_display_ref. That is loosely true: the renderer calls curated_alternatives directly, but reaches recipe_display_ref through a private one-line wrapper of the same name in model_catalog_text.rs. Say so, so the two names are not read as two direct imports. Docs only. Signed-off-by: Jussi Elo <jussi.elo@amd.com>
Signed-off-by: Jussi Elo <jussi.elo@amd.com> # Conflicts: # docs/architecture.md
|
Thanks for the approval and the notes. On |
Summary
apps/rocm/src/examine_report_text.rsheld two halves that never call each other: therocm examinereport plus the engine-inventory listing, and the renderer behindrocm model/rocm model --verbose. At 1,499 production lines (header comment and imports included) it sat one line under the planned 1,500-line module-size gate, and two open PRs (#678, #695) add to it. This moves therocm modelcatalog renderer into its own module,model_catalog_text.rs, so each half can be read and changed on its own. It is a pure move: no behaviour change, and the output ofrocm model,rocm models,rocm model --verboseand--helpis byte-identical before and after (captured with the built binary fromorigin/mainand from this branch, same host, compared withcmp).What moved
Everything from
model_catalog_platform_headingtoformat_gibinexamine_report_text.rsis one contiguous span, moved verbatim into the new file with its doc comments and#[allow(dead_code)]attributes.render_model_registry_text_with_context_and_host,render_model_registry_verbose_text_with_context_and_hostmodel_catalog_text.rspub(crate)as beforeformat_bytesmodel_catalog_text.rspub(crate)as beforemodel_registry_adapter_availability_notemodel_catalog_text.rspub(crate)(see below)model_catalog_platform_heading,model_catalog_header,model_recipe_memory_label,model_recipe_gpu_fit_labelmodel_catalog_text.rsappend_model_recipe_registry_source,append_model_recipe_metadata_lines,append_model_engine_recipe_settings_lines,append_model_recipe_staleness_lines,append_model_artifact_lines,append_artifact_source_policy_lines,append_model_host_ram_fit_lines,append_model_fit_lines,append_manual_alternative_lines,append_model_engine_support_linesmodel_catalog_text.rsartifact_source_policy_label,format_list_or_none,format_string_map_or_none,format_gib,manual_alternative_recommendations,recipe_is_manual_fit,recipe_display_ref,preferred_engine_action_target,model_registry_reason,once_per_callmodel_catalog_text.rsAgainst the symbol list in the original plan: nothing in that list had gone missing or moved elsewhere. Five symbols in the span were not on the list and moved with it because they only serve the catalog:
append_model_recipe_staleness_lines,append_model_host_ram_fit_lines,append_model_fit_lines,append_manual_alternative_linesandonce_per_call.engine_runtime_is_native_windows_unsupported, which the old module doc and architecture entry still listed, no longer exists in the code, so the rewritten docs do not name it.One helper is shared with the half that stays:
missing_packaged_engine_reasonis called by bothappend_engine_detect_summary(stays) andappend_model_engine_support_lines(moved). It lives at the crate root and is imported by both modules; nothing is duplicated.Visibility: only
model_registry_adapter_availability_notewidens, from private topub(crate), becauselinux_only_engine_runtime_status_is_explicit_on_native_windows(which stays, see below) calls it. Outside users are unchanged:main.rsimports the two renderers andformat_bytesfrom the new module, andchat.rs,storage.rsandautomations.rskeep reaching them ascrate::<name>, so the only consumer line that changed ismain.rs'suse.Tests
The 18 tests whose primary subject is the catalog moved with it and keep their leaf names:
format_bytes_steps_up_instead_of_printing_1024_of_the_smaller_unit, theformat_bytes_renders_a_size_in_its_own_unitproperty test with itsBYTE_UNITSconstant andbyte_count_strategygenerator,model_catalog_platform_heading_marks_the_host_gpu_in_ascii,render_model_registry_text_lists_builtin_recipes,render_model_registry_text_shows_fit_when_gpu_known,model_catalog_header_only_names_source_for_configured_index,render_model_registry_verbose_text_keeps_diagnostics,model_recipe_artifact_lines_surface_signed_index_metadata,render_model_registry_text_reports_host_ram_fit,render_model_registry_text_reports_supported_and_unsupported_gpu_fit,verbose_model_listing_shows_aim_gpu_families_and_token_requirement,engine_action_target_follows_what_serve_would_pick_on_this_host,once_per_call_runs_the_probe_once,verbose_model_listing_shows_a_token_requirement_without_gfx_families,model_recipe_staleness_lines_warn_only_for_stale_engine_recipes,render_model_registry_text_marks_tiny_recipe_as_gpu_smoke_support,model_registry_marks_windows_vllm_adapter_as_runtime_unsupportedandmodel_registry_engine_reasons_do_not_mention_cpu_fallbacks. The one test that touches both halves,linux_only_engine_runtime_status_is_explicit_on_native_windows, stays inexamine_report_text.rs: its primary subject isengine_runtime_status_label, and it importsmodel_registry_adapter_availability_notefor its second assertion. The function ispub(crate)only because that staying test calls it; moving the test's two assertions about it intomodel_catalog_text.rswould let it stay private, but that edits tests, which a pure move should not do, so it is left as a follow-up. Theheader_*,render_engine_inventory_*,examine_*,friendly_*andruntime_status_label_*tests stay. Leaf-name diff ofcargo test -p rocm --bin rocm -- --listand-- --list --ignoredbetweenorigin/mainand this branch: empty (1,475 listed tests and 8 ignored, same multiset), with the only difference being 18 paths changing fromexamine_report_text::tests::tomodel_catalog_text::tests::.Proptest seed file
proptest finds saved failure cases by the source file of the test, so the
format_bytesproperty test's seed (bytes = 1048525) is read fromapps/rocm/proptest-regressions/<source-stem>.txt. It was sitting inmain.txt, left behind by an earlier move, so it was not being replayed at all. The first commit renames it tomodel_catalog_text.txt(a pure rename, header comment kept,git diff -Mshows 0 changed lines). To prove proptest reads that path I appended a deliberately unparsable line, ran the property test with--nocapture, and proptest printedproptest: .../apps/rocm/proptest-regressions/model_catalog_text.txt:8: unparsable line, ignoring; I then removed the line again. No other moved code has a proptest.Size
Production lines per file, counting the header comment and imports and excluding the brace-matched
#[cfg(test)] mod tests:examine_report_text.rsmodel_catalog_text.rsImport edges
model_catalog_text.rsusescrate::engine_ipc(builtin_engine_available,resolve_engine_binary_path_with_paths), the crate-root itemsPlatformRuleOut,engine_ruled_out_by_platform_withandmissing_packaged_engine_reason(the first two are defined inmodel_fit.rsand re-imported bymain.rs, as before), and the qualifiedcrate::serve_cmd::select_serve_engine. It does not importexamine_report_text.rs, andexamine_report_text.rsreaches it only from its own test module. No new cycle, andcargo xtask check-crate-edgesis clean.Verification
Ran:
cargo fmt --all --check;cargo clippy -p rocm -p xtask --all-targets -- -D warnings;cargo test -p rocm --no-fail-fast(1,467 passed, 8 ignored, 0 failed in the bin target);cargo test -p rocm --bin rocm model(78 passed);cargo test -p rocm advised_commands(20 passed, 1 ignored, which is ignored on main too);cargo test -p xtask ascii(27 passed);cargo xtask check-crate-edges;cargo xtask manifest --check; each commit's tree was checked, and the full set was re-run on the branch tip. The before/after capture ofrocm model,rocm models,rocm model --verbose,rocm model --helpandrocm --helpis byte-identical.Not run: a clippy cross-check against
x86_64-pc-windows-msvcfails to build here (theaws-lc-sysC build needs the MSVC headers, unrelated to this change), so the Windows lane is the check for platform-gated code. The moved code has nocfg(windows)item; the only gates arecfg!(windows)runtime checks and one#[cfg(unix)]block inside tests, all moved intact.cargo xtask e2eandscripts/smoke_local.pywere not run; CI carries them.User-visible behaviour
None, so no scenario is added: this moves code without changing it, and the output of the moved commands is byte-identical. The existing
rocm modelcoverage (the ASCII-only assertions and the catalog tests above) moved with the code and still passes.Notes for reviewers
Two commits. The first moves the production code, the 18 tests, the
main.rsimport and the proptest seed file; it compiles and passes on its own. The second is documentation only: the newmodel_catalog_text.rsentry indocs/architecture.md, the rewrittenexamine_report_text.rsentry and module doc (which listed the moved items by name), and themodel_fit.rsmodule doc and architecture mentions that namedexamine_report_text.rsas the only reader of the platform gate. Path pins were checked: theadvised_commands.rsentry onexamine_report_text.rs(rocm interactive shell) is inrender_launch_summary, which stays;xtask/src/ascii_output_contract.rshas no entry on the moved code;docs/testing.mdfilters by test name, which is unchanged.Other open PRs that touch
examine_report_text.rs, checked withgit merge-treeagainst each PR head: #678 conflicts only in the three-lineuse crate::{...}block (it addsengine_inventory_noteto the line this PR edits), a mechanical resolution; its other conflicts (README.md,main.rs,serve_summary.rs,rocm-core/src/lib.rs,docs/testing.md) already exist againstmain. #695 already conflicts withmainin two hunks ofengine_runtime_status_labeland gains one more here, where its new test is inserted directly before the first moved test; all mechanical. #880 merges cleanly onmainbut conflicts after the move: its six-line removal of themissing_packaged_engine_reasonbranch lands inappend_model_engine_support_lines, which now lives inmodel_catalog_text.rs(reapply the removal there and drop that import in the new file), plus its edits to the module doc and architecture text, which this PR rewrites. #889 merges cleanly onmainand conflicts only in the module doc note anddocs/architecture.mdtext that this PR rewrites; its note concerns a test this PR no longer mentions, so the resolution is to drop it.