Repository navigation
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3747 +/- ##
===========================================
+ Coverage 91.90% 92.02% +0.11%
===========================================
Files 63 71 +8
Lines 13943 14649 +706
===========================================
+ Hits 12815 13481 +666
- Misses 1128 1168 +40 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
victorusu
approved these changes
Oct 29, 2026
victorusu
left a comment
Contributor
There was a problem hiding this comment.
lgtm
You are going to kill me with these long PRs! 🤣🤣🤣🤣
Contributor
Author
It is admittedly quite long but I don't think it can be split in standalone parts. The only preliminary work that could stand by its own was the update of the report schema in #3722 which was a prerequisite for this one. |
Signed-off-by: Vasileios Karakasis <vkarak@gmail.com>
Signed-off-by: Vasileios Karakasis <vkarak@gmail.com>
Signed-off-by: Vasileios Karakasis <vkarak@gmail.com>
Signed-off-by: Vasileios Karakasis <vkarak@gmail.com>
vkarak
force-pushed
the
feat/resultsdb-v2
branch
from
October 30, 2026 21:40
de34485 to
93d21d9
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Analytics: a new results backend
This adds
analytics, a results backend that records every session into acolumnar database and queries it back with SQL, and deprecates the SQLite
result storage it supersedes. The two are mutually exclusive and analytics is
off by default, so nothing changes for existing users until they opt in.
What it changes for users
being reachable only through a fixed set of command-line options.
ReFrame, that users can extend with their own and that resolve by name or
by path.
Five templates ship in
share/reframe/queries/duckdb/:perf,perf-stats,perf-compare,perf-reportandref-suggestion.--performance-reportnow takes ashow/compare[:<agg>[:<N>d]]spec thatmaps onto the
perf-reporttemplate.Queries run read-only on a connection that cannot modify the database or
reach the file system, and template parameters are passed as bind parameters,
so their values never become part of the SQL text.
Benchmark
1,017k rows / 64k sessions of synthetic results, written into both backends in
the same pass so they hold identical data: 1.35 GB as analytics, 2.29 GB as
result storage.
uv run python tools/gen_analytics_data.py -n 64k \ --duckdb duckdb:///path/to/bench.duckdb --sqlite /path/to/bench.dbSix queries, each expressed for both backends where the deprecated query
syntax can express it at all. The window is a full month (45,788 rows);
Q5takes no time period by design and runs over everything.
Timings wrap only the query call, so interpreter and ReFrame start-up are
excluded. cold purges the page cache before every measurement and runs
each in a fresh process; hot is the best of 3 after a warm-up. Anything
unfinished after 60 s was cut off.
Row counts agree in every case except Q3, where the deprecated syntax cannot
restrict to a single performance variable and so returns 12 rows where the
template returns 6, and Q5, which was cut off.
Why the spread is so wide, since a single number would be misleading:
filtering and aggregating in Python after decoding it. Analytics stores typed
columns and lets the database do that work.
name in SQL before any JSON is decoded, and that family runs in few sessions.
Q1 and Q2 have no such filter, so every session of the month is decoded.
storage does (1.7x), which is CPU-bound on JSON decoding either way. The
absolute gap stays an order of magnitude.
The six queries
Ad-hoc template files written for the benchmark rather than the shipped
templates, so that each one has a counterpart to compare against. The
analytics window is June 2026 shifted by the local UTC offset, since the
template bounds are cast to a naive timestamp that the database reads as UTC
whereas the deprecated store parses
%Y%m%das local time; both backends thenselect exactly the same 45,788 rows.
Elided below: analytics takes the database as
--database=duckdb://<path>,while the deprecated store reads it from the configuration and so needs
RFM_ENABLE_RESULTS_STORAGE=1andRFM_SQLITE_DB_FILE=<path>.Q1 -- average performance per test case over a period
reframe analyze --query q1.sql \ start=2026-05-31T22:00:00 end=2026-06-30T22:00:00 reframe --list-stored-testcases='20260601:20260701/mean:/'Q2 -- as Q1, for one session attribute, listing the results seen
reframe analyze --query q2.sql osver=1.0 \ start=2026-05-31T22:00:00 end=2026-06-30T22:00:00 reframe --list-stored-testcases='20260601:20260701?os_version=="1.0"/mean:/+presult'Q3 -- one test family, broken down by its parameters
reframe analyze --query q3.sql test=GEMMTest pvar=tflops \ start=2026-05-31T22:00:00 end=2026-06-30T22:00:00 reframe --name=GEMMTest \ --list-stored-testcases='20260601:20260701/mean:basename,dtype,mode,pvar,punit/'The deprecated form cannot restrict to one performance variable, since
--filter-exprruns before a test case is expanded into one row perperformance variable. It therefore aggregates all of them and returns 12 rows
where the template returns 6; the 6
tflopsrows agree exactly.Q4 -- as Q3, plus a second performance variable of the same test case
reframe analyze --query q4.sql test=GEMMTest pvar=tflops \ start=2026-05-31T22:00:00 end=2026-06-30T22:00:00Not expressible with the deprecated syntax: a row carries only its own
performance variable, so a
tflopsrow has no way to reach thepowerof thesame test case.
Q5 -- compare two sets of results over the whole data set
reframe analyze --query q5.sql osver_lhs=1.0 osver_rhs=3.0 reframe --term-lhs=3.0 --term-rhs=1.0 \ --performance-compare='?os_version=="3.0"/?os_version=="1.0"/mean:basename,sysenv,pvar,punit/'The two backends define the difference in opposite directions, hence the
reversed order of the two comparison subspecs; with that order the percentages
agree exactly.
Q6 -- compare two subsets of one test family
reframe analyze --query q6.sql test=AllreduceTest \ block_lhs=block01 block_rhs=block02 \ start=2026-05-31T22:00:00 end=2026-06-30T22:00:00 reframe --name=AllreduceTest \ -E 'topology_block=="block02"' -E 'topology_block=="block01"' \ --term-lhs=block02 --term-rhs=block01 \ --performance-compare='20260601:20260701/20260601:20260701/mean:basename,nodes,pvar,punit/'Test system
MacBookPro15,2)1c1ddf4eSingle-laptop numbers on a synthetic data set: enough to show the shape of the
difference, not a claim about any particular production database.
Installation
Analytics needs
duckdbandpyarrow, which come with a new extra:pip install 'reframe-hpc[analytics]'polarsis no longer a default dependency, since it serves only thedeprecated result storage, which now has an opt-in extra of its own:
pip install 'reframe-hpc[analytics-legacy]'The
no-analyticsextra is removed. It existed to excludepolars, whichpipcannot do for a default dependency, so it came with a documentedwork-around; making
polarsopt-in removes both. The error message that thedeprecated options already print when
polarsis missing names the new extra.Configuration
A new
analyticsconfiguration section withenable,database,query_search_path,target_systemsand thewrite_retries_max/write_retry_interval_base/write_retry_interval_maxtrio, plus matchingRFM_ANALYTICS_*environment variables. Thegeneral.perf_report_specoptionis documented for the first time.
Exit codes
Rebased onto the exit-code convention of #3745, which
analyzefollows:0on success,
1on a generic error and2on command-line misuse, such as amalformed query parameter or no action at all. The statuses that report test
failures,
3and4, cannot occur there, sinceanalyzeruns no tests. Twocases of the main command move from
1to2, as incompatible optioncombinations: enabling both backends at once, and a malformed
--performance-reportspec.Deprecations
The SQLite result storage and everything around it are deprecated, not
removed: the
storage.*configuration options, theRFM_SQLITE_*andRFM_ENABLE_RESULTS_STORAGEenvironment variables, and the--list-stored-sessions,--list-stored-testcases,--describe-stored-sessions,--describe-stored-testcases,--delete-stored-sessionsand--performance-compareoptions. Enabling bothbackends at once is an error.
Existing JSON run reports of a supported data version can be loaded with
reframe analyze --import.Documentation
A new
reframe-analyze(1)man page, generated fromdocs/analytics.rstandshipped in the wheel, covering the command, the templates, the table schema
and the configuration. The tutorial gains a parallel section, and the
deprecated material is marked in place rather than deleted. CI now asserts
that the man page and the query templates are present in the built wheel.
Two fixes in the installation section, found while documenting the extras: an
extra cannot be attached to a plain
git+httpsURL, so the dev-releaseexamples now show the direct-reference form that can carry one; and
uv tool install reframe-hpc --extra graylog, which that section documented,has never worked --
uv tool installhas no--extraflag, only the bracketsnotation.
Tests
unittests/test_analytics.pyadds 120 tests covering the schema, theflattening, the template sandbox, the read-only query gate and the backend;
unittests/test_cli.pyadds coverage for the new command. Note thatduckdbandpyarrowhad to be added to thedevdependency group: the testmodule guards on them at module scope, so without them the whole file was
skipped silently and the suite had no coverage at all.
Closes #3638.
🤖 Generated with Claude Code