Skip to content

Commit 488b94f

Browse files
committed
Add description fields for Implementation and Component
1 parent 0ed2a62 commit 488b94f

10 files changed

Lines changed: 84 additions & 40 deletions

File tree

‎ymmsl/conversion/convert_v0_1_to_v0_2.py‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ def convert_v0_1_to_v0_2(config: v0_1.PartialConfiguration) -> v0_2.Configuratio
3131

3232
def convert_component(component: v0_1.Component) -> v0_2.Component:
3333
"""Convert a v0.1 Component object to a v0.2 Component."""
34-
ports = component.ports if component.ports else v0_1.Ports()
34+
ports = component.ports if component.ports else v0_2.Ports()
3535
implementation: Optional[str] = None
3636
if component.implementation is not None:
3737
implementation = str(component.implementation)
3838

3939
return v0_2.Component(
40-
str(component.name), ports, implementation, component.multiplicity)
40+
str(component.name), ports, '', implementation, component.multiplicity)
4141

4242

4343
def convert_conduit(conduit: v0_1.Conduit) -> v0_2.Conduit:
@@ -56,10 +56,11 @@ def convert_model(model: v0_1.ModelReference) -> v0_2.Model:
5656
"""
5757
if isinstance(model, v0_1.Model):
5858
return v0_2.Model(
59-
str(model.name), None, list(map(convert_component, model.components)),
59+
str(model.name), None, '',
60+
list(map(convert_component, model.components)),
6061
list(map(convert_conduit, model.conduits)))
6162
else:
62-
return v0_2.Model(str(model.name), None, [], [])
63+
return v0_2.Model(str(model.name), None, '', [], [])
6364

6465

6566
def convert_implementation(impl: v0_1.Implementation) -> v0_2.Program:
@@ -78,7 +79,7 @@ def convert_implementation(impl: v0_1.Implementation) -> v0_2.Program:
7879
'In yMMSL v0.2 implementations have become programs, and you can now'
7980
' specify the ports of a program in the yMMSL description. If your program'
8081
' has fixed ports then you should do this, because it will make incorrect'
81-
' wiring easier to debug.')
82+
' wiring easier to debug. While there, add a description too!')
8283

8384
base_env: Optional[v0_1.BaseEnv] = impl.base_env
8485
env: Optional[Dict[str, str]] = impl.env
@@ -90,6 +91,6 @@ def convert_implementation(impl: v0_1.Implementation) -> v0_2.Program:
9091
env = None
9192

9293
return v0_2.Program(
93-
str(impl.name), None, base_env, impl.modules, impl.virtual_env, env,
94+
str(impl.name), None, '', base_env, impl.modules, impl.virtual_env, env,
9495
impl.execution_model, impl.executable, impl.args, impl.script,
9596
impl.can_share_resources, impl.keeps_state_for_next_use)

‎ymmsl/v0_2/component.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,28 @@ class Component:
1818
Attributes:
1919
name: The name of this component
2020
ports: The ports by which this component can be connected to others
21+
description: A human-readable description of this component
2122
implementation: A Model or Program implementing this component
2223
multiplicity: The shape of the set of instances
2324
"""
2425
def __init__(
2526
self, name: str, ports: Ports,
27+
description: str,
2628
implementation: Optional[str] = None,
2729
multiplicity: Union[None, int, List[int]] = None) -> None:
2830
"""Create a Component
2931
3032
Args:
3133
name: The name of the component, must be a valid Identifier
34+
description: Human-readable description of this component
3235
ports: Ports on this component that can be used to connect it
3336
implementation: The name of the implementation, must be a valid Reference
3437
multiplicity: The shape of the set of instances, or a number describing the
3538
size of a 1D set of them, or None to have a single instance.
3639
"""
3740
self.name = Identifier(name)
3841
self.ports = ports
42+
self.description = description
3943

4044
if implementation is not None:
4145
self.implementation: Optional[Reference] = Reference(implementation)

‎ymmsl/v0_2/implementation.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ class Implementation:
1717
ports: The ports this implementation has on which it sends and receives messages
1818
"""
1919
def __init__(
20-
self, name: str, ports: Optional[Ports] = None) -> None:
20+
self, name: str, ports: Optional[Ports] = None,
21+
description: str = 'Please add a description!') -> None:
2122
"""Create an Implementation
2223
2324
Args:
2425
name: Name of this implementation, must be a valid reference
2526
ports: The ports this implementation communicates on
27+
description: Human-readable description of this implementation
2628
"""
2729
if not isinstance(name, Reference):
2830
self.name = Reference(name)
@@ -33,3 +35,5 @@ def __init__(
3335
self.ports = Ports()
3436
else:
3537
self.ports = ports
38+
39+
self.description = description

‎ymmsl/v0_2/model.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,22 +143,25 @@ class Model(Implementation):
143143
Attributes:
144144
name: The name by which this simulation model is known to the system.
145145
ports: Ports through which this model can communicate with other models.
146+
description: Human-readable description of the model.
146147
components: A list of components making up the model.
147148
conduits: A list of conduits connecting the components.
148149
"""
149150
def __init__(
150151
self, name: str, ports: Optional[Ports] = None,
152+
description: str = '',
151153
components: Optional[List[Component]] = None,
152154
conduits: Optional[Sequence[AnyConduit]] = None) -> None:
153155
"""Create a Model.
154156
155157
Args:
156158
name: Name of this model, must be a valid reference
157159
ports: Ports of this model
160+
description: Human-readable description of the model
158161
components: A list of components making up the model
159162
conduits: A list of conduits connecting the components
160163
"""
161-
super().__init__(name, ports)
164+
super().__init__(name, ports, description)
162165

163166
if components is None:
164167
self.components = []

‎ymmsl/v0_2/program.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Program(Implementation):
4646
Attributes:
4747
name: Name of the program
4848
ports: Ports this program supports, if fixed
49+
description: Human-readable description of this program
4950
base_env: Base environment to start from
5051
modules: HPC software modules to load
5152
virtual_env: Path to a virtual env to activate
@@ -63,6 +64,7 @@ def __init__(
6364
self,
6465
name: str,
6566
ports: Optional[Ports] = None,
67+
description: str = '',
6668
base_env: Optional[BaseEnv] = None,
6769
modules: Union[str, List[str], None] = None,
6870
virtual_env: Optional[Path] = None,
@@ -89,6 +91,7 @@ def __init__(
8991
Args:
9092
name: Name of the program, must be a valid reference
9193
ports: Ports this program has
94+
description: Human-readable description of this program
9295
base_env: Base environment to start from, defaults to clean
9396
modules: HPC software modules to load
9497
virtual_env: Path to a virtual env to activate
@@ -102,7 +105,7 @@ def __init__(
102105
keeps_state_for_next_use: Does this program keep state for the next
103106
iteration of the reuse loop. See :class:`KeepsStateForNextUse`.
104107
"""
105-
super().__init__(name, ports)
108+
super().__init__(name, ports, description)
106109

107110
if script is not None:
108111
err_arg = []

‎ymmsl/v0_2/tests/conftest.py‎

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def test_config5() -> Configuration:
7878
'macro', Ports(
7979
f_init='init', o_i=['out1', 'out2'], s=['in1', 'in2'],
8080
o_f=['final']),
81+
'description',
8182
BaseEnv.LOGIN,
8283
['gcc/13.3.0', 'FFTW/3.2.1'],
8384
Path('/home/user/.venv'),
@@ -110,6 +111,7 @@ def test_config5_text() -> str:
110111
' - in2\n'
111112
' o_f:\n'
112113
' - final\n'
114+
' description: description\n'
113115
' base_env: login\n'
114116
' modules:\n'
115117
' - gcc/13.3.0\n'
@@ -132,6 +134,7 @@ def test_config6() -> Configuration:
132134
model1 = Model(
133135
'resources_test',
134136
None,
137+
'description',
135138
[
136139
Component('singlethreaded', Ports(), 'a'),
137140
Component('multithreaded', Ports(), 'b'),
@@ -141,6 +144,7 @@ def test_config6() -> Configuration:
141144
model2 = Model(
142145
'resources_test2',
143146
None,
147+
'description',
144148
[
145149
Component('mpi_cores1', Ports(), 'c'),
146150
Component('mpi_cores2', Ports(), 'd'),
@@ -161,9 +165,12 @@ def test_config6() -> Configuration:
161165

162166
@pytest.fixture
163167
def test_config7() -> Configuration:
164-
model1 = Model('got_resources', None, [Component('singlethreaded', Ports(), 'a')])
168+
model1 = Model(
169+
'got_resources', None, 'description',
170+
[Component('singlethreaded', Ports(), 'description', 'a')])
165171
model2 = Model(
166-
'missing_resources', None, [Component('singlethreaded', Ports(), 'b')])
172+
'missing_resources', None, 'description',
173+
[Component('singlethreaded', Ports(), 'description', 'b')])
167174
resources = [ThreadedResReq(Ref('got_resources.singlethreaded'), 1)]
168175

169176
return Configuration('test_config7', None, [model1, model2], None, None, resources)
@@ -173,24 +180,27 @@ def test_config7() -> Configuration:
173180
def test_config8() -> Configuration:
174181
model1 = Model(
175182
'implementations_test',
176-
None,
183+
None, 'description',
177184
[
178-
Component('no_implementation', Ports(o_i=['out'], s=['in']), None),
179185
Component(
180-
'impl_no_ports', Ports(f_init=['in'], o_f=['out']), 'no_ports'),
186+
'no_implementation', Ports(o_i=['out'], s=['in']), 'description',
187+
None),
188+
Component(
189+
'impl_no_ports', Ports(f_init=['in'], o_f=['out']), 'description',
190+
'no_ports'),
181191
])
182192

183193
model2 = Model(
184194
'implementations_test2',
185-
None,
195+
None, 'description',
186196
[
187197
Component(
188198
'impl_with_ports', Ports(f_init=['in'], o_f=['out']), 'with_ports'),
189199
])
190200

191201
programs = [
192202
Program(
193-
'no_ports', None,
203+
'no_ports', None, 'description',
194204
script='/home/user/models/bin/modela'),
195205
Program(
196206
'with_ports',
@@ -212,21 +222,25 @@ def test_config8() -> Configuration:
212222
def test_config9() -> Configuration:
213223
model1 = Model(
214224
'implementations_test_broken',
215-
None,
225+
None, 'description',
216226
[
217-
Component('no_implementation', Ports(o_i=['out'], s=['in']), None),
218227
Component(
219-
'impl_ports_mismatch', Ports(f_init=['in'], o_f=['out']), 'ports1'),
228+
'no_implementation', Ports(o_i=['out'], s=['in']), 'description',
229+
None),
230+
Component(
231+
'impl_ports_mismatch', Ports(f_init=['in'], o_f=['out']),
232+
'description', 'ports1'),
220233
])
221234

222235
model2 = Model(
223236
'implementations_test2',
224-
None,
237+
None, 'description',
225238
[
226239
Component(
227-
'impl_also_wrong', Ports(o_i=['out'], s=['in']), 'ports2'),
240+
'impl_also_wrong', Ports(o_i=['out'], s=['in']), 'description',
241+
'ports2'),
228242
Component(
229-
'impl_extra_ports', Ports(f_init=['in']), 'ports3'),
243+
'impl_extra_ports', Ports(f_init=['in']), 'description', 'ports3'),
230244
])
231245

232246
programs = [

‎ymmsl/v0_2/tests/test_component.py‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55

66
def test_component_declaration() -> None:
7-
test_decl = Component('test', Ports(), 'ns.model')
7+
test_decl = Component('test', Ports(), 'description', 'ns.model')
88
assert isinstance(test_decl.name, Identifier)
99
assert str(test_decl.name) == 'test'
1010

1111
assert len(test_decl.ports.f_init) == 0
1212

13+
assert test_decl.description == 'description'
14+
1315
assert isinstance(test_decl.implementation, Reference)
1416
assert str(test_decl.implementation) == 'ns.model'
1517

@@ -18,39 +20,39 @@ def test_component_declaration() -> None:
1820

1921

2022
def test_component_multiplicity() -> None:
21-
test_decl = Component('test', Ports(), 'ns.model', 10)
23+
test_decl = Component('test', Ports(), 'description', 'ns.model', 10)
2224
assert isinstance(test_decl.name, Identifier)
2325
assert str(test_decl.name) == 'test'
2426
assert test_decl.multiplicity == [10]
2527
assert str(test_decl) == 'test[0:10]'
2628

27-
test_decl = Component('test', Ports(), 'ns2.model2', [1, 2])
29+
test_decl = Component('test', Ports(), 'description', 'ns2.model2', [1, 2])
2830
assert isinstance(test_decl.name, Identifier)
2931
assert str(test_decl.name) == 'test'
3032
assert str(test_decl.implementation) == 'ns2.model2'
3133
assert test_decl.multiplicity == [1, 2]
3234
assert str(test_decl) == 'test[0:1][0:2]'
3335

3436
with pytest.raises(ValueError):
35-
test_decl = Component('test', Ports(), 'ns2.model2[1]')
37+
test_decl = Component('test', Ports(), 'description', 'ns2.model2[1]')
3638

3739

3840
def test_component_instances() -> None:
3941
c1 = Component('test', Ports(), 'model')
4042
assert c1.instances() == [Reference('test')]
4143

42-
c2 = Component('test', Ports(), 'model', 3)
44+
c2 = Component('test', Ports(), 'description', 'model', 3)
4345
assert c2.instances() == [
4446
Reference('test[0]'), Reference('test[1]'), Reference('test[2]')]
4547

46-
c3 = Component('test', Ports(), 'model', [2, 2])
48+
c3 = Component('test', Ports(), 'description', 'model', [2, 2])
4749
assert c3.instances() == [
4850
Reference('test[0][0]'), Reference('test[0][1]'),
4951
Reference('test[1][0]'), Reference('test[1][1]')]
5052

5153

5254
def test_component_ports() -> None:
53-
c = Component('test', Ports(['init'], ['out'], ['in'], ['final']))
55+
c = Component('test', Ports(['init'], ['out'], ['in'], ['final']), 'description')
5456
assert isinstance(c.ports, Ports)
5557

5658
assert c.ports.f_init == ['init']

‎ymmsl/v0_2/tests/test_configuration.py‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
def test_configuration() -> None:
1818
setting_values: OrderedDict[str, SettingValue] = OrderedDict()
1919
settings = Settings(setting_values)
20-
model1 = Model('model1', None, [])
21-
model2 = Model('model2', None, [])
22-
config = Configuration('testing', None, [model1, model2], settings)
20+
model1 = Model('model1', None, 'description', [])
21+
model2 = Model('model2', None, 'description', [])
22+
config = Configuration('description', None, [model1, model2], settings)
2323

24-
assert config.description == 'testing'
24+
assert config.description == 'description'
2525

2626
assert len(config.models) == 2
2727
assert config.models[Ref('model1')] is model1
@@ -42,16 +42,19 @@ def test_load_models() -> None:
4242
' ports:\n'
4343
' o_i: out\n'
4444
' s: in\n'
45+
' description: the macro component\n'
4546
' implementation: macro_program\n'
4647
' micro:\n'
4748
' ports:\n'
4849
' f_init: init\n'
4950
' o_f: final\n'
51+
' description: the micro component\n'
5052
' implementation: micro_program\n'
5153
' do_nothing:\n'
5254
' components:\n'
5355
' nil:\n'
5456
' ports: {}\n'
57+
' description: a component that does nothing\n'
5558
' implementation: nil_program\n'
5659
)
5760

@@ -198,23 +201,26 @@ def test_configuration_update_description() -> None:
198201

199202
def test_configuration_update_model_error() -> None:
200203
base = Configuration(
201-
'Configuration for testing', None, [Model('model', Ports(), [
202-
Component('macro', Ports(o_i='out', s='in')),
203-
Component('micro', Ports(f_init='init', o_f='final'))
204+
'Configuration for testing', None, [Model('model', Ports(), 'description', [
205+
Component('macro', Ports(o_i='out', s='in'), 'description'),
206+
Component('micro', Ports(f_init='init', o_f='final'), 'description')
204207
], [
205208
Conduit('macro.out', 'micro.init'),
206209
Conduit('micro.final', 'macro.in')]
207210
)])
208211

209212
overlay1 = Configuration(
210213
'Extra component', None,
211-
[Model('model', None, [Component('micro2', Ports())], [])])
214+
[
215+
Model('model', None, 'description',
216+
[Component('micro2', Ports(), 'description')], [])
217+
])
212218

213219
with pytest.raises(RuntimeError):
214220
base.update(overlay1)
215221

216222
overlay2 = Configuration(
217-
'Extra conduit', None, [Model('model', None, [], [
223+
'Extra conduit', None, [Model('model', None, 'description', [], [
218224
Conduit('micro.final', 'macro.in2')])])
219225

220226
with pytest.raises(RuntimeError):

0 commit comments

Comments
 (0)