30
30
OpVar = TypeVar ("OpVar" , bound = ops .Op )
31
31
32
32
33
+ class DataflowError (Exception ):
34
+ """Error building a :class:`DfBase` dataflow graph."""
35
+
36
+
33
37
@dataclass ()
34
38
class DefinitionBuilder (Generic [OpVar ]):
35
39
"""Base class for builders that can define functions, constants, and aliases.
@@ -55,12 +59,12 @@ def define_function(
55
59
output_types: The output types for the function.
56
60
If not provided, it will be inferred after the function is built.
57
61
type_params: The type parameters for the function, if polymorphic.
58
- parent: The parent node of the constant. Defaults to the root node.
62
+ parent: The parent node of the constant. Defaults to the entrypoint node.
59
63
60
64
Returns:
61
65
The new function builder.
62
66
"""
63
- parent_node = parent or self .hugr .root
67
+ parent_node = parent or self .hugr .entrypoint
64
68
parent_op = ops .FuncDefn (name , input_types , type_params or [])
65
69
func = Function .new_nested (parent_op , self .hugr , parent_node )
66
70
if output_types is not None :
@@ -72,7 +76,7 @@ def add_const(self, value: val.Value, parent: ToNode | None = None) -> Node:
72
76
73
77
Args:
74
78
value: The constant value to add.
75
- parent: The parent node of the constant. Defaults to the root node.
79
+ parent: The parent node of the constant. Defaults to the entrypoint node.
76
80
77
81
Returns:
78
82
The node holding the :class:`Const <hugr.ops.Const>` operation.
@@ -83,12 +87,12 @@ def add_const(self, value: val.Value, parent: ToNode | None = None) -> Node:
83
87
>>> dfg.hugr[const_n].op
84
88
Const(TRUE)
85
89
"""
86
- parent_node = parent or self .hugr .root
90
+ parent_node = parent or self .hugr .entrypoint
87
91
return self .hugr .add_node (ops .Const (value ), parent_node )
88
92
89
93
def add_alias_defn (self , name : str , ty : Type , parent : ToNode | None = None ) -> Node :
90
94
"""Add a type alias definition."""
91
- parent_node = parent or self .hugr .root
95
+ parent_node = parent or self .hugr .entrypoint
92
96
return self .hugr .add_node (ops .AliasDefn (name , ty ), parent_node )
93
97
94
98
@@ -114,7 +118,7 @@ class DfBase(ParentBuilder[DP], DefinitionBuilder, AbstractContextManager):
114
118
115
119
def __init__ (self , parent_op : DP ) -> None :
116
120
self .hugr = Hugr (parent_op )
117
- self .parent_node = self .hugr .root
121
+ self .parent_node = self .hugr .entrypoint
118
122
self ._init_io_nodes (parent_op )
119
123
120
124
def _init_io_nodes (self , parent_op : DP ):
@@ -141,7 +145,7 @@ def new_nested(
141
145
parent_op: The parent operation of the new dataflow graph.
142
146
hugr: The host HUGR instance to build the dataflow graph in.
143
147
parent: Parent of new dataflow graph's root node: defaults to the
144
- host HUGR root .
148
+ host HUGR entrypoint .
145
149
146
150
Example:
147
151
>>> hugr = Hugr()
@@ -152,10 +156,44 @@ def new_nested(
152
156
new = cls .__new__ (cls )
153
157
154
158
new .hugr = hugr
155
- new .parent_node = hugr .add_node (parent_op , parent or hugr .root )
159
+ new .parent_node = hugr .add_node (parent_op , parent or hugr .entrypoint )
156
160
new ._init_io_nodes (parent_op )
157
161
return new
158
162
163
+ @classmethod
164
+ def _new_existing (cls , hugr : Hugr , root : ToNode | None = None ) -> Self :
165
+ """Start a dataflow graph builder for an existing node.
166
+
167
+ Args:
168
+ hugr: The host HUGR instance to build the dataflow graph in.
169
+ root: The dataflow graph's root node.
170
+ Defaults to the host HUGR's entrypoint.
171
+
172
+ Example:
173
+ >>> hugr = Hugr(ops.DFG([]))
174
+ >>> dfg = Dfg._new_existing(hugr)
175
+ >>> dfg.parent_node
176
+ Node(4)
177
+
178
+ Raises:
179
+ :class:`DataflowError` if the `root` operation is not a dataflow
180
+ parent.
181
+ """
182
+ root = root or hugr .entrypoint
183
+
184
+ if not ops .is_df_parent_op (hugr [root ].op ):
185
+ msg = f"{ hugr [root ].op } is not a dataflow parent"
186
+ raise DataflowError (msg )
187
+
188
+ new = cls .__new__ (cls )
189
+ new .hugr = hugr
190
+ new .parent_node = root .to_node ()
191
+ [inp , out ] = hugr .children (root )[:2 ]
192
+ new .input_node = inp
193
+ new .output_node = out
194
+
195
+ return new
196
+
159
197
def _input_op (self ) -> ops .Input :
160
198
return self .hugr ._get_typed_op (self .input_node , ops .Input )
161
199
@@ -256,7 +294,7 @@ def insert_nested(self, dfg: Dfg, *args: Wire) -> Node:
256
294
args: The input wires to the graph.
257
295
258
296
Returns:
259
- The root node of the inserted graph.
297
+ The entrypoint node of the inserted graph.
260
298
261
299
Example:
262
300
>>> dfg = Dfg(tys.Bool)
@@ -482,7 +520,14 @@ def set_outputs(self, *args: Wire) -> None:
482
520
>>> dfg.set_outputs(dfg.inputs()[0]) # connect input to output
483
521
"""
484
522
self ._wire_up (self .output_node , args )
485
- self .parent_op ._set_out_types (self ._output_op ().types )
523
+ out_types = self ._output_op ().types
524
+ self .parent_op ._set_out_types (out_types )
525
+ if (
526
+ isinstance (self .parent_op , ops .DataflowOp )
527
+ and self .parent_op ._entrypoint_requires_wiring
528
+ and self .hugr .entrypoint == self .parent_node
529
+ ):
530
+ self .hugr ._connect_df_entrypoint_outputs ()
486
531
487
532
def _set_parent_output_count (self , count : int ) -> None :
488
533
"""Set the final number of output ports on the parent operation.
@@ -644,7 +689,7 @@ def _wire_up_port(self, node: Node, offset: PortOffset, p: Wire) -> tys.Type:
644
689
645
690
646
691
class Dfg (DfBase [ops .DFG ]):
647
- """Builder for a simple nested Dataflow graph, with root node of type
692
+ """Builder for a simple nested Dataflow graph, with entrypoint node of type
648
693
:class:`DFG <hugr.ops.DFG>`.
649
694
650
695
Args:
@@ -662,8 +707,8 @@ def __init__(self, *input_types: tys.Type) -> None:
662
707
super ().__init__ (parent_op )
663
708
664
709
def set_outputs (self , * outputs : Wire ) -> None :
665
- super ().set_outputs (* outputs )
666
710
self ._set_parent_output_count (len (outputs ))
711
+ super ().set_outputs (* outputs )
667
712
668
713
669
714
def _ancestral_sibling (h : Hugr , src : Node , tgt : Node ) -> Node | None :
0 commit comments