TailLoop#
- class hugr.build.cond_loop.TailLoop(just_inputs: TypeRow, rest: TypeRow)[source]#
-
Builder for a tail-controlled loop.
- Parameters:
just_inputs – Types that are only inputs to the loop body.
rest – The remaining input types that are also output types.
Examples
>>> tl = TailLoop([tys.Bool], [tys.Qubit]) >>> tl.parent_op TailLoop(just_inputs=[Bool], rest=[Qubit])
Methods
Add a command (holding a dataflow operation and the incoming wires) to the graph.
Add a type alias definition.
Start building a new CFG nested inside the current dataflow graph.
Start building a new conditional nested inside the current dataflow graph.
Add a static constant to the graph.
Start building a new if block nested inside the current dataflow graph.
Start building a nested dataflow graph.
Add a dataflow operation to the graph, wiring in input ports.
Add a state order link between two nodes.
Start building a new tail loop nested inside the current dataflow graph.
Call a static function in the graph.
Start building a function definition in the graph.
Add a series of commands to the DFG.
Generate an input port for this node.
List all incoming wires (output ports of the input node).
Insert a CFG into the current dataflow graph, wiring in the inputs.
Insert a conditional into the current dataflow graph, wiring in the inputs.
Insert a nested dataflow graph into the current graph, wiring in the inputs.
Insert a tail loop into the current dataflow graph, wiring in the inputs.
Load a constant into the graph as a dataflow value.
Load a static function into the graph as a higher-order value.
Start building a dataflow graph nested inside a larger HUGR.
Generate an output port for this node.
OutPort corresponding to this
Wire
.Returns an iterator over the output ports of this node.
Generate a port in direction for this node with offset.
Set the outputs of the loop body.
Set the outputs of the dataflow graph.
Convert to a
Node
.Attributes
Metadata associated with this node.
The parent node's operation.
The Hugr instance that the builder is using.
The parent node of the dataflow graph.
The input node of the dataflow graph.
The output node of the dataflow graph.
- add(com: ops.Command, *, metadata: dict[str, Any] | None = None) Node #
Add a command (holding a dataflow operation and the incoming wires) to the graph.
- Parameters:
com – The command to add.
metadata – Metadata to attach to the function definition. Defaults to None.
Example
>>> dfg = Dfg(tys.Bool) >>> (i,) = dfg.inputs() >>> dfg.add(ops.Noop()(i)) Node(3)
- add_alias_defn(name: str, ty: Type, parent: ToNode | None = None) Node #
Add a type alias definition.
- add_cfg(*args: Wire) Cfg #
Start building a new CFG nested inside the current dataflow graph.
- Parameters:
args – The input wires to the new CFG.
- Returns:
Builder for new nested CFG.
Example
>>> dfg = Dfg(tys.Bool) >>> with dfg.add_cfg(dfg.inputs()[0]) as cfg: cfg.parent_op CFG(inputs=[Bool])
- add_conditional(cond_wire: Wire, *args: Wire) Conditional #
Start building a new conditional nested inside the current dataflow graph.
- Parameters:
cond_wire – The wire holding the value (of Sum type) to branch the
on. (conditional)
args – Remaining input wires to the conditional.
- Returns:
Builder for new nested conditional.
Example
>>> dfg = Dfg(tys.Bool, tys.Unit) >>> (cond, unit) = dfg.inputs() >>> cond = dfg.add_conditional(cond, unit) >>> cond.parent_node Node(3)
- add_const(value: val.Value, parent: ToNode | None = None) Node #
Add a static constant to the graph.
- Parameters:
value – The constant value to add.
parent – The parent node of the constant. Defaults to the root node.
- Returns:
The node holding the
Const
operation.
Example
>>> dfg = Dfg() >>> const_n = dfg.add_const(val.TRUE) >>> dfg.hugr[const_n].op Const(TRUE)
- add_if(cond_wire: Wire, *args: Wire) If #
Start building a new if block nested inside the current dataflow graph.
- Parameters:
cond_wire – The wire holding the Bool value to branch the If on.
args – Remaining input wires to the If (and subsequent Else).
- Returns:
Builder for new nested If.
Example
>>> dfg = Dfg(tys.Bool) >>> (cond,) = dfg.inputs() >>> if_ = dfg.add_if(cond, cond) >>> if_.parent_op Case(inputs=[Bool])
- add_nested(*args: Wire) Dfg #
Start building a nested dataflow graph.
- Parameters:
args – The input wires to the nested DFG.
- Returns:
Builder for new nested dataflow graph.
Example
>>> dfg = Dfg(tys.Bool) >>> with dfg.add_nested(dfg.inputs()[0]) as dfg2: dfg2.parent_node Node(3)
- add_op(op: ops.DataflowOp, /, *args: Wire, metadata: dict[str, Any] | None = None) Node #
Add a dataflow operation to the graph, wiring in input ports.
- Parameters:
op – The operation to add.
args – The input wires to the operation.
metadata – Metadata to attach to the function definition. Defaults to None.
- Returns:
The node holding the new operation.
Example
>>> dfg = Dfg(tys.Bool) >>> dfg.add_op(ops.Noop(), dfg.inputs()[0]) Node(3)
- add_state_order(src: Node, dst: Node) None #
Add a state order link between two nodes.
- Parameters:
src – The source node.
dst – The destination node.
Examples
>>> df = dfg.Dfg() >>> df.add_state_order(df.input_node, df.output_node) >>> list(df.hugr.outgoing_order_links(df.input_node)) [Node(2)]
- add_tail_loop(just_inputs: Sequence[Wire], rest: Sequence[Wire]) TailLoop #
Start building a new tail loop nested inside the current dataflow graph.
- Parameters:
just_inputs – input wires for types that are only inputs to the loop body.
rest – input wires for types that are inputs and outputs of the loop
body.
- Returns:
Builder for new nested TailLoop.
Example
>>> dfg = Dfg(tys.Bool) >>> (cond,) = dfg.inputs() >>> tl = dfg.add_tail_loop([cond], [cond]) >>> tl.parent_op TailLoop(just_inputs=[Bool], rest=[Bool])
- call(func: ToNode, *args: Wire, instantiation: tys.FunctionType | None = None, type_args: Sequence[tys.TypeArg] | None = None) Node #
Call a static function in the graph. See
Call
for more on how polymorphic functions are handled.- Parameters:
func – The node corresponding to the function definition/declaration to call.
args – The input wires to the function call.
instantiation – The concrete function type to call (needed if polymorphic).
type_args – The type arguments for the function (needed if
polymorphic).
- Returns:
The node holding the
Call
operation.
- define_function(name: str, input_types: TypeRow, output_types: TypeRow | None = None, type_params: list[TypeParam] | None = None, parent: ToNode | None = None) Function #
Start building a function definition in the graph.
- Parameters:
name – The name of the function.
input_types – The input types for the function.
output_types – The output types for the function. If not provided, it will be inferred after the function is built.
type_params – The type parameters for the function, if polymorphic.
parent – The parent node of the constant. Defaults to the root node.
- Returns:
The new function builder.
- extend(*coms: ops.Command) list[Node] #
Add a series of commands to the DFG.
Shorthand for calling
add()
on each command in coms.- Parameters:
coms – Commands to add.
- Returns:
List of the new nodes in the same order as the commands.
- Raises:
IndexError – If any input index is not a tracked wire.
Examples
>>> dfg = Dfg(tys.Bool, tys.Unit) >>> (b, u) = dfg.inputs() >>> dfg.extend(ops.Noop()(b), ops.Noop()(u)) [Node(3), Node(4)]
- inp(offset: int) InPort #
Generate an input port for this node.
- Parameters:
offset – port offset.
- Returns:
Incoming port for this node.
Examples
>>> Node(0).inp(1) InPort(Node(0), 1)
- inputs() list[OutPort] #
List all incoming wires (output ports of the input node).
Example
>>> dfg = Dfg(tys.Bool) >>> dfg.inputs() [OutPort(Node(1), 0)]
- insert_cfg(cfg: Cfg, *args: Wire) Node #
Insert a CFG into the current dataflow graph, wiring in the inputs.
- Parameters:
cfg – The CFG to insert.
args – The input wires to the CFG.
- Returns:
The root node of the inserted CFG.
Example
>>> from hugr.cfg import Cfg >>> dfg = Dfg(tys.Bool) >>> cfg = Cfg(tys.Bool) >>> dfg.insert_cfg(cfg, dfg.inputs()[0]) Node(3)
- insert_conditional(cond: Conditional, cond_wire: Wire, *args: Wire) Node #
Insert a conditional into the current dataflow graph, wiring in the inputs.
- Parameters:
cond – The conditional to insert.
cond_wire – The wire holding the value (of Sum type) to branch the Conditional on.
args – Remaining input wires to the conditional.
- Returns:
The root node of the inserted conditional.
Example
>>> from hugr.cond_loop import Conditional >>> cond = Conditional(tys.Bool, []) >>> dfg = Dfg(tys.Bool) >>> cond_n = dfg.insert_conditional(cond, dfg.inputs()[0]) >>> dfg.hugr[cond_n].op Conditional(sum_ty=Bool, other_inputs=[])
- insert_nested(dfg: Dfg, *args: Wire) Node #
Insert a nested dataflow graph into the current graph, wiring in the inputs.
- Parameters:
dfg – The dataflow graph to insert.
args – The input wires to the graph.
- Returns:
The root node of the inserted graph.
Example
>>> dfg = Dfg(tys.Bool) >>> dfg2 = Dfg(tys.Bool) >>> dfg.insert_nested(dfg2, dfg.inputs()[0]) Node(3)
- insert_tail_loop(tl: TailLoop, just_inputs: Sequence[Wire], rest: Sequence[Wire]) Node #
Insert a tail loop into the current dataflow graph, wiring in the inputs.
- Parameters:
tl – The tail loop to insert.
just_inputs – input wires for types that are only inputs to the loop body.
rest – input wires for types that are inputs and outputs of the loop
body.
- Returns:
The root node of the inserted tail loop.
Example
>>> from hugr.cond_loop import TailLoop >>> tl = TailLoop([tys.Bool], [tys.Bool]) >>> dfg = Dfg(tys.Bool) >>> (b,) = dfg.inputs() >>> tl_n = dfg.insert_tail_loop(tl, [b], [b]) >>> dfg.hugr[tl_n].op TailLoop(just_inputs=[Bool], rest=[Bool])
- load(const: ToNode | val.Value, const_parent: ToNode | None = None) Node #
Load a constant into the graph as a dataflow value.
- Parameters:
const – The constant to load, either a Value that will be added as a child Const node then loaded, or a node corresponding to an existing Const.
const_parent – If const is a Value, the parent node for the new constant definition. Defaults to the current dataflow container.
- Returns:
The node holding the
LoadConst
operation.
Example
>>> dfg = Dfg() >>> const_n = dfg.load(val.TRUE) >>> len(dfg.hugr) # parent, input, output, const, load 5 >>> dfg.hugr[const_n].op LoadConst(Bool)
- load_function(func: ToNode, instantiation: tys.FunctionType | None = None, type_args: Sequence[tys.TypeArg] | None = None) Node #
Load a static function into the graph as a higher-order value.
- Parameters:
func – The node corresponding to the function definition/declaration to load.
instantiation – The concrete function type to load (needed if polymorphic).
type_args – The type arguments for the function (needed if
polymorphic).
- Returns:
The node holding the
LoadFunc
operation.
- classmethod new_nested(parent_op: DP, hugr: Hugr, parent: ToNode | None = None) Self #
Start building a dataflow graph nested inside a larger HUGR.
- Parameters:
parent_op – The parent operation of the new dataflow graph.
hugr – The host HUGR instance to build the dataflow graph in.
parent – Parent of new dataflow graph’s root node: defaults to the
root. (host HUGR)
Example
>>> hugr = Hugr() >>> dfg = Dfg.new_nested(ops.DFG([]), hugr) >>> dfg.parent_node Node(1)
- out(offset: int) OutPort #
Generate an output port for this node.
- Parameters:
offset – port offset.
- Returns:
Outgoing port for this node.
Examples
>>> Node(0).out(1) OutPort(Node(0), 1)
- property parent_op: OpVar#
The parent node’s operation.
- port(offset: int, direction: Direction) InPort | OutPort #
Generate a port in direction for this node with offset.
Examples
>>> Node(0).port(1, Direction.INCOMING) InPort(Node(0), 1) >>> Node(0).port(1, Direction.OUTGOING) OutPort(Node(0), 1)
- set_loop_outputs(sum_wire: Wire, *rest: Wire) None [source]#
Set the outputs of the loop body. The first wire must be the sum type that controls loop termination.
- Parameters:
sum_wire – The wire holding the sum type that controls loop termination.
rest – The remaining output wires (corresponding to the ‘rest’ types).