Skip to content

Commit

Permalink
more type-safe paraiso!
Browse files Browse the repository at this point in the history
  • Loading branch information
nushio3 committed Jun 5, 2012
1 parent f79bfab commit 08487c4
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 65 deletions.
10 changes: 6 additions & 4 deletions Language/Paraiso/OM/Arithmetic.hs
Expand Up @@ -6,7 +6,8 @@ module Language.Paraiso.OM.Arithmetic
Operator(..) Operator(..)
) where ) where


import NumericPrelude hiding (Ordering(..), Eq(..), Ord(..)) import qualified Data.Dynamic as Dynamic
import NumericPrelude hiding (Ordering(..), Eq(..), Ord(..))
import qualified NumericPrelude as P import qualified NumericPrelude as P


class Arity a where class Arity a where
Expand Down Expand Up @@ -60,8 +61,9 @@ data Operator =
Acos | Acos |
Atan | Atan |
Atan2 | Atan2 |
Sincos Sincos |
deriving (P.Eq, P.Ord, P.Show, P.Read) Cast Dynamic.TypeRep
deriving (P.Eq, P.Ord, P.Show)


instance Arity Operator where instance Arity Operator where
arity a = case a of arity a = case a of
Expand Down Expand Up @@ -105,4 +107,4 @@ instance Arity Operator where
Atan -> (1,1) Atan -> (1,1)
Atan2 -> (2,1) Atan2 -> (2,1)
Sincos -> (1,2) Sincos -> (1,2)

Cast _ -> (1,1)
147 changes: 89 additions & 58 deletions Language/Paraiso/OM/Builder/Internal.hs
Expand Up @@ -166,13 +166,11 @@ bind = fmap return


-- | Load from a static value. -- | Load from a static value.
load :: (TRealm r, Typeable c) => load :: (TRealm r, Typeable c) =>
Named (Val.Value r c) -- the named static value to be loaded. Named (Val.StaticValue r c) -- ^ the named static value to be loaded from.
-> B (Value r c) -- ^The loaded 'TArray' 'Value' as a result. -> B (Value r c) -- ^ The loaded 'Value' as a result.
load (Named name0 val0)= do load (Named name0 (Val.StaticValue r0 c0))= do
let let
r0 = Val.realm val0 type0 = mkDyn r0 c0
c0 = Val.content val0
type0 = toDyn val0
nv = Named name0 type0 nv = Named name0 type0
idx <- lookUpStatic nv idx <- lookUpStatic nv
n0 <- addNodeE [] $ NInst (Load idx) n0 <- addNodeE [] $ NInst (Load idx)
Expand All @@ -181,10 +179,10 @@ load (Named name0 val0)= do


-- | Store to a static value. -- | Store to a static value.
store :: (TRealm r, Typeable c) => store :: (TRealm r, Typeable c) =>
Name -- ^The 'Name' of the static value to store. Named (Val.StaticValue r c) -- ^ the named static value to be stored on.
-> Builder v g a (Value r c) -- ^The 'Value' to be stored. -> Builder v g a (Value r c) -- ^ The 'Value' to be stored.
-> Builder v g a () -- ^The result. -> Builder v g a () -- ^ The result.
store name0 builder0 = do store (Named name0 _) builder0 = do
val0 <- builder0 val0 <- builder0
let let
type0 = toDyn val0 type0 = toDyn val0
Expand Down Expand Up @@ -243,27 +241,30 @@ shift vec builder1 = do
return (FromNode TArray c1 n3) return (FromNode TArray c1 n3)


-- | Load the 'Axis' component of the mesh address, to a 'TArray' 'Value'. -- | Load the 'Axis' component of the mesh address, to a 'TArray' 'Value'.
loadIndex :: (Typeable c) => loadIndex :: (Typeable g)
c -- ^The 'Val.content' type. => Axis v -- ^ The axis for which index is required
-> Axis v -- ^ The axis for which index is required -> Builder v g a (Value TArray g) -- ^ The 'TArray' 'Value' that contains the address as a result.
-> Builder v g a (Value TArray c) -- ^ The 'TArray' 'Value' that contains the address as a result. loadIndex axis = do
loadIndex c0 axis = do -- create a phantom object of type g
let type0 = mkDyn TArray c0 c0 <- (return undefined) `asTypeOf` (fmap Val.content $ loadIndex axis)
let
type0 = mkDyn TArray c0
n0 <- addNodeE [] $ NInst (LoadIndex axis) n0 <- addNodeE [] $ NInst (LoadIndex axis)
n1 <- addNodeE [n0] $ NValue type0 n1 <- addNodeE [n0] $ NValue type0
return (FromNode TArray c0 n1) return (FromNode TArray c0 n1)


-- | Load the 'Axis' component of the mesh size, to either a 'TScalar' 'Value' or 'TArray' 'Value'.. -- | Load the 'Axis' component of the mesh size, to either a 'TScalar' 'Value' or 'TArray' 'Value'..
loadSize :: (TRealm r, Typeable c) loadSize :: (Typeable g)
=> r -- ^ The 'TRealm' => Axis v -- ^ The axis for which the size is required
-> c -- ^The 'Val.content' type. -> Builder v g a (Value TScalar g) -- ^ The 'TScalar' 'Value' that contains the size of the mesh in that direction.
-> Axis v -- ^ The axis for which the size is required loadSize axis = do
-> Builder v g a (Value r c) -- ^ The 'TScalar' 'Value' that contains the size of the mesh in that direction. -- create a phantom object of type g
loadSize r0 c0 axis = do c0 <- (return undefined) `asTypeOf` (fmap Val.content $ loadSize axis)
let type0 = mkDyn r0 c0 let
type0 = mkDyn TScalar c0
n0 <- addNodeE [] $ NInst (LoadSize axis) n0 <- addNodeE [] $ NInst (LoadSize axis)
n1 <- addNodeE [n0] $ NValue type0 n1 <- addNodeE [n0] $ NValue type0
return (FromNode r0 c0 n1) return (FromNode TScalar c0 n1)




-- | Create an immediate 'Value' from a Haskell concrete value. -- | Create an immediate 'Value' from a Haskell concrete value.
Expand All @@ -273,6 +274,13 @@ imm :: (TRealm r, Typeable c) =>
-> B (Value r c) -- ^'TArray' 'Value' with the @c@ stored. -> B (Value r c) -- ^'TArray' 'Value' with the @c@ stored.
imm c0 = return (FromImm unitTRealm c0) imm c0 = return (FromImm unitTRealm c0)




----------------------------------------------------------------
-- Here comes the Arith instruction emitters.
----------------------------------------------------------------


-- | Make a unary operator -- | Make a unary operator
mkOp1 :: (TRealm r, Typeable c) => mkOp1 :: (TRealm r, Typeable c) =>
A.Operator -- ^The operator symbol A.Operator -- ^The operator symbol
Expand Down Expand Up @@ -307,40 +315,6 @@ mkOp2 op builder1 builder2 = do
return $ FromNode r1 c1 n01 return $ FromNode r1 c1 n01




-- | Execute the builder under modifed annotation.
withAnnotation :: (a -> a) -> Builder v g a ret -> Builder v g a ret
withAnnotation f builder1 = do
stat0 <- State.get
let curAnot0 = currentAnnotation (context stat0)
curAnot1 = f curAnot0
State.put $ stat0{ context = (context stat0){ currentAnnotation = curAnot1 } }
ret <- builder1
stat1 <- State.get
State.put $ stat1{ context = (context stat1){ currentAnnotation = curAnot0} }
return ret


-- | Execute the builder, and annotate the very result with the givin function.
annotate :: (TRealm r, Typeable c) => (a -> a) -> Builder v g a (Value r c) -> Builder v g a (Value r c)
annotate f builder1 = do
v1 <- builder1
n1 <- valueToNode v1
let
r1 = Val.realm v1
c1 = Val.content v1
annotator con@(ins, n2, node2, outs)
| n1 /= n2 = con
| otherwise = (ins, n2, fmap f node2, outs)
stat0 <- State.get
State.put $ stat0 {
target = FGL.gmap annotator (target stat0)
}
return $ FromNode r1 c1 n1

-- | (<?>) = annotate
infixr 0 <?>
(<?>) :: (TRealm r, Typeable c) => (a -> a) -> Builder v g a (Value r c) -> Builder v g a (Value r c)
(<?>) = annotate


-- | Builder is Additive 'Additive.C'. -- | Builder is Additive 'Additive.C'.
-- You can use 'Additive.zero', 'Additive.+', 'Additive.-', 'Additive.negate'. -- You can use 'Additive.zero', 'Additive.+', 'Additive.-', 'Additive.negate'.
Expand Down Expand Up @@ -370,6 +344,8 @@ instance (TRealm r, Typeable c, Ring.C c) => Ring.C (Builder v g a (Value r c))
bx_n3 <- fmap return $ f x n3 bx_n3 <- fmap return $ f x n3
modify $ bx_n3*bx_n3 modify $ bx_n3*bx_n3


-- Here comes the Arith node creaters.

-- | Builder is Ring 'IntegralDomain.C'. -- | Builder is Ring 'IntegralDomain.C'.
-- You can use div and mod. -- You can use div and mod.
instance (TRealm r, Typeable c, IntegralDomain.C c) => IntegralDomain.C (Builder v g a (Value r c)) where instance (TRealm r, Typeable c, IntegralDomain.C c) => IntegralDomain.C (Builder v g a (Value r c)) where
Expand Down Expand Up @@ -438,3 +414,58 @@ instance (TRealm r, Typeable c, Transcendental.C c) =>
asin = mkOp1 A.Asin asin = mkOp1 A.Asin
acos = mkOp1 A.Acos acos = mkOp1 A.Acos
atan = mkOp1 A.Atan atan = mkOp1 A.Atan

-- | A special Arith operation that keeps the realm and casts the content
-- from one type to another.
cast :: (TRealm r, Typeable c1,Typeable c2) => (Builder v g a (Value r c1)) -> (Builder v g a (Value r c2))
cast builder1 = do
-- create a phantom object of type c2
v1 <- builder1
c2 <- return undefined `asTypeOf` (fmap Val.content $ cast builder1)
let
r1 = Val.realm v1
c1 = Val.content v1
n1 <- valueToNode v1
n0 <- addNodeE [n1] $ NInst (Arith $ A.Cast $ Dynamic.typeOf c2)
n01 <- addNodeE [n0] $ NValue (toDyn v1)
return $ FromNode r1 c2 n01





-- | Execute the builder under modifed annotation.
withAnnotation :: (a -> a) -> Builder v g a ret -> Builder v g a ret
withAnnotation f builder1 = do
stat0 <- State.get
let curAnot0 = currentAnnotation (context stat0)
curAnot1 = f curAnot0
State.put $ stat0{ context = (context stat0){ currentAnnotation = curAnot1 } }
ret <- builder1
stat1 <- State.get
State.put $ stat1{ context = (context stat1){ currentAnnotation = curAnot0} }
return ret


-- | Execute the builder, and annotate the very result with the givin function.
annotate :: (TRealm r, Typeable c) => (a -> a) -> Builder v g a (Value r c) -> Builder v g a (Value r c)
annotate f builder1 = do
v1 <- builder1
n1 <- valueToNode v1
let
r1 = Val.realm v1
c1 = Val.content v1
annotator con@(ins, n2, node2, outs)
| n1 /= n2 = con
| otherwise = (ins, n2, fmap f node2, outs)
stat0 <- State.get
State.put $ stat0 {
target = FGL.gmap annotator (target stat0)
}
return $ FromNode r1 c1 n1

-- | (<?>) = annotate
infixr 0 <?>
(<?>) :: (TRealm r, Typeable c) => (a -> a) -> Builder v g a (Value r c) -> Builder v g a (Value r c)
(<?>) = annotate

14 changes: 12 additions & 2 deletions Language/Paraiso/OM/DynValue.hs
Expand Up @@ -20,9 +20,19 @@ data DynValue = DynValue {realm :: R.Realm, typeRep :: TypeRep} deriving (Eq, Sh
mkDyn :: (R.TRealm r, Typeable c) => r -> c -> DynValue mkDyn :: (R.TRealm r, Typeable c) => r -> c -> DynValue
mkDyn r0 c0 = DynValue (R.tRealm r0) (typeOf c0) mkDyn r0 c0 = DynValue (R.tRealm r0) (typeOf c0)



-- | Something that can be converted to 'DynValue'
class ToDynable a where
toDyn :: a -> DynValue

-- | Convert 'Val.Value' to 'DynValue' -- | Convert 'Val.Value' to 'DynValue'
toDyn :: (R.TRealm r, Typeable c) => Val.Value r c -> DynValue instance (R.TRealm r, Typeable c) => ToDynable (Val.Value r c) where
toDyn x = mkDyn (Val.realm x) (Val.content x) toDyn x = mkDyn (Val.realm x) (Val.content x)

-- | Convert 'Val.StaticValue' to 'DynValue'
instance (R.TRealm r, Typeable c) => ToDynable (Val.StaticValue r c) where
toDyn (Val.StaticValue r c) = mkDyn r c



instance R.Realmable DynValue where instance R.Realmable DynValue where
realm = realm realm = realm
5 changes: 4 additions & 1 deletion Language/Paraiso/OM/Value.hs
Expand Up @@ -6,7 +6,7 @@


module Language.Paraiso.OM.Value module Language.Paraiso.OM.Value
( (
Value(..) Value(..), StaticValue(..)
) where ) where


import Data.Typeable import Data.Typeable
Expand All @@ -27,6 +27,9 @@ data
-- 'content' is the immediate value to be stored. -- 'content' is the immediate value to be stored.
FromImm {realm :: rea, content :: con} deriving (Eq, Show) FromImm {realm :: rea, content :: con} deriving (Eq, Show)


-- | static value type.
data StaticValue rea con = StaticValue rea con deriving (Eq, Show)



instance (R.TRealm rea, Typeable con) => R.Realmable (Value rea con) where instance (R.TRealm rea, Typeable con) => R.Realmable (Value rea con) where
realm (FromNode r _ _) = R.tRealm r realm (FromNode r _ _) = R.tRealm r
Expand Down

0 comments on commit 08487c4

Please sign in to comment.