Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions perun/templates/diff_sections/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ perun_templates_diff_section_files = files(
'section_environment.html.jinja2',
'section_flame_graphs.html.jinja2',
'section_metadata.html.jinja2',
'section_overview.html.jinja2',
'section_page_footer.html.jinja2',
'section_page_title.html.jinja2',
'section_profile_stats.html.jinja2',
Expand Down
48 changes: 48 additions & 0 deletions perun/templates/diff_sections/section_overview.html.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{% import 'macros/overview.html.jinja2' as o_macros %}
<script>
const topTraceDiffs = [
/* Top traces w.r.t. INCLUSIVE proportional delta */
[
/*
[0]: deleted from baseline,
[1]: added to target,
[2]: present in both profiles and the largest increase,
[3]: present in both profiles and the largest decrease.
*/
{{ o_macros.populate_top_diffs(top_diffs_trace_inclusive) }}
],
/* Top traces w.r.t. EXCLUSIVE proportional delta */
[
/*
[0]: deleted from baseline,
[1]: added to target,
[2]: present in both profiles and the largest increase,
[3]: present in both profiles and the largest decrease.
*/
{{ o_macros.populate_top_diffs(top_diffs_trace_exclusive) }}
]
];

const topFunctionDiffs = [
/* Top functions w.r.t. INCLUSIVE proportional delta */
[
/*
[0]: deleted from baseline,
[1]: added to target,
[2]: present in both profiles and the largest increase,
[3]: present in both profiles and the largest decrease.
*/
{{ o_macros.populate_top_diffs(top_diffs_func_inclusive) }}
],
/* Top functions w.r.t. EXCLUSIVE proportional delta */
[
/*
[0]: deleted from baseline,
[1]: added to target,
[2]: present in both profiles and the largest increase,
[3]: present in both profiles and the largest decrease.
*/
{{ o_macros.populate_top_diffs(top_diffs_func_exclusive) }}
]
];
</script>
3 changes: 3 additions & 0 deletions perun/templates/diff_views/report.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@

<!----------------------- SECTIONS ----------------------->

<!-- OVERVIEW -->
{% include 'diff_sections/section_overview.html.jinja2' %}

<!-- ENVIRONMENT -->
{% include 'diff_sections/section_environment.html.jinja2' %}

Expand Down
1 change: 1 addition & 0 deletions perun/templates/macros/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ perun_templates_macros_dir = perun_templates_dir / 'macros'
perun_templates_macros_files = files(
'comparison_table.html.jinja2',
'environment_sidepanel_property.html.jinja2',
'overview.html.jinja2',
'pin.html.jinja2',
'section_sankey.html.jinja2',
'section_title.html.jinja2',
Expand Down
9 changes: 9 additions & 0 deletions perun/templates/macros/overview.html.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% macro populate_top_diffs(top_diffs) %}
{%- for data_set in top_diffs %}
[
{%- for symbol, prop_delta in data_set %}
["{{ symbol }}", {{ prop_delta }}],
{%- endfor %}
],
{%- endfor %}
{% endmacro %}
85 changes: 69 additions & 16 deletions perun/view_diff/report_folded.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ class KeyDiffs:
The class stores the top increases and decreases of a key (metric) for baseline-only,
target-only, and common partitions of a merged profile.

The individual DataFrames contain only two columns: "symbol" and "diff".
- "symbol" identifies either a trace or a function by their IDs, and
- "diff" is the value of the diff metric.

:ivar baseline_top_inc: the largest increases in baseline-only records
:ivar baseline_top_dec: the largest decreases in baseline-only records
:ivar target_top_inc: the largest increases in target-only records
Expand Down Expand Up @@ -1171,9 +1175,10 @@ def generate_report_from_folded(
notes_enabled=True,
links=report_links,
default_theme=cli_kwargs.get("default_theme", "dark"),
# FIXME: the top diffs will be used in the future.
top_trace_diffs=trace_top_diffs,
top_func_diffs=func_top_diffs,
top_diffs_trace_inclusive=iterate_top_diffs(trace_top_diffs[0]),
top_diffs_trace_exclusive=iterate_top_diffs(trace_top_diffs[1]),
top_diffs_func_inclusive=iterate_top_diffs(func_top_diffs[0]),
top_diffs_func_exclusive=iterate_top_diffs(func_top_diffs[1]),
)
log.minor_success("HTML report", "rendered")

Expand Down Expand Up @@ -1430,6 +1435,32 @@ def merge_and_filter_polars_profiles(
)


def find_top_diffs(
data_lf: pl.LazyFrame, count: int, symbol_key: str, diff_key: str, *, top: bool = True
) -> pl.LazyFrame:
"""Find and format the top or bottom diffs w.r.t. the diff_key metric.

The resulting frame will contain up to <count> records maximal (resp. minimal) w.r.t. the
<diff_key>. The schema of the resulting frame will have only two columns: "symbol" and "diff"
corresponding to the <symbol_key> and <diff_key>.

:param data_lf: the data where to search for the maximal/minimal records.
:param count: the upper limit on the number of top records to search for.
:param symbol_key: the name of the column with symbols (e.g., "trace")
:param diff_key: the name of the column containing the diff metric
:param top: specifies whether to search for the maximal or minimal records.

:return: a lazy frame containing the maximal/minimal records.
"""
search_func = pl.LazyFrame.top_k if top else pl.LazyFrame.bottom_k

return (
search_func(data_lf, count, by=diff_key)
.select([symbol_key, diff_key])
.rename({symbol_key: "symbol", diff_key: "diff"})
)


def compute_top_diffs(
merged_profile: pl.LazyFrame,
common_symbols: pl.LazyFrame,
Expand Down Expand Up @@ -1462,7 +1493,7 @@ def compute_top_diffs(
# Partition the merged profile into baseline-only, target-only, and common parts based on
# the symbol_key and the set of common symbols.
common_lf = merged_profile.join(common_symbols, on=symbol_key, how="semi")
baseline_only_lf = merged_profile.join(common_symbols, on=symbol_key, how="anti").filter(
base_only_lf = merged_profile.join(common_symbols, on=symbol_key, how="anti").filter(
pl.col("inclusive_target") == 0
)
target_only_lf = merged_profile.join(common_symbols, on=symbol_key, how="anti").filter(
Expand All @@ -1472,18 +1503,20 @@ def compute_top_diffs(
# share the same lazy frames and collect_all is able to optimize across all those computations.
dfs = pl.collect_all(
[
baseline_only_lf.top_k(records_num, by=inclusive_diff_key),
baseline_only_lf.bottom_k(records_num, by=inclusive_diff_key),
target_only_lf.top_k(records_num, by=inclusive_diff_key),
target_only_lf.bottom_k(records_num, by=inclusive_diff_key),
common_lf.top_k(records_num, by=inclusive_diff_key),
common_lf.bottom_k(records_num, by=inclusive_diff_key),
baseline_only_lf.top_k(records_num, by=exclusive_diff_key),
baseline_only_lf.bottom_k(records_num, by=exclusive_diff_key),
target_only_lf.top_k(records_num, by=exclusive_diff_key),
target_only_lf.bottom_k(records_num, by=exclusive_diff_key),
common_lf.top_k(records_num, by=exclusive_diff_key),
common_lf.bottom_k(records_num, by=exclusive_diff_key),
# Inclusive diff metric.
find_top_diffs(base_only_lf, records_num, symbol_key, inclusive_diff_key),
find_top_diffs(base_only_lf, records_num, symbol_key, inclusive_diff_key, top=False),
find_top_diffs(target_only_lf, records_num, symbol_key, inclusive_diff_key),
find_top_diffs(target_only_lf, records_num, symbol_key, inclusive_diff_key, top=False),
find_top_diffs(common_lf, records_num, symbol_key, inclusive_diff_key),
find_top_diffs(common_lf, records_num, symbol_key, inclusive_diff_key, top=False),
# Exclusive diff metric.
find_top_diffs(base_only_lf, records_num, symbol_key, exclusive_diff_key),
find_top_diffs(base_only_lf, records_num, symbol_key, exclusive_diff_key, top=False),
find_top_diffs(target_only_lf, records_num, symbol_key, exclusive_diff_key),
find_top_diffs(target_only_lf, records_num, symbol_key, exclusive_diff_key, top=False),
find_top_diffs(common_lf, records_num, symbol_key, exclusive_diff_key),
find_top_diffs(common_lf, records_num, symbol_key, exclusive_diff_key, top=False),
]
)
return KeyDiffs(*dfs[:6]), KeyDiffs(*dfs[6:])
Expand Down Expand Up @@ -1562,6 +1595,26 @@ def polars_merged_to_tabular_profiles(
return PolarsTabularTraceProfiles(*pl.collect_all([table_traces_lf, table_funcs_lf]))


def iterate_top_diffs(top_diff: KeyDiffs) -> list[Iterator[tuple[str, float]]]:
"""Iterates over the top difference data frames and generates records for the report overview.

:param top_diff: the top difference data frames

:return: a generator of the overview table records
"""
diff_iterators: list[Iterator[tuple[str, float]]] = []
for diff_data in [
top_diff.baseline_top_dec,
top_diff.target_top_inc,
top_diff.common_top_inc,
top_diff.common_top_dec,
]:
diff_iterators.append(
((symbol, diff_metric) for symbol, diff_metric in diff_data.iter_rows())
)
return diff_iterators


def iterate_polars_tabular(
tabular_profile: PolarsTabularTraceProfiles,
common_functions: pl.DataFrame,
Expand Down
Loading