11from copy import deepcopy
2- from typing import Dict , Optional
2+ from typing import Dict , List , Optional
33import warnings
44
55import ymmsl .v0_1 as v0_1
@@ -15,11 +15,21 @@ def convert_v0_1_to_v0_2(config: v0_1.PartialConfiguration) -> v0_2.Configuratio
1515 Returns:
1616 The corresponding configuration expressed in yMMSL v0.2.
1717 """
18- description = '' if config .description is None else config .description
18+ description = 'Please add a description'
19+ if config .description :
20+ description = config .description
1921 models = [convert_model (config .model )] if config .model is not None else None
2022 settings = deepcopy (config .settings )
2123 programs = [
2224 convert_implementation (impl ) for impl in config .implementations .values ()]
25+ if programs :
26+ warnings .warn (
27+ 'In yMMSL v0.2 implementations have become programs, and you can now'
28+ ' specify the ports of a program in the yMMSL description. If your'
29+ ' program has fixed ports then you should do this, because it will make'
30+ ' incorrect wiring easier to debug. While there, add a description too!'
31+ )
32+
2333 resources = deepcopy (config .resources )
2434 checkpoints = deepcopy (config .checkpoints )
2535 resume = deepcopy (config .resume )
@@ -32,20 +42,57 @@ def convert_v0_1_to_v0_2(config: v0_1.PartialConfiguration) -> v0_2.Configuratio
3242def convert_component (component : v0_1 .Component ) -> v0_2 .Component :
3343 """Convert a v0.1 Component object to a v0.2 Component."""
3444 ports = component .ports if component .ports else v0_1 .Ports ()
45+ description = 'Please add a description'
3546 implementation : Optional [str ] = None
3647 if component .implementation is not None :
3748 implementation = str (component .implementation )
3849
3950 return v0_2 .Component (
40- str (component .name ), convert_ports (ports ), '' , False , implementation ,
41- component .multiplicity )
51+ str (component .name ), convert_ports (ports ), description , False ,
52+ implementation , component .multiplicity )
4253
4354
4455def convert_conduit (conduit : v0_1 .Conduit ) -> v0_2 .Conduit :
4556 """Convert a v0.1 Conduit to a v0.2 Conduit."""
4657 return v0_2 .Conduit (str (conduit .sender ), str (conduit .receiver ))
4758
4859
60+ def infer_ports (components : List [v0_2 .Component ], conduits : List [v0_2 .Conduit ]) -> None :
61+ """Infer component ports from conduits where absent.
62+
63+ This can create an incorrect result, because we have to guess at the operators. We
64+ assume that they're F_INIT for receiving ports and O_F for sending ports, but this
65+ can be wrong. Only the user knows, so we'll warn them that they have to check.
66+ """
67+ changed_components = list ()
68+ for component in components :
69+ if len (component .ports ) == 0 :
70+ for conduit in conduits :
71+ if conduit .sending_component () == component .name :
72+ component .ports [conduit .sending_port ()] = v0_2 .Port (
73+ conduit .sending_port (), v0_2 .Operator .O_F ,
74+ v0_2 .Timeline ('' ))
75+ if component .name not in changed_components :
76+ changed_components .append (component .name )
77+
78+ if conduit .receiving_component () == component .name :
79+ component .ports [conduit .receiving_port ()] = v0_2 .Port (
80+ conduit .receiving_port (), v0_2 .Operator .F_INIT ,
81+ v0_2 .Timeline ('' ))
82+ if component .name not in changed_components :
83+ changed_components .append (component .name )
84+
85+ if changed_components :
86+ ch_comp_list = '\n - ' + '\n - ' .join (map (str , changed_components ))
87+ warnings .warn (
88+ 'In yMMSL v0.2 components are required to declare their ports. The'
89+ ' following components did not have a ports declaration, so one has'
90+ ' been added based on the connected conduits. THIS MAY BE WRONG,'
91+ ' because the operators have all been set to F_INIT and O_F, while they'
92+ ' may really be O_I or S. Please check these components and adjust'
93+ f' as needed: { ch_comp_list } ' )
94+
95+
4996def convert_model (model : v0_1 .ModelReference ) -> v0_2 .Model :
5097 """Convert a v0.1 ModelReference object to a v0.2 Model.
5198
@@ -55,13 +102,16 @@ def convert_model(model: v0_1.ModelReference) -> v0_2.Model:
55102 Returns:
56103 The corresponding configuration expressed in yMMSL v0.2.
57104 """
105+ description = 'Please add a description'
106+
58107 if isinstance (model , v0_1 .Model ):
108+ components = list (map (convert_component , model .components ))
109+ conduits = list (map (convert_conduit , model .conduits ))
110+ infer_ports (components , conduits )
59111 return v0_2 .Model (
60- str (model .name ), None , '' , None ,
61- list (map (convert_component , model .components )),
62- list (map (convert_conduit , model .conduits )))
112+ str (model .name ), None , description , None , components , conduits )
63113 else :
64- return v0_2 .Model (str (model .name ), None , '' , None , [], [])
114+ return v0_2 .Model (str (model .name ), None , description , None , [], [])
65115
66116
67117def convert_implementation (impl : v0_1 .Implementation ) -> v0_2 .Program :
@@ -76,12 +126,7 @@ def convert_implementation(impl: v0_1.Implementation) -> v0_2.Program:
76126 Returns:
77127 The corresponding program expressed in yMMSL v0.2.
78128 """
79- warnings .warn (
80- 'In yMMSL v0.2 implementations have become programs, and you can now'
81- ' specify the ports of a program in the yMMSL description. If your program'
82- ' has fixed ports then you should do this, because it will make incorrect'
83- ' wiring easier to debug. While there, add a description too!' )
84-
129+ description = 'Please add a description'
85130 base_env : Optional [v0_1 .BaseEnv ] = impl .base_env
86131 env : Optional [Dict [str , str ]] = impl .env
87132
@@ -94,7 +139,7 @@ def convert_implementation(impl: v0_1.Implementation) -> v0_2.Program:
94139 env = None
95140
96141 return v0_2 .Program (
97- str (impl .name ), None , '' , None , base_env , impl .modules ,
142+ str (impl .name ), None , description , None , base_env , impl .modules ,
98143 impl .virtual_env , env , execution_model , impl .executable , impl .args ,
99144 impl .script , impl .can_share_resources , impl .keeps_state_for_next_use )
100145
0 commit comments