Skip to content

Commit

Permalink
Improved text truncation for publish. Purge deleted benchmarks on query
Browse files Browse the repository at this point in the history
  • Loading branch information
stanbrub committed Oct 18, 2023
1 parent 1d2c92b commit 7a30de4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 27 deletions.
File renamed without changes.
47 changes: 47 additions & 0 deletions docs/demo/NightlyDashboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Nightly Dashboard

Deephaven benchmarks run every night and summary tables (not show here) are published internally so that
developers can see how performance changed during the last nightly build. If more investigation is
needed, the logical next step is to search the benchmark data to get more details.

The Nightly Dashboard allows a quick way to dig into the available data to get some clues to
performance issues or see more clearer why performance has improved.

This Dashboard is built using Deephaven's [scripted UI](https://deephaven.io/core/docs/how-to-guides/plotting/category/)
using the Benchmark Tables snippet used in the previous notebook.

```python
from urllib.request import urlopen; import os

root = 'file:///nfs' if os.path.exists('/nfs/deephaven-benchmark') else 'https://storage.googleapis.com'
with urlopen(root + '/deephaven-benchmark/benchmark_tables.dh.py') as r:
benchmark_storage_uri_arg = root + '/deephaven-benchmark'
benchmark_category_arg = 'release' # release | nightly
benchmark_max_runs_arg = 5 # Latest X runs to include
exec(r.read().decode(), globals(), locals())
```
The script works with the benchmark data stored on this demo system but also works in any
[Deephaven Community Core](https://deephaven.io/core/docs/) instance that has
internet connectivity. Copy the script and any additions you have made to another
Deephaven notebook and run just as you did here.

## How Does This Python Snippet Work?

The following is a line-by-line walkthrough of what the above script is doing:
1. Import the [_urllib.request_](https://docs.python.org/3/library/urllib.request.html) package and set up _urlopen_ for use
2. Blank
3. Detect the parent location of the benchmark data; local Deephaven data directory or GCloud data directory
4. Open the *benchmark_tables* script from the discovered parent location
5. Tell the *benchmark_tables* script where the benchmark data is
6. Tell the *benchmark_tables* script what set of data to process
7. Tell the *benchmark_tables* script how many benchmark runs to include
8. Execute the *benchmark_tables* script to generate the tables

Script Arguments:
1. *benchmark_storage_uri_arg*:
- Where to load benchmark data from (don't change if you want to use Deephaven data storage)
2. *benchmark_category_arg*:
- _release_ for benchmarks collected on a specific [Deephaven releases](https://github.com/deephaven/deephaven-core/releases)
- _nightly_ for benchmarks collected every night
3. *benchmark_max_runs_arg*:
- The number of benchmark runs to include, starting from latest
47 changes: 25 additions & 22 deletions src/main/java/io/deephaven/benchmark/run/PublishNotification.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,32 @@ public void publish() {
var query = Filer.getURLText(queryFile);
var svgTemp = new String[] {Filer.getURLText(svgTemplate)};
Bench api = Bench.create("# Publish Notification");
api.setName("# Publish");
slackChannel = api.property("slack.channel", "");
slackToken = api.property("slack.token", "");
if (slackChannel.isBlank() || slackToken.isBlank()) {
api.close();
System.out.println("-- Slack properties is not defined, skipping query notification --");
return;
}
System.out.println("-- Running notification queries --");
var aquery = api.query(query);
aquery.fetchAfter("platform_details", table -> {
svgTemp[0] = updatePlatformDetails(table, svgTemp[0]);
});
for (String tableName : tables) {
aquery.fetchAfter(tableName + "_small", table -> {
generateCsv(table, outputDir, tableName + ".csv");
});
aquery.fetchAfter(tableName + "_large", table -> {
generateSvg(table, svgTemp[0], outputDir, tableName + ".svg");
try {
api.setName("# Publish");
slackChannel = api.property("slack.channel", "");
slackToken = api.property("slack.token", "");
if (slackChannel.isBlank() || slackToken.isBlank()) {
api.close();
System.out.println("-- Slack properties is not defined, skipping query notification --");
return;
}
System.out.println("-- Running notification queries --");
var aquery = api.query(query);
aquery.fetchAfter("platform_details", table -> {
svgTemp[0] = updatePlatformDetails(table, svgTemp[0]);
});
for (String tableName : tables) {
aquery.fetchAfter(tableName + "_small", table -> {
generateCsv(table, outputDir, tableName + ".csv");
});
aquery.fetchAfter(tableName + "_large", table -> {
generateSvg(table, svgTemp[0], outputDir, tableName + ".svg");
});
}
aquery.execute();
} finally {
api.close();
}
aquery.execute();
api.close();

publishToSlack(outputDir);
}
Expand All @@ -82,7 +85,7 @@ void publishToSlack(Path outDir) {
}

var payload = """
{"channel": "${channel}", "icon_emoji": ":horse_racing:", "unfurl_links": "false",
{"channel": "${channel}", "icon_emoji": ":horse_racing", "unfurl_links": "false",
"unfurl_media": "false", "text": "${msg}"}
""";
payload = payload.replace("${channel}", slackChannel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@ def zscore(rate, rates):
return (rate - statistics.mean(rates)) / statistics.pstdev(rates)

def zprob(zscore):
lower = -abs(zscore)
upper = abs(zscore)
return 1 - (statistics.NormalDist().cdf(upper) - statistics.NormalDist().cdf(lower))
lower = -abs(zscore)
upper = abs(zscore)
return 1 - (statistics.NormalDist().cdf(upper) - statistics.NormalDist().cdf(lower))

def truncate(text, size):
if len(text) < size - 3: return text
return text[:size-3] + '...'

# Used to provide platform (e.g. hardware, jvm version) for SVG footer during publish
platform_details = bench_platforms.sort_descending(['run_id']).group_by(['run_id']).first_by().ungroup()

# Ensure that deleted benchmarks are not included in latest benchmarks
latest_benchmark_names = bench_results.view([
'epoch_day=(int)(timestamp/1000/60/60/24)','benchmark_name'
]).group_by(['epoch_day']).sort_descending(['epoch_day']).first_by().ungroup()
bench_results = bench_results.where_in(latest_benchmark_names,['benchmark_name=benchmark_name'])

nightly_worst_rate_change = bench_results.where([
'benchmark_name.endsWith(`-Static`)'
]).exact_join(
Expand Down Expand Up @@ -60,8 +71,8 @@ def zprob(zscore):
])

nightly_worst_rate_change_small = nightly_worst_rate_change.head_by(10).view([
'Static_Benchmark=Static_Benchmark.substring(0, Math.min(50,Static_Benchmark.length()))+`...`',
'Chng5d=Change','Var5d=Variability','Rate','ChngRls=Since_Release','ScrProb=Score_Prob'
'Static_Benchmark=truncate(Static_Benchmark,50)','Chng5d=Change',
'Var5d=Variability','Rate','ChngRls=Since_Release','ScrProb=Score_Prob'
]).format_columns([
'Rate=Decimal(`###,##0`)','Chng5d=Decimal(`0.0%`)','Var5d=Decimal(`0.0%`)',
'ChngRls=Decimal(`0.0%`)','ScrProb=Decimal(`0.00%`)'
Expand Down

0 comments on commit 7a30de4

Please sign in to comment.