formura-1.0: src/Formura/OrthotopeMachine/Graph.hs
{- |
Copyright : (c) Takayuki Muranushi, 2015
License : MIT
Maintainer : muranushi@gmail.com
Stability : experimental
A virtual machine with multidimensional vector instructions that operates on structured lattices, as described
in http://arxiv.org/abs/1204.4779 .
-}
{-# LANGUAGE DataKinds, DeriveFunctor, DeriveFoldable, DeriveTraversable, FlexibleInstances, PatternSynonyms,TemplateHaskell, TypeSynonymInstances, ViewPatterns #-}
module Formura.OrthotopeMachine.Graph where
import Algebra.Lattice
import Control.Lens
import qualified Data.IntMap as G
import qualified Formura.Annotation as A
import Formura.Language.Combinator
import Formura.Syntax
import Formura.Type
import Formura.Vec
-- | The functor for orthotope machine-specific instructions. Note that arithmetic operations are outsourced.
data DataflowInstF x
= LoadF IdentName
| StoreF IdentName x
| LoadIndexF Int
| LoadExtentF Int
| ShiftF (Vec Int) x
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
-- | smart patterns
pattern Load n <- ((^? match) -> Just (LoadF n)) where
Load n = match # LoadF n
pattern Store n x <- ((^? match) -> Just (StoreF n x)) where
Store n x = match # StoreF n x
pattern LoadIndex n <- ((^? match) -> Just (LoadIndexF n)) where
LoadIndex n = match # LoadIndexF n
pattern LoadExtent n <- ((^? match) -> Just (LoadExtentF n)) where
LoadExtent n = match # LoadExtentF n
pattern Shift v x <- ((^? match) -> Just (ShiftF v x)) where
Shift v x = match # ShiftF v x
type OMInstF = Sum '[DataflowInstF, OperatorF, ImmF]
type OMInst = Fix OMInstF
type NodeTypeF = Sum '[ TopTypeF, GridTypeF, ElemTypeF ]
type NodeType = Fix NodeTypeF
instance MeetSemiLattice NodeType where
(/\) = semiLatticeOfNodeType
semiLatticeOfNodeType :: NodeType -> NodeType -> NodeType
semiLatticeOfNodeType a b = case go a b of
TopType -> go b a
c -> c
where
go :: NodeType -> NodeType -> NodeType
go a b | a == b = a
go (ElemType ea) (ElemType eb) = subFix (ElemType ea /\ ElemType eb :: ElementalType)
go a@(ElemType _) b@(GridType v c) = let d = a /\ c in
if d==TopType then TopType else GridType v d
go (GridType v1 c1) (GridType v2 c2) = (if v1 == v2 then GridType v1 (c1 /\ c2) else TopType)
go _ _ = TopType
type NodeID = G.Key
data Node = Node {_nodeInst :: OMInstF NodeID, _nodeType :: NodeType, _nodeAnnot :: A.Annotation}
instance Show Node where
show (Node i t _) = show i ++ " :: " ++ show t
makeLenses ''Node
instance A.Annotated Node where
annotation = nodeAnnot
type Graph = G.IntMap Node
data NodeValueF x = NodeValueF NodeID NodeType
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
pattern NodeValue n t <- ((^? match) -> Just (NodeValueF n t)) where NodeValue n t = match # NodeValueF n t
pattern n :. t <- ((^? match) -> Just (NodeValueF n t)) where n :. t = match # NodeValueF n t
data FunValueF x = FunValueF LExpr RXExpr
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
pattern FunValue l r <- ((^? match) -> Just (FunValueF l r)) where FunValue l r = match # FunValueF l r
-- | RXExpr is RExpr extended with NodeValue constructors
type RXExprF = Sum '[ LetF, LambdaF, ApplyF, GridF, TupleF, OperatorF, IdentF, FunValueF, NodeValueF, ImmF ]
type RXExpr = Fix RXExprF
type ValueExprF = Sum '[TupleF, FunValueF, NodeValueF, ImmF]
type ValueExpr = Fix ValueExprF
type ValueLexExprF = Sum '[TupleF, FunValueF, NodeValueF, IdentF, ImmF]
type ValueLexExpr = Fix ValueLexExprF