Skip to content
Projects

scope_profiler.plotting_scripts

Plotting utilities for visualizing profiling data using maxplotlib.

This package provides plotting functions that can export to both matplotlib and plotly backends using maxplotlib as the unified interface. It is split into one module per chart type; everything is re-exported here so scope_profiler.plotting_scripts keeps behaving like a single module for callers and tests (including attribute-level monkeypatching).

Attributes

NameDescription
DEFAULT_CMAPNo description.
FLAME_CMAPNo description.
plot_flameNo description.

Functions

NameDescription
_add_pyvis_controlsAdd lightweight search/focus/collapse controls to a PyVis document.
_aggregate_gantt_intervalsFilter and optionally coalesce timeline intervals.
_as_runsNormalize the input, dropping result sets this rank must not draw.
_close_matplotlib_figureRelease the figure maxplotlib keeps open after rendering.
_display_matplotlib_figure_in_notebookUse IPython rich display when running inside a Jupyter kernel.
_duration_timeseriesAggregate one region's calls over ranks into a duration-versus-time series.
_filename_slugMake a label safe to paste into a filename.
_get_canvasGet maxplotlib Canvas for plotting.
_get_cmap_colorsSample n_colors #rrggbb strings from a matplotlib colormap.
_group_regionsCollapse regions matching a pattern into a single combined bar.
_hover_regionPick the region object whose summary matches what is being plotted.
_hover_summaryRender a region's own get_summary() as Plotly hover text.
_hover_valueFormat one get_summary() entry for the hover box.
_normalize_ranksNo description.
_panel_gridspecReserve figure margins for tick labels, axis labels and titles.
_prepare_gantt_dataNo description.
_region_color_mapAssign each region name a stable color from a canonical sorted order.
_region_summaryA region's get_summary(), minus what a broken call graph withholds.
_renderSave and/or display a canvas.
_save_matplotlib_figureSave a materialized Matplotlib figure using canvas-level DPI if present.
_set_xticksSet x ticks, returning whether optional tick-label kwargs were accepted.
_show_matplotlib_figureDisplay a Matplotlib figure in notebooks and regular Python sessions.
_stacked_segmentsSplit each bar's inclusive time into self time plus its direct children.
_to_hexConvert a matplotlib color (e.g. an RGBA tuple) to a #rrggbb string.
_unique_labelsNo description.
_write_csvWrite rows of plotting data to a plain-text CSV file.
_write_jsonWrite the exact data behind a plot to a JSON file.
_write_parquetWrite the same rows writecsv would to a columnar Parquet file.
available_likwid_metricsList the LIKWID metric/event names available for :func:plot_likwid.
available_perf_event_metricsList available raw events and valid derived perf-event ratios.
collect_region_statisticsCollect aggregate region-duration statistics for one or more profiling files.
collect_roofline_pointsDerive one roofline point per selected LIKWID region and rank.
plot_callgraphPlot the explicit call graph, without using timestamps or durations.
plot_duration_histogramPlot each region's call-duration distribution as a frequency line.
plot_duration_timeseriesPlot each region's call duration over wall-clock time, with a min-max band.
plot_durationsPlot duration bar charts for one or more profiling files using maxplotlib.
plot_flame_chartPlot a flame chart reconstructing the call stack from region timings.
plot_flame_graphPlot an aggregated flame graph whose x-axis represents total time.
plot_ganttPlot a Gantt chart of all (or selected) regions with per-rank lanes using maxplotlib.
plot_imbalancePlot each region's duration statistic per rank, to surface load imbalance.
plot_likwidPlot one LIKWID derived metric or raw event, grouped by region and rank.
plot_perf_eventsPlot one raw perf event or derived ratio for every region and rank.
plot_rank_heatmapPlot total or exclusive region time as a rank-by-region heatmap.
plot_rooflinePlot attained performance against arithmetic intensity for LIKWID regions.
plot_scaling_efficiencyPlot parallel scaling efficiency (measured speedup / ideal speedup).
plot_speedupPlot scope speedup versus a chosen parallelism/metadata field using maxplotlib.
plot_timeline_densityPlot binned region occupancy instead of individual timeline bars.
plot_weak_scalingPlot weak-scaling runtime versus a chosen parallelism/metadata field.
plot_weak_scaling_efficiencyPlot weak-scaling efficiency: baseline runtime over runtime at each scale.
write_region_statistics_jsonWrite aggregate region-duration statistics to a JSON file.

Modules

  • callgraphCall-graph rendering (PyVis network view of explicit caller/callee edges).
  • duration_timeseriesDuration-vs-time scatter: per-region call durations across the run.
  • durationsDuration bar charts: per-region totals/averages, optionally stacked by caller.
  • flameFlame chart rendering: nested call-stack frames sized by duration.
  • ganttGantt chart rendering: per-rank timeline bars for one or more profiling runs.
  • heatmapRank x region duration heatmap.
  • histogramPer-region duration-distribution histograms.
  • imbalanceRank-imbalance plots: per-region duration spread across ranks.
  • likwidLIKWID hardware-counter bar charts.
  • perf_eventsBar charts for built-in Linux perf-event counter totals and ratios.
  • rooflineRoofline analysis from LIKWID FLOP-rate and memory-bandwidth metrics.
  • scalingScaling charts: speedup, weak-scaling, and parallel-efficiency curves.
  • statisticsRegion-duration statistics collection (JSON export, no chart rendering).
  • timelineTimeline density heatmap: call-count intensity over time, per region.

DEFAULT_CMAPattributemodule attribute#

Re-exported from scope_profiler.plotting_scripts._utilsView source
DEFAULT_CMAP = 'tab20'

FLAME_CMAPattributemodule attribute#

FLAME_CMAP = 'inferno'

plot_flameattributemodule attribute#

plot_flame = plot_flame_chart

_add_pyvis_controlsfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _add_pyvis_controls(filepath: str | Path) -> None

Add lightweight search/focus/collapse controls to a PyVis document.

_aggregate_gantt_intervalsfunction#

def _aggregate_gantt_intervals(intervals: Sequence[tuple[float, float]], *, min_duration: float = 0.0, start_time: float | None = None, end_time: float | None = None, block_size: int = 1) -> list[tuple[float, float, int]]

Filter and optionally coalesce timeline intervals.

start_time/end_time are relative to the plot origin. Intervals crossing a window boundary are clipped. Coalescing preserves event order and reports the number of calls represented by each returned bar.

_as_runsfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _as_runs(profiling_data: ProfilingResults | Sequence[ProfilingResults]) -> list[ProfilingResults]

Normalize the input, dropping result sets this rank must not draw.

Under MPI only rank 0 holds the run’s data; every other rank gets an empty, non-root result set from finalize(return_results=True). Dropping those here is what lets a parallel script call the plot functions and exporters unguarded and still produce exactly one set of figures. An empty list back therefore means “not this rank’s job” - callers return quietly - while an empty input is a mistake and raises.

_close_matplotlib_figurefunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _close_matplotlib_figure(canvas, fig=None) -> None

Release the figure maxplotlib keeps open after rendering.

_display_matplotlib_figure_in_notebookfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _display_matplotlib_figure_in_notebook(fig) -> bool

Use IPython rich display when running inside a Jupyter kernel.

_duration_timeseriesfunction#

def _duration_timeseries(region, ranks: list[int] | None, first_start_time: float) -> dict[str, np.ndarray] | None

Aggregate one region’s calls over ranks into a duration-versus-time series.

Calls are matched across ranks by call index, so point i describes the i-th call of the region on every rank that got that far. Ranks that stopped calling the region earlier simply drop out of the later points, which keeps ragged call counts (e.g. a rank-dependent number of iterations) usable.

Returns None if no selected rank recorded any call.

_filename_slugfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _filename_slug(label: str) -> str

Make a label safe to paste into a filename.

Labels are free text and are used to name exported files, so a perfectly reasonable one like "128 ranks" would otherwise produce profile_128 ranks_rank0.prof. Only the path is sanitized; the label inside the exported document stays as the user wrote it.

_get_canvasfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _get_canvas()

Get maxplotlib Canvas for plotting.

_get_cmap_colorsfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _get_cmap_colors(cmap: str, n_colors: int) -> list[str]

Sample n_colors #rrggbb strings from a matplotlib colormap.

Hex strings (rather than RGBA tuples) are returned so the colors can be handed to any maxplotlib backend unchanged.

_group_regionsfunction#

def _group_regions(region_names: list[str], combine_regions: dict[str, list[str] | str] | None) -> tuple[list[str], dict[str, list[str]]]

Collapse regions matching a pattern into a single combined bar.

combine_regions maps a display name (e.g. "setup") to one or more regex patterns (matched the same way as include); every region in region_names matching one of a group’s patterns is pooled into a single bar under that display name, in the position of its first match. A region matching patterns from more than one group is claimed by whichever group is listed first. Regions matching no group pass through unchanged, one bar each.

Returns the ordered list of bar display names, plus a {display_name: [member region names]} map used to pool each bar’s underlying data.

_hover_regionfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _hover_region(region, ranks: list[int] | None, num_ranks: int | None = None)

Pick the region object whose summary matches what is being plotted.

A plot restricted to a single rank should not describe itself with statistics pooled over every rank, and MPIRegion[rank] is the same get_summary() one level down. num_ranks is the run’s rank count, which decides whether the title names the rank.

_hover_summaryfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _hover_summary(region, title: str | None = None, extra: Sequence[tuple[str, object]] = ()) -> str

Render a region’s own get_summary() as Plotly hover text.

Both :class:~scope_profiler.region.Region (one rank) and :class:~scope_profiler.mpi_region.MPIRegion (pooled over ranks) expose get_summary(), so hovering shows exactly the statistics that region object reports - there is no second, parallel definition of “the usual information” to keep in step with it.

extra lines (the hovered call’s own start and duration, a bar’s value, …) are placed above the summary, since they are what identifies the point being hovered.

_hover_valuefunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _hover_value(key: str, value) -> str

Format one get_summary() entry for the hover box.

_normalize_ranksfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _normalize_ranks(ranks: list[int] | int | None) -> list[int] | None

_panel_gridspecfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _panel_gridspec(fig_width: float, fig_height: float, label_chars: int, multi_panel: bool) -> dict

Reserve figure margins for tick labels, axis labels and titles.

maxplotlib renders without tight_layout, so long y-tick labels (region names) and the x-axis label would otherwise be cut off at the figure edge.

_prepare_gantt_datafunction#

def _prepare_gantt_data(profiling_data: ProfilingResults, ranks: list[int] | int | None, include: list[str] | str | None, exclude: list[str] | str | None) -> tuple[list, list[int], float]

_region_color_mapfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _region_color_map(region_names, cmap: str = DEFAULT_CMAP) -> dict

Assign each region name a stable color from a canonical sorted order.

_region_summaryfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _region_summary(region) -> dict

A region’s get_summary(), minus what a broken call graph withholds.

get_summary() reports exclusive time, which is reconstructed from timestamp containment and therefore unavailable on a rank whose calls are not properly nested. That is a reason to leave one line out of a hover box, not to fail the plot.

_renderfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _render(canvas, filepath: str | None, show: bool, backend: str, plotly_layout: dict | None = None, x_tick_rotation: float | None = None, return_fig: bool = False, matplotlib_postprocess=None, plotly_postprocess=None) -> tuple[object, object] | object

Save and/or display a canvas.

_save_matplotlib_figurefunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _save_matplotlib_figure(fig, canvas, filepath: str | Path) -> None

Save a materialized Matplotlib figure using canvas-level DPI if present.

_set_xticksfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _set_xticks(canvas, ticks, labels=None, **kwargs) -> bool

Set x ticks, returning whether optional tick-label kwargs were accepted.

_show_matplotlib_figurefunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _show_matplotlib_figure(fig) -> bool

Display a Matplotlib figure in notebooks and regular Python sessions.

_stacked_segmentsfunction#

def _stacked_segments(run: ProfilingResults, region_members: dict[str, list[str]], ranks: list[int] | None = None) -> dict[str, dict[str, float]]

Split each bar’s inclusive time into self time plus its direct children.

Regions record no call graph, so the nesting is reconstructed from timestamp containment (:func:~scope_profiler.call_stack.build_call_arrays)

  • the same call graph the flame chart draws, over all the run’s regions, not just the plotted ones, since a region filtered out of the bars is still somebody’s parent.

Every call is credited to the bar its parent belongs to. A call whose parent is in the same bar (a recursive region, or two members of one combine_regions group nested in each other) is left in that bar’s self time rather than becoming a segment of itself, so a bar’s segments always sum to time spent inside it, counted once.

Returns {bar name: {segment label: total nanoseconds}}, where the "self" segment is exclusive time and every other key is a child region’s name - its bar name when that child is itself a plotted bar.

_to_hexfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _to_hex(color) -> str

Convert a matplotlib color (e.g. an RGBA tuple) to a #rrggbb string.

_unique_labelsfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _unique_labels(labels: Sequence[str]) -> list[str]

_write_csvfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _write_csv(filepath: str | Path, header: Sequence[str], rows: Sequence[Sequence]) -> None

Write rows of plotting data to a plain-text CSV file.

_write_jsonfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _write_json(filepath: str | Path, payload: dict, plot: str) -> None

Write the exact data behind a plot to a JSON file.

Every plot-data document carries the same envelope - format, format_version and the plot kind that produced it - so a consumer (e.g. the @scope-profiler/plotly package) can dispatch on the file itself instead of guessing from its keys. Stamping it here rather than at each call site is what keeps the envelope on every kind.

_write_parquetfunction#

Re-exported from scope_profiler.plotting_scripts._utilsView source
def _write_parquet(filepath: str | Path, header: Sequence[str], rows: Sequence[Sequence]) -> None

Write the same rows _write_csv would to a columnar Parquet file.

Same tabular shape as the CSV export, for a caller that wants a typed, columnar file to load with pandas/polars/DuckDB rather than parse a delimited text file.

available_likwid_metricsfunction#

def available_likwid_metrics(profiling_data: ProfilingResults | Sequence[ProfilingResults]) -> list[str]

List the LIKWID metric/event names available for :func:plot_likwid.

Union over every run, rank and region, in the order LIKWID reported them (derived metrics first, then raw events) - so a caller who does not know what a run measured can list the valid metric values before plotting.

available_perf_event_metricsfunction#

def available_perf_event_metrics(profiling_data: ProfilingResults | Sequence[ProfilingResults]) -> list[str]

List available raw events and valid derived perf-event ratios.

collect_region_statisticsfunction#

def collect_region_statistics(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, labels: Sequence[str] | None = None) -> dict

Collect aggregate region-duration statistics for one or more profiling files.

collect_roofline_pointsfunction#

def collect_roofline_points(profiling_data: ProfilingResults | Sequence[ProfilingResults], *, flops_metric: str | None = None, bandwidth_metric: str | None = None, ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None) -> list[dict]

Derive one roofline point per selected LIKWID region and rank.

flops_metric and bandwidth_metric select exact LIKWID derived metric names. When omitted, the first names containing FLOP/s and bandwidth respectively are selected for each region. Supplying exact names is recommended when a group offers both single- and double-precision FLOP rates.

plot_callgraphfunction#

def plot_callgraph(profiling_data: ProfilingResults, rank: int = 0, include=None, exclude=None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False, compact: bool = False, fluid: bool = False) -> object | None

Plot the explicit call graph, without using timestamps or durations.

When compact is true, all invocations of a region are represented by one node named after that region. Edges then describe distinct caller/callee region relationships rather than individual call IDs. fluid applies a deterministic force-directed layout to the compact graph, similar to an Obsidian-style node graph.

plot_duration_histogramfunction#

def plot_duration_histogram(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, bins: int = 30, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, log_scale: bool = False, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib') -> None

Plot each region’s call-duration distribution as a frequency line.

One panel per file, one line per region, giving the count of calls falling in each duration bin - so a region whose calls are mostly fast with an occasional slow outlier shows up as a peak with a long tail, something the mean/min/max in :func:plot_durations cannot distinguish from a uniformly slower region.

Parameters

bins : int Number of histogram bins spanning each file’s observed duration range (default: 30). All regions in a panel share the same bin edges, so the curves are directly comparable. backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”.

plot_duration_timeseriesfunction#

def plot_duration_timeseries(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, log_scale: bool = False, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> None

Plot each region’s call duration over wall-clock time, with a min-max band.

One line per region tracks the mean duration over the ranks that recorded each call, shaded between the minimum and maximum duration seen across those ranks, so rank imbalance shows up as a widening band.

Parameters

backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”. return_fig : bool Return the rendered figure instead of the default None. Matplotlib returns (fig, axes); Plotly returns its figure object.

plot_durationsfunction#

def plot_durations(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, labels: Sequence[str] | None = None, metric: str = 'total', metrics: Sequence[str] | None = None, sort_by: str | None = None, top_n: int | None = None, combine_regions: dict[str, list[str] | str] | None = None, stack_children: bool = False, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, log_scale: bool = False, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> list[str] | list[object] | object

Plot duration bar charts for one or more profiling files using maxplotlib.

Parameters

combine_regions : dict[str, list[str] | str], optional Merge several regions into a single bar, e.g. {"setup": ["setup: .*"]} combines every setup: ... region into one bar named “setup”, pooling their calls the same way sort_by and the other duration statistics pool a single region’s calls. Each value is one or more regex patterns (matched like include); a region matching several groups is claimed by whichever group is listed first. metric : str Duration metric to render (avg, min, max, total, first or last). first/last are the durations of the chronologically first and last call, which show how much of a region’s cost is one-off warmup rather than steady state. metrics : Sequence[str], optional Render several metrics instead of one. Each gets its own figure — filepath is suffixed with the metric name, as it always was for multiple metrics - but a single data_filepath holds them all, with the metric named per row, so one export can back a chart whose metric the viewer switches. Overrides metric when given. stack_children : bool Split each bar into the region’s own (exclusive) time plus one segment per region called directly from it, stacked on top of each other, so a bar shows where its time went instead of only how much there was. The nesting comes from timestamp containment, the same reconstruction the flame chart uses, over every region in the run — a child that is filtered out of the bars still gets its own segment. Only total and avg decompose this way; min/max are rejected. Colors then identify segments rather than runs, so with several runs the bars are still grouped per region in run order but the legend names the segments. backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”. return_fig : bool Return the rendered figure instead of the saved filepath list.

Returns

list[str] List of filepaths that were written (empty if filepath is None). With return_fig, the rendered figure, or the list of figures when several metrics were requested.

plot_flame_chartfunction#

def plot_flame_chart(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = FLAME_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot a flame chart reconstructing the call stack from region timings.

Parameters

backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”. return_fig : bool Return the rendered figure instead of the default None. Matplotlib returns (fig, axes); Plotly returns its figure object.

plot_flame_graphfunction#

def plot_flame_graph(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = FLAME_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot an aggregated flame graph whose x-axis represents total time.

plot_ganttfunction#

def plot_gantt(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False, min_duration: float = 0.0, start_time: float | None = None, end_time: float | None = None, aggregate_calls: int = 1, collapse_depth: int | None = None) -> object | None

Plot a Gantt chart of all (or selected) regions with per-rank lanes using maxplotlib.

Parameters

backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”. return_fig : bool Return the rendered figure instead of the default None. Matplotlib returns (fig, axes); Plotly returns its figure object.

plot_imbalancefunction#

def plot_imbalance(profiling_data: ProfilingResults | Sequence[ProfilingResults], metric: str = 'total', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, log_scale: bool = False, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib') -> None

Plot each region’s duration statistic per rank, to surface load imbalance.

One point per (region, rank), connected by a line in rank order, with a dashed horizontal line at the mean over ranks - so a straggler rank shows up as a point sitting well off its region’s line. This is a per-rank view of the same statistics :func:plot_durations aggregates across ranks.

Parameters

metric : str Which per-call duration statistic to plot per rank; one of "avg", "min", "max", "total" (default: "total", the total time a rank spent in the region). backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”.

plot_likwidfunction#

def plot_likwid(profiling_data: ProfilingResults | Sequence[ProfilingResults], metric: str, ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, labels: Sequence[str] | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, log_scale: bool = False, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib') -> None

Plot one LIKWID derived metric or raw event, grouped by region and rank.

LIKWID counters are otherwise only visible as text tables (:func:~scope_profiler.summary.print_likwid_tables); this gives the same numbers a bar chart, one group of bars per region and one bar per rank, so a metric like memory bandwidth or CPI can be compared across regions (or across files, for a single rank) the same way :func:plot_durations compares timings.

Parameters

metric : str Name of a LIKWID derived metric (e.g. "CPI") or raw event/event label (e.g. "CAS_COUNT_RD"). See :func:available_likwid_metrics for the names a run actually recorded. backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”.

plot_perf_eventsfunction#

def plot_perf_events(profiling_data: ProfilingResults | Sequence[ProfilingResults], metric: str = 'ipc', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, labels: Sequence[str] | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, backend: str = 'matplotlib') -> None

Plot one raw perf event or derived ratio for every region and rank.

metric may be an event name recorded in the run, "ipc" (instructions/cycle), or "cache-misses-per-ki". Derived metrics are calculated from the region’s aggregated counters, not averages of call ratios, which preserves their proper weighting.

plot_rank_heatmapfunction#

def plot_rank_heatmap(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = 'viridis', data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False, exclusive: bool = False) -> object | None

Plot total or exclusive region time as a rank-by-region heatmap.

plot_rooflinefunction#

def plot_roofline(profiling_data: ProfilingResults | Sequence[ProfilingResults], *, flops_metric: str | None = None, bandwidth_metric: str | None = None, peak_flops: float | None = None, peak_bandwidth: float | None = None, ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib') -> dict

Plot attained performance against arithmetic intensity for LIKWID regions.

peak_flops (GFLOP/s) and peak_bandwidth (GB/s) should be measured hardware ceilings for a true roofline. If either is absent, the largest selected observation supplies that ceiling and the plot labels it empirical; it is useful for comparing regions but must not be read as a machine limit.

plot_scaling_efficiencyfunction#

def plot_scaling_efficiency(profiling_data: ProfilingResults | Sequence[ProfilingResults], x_field: str = 'num_ranks', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot parallel scaling efficiency (measured speedup / ideal speedup).

plot_speedupfunction#

def plot_speedup(profiling_data: ProfilingResults | Sequence[ProfilingResults], x_field: str = 'num_ranks', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot scope speedup versus a chosen parallelism/metadata field using maxplotlib.

Parameters

backend : str Backend to use for rendering: “matplotlib” (default) or “plotly”.

plot_timeline_densityfunction#

def plot_timeline_density(profiling_data: ProfilingResults | Sequence[ProfilingResults], ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = 'magma', bins: int = 200, start_time: float | None = None, end_time: float | None = None, min_duration: float = 0.0, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot binned region occupancy instead of individual timeline bars.

Each cell contains the seconds of a region overlapping that time bin. This is intentionally an aggregate visualization: it remains readable when a run contains millions of short calls.

plot_weak_scalingfunction#

def plot_weak_scaling(profiling_data: ProfilingResults | Sequence[ProfilingResults], x_field: str = 'num_ranks', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot weak-scaling runtime versus a chosen parallelism/metadata field.

Runtime is normalized to the smallest scale, so ideal weak scaling is a horizontal line at 1.0. Lower values are not inherently better here: the useful signal is how closely each region stays near that line.

See :func:plot_weak_scaling_efficiency for the same data read as a fraction of ideal instead.

plot_weak_scaling_efficiencyfunction#

def plot_weak_scaling_efficiency(profiling_data: ProfilingResults | Sequence[ProfilingResults], x_field: str = 'num_ranks', ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, work_per_rank: Sequence[float] | None = None, filepath: str | None = None, show: bool = False, verbose: bool = True, cmap: str = DEFAULT_CMAP, data_filepath: str | Path | None = None, data_format: str = 'csv', backend: str = 'matplotlib', return_fig: bool = False) -> object | None

Plot weak-scaling efficiency: baseline runtime over runtime at each scale.

A weak-scaling study grows the problem with the machine, so every run does the same work per rank and ideal efficiency is a flat 1.0. A region at 0.6 on 64 ranks is spending 40% of its time on costs that only appear at that scale - communication, load imbalance, or contention.

This differs from :func:plot_scaling_efficiency, which is for a strong-scaling study: there the problem size is fixed, so the ideal is a speedup proportional to the rank count and efficiency divides the measured speedup by that. Here the ideal is constant runtime, so no such division applies - using the strong-scaling plot on weak-scaling runs reports a near-zero efficiency that means nothing.

Parameters

work_per_rank : Sequence[float], optional Work per rank for each profiling run, in whatever unit suits the problem (grid cells, particles, unknowns). Only the caller can know this - it is a property of the problem, not of the profile - so it is optional, but when given it is checked: the runs must agree, and a mismatch raises rather than plotting an efficiency that silently compares runs doing different amounts of work. The value is recorded in the exported plot data.

write_region_statistics_jsonfunction#

def write_region_statistics_json(profiling_data: ProfilingResults | Sequence[ProfilingResults], filepath: str | Path, ranks: list[int] | int | None = None, include: list[str] | str | None = None, exclude: list[str] | str | None = None, labels: Sequence[str] | None = None) -> dict

Write aggregate region-duration statistics to a JSON file.