25 | import public Control.Monad.State
26 | import Control.Monad.Error.Either
27 | import Syntax.PreorderReasoning
29 | import Compiler.Eval
31 | import Compiler.Xla.Shape
32 | import Compiler.Xla.ShapeUtil
33 | import Compiler.LiteralRW
34 | import Compiler.Passes
37 | import public Literal
42 | XlaShape = Xla.Shape
48 | data Tensor : Shape -> DType -> Type where
49 | MkTensor : Value -> {shape : _} -> {dtype : _} -> Tensor shape dtype
53 | data TagT : (Type -> Type) -> Type -> Type where
54 | MkTagT : StateT Env m a -> TagT m a
61 | Functor m => Functor (TagT m) where
62 | map f (MkTagT x) = MkTagT (map f x)
65 | Monad m => Applicative (TagT m) where
66 | pure x = MkTagT (pure x)
67 | (MkTagT f) <*> (MkTagT x) = MkTagT (f <*> x)
70 | Monad m => Monad (TagT m) where
71 | (MkTagT x) >>= f = MkTagT $
x >>= (\y => let MkTagT z = f y in z)
74 | MonadTrans TagT where
75 | lift = MkTagT . lift
78 | interface Taggable a where
95 | tag : Monad m => a -> TagT m a
97 | Taggable OpRef where
98 | tag = MkTagT . tagOpRef
101 | Taggable (Tensor shape dtype) where
102 | tag (MkTensor $
V idx op) = map (\op => MkTensor $
V idx op) (tag op)
105 | (Taggable a, Taggable b) => Taggable (a, b) where
106 | tag (a, b) = [| (tag a, tag b) |]
109 | val0 = V 0 . Concrete
111 | t0 : {shape : _} -> {dtype : _} -> Op -> Tensor shape dtype
112 | t0 x = MkTensor $
val0 x
121 | tensor : {shape : _} -> {dtype : _} -> Literal shape (idrisType dtype) -> Tensor shape dtype
122 | tensor lit = t0 $
Lit shape dtype lit
126 | fromDouble : Double -> Tensor [] F64
127 | fromDouble = tensor . Scalar
129 | try : Show e => EitherT e IO a -> IO a
130 | try = eitherT (\e => assert_total $
idris_crash $
show e) pure
132 | %hide Literal.All2.All2
150 | forall shapes, dtypes .
152 | Tag (All2 Tensor shapes dtypes) ->
153 | IO (All2 Literal shapes (DType.idrisType <$> dtypes))
154 | eval device (MkTagT xs) =
155 | let (env, xs) = runState empty xs
157 | xlaShapes <- buildShapes xs
158 | let (
outputs ** eq)
= lengthC xs
159 | main = MkFn 0 [] (resultTypes xs) (results xs) env
160 | lits <- execute device main {outputs} (rewrite eq in xlaShapes)
161 | readAll xs $
rewrite sym eq in lits
165 | lengthC : All2 Tensor s t -> (
n ** n === length s)
166 | lengthC [] = (
0 ** Refl)
167 | lengthC (_ :: xs) = let (
n ** eq)
= lengthC xs in (
S n ** cong S eq)
169 | buildShapes : HasIO io => All2 Tensor s t -> io $
Vect (length s) XlaShape
170 | buildShapes [] = pure []
171 | buildShapes (MkTensor {shape, dtype} _ :: ts) = [| mkShape shape dtype :: buildShapes ts |]
173 | results : All2 Tensor s t -> Vect (length s) Value
175 | results (MkTensor x :: xs) = x :: results xs
177 | resultTypes : All2 Tensor s t -> Vect (length s) ValueType
178 | resultTypes [] = []
179 | resultTypes (MkTensor {shape, dtype} _ :: xs) = TensorType shape dtype :: resultTypes xs
184 | Vect (length s) Literal ->
185 | io $
All2 Literal s (DType.idrisType <$> t)
186 | readAll [] _ = pure []
187 | readAll (MkTensor {dtype} _ :: ts) (l :: ls) = [| read dtype l :: readAll ts ls |]
192 | forall shapes, dtypes .
194 | All2 Tensor shapes dtypes ->
195 | IO (All2 Literal shapes (DType.idrisType <$> dtypes))
196 | eval device xs = eval device (pure xs)
206 | eval : Device -> Tag (Tensor shape dtype) -> IO (Literal shape (DType.idrisType dtype))
207 | eval device x = map (\[z] => z) $
List.Tag.eval device $
map (\z => [z]) x
211 | eval : Device -> Tensor shape dtype -> IO (Literal shape (DType.idrisType dtype))
212 | eval device x = eval device (pure x)
218 | Show (Tag $
Tensor shape dtype) where
220 | let (env, MkTensor x) = runState empty x
221 | in show (MkFn 0 [] [TensorType shape dtype] [x] env)
224 | Show (Tensor shape dtype) where show = show . pure {f = Tag}
228 | inf : Tensor [] F64
232 | nan : Tensor [] F64
237 | min : Ord dtype => Tensor [] dtype
238 | min @{OrdS32} = t0 $
MinValue S32
239 | min @{OrdS64} = t0 $
MinValue S64
240 | min @{OrdU32} = t0 $
MinValue U32
241 | min @{OrdU64} = t0 $
MinValue U64
242 | min @{OrdF64} = tensor $
Scalar $
-1.0 / 0.0
246 | max : Ord dtype => Tensor [] dtype
247 | max @{OrdS32} = t0 $
MaxValue S32
248 | max @{OrdS64} = t0 $
MaxValue S64
249 | max @{OrdU32} = t0 $
MaxValue U32
250 | max @{OrdU64} = t0 $
MaxValue U64
251 | max @{OrdF64} = tensor $
Scalar $
1.0 / 0.0
255 | minFinite : Tensor [] F64
256 | minFinite = t0 MinFiniteFloat
260 | maxFinite : Tensor [] F64
261 | maxFinite = t0 MaxFiniteFloat
266 | castDtype : Integral dtype => Tensor shape dtype -> Tensor shape F64
267 | castDtype $
MkTensor {shape} x = t0 $
Convert F64 shape x
271 | Func : Vect arity Type -> Type -> Type
273 | Func (t :: ts) r = t -> Func ts r
275 | mapFunc : (a -> b) -> {arity : Nat} -> {0 xs : Vect arity Type} -> Func xs a -> Func xs b
276 | mapFunc f {arity = 0} {xs = []} g = f g
277 | mapFunc f {arity = (S k)} {xs = _ :: _} g = \x => mapFunc f (g x)
280 | forall arity, rshapes, rdtypes . (shapes : Vect arity Shape) -> (dtypes : Vect arity DType) ->
281 | Func [| Tensor shapes dtypes |] (Tag $
All2 Tensor rshapes rdtypes) ->
282 | Tag (Fn arity, All2 Tensor rshapes rdtypes)
283 | mkFn' shapes dtypes f = MkTagT $
do
286 | let leq : length shapes === arity
287 | leq = lengthCorrect shapes
289 | let MkTagT res = applyNary addr (length shapes) _ _ $
rewrite leq in f
290 | (env, results) = runState (emptyFrom !get) res
291 | resAndTys = fromList $
resultsAndTypes results
292 | argValueTypes = zipWith TensorType shapes dtypes
293 | f : Fn arity = MkFn addr argValueTypes (snd <$> resAndTys) (fst <$> resAndTys) env
295 | updateCounterFrom env
302 | (addr, ar : Nat) ->
303 | (ss : Vect ar Shape) ->
304 | (ds : Vect ar DType) ->
305 | Func [| Tensor ss ds |] a -> a
306 | applyNary addr 0 [] [] f = f
307 | applyNary addr (S a) (s :: ss) (t :: ts) f =
308 | applyNary addr a ss ts (f $
MkTensor $
V (length shapes `minus` S a) $
BoundSet addr)
310 | resultsAndTypes : All2 Tensor s d -> List (Value, ValueType)
311 | resultsAndTypes [] = []
312 | resultsAndTypes ((MkTensor {shape, dtype} x) :: xs) =
313 | (x, TensorType shape dtype) :: resultsAndTypes xs
316 | {arity : _} -> (shapes : Vect arity Shape) -> (dtypes : Vect arity DType) ->
317 | forall rshapes, rdtypes .
318 | Func [| Tensor shapes dtypes |] (Tag $
All2 Tensor rshapes rdtypes) -> Tag $
Fn arity
319 | mkFn shapes dtypes f = fst <$> mkFn' shapes dtypes f
322 | {arity : _} -> (shapes : Vect arity Shape) -> (dtypes : Vect arity DType) ->
323 | Func [| Tensor shapes dtypes |] (Tag $
Tensor rshape rdtype) -> Tag $
Fn arity
324 | mkFn1 shapes dtypes f =
325 | mkFn shapes dtypes $
mapFunc (\x => pure $
the (All2 _ _ _) [!x]) f
339 | forall arity, rshapes, rdtypes . {shapes : Vect arity Shape} -> {dtypes : Vect arity DType} ->
340 | let fn = Func [| Tensor shapes dtypes |] $
Tag $
All2 Tensor rshapes rdtypes in fn -> Tag fn
342 | let leq : length shapes === arity
343 | leq = lengthCorrect shapes
345 | (f, results) <- mkFn' shapes dtypes {rshapes, rdtypes} f
347 | let (extraArgs, f) = snd $
removeCaptures {n = length shapes} $
rewrite leq in f
348 | MkTagT $
modify {ops $= ((f.tag, NamedFunc f) ::)}
350 | let remapResults : List Value -> Tag $
All2 Tensor rshapes rdtypes
352 | let op = Concrete $
CallByName f.tag (toList $
f.resultTypes) (x ++ toList extraArgs)
353 | in retarget 0 results <$> tag op
355 | args := args [] (length shapes) (rewrite leq in shapes) (rewrite leq in dtypes)
357 | pure $
rewrite sym leq in mapFunc {arity = length shapes} remapResults args
362 | (acc : List Value) ->
364 | (ss : Vect ar Shape) ->
365 | (ds : Vect ar DType) ->
366 | Func [| Tensor ss ds |] $
List Value
367 | args acc 0 [] [] = acc
368 | args acc (S a) (s :: ss) (t :: ts) = \(MkTensor x) => args (snoc acc x) a ss ts
370 | retarget : Nat -> All2 Tensor ss ds -> OpRef -> All2 Tensor ss ds
371 | retarget k [] x = []
372 | retarget k (MkTensor {shape, dtype} _ :: xs) x =
373 | MkTensor {shape, dtype} (V k x) :: retarget (S k) xs x
392 | grad : (Tensor shape F64 -> Tag $
Tensor [] F64) -> Tensor shape F64 -> Tag $
Tensor shape F64
393 | grad f (MkTensor x) = pure $
t0 $
Grad shape !(mkFn1 [shape] [_] f) x
400 | {auto 0 sizesEqual : product from = product to} ->
401 | Tensor from dtype ->
403 | reshape $
MkTensor {shape} x = t0 $
Reshape dtype to x
411 | {auto 0 inBounds : axis `LTE` length shape} ->
412 | Tensor shape dtype ->
413 | Tensor (insertAt axis 1 shape) dtype
414 | expand axis $
MkTensor {shape = _} x = t0 $
Reshape dtype (insertAt axis 1 shape) x
416 | namespace Squeezable
420 | data Squeezable : (0 from : Shape) -> (0 to : Shape) -> Type where
425 | Same : Squeezable x x
431 | Match : Squeezable from to -> Squeezable (x :: from) (x :: to)
436 | Nest : Squeezable from to -> Squeezable (1 :: from) to
457 | {auto 0 shapesSqueezable : Squeezable from to} ->
458 | Tensor from dtype ->
460 | squeeze $
MkTensor {shape} x = t0 $
Reshape dtype to x
465 | data SliceOrIndex : Nat -> Type where
467 | (from, to : Nat) ->
469 | {auto 0 fromTo : from + size = to} ->
470 | {auto 0 inDim : LTE to d} ->
472 | Index : (idx : Nat) -> {auto 0 inDim : LT idx d} -> SliceOrIndex d
473 | DynamicSlice : Tensor [] U64 -> (size : Nat) -> {auto 0 inDim : LTE size d} -> SliceOrIndex d
474 | DynamicIndex : Tensor [] U64 -> SliceOrIndex d
478 | at : (idx : Nat) -> {auto 0 inDim : LT idx d} -> SliceOrIndex d
484 | at : Tensor [] U64 -> SliceOrIndex d
490 | (from, to : Nat) ->
492 | {auto 0 fromTo : from + size = to} ->
493 | {auto 0 inDim : LTE to d} ->
499 | (.size) : Tensor [] U64 -> (size : Nat) -> {auto 0 inDim : LTE size d} -> SliceOrIndex d
500 | (.size) = DynamicSlice
504 | all : {d : _} -> SliceOrIndex d
505 | all = Slice 0 @{%search} @{reflexive {ty = Nat}} d
510 | data MultiSlice : Shape -> Type where
511 | Nil : MultiSlice ds
512 | (::) : SliceOrIndex d -> MultiSlice ds -> MultiSlice (d :: ds)
514 | namespace MultiSlice
518 | slice : {shape : _} -> MultiSlice shape -> Shape
519 | slice {shape} [] = shape
520 | slice {shape = (_ :: _)} (Slice {size} _ _ :: xs) = size :: slice xs
521 | slice {shape = (_ :: _)} (Index _ :: xs) = slice xs
522 | slice {shape = (_ :: _)} (DynamicSlice _ size :: xs) = size :: slice xs
523 | slice {shape = (_ :: _)} (DynamicIndex _ :: xs) = slice xs
611 | slice : (at : MultiSlice shape) -> Tensor shape dtype -> Tensor (slice at) dtype
612 | slice at $
MkTensor x = MkTensor $
613 | let x = val0 $
Slice (mapd start (const 0) at) (mapd stop id at) (replicate (length shape) 1) x
615 | x = if isDynamic at then val0 $
DynamicSlice (dynStarts [] at) (mapd size id at) x else x
616 | in val0 $
Reshape dtype (MultiSlice.slice at) x
619 | mapd : ((Nat -> a) -> {d : Nat} -> SliceOrIndex d -> a) ->
622 | MultiSlice shape ->
624 | mapd _ dflt {shape} [] = Prelude.map dflt shape
625 | mapd f dflt (x :: xs) = f dflt x :: mapd f dflt xs
627 | start : (Nat -> Nat) -> {d : Nat} -> SliceOrIndex d -> Nat
628 | start _ (Slice from _) = from
629 | start _ (Index idx) = idx
630 | start f {d} _ = f d
632 | stop : (Nat -> Nat) -> {d : Nat} -> SliceOrIndex d -> Nat
633 | stop _ (Slice _ to) = to
634 | stop _ (Index idx) = S idx
637 | size : (Nat -> Nat) -> {d : Nat} -> SliceOrIndex d -> Nat
638 | size _ (Slice {size = size'} _ _) = size'
639 | size _ (Index _) = 1
640 | size _ (DynamicSlice _ size') = size'
641 | size _ (DynamicIndex _) = 1
644 | zero = val0 $
Lit [] U64 $
Scalar 0
646 | isDynamic : {shape : _} -> MultiSlice shape -> Bool
647 | isDynamic [] = False
648 | isDynamic {shape = (_ :: _)} (DynamicSlice _ _ :: _) = True
649 | isDynamic {shape = (_ :: _)} (DynamicIndex _ :: _) = True
650 | isDynamic (_ :: ds) = isDynamic ds
652 | dynStarts : List Value -> {shape : _} -> MultiSlice shape -> List Value
653 | dynStarts idxs {shape} [] = replicate (length shape) zero ++ idxs
654 | dynStarts idxs (DynamicSlice (MkTensor i) _ :: ds) = i :: dynStarts idxs ds
655 | dynStarts idxs (DynamicIndex (MkTensor i) :: ds) = i :: dynStarts idxs ds
656 | dynStarts idxs (_ :: ds) = zero :: dynStarts idxs ds
667 | {auto 0 inBounds : (InBounds axis s, InBounds axis s')} ->
668 | {auto 0 shapesConcatenable : deleteAt axis s = deleteAt axis s'} ->
669 | Tensor (replaceAt axis (index axis s + index axis s') s) dtype
670 | concat axis (MkTensor x) (MkTensor x') = t0 $
Concat axis [x, x']
674 | (.T) : Tensor [m, n] dtype -> Tensor [n, m] dtype
675 | (MkTensor x).T = t0 $
Transpose [1, 0] x
723 | (ordering : List Nat) ->
724 | Tensor shape dtype ->
725 | {auto 0 lengths : length ordering = length shape} ->
726 | {auto 0 axesUnique : unique ordering = True} ->
727 | {auto 0 inBounds : All (flip InBounds shape) ordering} ->
728 | Tensor (multiIndex ordering shape) dtype
729 | transpose ordering $
MkTensor x = t0 $
Transpose ordering x
734 | data DimBroadcastable : (0 from : Nat) -> (0 to : Nat) -> Type where
737 | Same : DimBroadcastable x x
741 | Stack : DimBroadcastable 1 _
744 | Zero : DimBroadcastable _ 0
746 | namespace Broadcastable
750 | data Broadcastable : (0 from : Shape) -> (0 to : Shape) -> Type where
759 | Same : Broadcastable x x
767 | Match : forall from, to .
768 | {auto 0 ranksEq : length from = length to} ->
769 | {auto 0 dimBroadcastable : DimBroadcastable f t} ->
770 | Broadcastable from to ->
771 | Broadcastable (f :: from) (t :: to)
777 | Nest : Broadcastable f t -> Broadcastable f (_ :: t)
783 | broadcastableByLeading : (leading : List Nat) -> Broadcastable shape (leading ++ shape)
784 | broadcastableByLeading [] = Same
785 | broadcastableByLeading (l :: ls) = Nest (broadcastableByLeading ls)
790 | scalarToAnyOk : (to : Shape) -> Broadcastable [] to
791 | scalarToAnyOk to = rewrite sym $
appendNilRightNeutral to in broadcastableByLeading to
805 | {to : _} -> {dtype : _} ->
806 | {auto shapesOK : Broadcastable from to} ->
807 | Tensor from dtype ->
809 | broadcast $
MkTensor {shape = _} x = t0 $
Broadcast dtype from to x
823 | fill : {shape : _} -> {dtype : _} -> idrisType dtype -> Tensor shape dtype
824 | fill x = broadcast {shapesOK = scalarToAnyOk shape} (tensor (Scalar x))
854 | {auto 0 _ : Num dtype} ->
856 | {auto 0 inBounds : InBounds axis shape} ->
858 | iota dimension = t0 $
Iota shape dtype dimension
873 | (condition : Tensor shape dtype -> Tag $
Tensor [] PRED) ->
874 | (body : Tensor shape dtype -> Tag $
Tensor shape dtype) ->
875 | (initial : Tensor shape dtype) ->
876 | Tag $
Tensor shape dtype
877 | while1 condition body (MkTensor i0) =
878 | pure $
t0 $
While !(mkFn1 [_] [_] condition) !(mkFn1 [_] [_] body) [i0]
894 | (condition : Tensor s a -> Tensor s' a' -> Tag $
Tensor [] PRED) ->
895 | (body : Tensor s a -> Tensor s' a' -> Tag $
All2 Tensor [s, s'] [a, a']) ->
896 | (initial : Tensor s a) -> (initial' : Tensor s' a') ->
897 | Tag $
All2 Tensor [s, s'] [a, a']
898 | while2 condition body (MkTensor i) (MkTensor i') = do
899 | res <- tag $
Concrete $
While !(mkFn1 [_, _] [_, _] condition) !(mkFn [_, _] [_, _] body) [i, i']
900 | pure [MkTensor $
V 0 res, MkTensor $
V 1 res]
914 | map : {b : _} -> (Tensor [] a -> Tag $
Tensor [] b) -> Tensor shape a -> Tag $
Tensor shape b
915 | map f $
MkTensor {shape = _} x =
916 | pure $
t0 $
Map !(mkFn1 [_] [_] f) [x] (TensorType shape b) (range $
length shape)
932 | (Tensor [] a -> Tensor [] b -> Tag $
Tensor [] c) ->
933 | Tensor shape a -> Tensor shape b -> Tag $
Tensor shape c
934 | map2 f (MkTensor {shape = _} x) (MkTensor x') =
935 | pure $
t0 $
Map !(mkFn1 [_, _] [_, _] f) [x, x'] (TensorType shape c) (range $
length shape)
953 | (reducer : Monoid (Tensor [] dtype)) =>
954 | (axes : List Nat) ->
955 | {auto 0 axesUnique : Sorted LT axes} ->
956 | {auto 0 axesInBounds : All (flip InBounds shape) axes} ->
957 | Tensor shape dtype ->
958 | Tag $
Tensor (deleteAt axes shape) dtype
959 | reduce axes $
MkTensor x = do
960 | let semigroup : Monoid a -> Semigroup a
961 | semigroup _ = %search
963 | g <- mkFn1 [_, _] [_, _] (pure .: (<+>) @{semigroup reducer})
964 | let MkTensor neutral' = neutral @{reducer}
965 | pure $
t0 $
Reduce g [neutral'] axes [x]
986 | (Tensor [] dtype -> Tensor [] dtype -> Tensor [] PRED) ->
987 | (dimension : Nat) ->
988 | Tensor shape dtype ->
989 | {auto 0 dimInBounds : InBounds dimension shape} ->
990 | Tag $
Tensor shape dtype
991 | sort comp dimension $
MkTensor x =
992 | pure $
t0 $
Sort !(mkFn1 [_, _] [_, _] $
pure .: comp) dimension False x
1025 | {auto 0 axesUnique : Sorted LT axes} ->
1026 | {auto 0 axesInBounds : All (flip InBounds shape) axes} ->
1029 | reverse axes $
MkTensor x = t0 $
Reverse axes x
1031 | ewUnary : UnaryOp -> Tensor s a -> Tensor s a
1032 | ewUnary op $
MkTensor x = t0 $
UnaryElementwise op x
1034 | ewBinary : BinaryOp -> Tensor s a -> Tensor s a -> Tensor s a
1035 | ewBinary op (MkTensor x) (MkTensor x') = t0 $
BinaryElementwise op x x'
1037 | ewBinary' : {out : _} -> BinaryOp -> Tensor s a -> Tensor s a -> Tensor s out
1038 | ewBinary' op (MkTensor x) (MkTensor x') = t0 $
BinaryElementwise op x x'
1043 | (==) : Eq dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1044 | (==) = ewBinary' $
Compare Eq
1049 | (/=) : Eq dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1050 | (/=) = ewBinary' $
Compare Ne
1055 | (<) : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1056 | (<) = ewBinary' $
Compare Lt
1061 | (>) : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1062 | (>) = ewBinary' $
Compare Gt
1067 | (<=) : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1068 | (<=) = ewBinary' $
Compare Le
1073 | (>=) : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape PRED
1074 | (>=) = ewBinary' $
Compare Ge
1080 | (&&) : Tensor shape PRED -> Tensor shape PRED -> Tensor shape PRED
1085 | [All] Semigroup (Tensor shape PRED) where
1090 | [All] {shape : _} -> Monoid (Tensor shape PRED) using Tensor.Semigroup.All where
1097 | (||) : Tensor shape PRED -> Tensor shape PRED -> Tensor shape PRED
1102 | [Any] Semigroup (Tensor shape PRED) where
1107 | [Any] {shape : _} -> Monoid (Tensor shape PRED) using Tensor.Semigroup.Any where
1113 | not : Tensor shape PRED -> Tensor shape PRED
1136 | (onTrue, onFalse : Tensor shape dtype) ->
1138 | select (MkTensor p) (MkTensor t) (MkTensor f) = t0 $
Select p t f
1159 | {shape : _} -> {dtype : _} ->
1161 | (onTrue, onFalse : Tag $
Tensor shape dtype) ->
1162 | Tag $
Tensor shape dtype
1163 | if_ (MkTensor pred) onTrue onFalse =
1164 | pure $
t0 $
If (TensorType shape dtype) pred !(mkFn1 [] [] onTrue) !(mkFn1 [] [] onFalse)
1178 | identity : {n : _} -> {dtype : _} -> Num dtype => Tensor [n, n] dtype
1180 | let MkTensor x = iota 0 {shape = [n, n], dtype = U64} == iota 1
1181 | in t0 $
Convert dtype [n, n] x
1191 | (@@) : Num dtype => Tensor [S m] dtype -> Tensor [S m] dtype -> Tensor [] dtype
1192 | (MkTensor x) @@ (MkTensor x') = t0 $
DotGeneral [] [] [0] [0] (TensorType [] dtype) x x'
1215 | Tensor [n, S m] dtype ->
1216 | Tensor (S m :: tl) dtype ->
1217 | {auto 0 vectorTail : length tl `LTE` 1} ->
1219 | (MkTensor x) @@ (MkTensor x') = t0 $
DotGeneral [] [] [1] [0] (TensorType (n :: tl) dtype) x x'
1223 | contract : (lBatch, rBatch, lContract, rContract : List Nat) ->
1225 | {auto 0 lInBoundsBatch : All (flip InBounds ls) lBatch} ->
1226 | {auto 0 rInBoundsBatch : All (flip InBounds rs) rBatch} ->
1227 | {auto 0 lInBoundsContract : All (flip InBounds ls) lContract} ->
1228 | {auto 0 rInBoundsContract : All (flip InBounds rs) rContract} ->
1230 | contract lBatch rBatch lContract rContract ls rs =
1231 | let lResultDims = deleteAt {inBounds = lInBoundsBatch ++ lInBoundsContract}
1232 | (lBatch ++ lContract) ls
1233 | rResultDims = deleteAt {inBounds = rInBoundsBatch ++ rInBoundsContract}
1234 | (rBatch ++ rContract) rs
1235 | in multiIndex lBatch ls ++ lResultDims ++ rResultDims
1265 | (lBatch, rBatch, lContract, rContract : List Nat) ->
1266 | {auto 0 lUnique : unique (lBatch ++ lContract) = True} ->
1267 | {auto 0 rUnique : unique (rBatch ++ rContract) = True} ->
1268 | {auto 0 lInBoundsBatch : All (flip InBounds ls) lBatch} ->
1269 | {auto 0 rInBoundsBatch : All (flip InBounds rs) rBatch} ->
1270 | {auto 0 lInBoundsContract : All (flip InBounds ls) lContract} ->
1271 | {auto 0 rInBoundsContract : All (flip InBounds rs) rContract} ->
1272 | {auto 0 batchDimsEq : multiIndex lBatch ls = multiIndex rBatch rs} ->
1273 | {auto 0 contractDimsEq : multiIndex lContract ls = multiIndex rContract rs} ->
1276 | Tensor (contract lBatch rBatch lContract rContract ls rs) dtype
1277 | dotGeneral lb rb lc rc (MkTensor x) (MkTensor y) =
1278 | let resultType = TensorType (contract lb rb lc rc ls rs) dtype
1279 | in t0 $
DotGeneral lb rb lc rc resultType x y
1284 | (+) : Num dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1289 | [Sum] Num dtype => Semigroup (Tensor shape dtype) where
1294 | [Sum] {shape : _} -> {dtype : _} -> Prelude.Num (idrisType dtype) => Num dtype =>
1295 | Monoid (Tensor shape dtype) using Semigroup.Sum where
1300 | negate : Neg dtype => Tensor shape dtype -> Tensor shape dtype
1301 | negate $
MkTensor i = t0 $
UnaryElementwise Neg i
1306 | (-) : Neg dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1312 | (*) : Num dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1321 | (*) : Num dtype => Tensor [] dtype -> Tensor (d :: ds) dtype -> Tensor (d :: ds) dtype
1323 | let MkTensor {shape = _ :: _} _ = r
1324 | in broadcast {shapesOK = scalarToAnyOk (d :: ds)} l * r
1328 | [Prod] Num dtype => Semigroup (Tensor shape dtype) where
1333 | [Prod] {shape : _} -> {dtype : _} -> Prelude.Num (idrisType dtype) => Num dtype =>
1334 | Monoid (Tensor shape dtype) using Semigroup.Prod where
1340 | (/) : Fractional dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1349 | (/) : Fractional dtype => Tensor (d :: ds) dtype -> Tensor [] dtype -> Tensor (d :: ds) dtype
1351 | let MkTensor {shape = _ :: _} _ = l
1352 | in l / broadcast {shapesOK = scalarToAnyOk (d :: ds)} r
1354 | inf = tensor 1.0 / tensor 0.0
1355 | nan = tensor 0.0 / tensor 0.0
1360 | div : Tensor shape U64 ->
1361 | (denom : Literal shape Nat) ->
1362 | {auto 0 isSucc : All IsSucc denom} ->
1365 | _ | (MkTensor {shape = _} _) = ewBinary Div x (tensor {dtype = U64} $
cast <$> y)
1371 | rem : Tensor shape U64 ->
1372 | (denom : Literal shape Nat) ->
1373 | {auto 0 isSucc : All IsSucc denom} ->
1376 | _ | (MkTensor {shape = _} _) = ewBinary Rem x (tensor {dtype = U64} $
cast <$> y)
1388 | (^) : Tensor shape F64 -> Tensor shape F64 -> Tensor shape F64
1391 | (>>) : Tensor shape U64 -> Tensor shape U64 -> Tensor shape U64
1392 | (>>) = ewBinary ShiftRightLogical
1396 | abs : Abs dtype => Tensor shape dtype -> Tensor shape dtype
1402 | exp : Tensor shape F64 -> Tensor shape F64
1409 | floor : Tensor shape F64 -> Tensor shape F64
1416 | ceil : Tensor shape F64 -> Tensor shape F64
1422 | log : Tensor shape F64 -> Tensor shape F64
1427 | logistic : Tensor shape F64 -> Tensor shape F64
1428 | logistic = ewUnary Logistic
1432 | sin : Tensor shape F64 -> Tensor shape F64
1437 | cos : Tensor shape F64 -> Tensor shape F64
1442 | tan : Tensor shape F64 -> Tensor shape F64
1447 | asin : Tensor shape F64 -> Tensor shape F64
1452 | acos : Tensor shape F64 -> Tensor shape F64
1457 | atan : Tensor shape F64 -> Tensor shape F64
1462 | sinh : Tensor shape F64 -> Tensor shape F64
1467 | cosh : Tensor shape F64 -> Tensor shape F64
1472 | tanh : Tensor shape F64 -> Tensor shape F64
1477 | asinh : Tensor shape F64 -> Tensor shape F64
1482 | acosh : Tensor shape F64 -> Tensor shape F64
1487 | atanh : Tensor shape F64 -> Tensor shape F64
1492 | erf : Tensor shape F64 -> Tensor shape F64
1495 | erfInv : Tensor shape F64 -> Tensor shape F64
1496 | erfInv = ewUnary ErfInv
1501 | square : Tensor shape F64 -> Tensor shape F64
1502 | square = ewUnary Square
1507 | sqrt : Tensor shape F64 -> Tensor shape F64
1513 | min : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1514 | min (MkTensor x) (MkTensor x') = t0 $
BinaryElementwise Min x x'
1518 | [Min] {shape : _} -> Ord dtype => Semigroup (Tensor shape dtype) where
1523 | [Min] {shape : _} -> {dtype : _} -> Ord dtype =>
1524 | Monoid (Tensor shape dtype) using Semigroup.Min where
1525 | neutral = broadcast max
1530 | max : Ord dtype => Tensor shape dtype -> Tensor shape dtype -> Tensor shape dtype
1531 | max (MkTensor x) (MkTensor x') = t0 $
BinaryElementwise Max x x'
1535 | [Max] Ord dtype => Semigroup (Tensor shape dtype) where
1540 | [Max] {shape : _} -> {dtype : _} -> Ord dtype =>
1541 | Monoid (Tensor shape dtype) using Semigroup.Max where
1542 | neutral = broadcast min
1553 | diag : Num dtype => Prelude.Num (idrisType dtype) => Tensor [n, n] dtype -> Tensor [n] dtype
1554 | diag {n = 0} x@(MkTensor {shape = [0, 0]} _) = reshape x
1555 | diag {n = S n} x@(MkTensor {shape = [S n, S n]} _) = (x * identity) @@ fill 1
1559 | (Tensor [] dtype -> Tensor [] dtype -> Tensor [] PRED) ->
1563 | argmxx cmp (MkTensor bound) x@(MkTensor {shape = _} _) = do
1564 | let MkTensor idxs : Tensor [S n] U64 = iota 0
1566 | MkTensor zero = tensor {dtype = U64} 0
1569 | Tensor [] dtype -> Tensor [] U64 ->
1570 | Tensor [] dtype -> Tensor [] U64 ->
1571 | Tag (Tensor [] dtype, Tensor [] U64)
1573 | let useNext = x == x && (cmp x' x || x' /= x')
1574 | in pure (select useNext x' x, select useNext y' y)
1580 | (MkTensor $
V 0 $
BoundSet addr)
1581 | (MkTensor $
V 1 $
BoundSet addr)
1582 | (MkTensor $
V 2 $
BoundSet addr)
1583 | (MkTensor $
V 3 $
BoundSet addr)
1584 | (env, (MkTensor m, MkTensor i)) = runState (emptyFrom !get) res
1585 | argTys = [TensorType [] dtype, TensorType [] U64]
1586 | f = MkFn addr (argTys ++ argTys) argTys [m, i] env
1589 | pure $
MkTensor $
V 1 $
Concrete $
Reduce f [bound, zero] [0] [x, idxs]
1595 | argmax : Ord dtype => Tensor [S n] dtype -> Tag $
Tensor [] U64
1596 | argmax x@(MkTensor {dtype} _) = argmxx (>) min x
1602 | argmin : Ord dtype => Tensor [S n] dtype -> Tag $
Tensor [] U64
1603 | argmin x@(MkTensor {dtype} _) = argmxx (<) max x
1607 | data Triangle = Upper | Lower
1626 | Prelude.Num (idrisType dtype) =>
1629 | Tag $
Tensor [n, n] dtype
1630 | triangle tri (MkTensor x) = do
1631 | let range : Tensor [n * n] U64 = iota 0
1632 | indices <- tag $
reshape {to = [n, n], sizesEqual = productSquare n} range
1636 | pure $
select (op indices indices.T) (fill $
fromInteger 0) (MkTensor x)
1640 | productSquare : (m : Nat) -> product (the Shape [m * m]) = product (the Shape [m, m])
1644 | ~~ m * m ... plusZeroRightNeutral (m * m)
1645 | ~~ (m + 0) * m ..< cong (* m) (plusZeroRightNeutral m)
1652 | cholesky : Tensor [S n, S n] F64 -> Tag $
Tensor [S n, S n] F64
1653 | cholesky $
MkTensor x = triangle Lower (t0 $
Cholesky x)
1666 | (|\) : Tensor [m, m] F64 -> Tensor [m, n] F64 -> Tensor [m, n] F64
1667 | (MkTensor a) |\ (MkTensor b) = t0 $
TriangularSolve a b True
1677 | (\|) : Tensor [m, m] F64 -> Tensor [m, n] F64 -> Tensor [m, n] F64
1678 | (MkTensor a) \| (MkTensor b) = t0 $
TriangularSolve a b False
1689 | (|\) : Tensor [m, m] F64 -> Tensor [m] F64 -> Tensor [m] F64
1690 | a |\ b = let (MkTensor {shape = [_]} _) = b in squeeze (a |\ expand 1 b)
1700 | (\|) : Tensor [m, m] F64 -> Tensor [m] F64 -> Tensor [m] F64
1701 | a \| b = let (MkTensor {shape = [_]} _) = b in squeeze (a \| expand 1 b)
1706 | trace : Num dtype => Prelude.Num (idrisType dtype) =>
1707 | Tensor [S n, S n] dtype ->
1710 | _ | MkTensor {shape = [_, _]} _ = reduce @{Sum} [0, 1] $
x * identity
1716 | Rand = StateT (Tensor [2] U64) Tag
1729 | rng : {shape : _} -> Rand $
Tensor shape U64
1730 | rng = ST $
\(MkTensor state) => do
1731 | res <- tag $
Concrete $
Rng state (TensorType shape U64)
1732 | pure (MkTensor $
V 0 res, MkTensor $
V 1 res)
1745 | uniform : {shape : _} -> Rand $
Tensor shape F64
1747 | let numMantissaBits : Bits64 = 52
1748 | scale = broadcast $
2.0 ^ tensor (Scalar $
- cast {to = Double} numMantissaBits)
1749 | shift = fill $
64 - numMantissaBits
1750 | in rng {shape} <&> \x => castDtype (x >> shift) * scale
1764 | normal : {shape : _} -> Rand $
Tensor shape F64
1765 | normal = uniform <&> \x => sqrt (broadcast 2.0) * erfInv (broadcast 2.0 * x - broadcast 1.0)