scope_profiler.report_model
What a profiling report says, as plain data.
The HTML report and the Astro catalogue pages show the same things: headline numbers, findings, hotspots, tables, charts. The decisions about what to say (which findings apply, how a change is classified, which rows lead) live here, as JSON-serializable models, so the two renderers cannot drift apart: each only decides how to draw them.
Text that mentions a region is a list of parts: a plain string, or a mapping
such as {"region": "solve"} (a region to link to its row in the table) or
{"anchor": "balance", "text": "load balance"} (a link to a section). The
renderer escapes the strings and decides where the links point.
Functions
| Name | Description |
|---|---|
balance_model | How evenly each region's time is spread over the ranks. |
candidate_model | One run against the baseline: headline numbers and what moved. |
change_model | How value compares with base, for a comparison table cell. |
chart_description_text | Explain how to read one chart; "" for a chart without an explanation. |
chart_panels | The chart panels of a report, from collect_chart_payloads' charts. |
compare_dataset | Everything needed to compare any two of the runs, compactly, for a browser. |
compare_table_model | Every region's duration in every run, against the baseline. |
comparison_page_model | Everything the report shows about a comparison of runs, except its charts. |
deviation | How a value shades against its mean: red above, blue below, none near it. |
hardware_model | Counter tables, only for the runs and ranks that recorded hardware metrics. |
hotspots_model | The largest leaves of the call tree, ranked, with their share of base. |
line_profile_list_model | Line profiles of regions the table does not show: one entry per function. |
line_profile_location | Where a profiled function is, and on how many ranks it ran. |
line_profile_model | One profiled function's source, each line with the time spent on it. |
matrix_model | Every rank side by side, region by region, against the region's mean. |
metadata_model | The run's recorded metadata as sorted [key, value] pairs. |
partition_line_profiles | Line profiles split into those of tabled regions and the rest. |
region_detail_model | What a region's expandable detail shows: call site, tags, ranks, lines. |
region_table_model | Region statistics laid out like the terminal summary table. |
report_rows | The region rows a report is built from. |
run_meta_model | One line on where, when and for how long a run was profiled. |
run_page_model | Everything the report shows about one run, except its charts. |
runs_table_model | One line per compared run: its recording, size, wall time and change. |
summary_model | Headline numbers and a few sentences on what stands out in one run. |
wall_model | Wall time of run against base_run: both, the change and its tone. |
balance_modelfunction#
def balance_model(results, balance: dict) -> dictHow evenly each region’s time is spread over the ranks.
rows are ordered by excess (the time balancing could save); each has the
mean, min and max per-rank time, the slowest rank, the imbalance in percent,
and low, high and mean_pos as percentages of the widest bar for
the min-mean-max spread. limit rows are shown before “show all”.
candidate_modelfunction#
def candidate_model(runs, entries, run_index: int) -> dictOne run against the baseline: headline numbers and what moved.
improvements and regressions are the largest own-time changes, each
with its size, share of the widest change (width) and a label.
change_modelfunction#
def change_model(base, value, metric: str) -> dictHow value compares with base, for a comparison table cell.
kind is "none" (neither has it), "new", "gone" or "delta";
a delta has a tone (faster, slower, same, or, for call counts,
neutral), a pct change and a title giving its size. size is
the magnitude of the change, for sorting by it.
chart_description_textfunction#
def chart_description_text(title: str, payload: dict, comparison: bool = False) -> strExplain how to read one chart; "" for a chart without an explanation.
A scaling chart’s text names its x-axis as {axis}, which the renderer
replaces by the current axis label, since the reader can switch axes.
chart_panelsfunction#
def chart_panels(charts, comparison: bool = False, scaling: str = 'both') -> list[dict]The chart panels of a report, from collect_chart_payloads’ charts.
Each panel has the chart’s title, payload and view options, its
description (with {axis} placeholders, see
:func:chart_description_text), its axis label, whether it starts
open, and, for a scaling chart, its x-axis variants (each with a
label and its own payload) with the index of the default_variant.
compare_datasetfunction#
def compare_dataset(runs, per_run_rows, per_rank: bool) -> dictEverything needed to compare any two of the runs, compactly, for a browser.
A comparison of 100 runs has 9,900 ordered pairs, too many to compute in
advance, so a page that lets the reader pick the two runs computes the pair in
the browser from this: regions ({key: {name, depth, context}}, a key
being the region’s call path) and, per run, its wall time, the order of
its rows (the call tree) and values, {key: [total, own, avg, calls]}
with None where the run did not time the region. per_rank says that
the runs differ in rank counts, so totals and own times are per rank.
compare_table_modelfunction#
def compare_table_model(runs, entries, per_rank: bool = False) -> dictEvery region’s duration in every run, against the baseline.
rows follow the baseline’s call tree. Each row has, per run, the text of
every metric in metrics and, for the runs after the baseline, a
:func:change_model against the baseline; sizes holds the size of the
last run’s change per metric, to sort by.
comparison_page_modelfunction#
def comparison_page_model(runs, include=None, exclude=None, ranks=None, sort='start', reference=None) -> dictEverything the report shows about a comparison of runs, except its charts.
dataset (see :func:compare_dataset) holds what a page needs to compare any
two runs. candidates and table are the report’s comparison of the runs
against the first; with reference they cover only that many runs after the
first, as the reference a page’s own computation is checked against.
deviationfunction#
def deviation(value: float, mean: float) -> dict | NoneHow a value shades against its mean: red above, blue below, none near it.
Returns {"sign": 1 | -1, "alpha": float}, or None for a value within
the noise of the mean.
hardware_modelfunction#
def hardware_model(runs, include=None, exclude=None, ranks=None) -> list[dict]Counter tables, only for the runs and ranks that recorded hardware metrics.
Each panel has a kind (likwid or perf), a title, and tables:
a columns list and rows of already formatted cell texts.
hotspots_modelfunction#
def hotspots_model(entries, base) -> dictThe largest leaves of the call tree, ranked, with their share of base.
items is empty when there is nothing to rank against (fewer than two
entries). Each item has the entry’s name, context and kind
(leaf, own or outside), its share in percent, details
(time, calls, time per call) and, for a slow leaf, a flag.
line_profile_list_modelfunction#
def line_profile_list_model(results, functions) -> dictLine profiles of regions the table does not show: one entry per function.
line_profile_locationfunction#
def line_profile_location(results, entry: dict) -> dictWhere a profiled function is, and on how many ranks it ran.
line_profile_modelfunction#
def line_profile_model(entry: dict) -> dictOne profiled function’s source, each line with the time spent on it.
rows has a row per line: number, source (HTML with syntax
classes) and, for a line that was timed, hits, seconds, per_hit
and percent; the hottest line has hot set. has_source is false
when no line’s source could be found, and then only timed lines are listed.
matrix_modelfunction#
def matrix_model(balance: dict) -> dictEvery rank side by side, region by region, against the region’s mean.
rows and totals hold one cell per rank: its value in seconds, its
label (the percent against the mean), its title and its shade.
metadata_modelfunction#
def metadata_model(metadata: dict, keys=None) -> list[list[str]]The run’s recorded metadata as sorted [key, value] pairs.
keys limits which fields are included; all of them by default.
partition_line_profilesfunction#
def partition_line_profiles(results, rows, ranks)Line profiles split into those of tabled regions and the rest.
Returns (by_region, unmatched): by_region maps a region in the table
to its profiled functions, which its detail shows; unmatched lists the
functions of regions the table does not show, largest first.
region_detail_modelfunction#
def region_detail_model(results, region, ranks, functions=()) -> dictWhat a region’s expandable detail shows: call site, tags, ranks, lines.
region_table_modelfunction#
def region_table_model(results, rows, ranks, columns, line_profiles=None) -> dictRegion statistics laid out like the terminal summary table.
Cell text comes from :func:~scope_profiler.summary.format_region_table, so
every renderer shows the same tree, call counts and (own) rows. Each
region is one entry of groups, holding its row, its own row when it
has children, its sort keys, its call durations for a trend line and its
detail.
report_rowsfunction#
def report_rows(results, include, exclude, ranks, sort) -> list[dict]The region rows a report is built from.
run_meta_modelfunction#
def run_meta_model(results, region_count: int, metadata_keys=None) -> dictOne line on where, when and for how long a run was profiled.
metadata_keys limits which of the host-describing metadata fields
(hostname, chip_information) are included; all of them by default.
run_page_modelfunction#
def run_page_model(results, include=None, exclude=None, ranks=None, sort='start', columns=None, host_keys=None, metadata_keys=None) -> dictEverything the report shows about one run, except its charts.
The sections are meta, summary, hotspots, regions (the table),
balance and matrix (None for a single rank), line_profiles (None
without any), metadata and hardware. region_ids maps a region to
the id of its first row in regions["groups"], for links to it.
host_keys and metadata_keys limit which host-describing fields the
header shows and which metadata fields are listed (all by default), for a
report that is published.
runs_table_modelfunction#
def runs_table_model(runs) -> dictOne line per compared run: its recording, size, wall time and change.
change is a :func:change_model of the run’s wall time against the
baseline’s, or {"kind": "base"} for the baseline itself.
summary_modelfunction#
def summary_model(results, rows, entries, base, balance) -> dictHeadline numbers and a few sentences on what stands out in one run.
Returns {"empty": True} without timed regions; otherwise {"kpis": [...], "findings": [...]}, where each finding is {"tone": "info" | "warn", "parts": [...]}.
wall_modelfunction#
def wall_model(base_run, run) -> dictWall time of run against base_run: both, the change and its tone.