Skip to content

Commit feb42a8

Browse files
Merge pull request #1233 from dapomeroy/move_var_classes
Move variable classes from workload to new module
2 parents 3da0f39 + b043601 commit feb42a8

File tree

7 files changed

+234
-245
lines changed

7 files changed

+234
-245
lines changed

lib/ramble/ramble/cmd/common/info.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import ramble.cmd.common.arguments as arguments
1616
import ramble.repository
1717
import ramble.util.colors
18+
from ramble.definitions.variables import Variable
1819
from ramble.util.logger import logger
19-
from ramble.workload import WorkloadVariable
2020

2121
supported_formats = enum.Enum("formats", ["text", "lists"])
2222

@@ -203,7 +203,7 @@ def _print_verbose_dict_attr(internal_attr, pattern="*", indentation=(" " * 4)):
203203
color.cprint(f"{color_name}:")
204204
for sub_name, sub_val in vals.items():
205205
# Avoid showing duplicate names for variables
206-
if isinstance(sub_val, WorkloadVariable) and sub_name == sub_val.name:
206+
if isinstance(sub_val, Variable) and sub_name == sub_val.name:
207207
to_print = f"{indentation}{sub_val}"
208208
else:
209209
color_sub_name = ramble.util.colors.nested_1(sub_name)

lib/ramble/ramble/definitions/variables.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# option. This file may not be copied, modified, or distributed
77
# except according to those terms.
88

9+
import copy
910
from typing import List, Optional
1011

1112
import ramble.util.colors as rucolor
@@ -27,6 +28,213 @@ def _title_color(title: str, n_indent: int = 0):
2728
return out_str
2829

2930

31+
class Variable:
32+
"""Class representing a variable definition"""
33+
34+
def __init__(
35+
self,
36+
name: str,
37+
default=None,
38+
description: str = None,
39+
values=None,
40+
expandable: bool = True,
41+
track_used: bool = True,
42+
when=None,
43+
**kwargs,
44+
):
45+
"""Constructor for a new variable
46+
47+
Args:
48+
name (str): Name of variable
49+
default: Default value of variable
50+
description (str): Description of variable
51+
values: List of suggested values for variable
52+
expandable (bool): True if variable can be expanded, False otherwise
53+
track_used (bool): True if variable should be considered used,
54+
False to ignore it for vectorizing experiments
55+
when (list | None): List of when conditions to apply to directive
56+
"""
57+
self.name = name
58+
self.default = default
59+
self.description = description
60+
self.values = values.copy() if isinstance(values, list) else [values]
61+
self.expandable = expandable
62+
self.track_used = track_used
63+
self.when = when.copy() if when else []
64+
65+
def __str__(self):
66+
if not hasattr(self, "_str_indent"):
67+
self._str_indent = 0
68+
return self.as_str(n_indent=self._str_indent)
69+
70+
def as_str(self, n_indent: int = 0, verbose: bool = False):
71+
"""String representation of this variable
72+
73+
Args:
74+
n_indent (int): Number of spaces to indent string lines with
75+
76+
Returns:
77+
(str): Representation of this variable
78+
"""
79+
indentation = " " * n_indent
80+
81+
if verbose:
82+
print_attrs = ["Description", "Default", "Values"]
83+
84+
out_str = _title_color(f"{indentation}{self.name}:\n", n_indent)
85+
for print_attr in print_attrs:
86+
name = print_attr
87+
if print_attr == "Values":
88+
name = "Suggested Values"
89+
attr_name = print_attr.lower()
90+
91+
attr_val = getattr(self, attr_name, None)
92+
if attr_val:
93+
out_str += (
94+
f"{indentation} {_title_color(name, n_indent=n_indent + 4)}: "
95+
f'{str(attr_val).replace("@", "@@")}\n'
96+
)
97+
else:
98+
out_str = f"{indentation}{self.name}"
99+
100+
return out_str
101+
102+
def copy(self):
103+
return copy.deepcopy(self)
104+
105+
106+
class VariableModification:
107+
"""Class representing a variable modification"""
108+
109+
def __init__(
110+
self,
111+
name: str,
112+
modification: str,
113+
method: str = "set",
114+
separator: str = " ",
115+
when=None,
116+
**kwargs,
117+
):
118+
"""Constructor for a new variable modification
119+
120+
Args:
121+
name (str): The variable to modify
122+
modification (str): The value to modify 'name' with
123+
method (str): How the modification should be applied
124+
mode (str): Single mode to group this modification into
125+
modes (str): List of modes to group this modification into
126+
separator (str): Optional separator to use when modifying with 'append' or
127+
'prepend' methods.
128+
when (list | None): List of when conditions this modification should apply in
129+
130+
Supported values are 'append', 'prepend', and 'set':
131+
'append' will add the modification to the end of 'name'
132+
'prepend' will add the modification to the beginning of 'name'
133+
'set' (Default) will overwrite 'name' with the modification
134+
"""
135+
self.name = name
136+
self.modification = modification
137+
self.method = method
138+
self.separator = separator
139+
self.when = when.copy() if when else []
140+
141+
def __str__(self):
142+
if not hasattr(self, "_str_indent"):
143+
self._str_indent = 0
144+
return self.as_str(n_indent=self._str_indent)
145+
146+
def as_str(self, n_indent: int = 0, verbose: bool = False):
147+
"""String representation of this variable
148+
149+
Args:
150+
n_indent (int): Number of spaces to indent string lines with
151+
152+
Returns:
153+
(str): Representation of this variable
154+
"""
155+
indentation = " " * n_indent
156+
157+
print_attrs = ["Modification", "Method", "Separator", "When"]
158+
159+
out_str = _title_color(f"{indentation}{self.name}:\n", n_indent)
160+
for print_attr in print_attrs:
161+
name = print_attr
162+
attr_name = print_attr.lower()
163+
164+
attr_val = getattr(self, attr_name, None)
165+
if attr_val:
166+
if print_attr == "Separator":
167+
attr_val = f"'{attr_val}'"
168+
out_str += (
169+
f"{indentation} {_title_color(name, n_indent=n_indent + 4)}: "
170+
f'{str(attr_val).replace("@", "@@")}\n'
171+
)
172+
return out_str
173+
174+
def copy(self):
175+
return copy.deepcopy(self)
176+
177+
178+
class EnvironmentVariable:
179+
"""Class representing an environment variable"""
180+
181+
def __init__(
182+
self,
183+
name: str,
184+
value=None,
185+
description: str = None,
186+
when=None,
187+
**kwargs,
188+
):
189+
"""EnvironmentVariable constructor
190+
191+
Args:
192+
name (str): Name of environment variable
193+
value: Value to set environment variable to
194+
description (str): Description of the environment variable
195+
when (list | None): List of when conditions to apply to directive
196+
"""
197+
self.name = name
198+
self.value = value
199+
self.description = description
200+
self.when = when.copy() if when else []
201+
202+
def __str__(self):
203+
if not hasattr(self, "_str_indent"):
204+
self._str_indent = 0
205+
return self.as_str(n_indent=self._str_indent)
206+
207+
def as_str(self, n_indent: int = 0, verbose: bool = False):
208+
"""String representation of environment variable
209+
210+
Args:
211+
n_indent (int): Number of spaces to indent string representation by
212+
213+
Returns:
214+
(str): String representing this environment variable
215+
"""
216+
indentation = " " * n_indent
217+
218+
if verbose:
219+
print_attrs = ["Description", "Value"]
220+
out_str = _title_color(f"{indentation}{self.name}:\n", n_indent)
221+
for name in print_attrs:
222+
attr_name = name.lower()
223+
attr_val = getattr(self, attr_name, None)
224+
if attr_val:
225+
out_str += (
226+
f"{indentation} {_title_color(name, n_indent=n_indent + 4)}: "
227+
f'{str(attr_val).replace("@", "@@")}\n'
228+
)
229+
else:
230+
out_str = f"{indentation}{self.name}"
231+
232+
return out_str
233+
234+
def copy(self):
235+
return copy.deepcopy(self)
236+
237+
30238
class EnvironmentVariableModifications:
31239
"""Class representing modifications of an environment variable"""
32240

@@ -123,6 +331,9 @@ def as_str(self, n_indent: int = 0, verbose: bool = False):
123331

124332
return out_str
125333

334+
def copy(self):
335+
return copy.deepcopy(self)
336+
126337
def add_modification(
127338
self,
128339
modification: str,

lib/ramble/ramble/language/application_language.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# option. This file may not be copied, modified, or distributed
77
# except according to those terms.
88

9+
import ramble.definitions.variables
910
import ramble.language.language_helpers
1011
import ramble.language.shared_language
1112
import ramble.workload
@@ -266,7 +267,7 @@ def _execute_workload_variable(app):
266267
when, app, name, "workload_variable"
267268
)
268269

269-
workload_var = ramble.workload.WorkloadVariable(
270+
workload_var = ramble.definitions.variables.Variable(
270271
name,
271272
default=default,
272273
description=description,

lib/ramble/ramble/language/modifier_language.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import ramble.definitions.requirements
1212
import ramble.language.language_helpers
1313
import ramble.language.shared_language
14-
from ramble.definitions.variables import EnvironmentVariableModifications
14+
from ramble.definitions.variables import EnvironmentVariableModifications, VariableModification
1515
from ramble.language.language_base import DirectiveError
1616

1717

@@ -99,8 +99,6 @@ def variable_modification(
9999
"""
100100

101101
def _execute_variable_modification(mod):
102-
import ramble.workload
103-
104102
supported_methods = ["append", "prepend", "set"]
105103
if method not in supported_methods:
106104
raise DirectiveError(
@@ -120,7 +118,7 @@ def _execute_variable_modification(mod):
120118
mod.variable_modifications[when_set][name] = []
121119

122120
mod.variable_modifications[when_set][name].append(
123-
ramble.workload.WorkloadVariableModification(
121+
VariableModification(
124122
name=name,
125123
modification=modification,
126124
method=method,
@@ -296,7 +294,6 @@ def modifier_variable(
296294
"""
297295

298296
def _define_modifier_variable(mod):
299-
import ramble.workload
300297

301298
all_modes = ramble.language.language_helpers.merge_definitions(
302299
mode, modes, mod.modes, "mode", "modes", "modifier_variable"

lib/ramble/ramble/language/shared_language.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ def variable(
798798
"""
799799

800800
def _define_variable(obj):
801-
import ramble.workload
801+
import ramble.definitions.variables
802802

803803
when_list = ramble.language.language_helpers.build_when_list(
804804
when, obj, name, error_context
@@ -810,7 +810,7 @@ def _define_variable(obj):
810810
obj.object_variables[when_set] = []
811811

812812
obj.object_variables[when_set].append(
813-
ramble.workload.WorkloadVariable(
813+
ramble.definitions.variables.Variable(
814814
name,
815815
default=default,
816816
description=description,
@@ -854,7 +854,7 @@ def _execute_environment_variable(obj):
854854
when, obj, name, "environment_variable"
855855
)
856856

857-
workload_env_var = ramble.workload.WorkloadEnvironmentVariable(
857+
workload_env_var = ramble.definitions.variables.EnvironmentVariable(
858858
name, value=value, description=description, when=when_list, **kwargs
859859
)
860860

lib/ramble/ramble/test/application.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import pytest
1111

12+
import ramble.definitions.variables
1213
import ramble.workload
1314
import ramble.workspace
1415

@@ -415,7 +416,7 @@ def test_set_variables_and_variants(mutable_mock_apps_repo):
415416

416417
test_wl = ramble.workload.Workload("test_wl", executables=["foo"], inputs=["input"])
417418
test_wl2 = ramble.workload.Workload("test_wl2", executables=["bar"], inputs=["input"])
418-
test_wl2.add_variable(ramble.workload.WorkloadVariable("n_ranks", default="1"))
419+
test_wl2.add_variable(ramble.definitions.variables.Variable("n_ranks", default="1"))
419420
executable_application_instance.workloads[_FS] = {"test_wl": test_wl, "test_wl2": test_wl2}
420421

421422
executable_application_instance.internals = {}
@@ -442,7 +443,7 @@ def test_define_commands(mutable_mock_apps_repo):
442443

443444
test_wl = ramble.workload.Workload("test_wl", executables=["foo"], inputs=["input"])
444445
test_wl2 = ramble.workload.Workload("test_wl2", executables=["bar"], inputs=["input"])
445-
test_wl2.add_variable(ramble.workload.WorkloadVariable("n_ranks", default="1"))
446+
test_wl2.add_variable(ramble.definitions.variables.Variable("n_ranks", default="1"))
446447
executable_application_instance.workloads[_FS] = {"test_wl": test_wl, "test_wl2": test_wl2}
447448

448449
executable_application_instance.internals = {}
@@ -508,7 +509,7 @@ def test_derive_variables_for_template_path(mutable_mock_apps_repo, workspace_na
508509

509510
test_wl = ramble.workload.Workload("test_wl", executables=["foo"], inputs=["input"])
510511
test_wl2 = ramble.workload.Workload("test_wl2", executables=["bar"], inputs=["input"])
511-
test_wl2.add_variable(ramble.workload.WorkloadVariable("n_ranks", default="1"))
512+
test_wl2.add_variable(ramble.definitions.variables.Variable("n_ranks", default="1"))
512513
executable_application_instance.workloads[_FS] = {"test_wl": test_wl, "test_wl2": test_wl2}
513514

514515
executable_application_instance.internals = {}

0 commit comments

Comments
 (0)