Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile Prim nodes to Hugr DFG #34

Merged
merged 9 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions brat/Brat/Compile/Hugr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
addOp op name | track ("addOp " ++ show op ++ show name) False = undefined
addOp op name = do
st <- get
let new_nodes = M.alter (\Nothing -> Just op) name (nodes st) -- fail if key already present

Check warning on line 191 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive

Check warning on line 191 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive
put (st { nodes = new_nodes })

registerCompiled :: Name -> NodeId -> Compile ()
Expand Down Expand Up @@ -227,7 +227,7 @@

renameAndSortHugr :: M.Map NodeId (HugrOp NodeId) -> [(PortId NodeId, PortId NodeId)] -> Hugr Int
renameAndSortHugr nodes edges = fmap update (Hugr (fst <$> sorted_nodes) (edges ++ orderEdges)) where
sorted_nodes = let ([root], rest) = partition (\(n, nid) -> nid == getParent n) (swap <$> M.assocs nodes) in

Check warning on line 230 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive

Check warning on line 230 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive
root : sort rest

names2Pos = M.fromList $ zip (snd <$> sorted_nodes) ([0..] :: [Int])
Expand Down Expand Up @@ -338,7 +338,7 @@
-- We are loading idNode as a value (not an Eval'd thing), and it is a FuncDef directly
-- corresponding to a Brat TLD (not that produces said TLD when eval'd)
False -> addNode ("load_thunk(" ++ show funcDef ++ ")")
(OpLoadConstant (LoadConstantOp parent (let [ty] = hTys in ty)))

Check warning on line 341 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive

Check warning on line 341 in brat/Brat/Compile/Hugr.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match(es) are non-exhaustive
-- the only input
pure $ Just (nod, [(Port funcDef 0, 0)])
compileNode in_edges = do
Expand Down Expand Up @@ -387,8 +387,18 @@
-- This should only have one outgoing wire which leads to an `Id` node for
-- the brat representation of the function, and that wire should have a
-- function type
Prim _ -> error $ "TODO: Compiling a Prim node being used as a thunk, not directly Evaled."
++ " Should construct trivial 4-node DFG+I/O+CustomOp Hugr."
Prim (ext,op) -> do
let n = ext ++ ('_':op)
let [] = ins
let [(_, VFun Braty cty)] = outs
box_sig@(FunctionType inputTys outputTys) <- body <$> compileSig Braty cty
((p, _ty), ()) <- compileConstDfg parent n box_sig $ \dfg_id -> do
ins <- addNodeWithInputs ("Inputs" ++ n) (OpIn (InputNode dfg_id inputTys)) [] inputTys
outs <- addNodeWithInputs n (OpCustom (CustomOp dfg_id ext op box_sig [])) ins outputTys
addNodeWithInputs ("Outputs" ++ n) (OpOut (OutputNode dfg_id outputTys)) outs [] >>= \case
[] -> pure ()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test that there's no outputs seems superfluous (+ haskell will emit a warning about the incomplete pattern match)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, not superfluous exactly, but I don't think we need to be quite so defensive

Copy link
Collaborator Author

@acl-cqc acl-cqc Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is pretty much the same thing as your other comment - it does seem dang hard to write what are basically assertions, so instead we just drop the value and lose a (small in terms of source code) check that things are working the way we expect. And the warnings against incomplete matches (there are loads in this file!) just require us to write much longer/more verbose code to turn one kind of runtime failure into another...

What's the right thing to do here? Can we instance MonadFail Compile and handle all these incomplete matches in our own code (which might still just error but at least it'd silence the warnings)? For another PR, I mean - I've shortened/silenced these here for the time being.

case p of
(Port loadConst 0) -> pure $ default_edges loadConst
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the sake of the GHC warning, we should add a catch all that throws an error


-- Check if the node has prefix "globals", hence should be a direct call
Eval (Ex outNode outPort) -> do
Expand Down
3 changes: 3 additions & 0 deletions brat/examples/holes.brat
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
ha :: Nat
ha = ?idx

-- Holes can go in kernels
f :: { Qubit -o Qubit, Bool }
f = { q => q, ?b }
Expand Down
File renamed without changes.
15 changes: 15 additions & 0 deletions brat/examples/vec_map.brat
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ext "to_float" to_float(i :: Int) -> Float
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this file would be better called "mono_vec_map.brat" (or monomorphic...)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also "list" rather than "vec"


map1({ Int -> Float }, List(Int)) -> List(Float)
map1(_, []) = []
map1(f, x ,- xs) = f(x) ,- map1(f, xs)

test1 :: List(Float)
test1 = map1(to_float, [5])

map2({ {Int -> Float} -> Float}, List({Int->Float})) -> List(Float)
map2(_, []) = []
map2(f, x ,- xs) = f(x) ,- map2(f, xs)

test2 :: List(Float)
test2 = map2({f => f(5)}, [to_float])
9 changes: 0 additions & 9 deletions brat/examples/vector.brat
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,12 @@
swap(Nat, Nat) -> Nat, Nat
swap = a, b => b, a

nat :: Nat
nat = 0

-- comp :: Nat, Nat -> Nat
-- comp = x, y => fst(swap(x, y))

-- te :: Vec Bool 2
-- te = [true, true]

test :: Nat
test = 1

ha :: Nat
ha = ?idk

type A = Nat

isNil :: { Vec(A, 0) -> Bool }
Expand Down
2 changes: 1 addition & 1 deletion brat/test/Test/Compile/Hugr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ nonCompilingExamples = (expectedCheckingFails ++ expectedParsingFails ++
,"kernel-syntax"
,"kinds"
,"let"
,"list"
,"listpair"
,"one"
,"patterns"
,"qft"
,"test"
,"type_alias"
,"vector"
-- Conjecture: These examples don't compile because number patterns in type
-- signatures causes `kindCheck` to call `abstract`, creating "Selector"
Expand Down
Loading