Skip to content

Commit 1940b76

Browse files
Add success criteria summary to results
This commit adds a summary of each success criteria for each experiment, along with the result of the success criteria. This can be useful to help debug what causes the experiment result to be whatever it was.
1 parent a32170b commit 1940b76

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

lib/ramble/ramble/experiment_result.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class ExperimentStatus(str, Enum):
3636
"raw_variables": "RAMBLE_RAW_VARIABLES",
3737
namespace.tags: "TAGS",
3838
"experiment_chain": "EXPERIMENT_CHAIN",
39+
"success_criteria": "SUCCESS_CRITERIA",
3940
}
4041

4142

@@ -56,6 +57,7 @@ def __init__(self, app_inst):
5657
self.experiment_chain = app_inst.chain_order.copy()
5758
self.tags = list(app_inst.experiment_tags)
5859
self.contexts = []
60+
self.success_criteria = {}
5961
self.software = {}
6062

6163
self.keys = {}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright 2022-2025 The Ramble Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
# https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
# option. This file may not be copied, modified, or distributed
7+
# except according to those terms.
8+
9+
import os
10+
11+
import pytest
12+
13+
import ramble.workspace
14+
from ramble.main import RambleCommand
15+
16+
# everything here uses the mock_workspace_path
17+
pytestmark = pytest.mark.usefixtures("mutable_config", "mutable_mock_workspace_path")
18+
19+
workspace = RambleCommand("workspace")
20+
ramble_on = RambleCommand("on")
21+
22+
23+
def test_success_criteria_summary(mock_applications, workspace_name):
24+
test_config = """
25+
ramble:
26+
variables:
27+
mpi_command: 'mpirun -n {n_ranks} -ppn {processes_per_node}'
28+
batch_submit: '{execute_experiment}'
29+
processes_per_node: '1'
30+
n_threads: '1'
31+
applications:
32+
basic:
33+
workloads:
34+
working_wl:
35+
experiments:
36+
pass-experiment:
37+
variables:
38+
n_nodes: 1
39+
success_criteria:
40+
- name: always-pass
41+
mode: string
42+
match: '.*seconds.*'
43+
fail-experiment:
44+
variables:
45+
n_nodes: 1
46+
success_criteria:
47+
- name: always-fail
48+
mode: string
49+
match: 'Blarg'
50+
software:
51+
packages: {}
52+
environments: {}
53+
"""
54+
with ramble.workspace.create(workspace_name) as ws:
55+
ws.write()
56+
57+
config_path = os.path.join(ws.config_dir, ramble.workspace.config_file_name)
58+
59+
with open(config_path, "w+") as f:
60+
f.write(test_config)
61+
ws._re_read()
62+
63+
workspace("setup", global_args=["-w", workspace_name])
64+
ramble_on(global_args=["-w", workspace_name])
65+
workspace("analyze", "-f", "text", "json", "yaml", global_args=["-w", workspace_name])
66+
67+
for extension in ["txt", "json", "yaml"]:
68+
with open(os.path.join(ws.root, "results.latest.txt")) as f:
69+
data = f.read()
70+
assert "Success criteria summary:" in data
71+
assert "_application_function = PASSED" in data
72+
assert "always-pass = PASSED" in data
73+
assert "always-fail = FAILED" in data

lib/ramble/ramble/workspace/workspace.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,10 @@ def dump_results(self, output_formats=None, print_results=False, summary_only=Fa
16621662
if software_key in exp and exp[software_key]:
16631663
self.write_software_info(f, exp)
16641664

1665+
if exp["SUCCESS_CRITERIA"]:
1666+
f.write(" Success criteria summary:\n")
1667+
for name, result in exp["SUCCESS_CRITERIA"].items():
1668+
f.write(f" {name} = {result}\n")
16651669
else:
16661670
logger.msg("No results to write")
16671671

var/ramble/repos/builtin/base_classes/application-base/base_class.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,12 @@ def format_context(context_match, context_format):
23902390

23912391
self._init_result()
23922392

2393+
for criteria_obj in criteria_list.all_criteria():
2394+
if criteria_obj.ok():
2395+
self.result.success_criteria[criteria_obj.name] = "PASSED"
2396+
else:
2397+
self.result.success_criteria[criteria_obj.name] = "FAILED"
2398+
23932399
for context, fom_map in fom_values.items():
23942400
context_map = {
23952401
"name": context,

0 commit comments

Comments
 (0)