horde-ad-0.3.0.0: src/HordeAd/Core/AstMethodLet.hs
{-# LANGUAGE CPP #-}
#if MIN_VERSION_GLASGOW_HASKELL(9,12,1,0)
{-# OPTIONS_GHC -fno-expose-overloaded-unfoldings #-}
#endif
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- | Arithmetic instances for AST with sharing method AstMethodLet.
-- The bulk of the instances is defined in "AstSimplify", the remaining
-- instances are here.
module HordeAd.Core.AstMethodLet
(
) where
import Prelude
import Data.Type.Equality (testEquality, (:~:) (Refl))
import Data.Array.Nested qualified as Nested
import Data.Array.Nested.Convert (withShsFromShR, withShsFromShX)
import Data.Array.Nested.Shaped.Shape
import HordeAd.Core.Ast
import HordeAd.Core.AstSimplify
import HordeAd.Core.AstTools
import HordeAd.Core.CarriersAst
import HordeAd.Core.OpsConcrete ()
import HordeAd.Core.TensorKind
import HordeAd.Core.Types
liftRFromS1 :: forall n x s. KnownSpan s
=> (forall sh.
AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x))
-> AstTensor AstMethodLet s (TKR2 n x)
-> AstTensor AstMethodLet s (TKR2 n x)
{-# INLINE liftRFromS1 #-}
liftRFromS1 f a = case ftkAst a of
FTKR sh' x ->
withShsFromShR sh' $ \(sh :: ShS sh) ->
astConvUpRFromS sh x $ f (astConvDownSFromR sh x a)
liftRFromS2 :: forall n x s. KnownSpan s
=> (forall sh.
AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x))
-> AstTensor AstMethodLet s (TKR2 n x)
-> AstTensor AstMethodLet s (TKR2 n x)
-> AstTensor AstMethodLet s (TKR2 n x)
{-# INLINE liftRFromS2 #-}
liftRFromS2 f a b = case ftkAst a of
FTKR sh' x ->
withShsFromShR sh' $ \(sh :: ShS sh) ->
astConvUpRFromS sh x
$ f (astConvDownSFromR sh x a) (astConvDownSFromR sh x b)
liftXFromS1 :: forall sh' x s. KnownSpan s
=> (forall sh.
AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x))
-> AstTensor AstMethodLet s (TKX2 sh' x)
-> AstTensor AstMethodLet s (TKX2 sh' x)
{-# INLINE liftXFromS1 #-}
liftXFromS1 f a = case ftkAst a of
FTKX sh' x ->
withShsFromShX sh' $ \(sh :: ShS sh) ->
astConvUpXFromS sh' x $ f (astConvDownSFromX sh x a)
liftXFromS2 :: forall sh' x s. KnownSpan s
=> (forall sh.
AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x)
-> AstTensor AstMethodLet s (TKS2 sh x))
-> AstTensor AstMethodLet s (TKX2 sh' x)
-> AstTensor AstMethodLet s (TKX2 sh' x)
-> AstTensor AstMethodLet s (TKX2 sh' x)
{-# INLINE liftXFromS2 #-}
liftXFromS2 f a b = case ftkAst a of
FTKX sh' x ->
withShsFromShX sh' $ \(sh :: ShS sh) ->
astConvUpXFromS sh' x
$ f (astConvDownSFromX sh x a) (astConvDownSFromX sh x b)
-- * Unlawful numeric instances for ranked AST; lawful modulo evaluation
instance (NumScalar r, KnownSpan s)
=> Num (AstTensor AstMethodLet s (TKR n r)) where
(+) = liftRFromS2 (+)
(-) = liftRFromS2 (-)
(*) = liftRFromS2 (*)
negate = liftRFromS1 negate
abs = liftRFromS1 abs
signum = liftRFromS1 signum
fromInteger i = error $ "fromInteger is not defined for ranked tensors: "
++ show i
instance (NumScalar r, IntegralH r, Nested.IntElt r, KnownSpan s)
=> IntegralH (AstTensor AstMethodLet s (TKR n r)) where
quotH = liftRFromS2 quotH
remH = liftRFromS2 remH
instance (NumScalar r, Differentiable r, KnownSpan s)
=> Fractional (AstTensor AstMethodLet s (TKR n r)) where
(/) = liftRFromS2 (/)
recip = liftRFromS1 recip
fromRational r = error $ "fromRational is not defined for ranked tensors: "
++ show r
instance (NumScalar r, Differentiable r, KnownSpan s)
=> Floating (AstTensor AstMethodLet s (TKR n r)) where
pi = error "pi is not defined for tensors"
exp = liftRFromS1 exp
log = liftRFromS1 log
sqrt = liftRFromS1 sqrt
(**) = liftRFromS2 (**)
logBase = liftRFromS2 logBase
sin = liftRFromS1 sin
cos = liftRFromS1 cos
tan = liftRFromS1 tan
asin = liftRFromS1 asin
acos = liftRFromS1 acos
atan = liftRFromS1 atan
sinh = liftRFromS1 sinh
cosh = liftRFromS1 cosh
tanh = liftRFromS1 tanh
asinh = liftRFromS1 asinh
acosh = liftRFromS1 acosh
atanh = liftRFromS1 atanh
instance (NumScalar r, Differentiable r, KnownSpan s)
=> RealFloatH (AstTensor AstMethodLet s (TKR n r)) where
atan2H = liftRFromS2 atan2H
-- TODO: refactor with something like liftRFromS2
instance (KnownSpan s, NumScalar r)
=> EqH (AstTensor AstMethodLet s) (TKR n r) where
v ==. u = case ftkAst v of
FTKR shv' x -> case ftkAst u of
FTKR shu' _ ->
withShsFromShR shv' $ \shv ->
withShsFromShR shu' $ \shu ->
case testEquality shv shu of
Just Refl ->
astConvDownSFromR shu x v ==. astConvDownSFromR shv x u
_ -> error $ "(==.): shapes don't match: "
++ show (shu, shv)
instance (KnownSpan s, NumScalar r)
=> OrdH (AstTensor AstMethodLet s) (TKR n r) where
v <=. u = case ftkAst v of
FTKR shv' x -> case ftkAst u of
FTKR shu' _ ->
withShsFromShR shv' $ \shv ->
withShsFromShR shu' $ \shu ->
case testEquality shv shu of
Just Refl ->
astConvDownSFromR shu x v <=. astConvDownSFromR shv x u
_ -> error $ "(<=.): shapes don't match: "
++ show (shu, shv)
-- * Unlawful numeric instances for mixed AST; lawful modulo evaluation
instance (NumScalar r, KnownSpan s)
=> Num (AstTensor AstMethodLet s (TKX sh r)) where
(+) = liftXFromS2 (+)
(-) = liftXFromS2 (-)
(*) = liftXFromS2 (*)
negate = liftXFromS1 negate
abs = liftXFromS1 abs
signum = liftXFromS1 signum
fromInteger i = error $ "fromInteger is not defined for mixed tensors: "
++ show i
instance (NumScalar r, IntegralH r, Nested.IntElt r, KnownSpan s)
=> IntegralH (AstTensor AstMethodLet s (TKX sh r)) where
quotH = liftXFromS2 quotH
remH = liftXFromS2 remH
instance (NumScalar r, Differentiable r, KnownSpan s)
=> Fractional (AstTensor AstMethodLet s (TKX sh r)) where
(/) = liftXFromS2 (/)
recip = liftXFromS1 recip
fromRational r = error $ "fromRational is not defined for mixed tensors: "
++ show r
instance (NumScalar r, Differentiable r, KnownSpan s)
=> Floating (AstTensor AstMethodLet s (TKX sh r)) where
pi = error "pi is not defined for tensors"
exp = liftXFromS1 exp
log = liftXFromS1 log
sqrt = liftXFromS1 sqrt
(**) = liftXFromS2 (**)
logBase = liftXFromS2 logBase
sin = liftXFromS1 sin
cos = liftXFromS1 cos
tan = liftXFromS1 tan
asin = liftXFromS1 asin
acos = liftXFromS1 acos
atan = liftXFromS1 atan
sinh = liftXFromS1 sinh
cosh = liftXFromS1 cosh
tanh = liftXFromS1 tanh
asinh = liftXFromS1 asinh
acosh = liftXFromS1 acosh
atanh = liftXFromS1 atanh
instance (NumScalar r, Differentiable r, KnownSpan s)
=> RealFloatH (AstTensor AstMethodLet s (TKX sh r)) where
atan2H = liftXFromS2 atan2H
instance (KnownSpan s, NumScalar r)
=> EqH (AstTensor AstMethodLet s) (TKX sh r) where
v ==. u = case ftkAst v of
FTKX shv' x -> case ftkAst u of
FTKX shu' _ ->
withShsFromShX shv' $ \shv ->
withShsFromShX shu' $ \shu ->
case testEquality shv shu of
Just Refl ->
astConvDownSFromX shu x v ==. astConvDownSFromX shv x u
_ -> error $ "(==.): shapes don't match: "
++ show (shu, shv)
instance (KnownSpan s, NumScalar r)
=> OrdH (AstTensor AstMethodLet s) (TKX sh r) where
v <=. u = case ftkAst v of
FTKX shv' x -> case ftkAst u of
FTKX shu' _ ->
withShsFromShX shv' $ \shv ->
withShsFromShX shu' $ \shu ->
case testEquality shv shu of
Just Refl ->
astConvDownSFromX shu x v <=. astConvDownSFromX shv x u
_ -> error $ "(<=.): shapes don't match: "
++ show (shu, shv)
--- * AstNoVectorize and AstNoSimplify instances
instance Boolean (AstNoVectorize PlainSpan (TKScalar Bool)) where
true = AstNoVectorize true
false = AstNoVectorize false
notB b = AstNoVectorize (notB $ unAstNoVectorize b)
b &&* c = AstNoVectorize (unAstNoVectorize b &&* unAstNoVectorize c)
b ||* c = AstNoVectorize (unAstNoVectorize b ||* unAstNoVectorize c)
instance (EqH (AstTensor AstMethodLet s) y)
=> EqH (AstNoVectorize s) y where
AstNoVectorize v ==. AstNoVectorize u = AstNoVectorize $ v ==. u
instance (OrdH (AstTensor AstMethodLet s) y)
=> OrdH (AstNoVectorize s) y where
AstNoVectorize v <=. AstNoVectorize u = AstNoVectorize $ v <=. u
deriving instance Eq (AstNoVectorize s y)
deriving instance Ord (AstNoVectorize s y)
deriving instance Num (AstTensor AstMethodLet s y) => Num (AstNoVectorize s y)
deriving instance (IntegralH (AstTensor AstMethodLet s y))
=> IntegralH (AstNoVectorize s y)
deriving instance Fractional (AstTensor AstMethodLet s y)
=> Fractional (AstNoVectorize s y)
deriving instance Floating (AstTensor AstMethodLet s y)
=> Floating (AstNoVectorize s y)
deriving instance (RealFloatH (AstTensor AstMethodLet s y))
=> RealFloatH (AstNoVectorize s y)
instance Boolean (AstNoSimplify PlainSpan (TKScalar Bool)) where
true = AstNoSimplify true
false = AstNoSimplify false
notB b = AstNoSimplify (notB $ unAstNoSimplify b)
b &&* c = AstNoSimplify (unAstNoSimplify b &&* unAstNoSimplify c)
b ||* c = AstNoSimplify (unAstNoSimplify b ||* unAstNoSimplify c)
instance (EqH (AstTensor AstMethodLet s) y)
=> EqH (AstNoSimplify s) y where
AstNoSimplify v ==. AstNoSimplify u = AstNoSimplify $ v ==. u
instance (OrdH (AstTensor AstMethodLet s) y)
=> OrdH (AstNoSimplify s) y where
AstNoSimplify v <=. AstNoSimplify u = AstNoSimplify $ v <=. u
deriving instance Eq (AstNoSimplify s y)
deriving instance Ord (AstNoSimplify s y)
deriving instance Num (AstTensor AstMethodLet s y) => Num (AstNoSimplify s y)
deriving instance (IntegralH (AstTensor AstMethodLet s y))
=> IntegralH (AstNoSimplify s y)
deriving instance Fractional (AstTensor AstMethodLet s y)
=> Fractional (AstNoSimplify s y)
deriving instance Floating (AstTensor AstMethodLet s y)
=> Floating (AstNoSimplify s y)
deriving instance (RealFloatH (AstTensor AstMethodLet s y))
=> RealFloatH (AstNoSimplify s y)