Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor/linear_classic
Browse files Browse the repository at this point in the history
  • Loading branch information
acl-cqc committed Jul 12, 2023
2 parents 079dd6f + e22eee1 commit dd6c705
Show file tree
Hide file tree
Showing 25 changed files with 657 additions and 354 deletions.
41 changes: 22 additions & 19 deletions specification/hugr.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ As well as the type, dataflow edges are also parametrized by a
```
SimpleType ::= ClassicType | LinearType
EdgeKind ::= Hierarchy | Value(Locality, SimpleType) | Static(Locality, ClassicType) | Order | ControlFlow
EdgeKind ::= Hierarchy | Value(Locality, SimpleType) | Static(Local | Ext, ClassicType) | Order | ControlFlow
Locality ::= Local | Ext | Dom
```
Expand Down Expand Up @@ -209,10 +209,9 @@ source node, to an incoming port of the target node.

A `Static` edge represents dataflow that is statically knowable - i.e.
the source is a compile-time constant defined in the program. Hence, the types on these edges
do not include a resource specification. Only a few nodes may be
are classical, and do not include a resource specification. Only a few nodes may be
sources (`FuncDefn`, `FuncDecl` and `Const`) and targets (`Call` and `LoadConstant`) of
these edges; see
[operations](#node-operations).
these edges; see [operations](#node-operations).

#### `Order` edges

Expand Down Expand Up @@ -256,8 +255,12 @@ edges. The following operations are *only* valid as immediate children of a
replaced with the definition. An alias declared with `AliasDecl` is equivalent to a
named opaque type.

The following operations are valid at the module level, but *also* in dataflow
regions:
There may also be other [scoped definitions](#scoped-definitions).

#### Scoped Definitions

The following operations are valid at the module level as well as in dataflow
regions and control-flow regions:

- `Const<T>` : a static constant value of type T stored in the node
weight. Like `FuncDecl` and `FuncDefn` this has one `Static<T>` out-edge per use.
Expand All @@ -282,7 +285,7 @@ not be executable.

Within dataflow regions, which include function definitions,
the following basic dataflow operations are available (in addition to the
operations valid at both Module level and within dataflow regions):
[scoped definitions](#scoped-definitions)):

- `Input/Output`: input/output nodes, the outputs of `Input` node are
the inputs to the function, and the inputs to `Output` are the
Expand Down Expand Up @@ -403,15 +406,13 @@ There are two kinds of `BasicBlock`: `DFB` (dataflow block) and `Exit`.
`DFB` nodes are CFG basic blocks. Edges between them are
control-flow (as opposed to dataflow), and express traditional
control-flow concepts of branch/merge. Each `DFB` node is
parent to a dataflow sibling graph.
parent to a dataflow sibling graph. `Exit` blocks have only incoming control-flow edges, and no children.

A `CFG` node is a dataflow node which is defined by a child control
sibling graph. All children except the second are `DFB`-nodes,
the first is the entry block. The second child is an
`Exit` node, which has no children, this is the single exit
point of the CFG and the inputs to this node match the outputs of
the CFG-node. The inputs to the CFG-node are wired to the inputs of
the entry block.
sibling graph. The children are all `BasicBlock`s or [scoped definitions](#scoped-definitions).
The first child is the entry block and must be a `DFB`, with inputs the same as the CFG-node; the second child is an
`Exit` node, whose inputs match the outputs of the CFG-node.
The remaining children are either `DFB`s or [scoped definitions](#scoped-definitions).

The first output of the DSG contained in a `BasicBlock` has type
`Predicate(#t0,...#t(n-1))`, where the node has `n` successors, and the
Expand Down Expand Up @@ -543,7 +544,7 @@ may be a `FuncDefn`, `TailLoop`, `DFG`, `Case` or `DFB` node.
| Hierarchy | Defines hierarchy; each node has \<=1 parent |
| Order, Control | Local (Source + target have same parent) |
| Value | Local, Ext or Dom - see [Non-local edges](#non-local-edges) |
| Static | Local, Ext or Dom - see [Non-local edges](#non-local-edges) |
| Static | Local or Ext - see [Non-local edges](#non-local-edges) |

### Exception Handling

Expand Down Expand Up @@ -583,8 +584,10 @@ may be a `FuncDefn`, `TailLoop`, `DFG`, `Case` or `DFB` node.

**For classical values only** we allow dataflow edges (i.e. both Value and Static)
n<sub>1</sub>→n<sub>2</sub> where parent(n<sub>1</sub>) \!=
parent(n<sub>2</sub>) when the edge's locality is either Ext or Dom, as
follows:
parent(n<sub>2</sub>) when the edge's locality is:
* for Value edges, Ext or Dom;
* for Static edges, Ext.
Each of these localities have additional constraints as follows:

1. For Ext edges, ** we require parent(n<sub>1</sub>) ==
parent<sup>i</sup>(n<sub>2</sub>) for some i\>1, *and* for Value edges only there must be a order edge from parent(n<sub>1</sub>) to
Expand Down Expand Up @@ -1976,8 +1979,8 @@ an edge weight.
- **node index**: An identifier for a node that is unique within the
HUGR.

- **non-local edge**: A Value or Static edge with Locality Ext or Dom
(i.e. not Local)
- **non-local edge**: A Value or Static edge with Locality Ext,
or a Value edge with locality Dom (i.e. not Local)

- **operation**: TODO

Expand Down
2 changes: 1 addition & 1 deletion src/algorithm/half_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::hash::Hash;

use super::nest_cfgs::CfgView;
use crate::hugr::view::HugrView;
use crate::ops::tag::OpTag;
use crate::ops::OpTag;
use crate::ops::OpTrait;
use crate::{Direction, Node};

Expand Down
35 changes: 21 additions & 14 deletions src/algorithm/nest_cfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use std::hash::Hash;
use itertools::Itertools;

use crate::hugr::view::HugrView;
use crate::ops::tag::OpTag;
use crate::ops::OpTag;
use crate::ops::OpTrait;
use crate::{Direction, Node};

Expand Down Expand Up @@ -398,7 +398,7 @@ impl<T: Copy + Clone + PartialEq + Eq + Hash> EdgeClassifier<T> {
pub(crate) mod test {
use super::*;
use crate::builder::{BuildError, CFGBuilder, Container, DataflowSubContainer, HugrBuilder};
use crate::hugr::region::FlatRegionView;
use crate::hugr::region::{FlatRegionView, Region};
use crate::ops::{
handle::{BasicBlockID, ConstID, NodeHandle},
ConstValue,
Expand Down Expand Up @@ -427,11 +427,14 @@ pub(crate) mod test {
// entry -> split > merge -> head -> tail -> exit
// \-> right -/ \-<--<-/
let mut cfg_builder = CFGBuilder::new(type_row![NAT], type_row![NAT])?;
let mut entry_builder = cfg_builder.simple_entry_builder(type_row![NAT], 1)?;
let pred_const = entry_builder.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = entry_builder.add_constant(ConstValue::simple_unary_predicate())?;

let entry = n_identity(entry_builder, &const_unit)?;
let pred_const = cfg_builder.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = cfg_builder.add_constant(ConstValue::simple_unary_predicate())?;

let entry = n_identity(
cfg_builder.simple_entry_builder(type_row![NAT], 1)?,
&const_unit,
)?;
let (split, merge) = build_if_then_else_merge(&mut cfg_builder, &pred_const, &const_unit)?;
cfg_builder.branch(&entry, 0, &split)?;
let (head, tail) = build_loop(&mut cfg_builder, &pred_const, &const_unit)?;
Expand Down Expand Up @@ -644,11 +647,13 @@ pub(crate) mod test {
separate: bool,
) -> Result<(Hugr, BasicBlockID, BasicBlockID), BuildError> {
let mut cfg_builder = CFGBuilder::new(type_row![NAT], type_row![NAT])?;
let mut entry = cfg_builder.simple_entry_builder(type_row![NAT], 2)?;
let pred_const = entry.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = entry.add_constant(ConstValue::simple_unary_predicate())?;
let pred_const = cfg_builder.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = cfg_builder.add_constant(ConstValue::simple_unary_predicate())?;

let entry = n_identity(entry, &pred_const)?;
let entry = n_identity(
cfg_builder.simple_entry_builder(type_row![NAT], 2)?,
&pred_const,
)?;
let merge = build_then_else_merge_from_if(&mut cfg_builder, &const_unit, entry)?;
let head = if separate {
let h = n_identity(
Expand Down Expand Up @@ -676,12 +681,14 @@ pub(crate) mod test {
//let sum2_type = SimpleType::new_predicate(2);

let mut cfg_builder = CFGBuilder::new(type_row![NAT], type_row![NAT])?;
let mut entry_builder = cfg_builder.simple_entry_builder(type_row![NAT], 1)?;

let pred_const = entry_builder.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = entry_builder.add_constant(ConstValue::simple_unary_predicate())?;
let pred_const = cfg_builder.add_constant(ConstValue::simple_predicate(0, 2))?; // Nothing here cares which
let const_unit = cfg_builder.add_constant(ConstValue::simple_unary_predicate())?;

let entry = n_identity(entry_builder, &const_unit)?;
let entry = n_identity(
cfg_builder.simple_entry_builder(type_row![NAT], 1)?,
&const_unit,
)?;
let (split, merge) = build_if_then_else_merge(&mut cfg_builder, &pred_const, &const_unit)?;

let (head, tail) = if separate_headers {
Expand Down
2 changes: 1 addition & 1 deletion src/builder/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod test {

use crate::builder::build_traits::DataflowHugr;
use crate::builder::{DataflowSubContainer, ModuleBuilder};
use crate::ops::tag::OpTag;
use crate::ops::OpTag;
use crate::ops::OpTrait;
use crate::types::SimpleType;
use crate::{
Expand Down
2 changes: 1 addition & 1 deletion src/builder/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{
ops::{
handle::{BasicBlockID, CaseID, DfgID, FuncID, NodeHandle, TailLoopID},
tag::OpTag,
OpTag,
},
Port,
};
Expand Down
46 changes: 15 additions & 31 deletions src/extensions/rotation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use std::collections::HashMap;
use pyo3::prelude::*;

use crate::ops::constant::CustomConst;
use crate::resource::{CustomSignatureFunc, OpDef, ResourceSet, SignatureError, TypeDef};
use crate::types::{type_param::TypeArg, ClassicType, CustomType, SimpleType, TypeRow};
use crate::resource::{OpDef, ResourceSet, TypeDef};
use crate::types::type_param::TypeArg;
use crate::types::{ClassicType, CustomType, SimpleType, TypeRow};
use crate::Resource;

pub const fn resource_id() -> SmolStr {
Expand All @@ -27,15 +28,18 @@ pub fn resource() -> Resource {
resource.add_type(Type::Angle.type_def());
resource.add_type(Type::Quaternion.type_def());

resource
.add_op(OpDef::new_with_custom_sig(
"AngleAdd".into(),
"".into(),
vec![],
HashMap::default(),
AngleAdd,
))
.unwrap();
let op = OpDef::new_with_custom_sig(
"AngleAdd".into(),
"".into(),
vec![],
HashMap::default(),
|_arg_values: &[TypeArg]| {
let t: TypeRow = vec![SimpleType::Classic(Type::Angle.custom_type().into())].into();
Ok((t.clone(), t, ResourceSet::default()))
},
);

resource.add_op(op).unwrap();
resource
}

Expand Down Expand Up @@ -98,26 +102,6 @@ impl CustomConst for Constant {
}
}

#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct AngleAdd;

/// When we have a YAML type-scheme interpreter, we'll be able to use that;
/// there is no need for a binary compute_signature for a case this simple.
impl CustomSignatureFunc for AngleAdd {
fn compute_signature(
&self,
_name: &SmolStr,
_arg_values: &[TypeArg],
_misc: &HashMap<String, serde_yaml::Value>,
) -> Result<(TypeRow, TypeRow, ResourceSet), SignatureError> {
let t: TypeRow = vec![SimpleType::Classic(
Into::<CustomType>::into(Type::Angle).into(),
)]
.into();
Ok((t.clone(), t, ResourceSet::default()))
}
}

//
// TODO:
//
Expand Down
2 changes: 1 addition & 1 deletion src/hugr/hugrmut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ fn insert_hugr_internal(
root: Node,
other: &impl HugrView,
) -> Result<(Node, HashMap<NodeIndex, NodeIndex>), HugrError> {
let node_map = hugr.graph.insert_graph(other.as_portgraph())?;
let node_map = hugr.graph.insert_graph(other.portgraph())?;
let other_root = node_map[&other.root().index];

// Update hierarchy and optypes
Expand Down
Loading

0 comments on commit dd6c705

Please sign in to comment.