0 | {--
1 | Copyright (C) 2021 Joel Berkeley
3 | This program is free software: you can redistribute it and/or modify
4 | it under the terms of the GNU Affero General Public License as published
5 | by the Free Software Foundation, either version 3 of the License, or
6 | (at your option) any later version.
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU Affero General Public License for more details.
13 | You should have received a copy of the GNU Affero General Public License
14 | along with this program. If not, see <https://www.gnu.org/licenses/>.
15 | --}
16 | ||| Defines `Tensor`, an array of numbers or booleans, along with a number of functions operating on
17 | ||| `Tensor`s. `Tensor` operations typically leverage hardware acceleration and graph compilation.
18 | ||| spidr tracks tensor shape and data type in the types, so you can be sure that if your tensor
19 | ||| code compiles, these are consistent.
20 | |||
21 | ||| spidr achieves efficient reuse of tensor computations with `Tag`. See the tutorial
22 | ||| _Nuisances in the Tensor API_ for a discussion of pitfalls to avoid when using `Tag`.
41 | ||| A scalar or array. Construct a `Tensor` with function `tensor`.
42 | export
52 | ||| The effect of tagging nodes in a computational graph.
53 | export
61 | export
65 | export
70 | export
74 | export
80 | ||| Mark an expression to be efficiently reused. For example, in
81 | ||| ```
82 | ||| bad : Tensor [9999999] F64
83 | ||| bad = let x = fill {shape = [9999999]} 1.0 in x + x
84 | |||
85 | ||| good : Tag $ Tensor [9999999] F64
86 | ||| good = do x <- tag $ fill {shape = [9999999]} 1.0
87 | ||| pure (x + x)
88 | ||| ```
89 | ||| the large vector `x` is calculated twice in `bad`, but once in `good`, as `tag` marks it for
90 | ||| sharing.
91 | |||
92 | ||| Types that implement this interface should `tag` constituent components it deems worth sharing.
93 | ||| For example, see the implementation for tuples.
94 | |||
95 | ||| See tutorial _Nuisances in the Tensor API_ for details.
101 | export
105 | export
115 | ||| Construct a `Tensor` from `Literal` data. For example
116 | ||| ```
117 | ||| x : Tensor [2, 3] S32
118 | ||| x = tensor [[1, 2, 3],
119 | ||| [4, 5, 6]]
120 | ||| ```
121 | export
126 | export
133 | %hide Literal.All2.All2
137 | ||| Evaluate a list of `Tensor`s as a list of `Literal`s. Tensors in the list can have different
138 | ||| shapes and element types. For example,
139 | ||| ```
140 | ||| main : Device -> IO ()
141 | ||| main device = do [x, y] <- eval device $ do let x = tensor {dtype = F64} [1.2, 3.4]
142 | ||| y <- reduce @{Sum} [0] x
143 | ||| pure [x, y]
144 | ||| printLn x
145 | ||| printLn y
146 | ||| ```
147 | ||| In contrast to `Tensor.eval` when called on multiple tensors, this function constructs and
148 | ||| compiles the graph just once.
161 | where
173 | ||| A convenience wrapper for `List.Tag.eval`, for use with a bare list of `Tensor`s.
183 | ||| Evaluate a `Tensor`, returning its value as a `Literal`. This function builds and executes the
184 | ||| computational graph.
185 | |||
186 | ||| **Note:** Each call to `eval` will rebuild and execute the graph; multiple calls to `eval` on
187 | ||| different tensors, even if they are in the same computation, will be treated independently.
188 | ||| To efficiently evaluate multiple tensors at once, use `List.Tag.eval`.
193 | ||| A convenience wrapper for `Tag.eval`, for use with a bare `Tensor`.
198 | ||| A string representation of a tensor graph.
199 | |||
200 | ||| There are no guarantees whatsoever as to the string structure and contents.
201 | export
207 | export
210 | ||| Positive infinity.
211 | export
214 | ||| NaN (not a number).
215 | export
219 | ||| Compares less than or equal to any other value (except NaN).
220 | export
228 | ||| Compares greater than or equal to any other value (except NaN).
229 | export
237 | ||| The most negative possible finite float, approx. -1.8e308
238 | export
242 | ||| The most positive possible finite float, approx. 1.8e308
243 | export
247 | ||| Cast the element type. For example, `castDtype (tensor {dtype = S32} [1, -2])` is
248 | ||| `tensor {dtype = F64} [1.0, -2.0]`.
249 | export
253 | ||| A function type. For example `Func [Nat, String] Bool` is `Nat -> String -> Bool`.
264 | forall arity, rshapes, rdtypes . (shapes : Vect arity Shape) -> (dtypes : Vect arity DType) ->
283 | where
311 | covering
328 | where
345 | ||| Function abstraction in the framework IR.
346 | |||
347 | ||| Operations in spidr are, by default, inlined, which can lead to large IRs. `func` abstracts
348 | ||| (and names) a function in the IR. The resulting function will have the exact same semantics as
349 | ||| the input, though may perform differently, depending on ML compiler behaviour.
350 | |||
351 | ||| Implementation note: MLIR (more specifically the "func" dialect) only supports named functions
352 | ||| at the top (or module) level. To achieve this, `func` lifts its function to the top level,
353 | ||| and automatically converts any variable capture to new function arguments. As such, the IR
354 | ||| may appear different to the Idris code from which it derives.
366 | where
371 | ||| (Experimental) function vectorization.
372 | |||
373 | ||| Lift a function on tensors, so that it applies element-wise across the common leading dimension
374 | ||| of its tensor arguments. For example, for
375 | ||| ```
376 | ||| xs : Tensor [2, 3, 3] S32
377 | ||| xs = tensor [[[ 0, 1, 2],
378 | ||| [ 3, 4, 5],
379 | ||| [ 6, 7, 8]],
380 | ||| [[ 9, 10, 11],
381 | ||| [12, 13, 14],
382 | ||| [15, 16, 17]]]
383 | |||
384 | ||| ys : Tensor [2] S32
385 | ||| ys = Tensor [2, -1]
386 | ||| ```
387 | ||| `do !(vmap (\x, y => pure $ y * diag x)) xs ys` produces `tensor [[0, 8, 16], [-9, -13, -17]]`.
388 | |||
389 | ||| **Warning:** `vmap` is experimental, and only implemented for a subset of the tensor API. You
390 | ||| can see approximately which operations are supported on the Enzyme [tracking issue](https://github.com/EnzymeAD/Enzyme-JAX/issues/152).
404 | where
411 | ||| (Experimental) reverse-mode automatic differentiation.
412 | |||
413 | ||| `grad` can be applied repeatedly to obtain higher derivatives, though we do not yet support
414 | ||| derivatives of vector-valued functions.
415 | |||
416 | ||| For example, for
417 | ||| ```
418 | ||| f : Tensor [2] F64 -> Tag $ Tensor [] F64
419 | ||| f x = do
420 | ||| x <- tag x
421 | ||| let (x0, x1) = (slice [at 0] x, slice [at 1] x)
422 | ||| pure $ x0 / x1
423 | ||| ```
424 | ||| `grad f (tensor [3.0, 2.0])` produces `tensor [0.5, -0.75]`.
425 | |||
426 | ||| **Warning:** `grad` is experimental, and only implemented for a subset of the tensor API. You
427 | ||| can see approximately which operations are supported on the Enzyme [tracking issue](https://github.com/EnzymeAD/Enzyme-JAX/issues/88).
429 | grad : (Tensor shape F64 -> Tag $ Tensor [] F64) -> Tensor shape F64 -> Tag $ Tensor shape F64
432 | %hide Prelude.Interfaces.product
439 | export
444 | ||| Reshape a `Tensor`. For example, `reshape {to = [2, 1]} (tensor [3, 4])` is
445 | ||| `tensor [[3], [4]]`. The output can have a different rank to the input.
446 | export
454 | ||| Add a dimension of length one at the specified `axis`. The new dimension will be at the
455 | ||| specified `axis` in the new `Tensor` (as opposed to the original `Tensor`). For example,
456 | ||| `expand 1 $ tensor [[1, 2], [3, 4], [5, 6]]` is `tensor [[[1, 2]], [[3, 4]], [[5, 6]]]`.
457 | export
466 | ||| A `Squeezable from to` constitutes proof that the shape `from` can be squeezed to the
467 | ||| shape `to`. Squeezing is the process of removing any number of dimensions of length one.
470 | ||| Proof that a shape can be squeezed to itself. For example:
471 | |||
472 | ||| [] to []
473 | ||| [3, 4] to [3, 4]
476 | ||| Proof that any dimensions (including those of length 1) can be preserved in the process of
477 | ||| squeezing. For example:
478 | |||
479 | ||| ...
482 | ||| Proof that any dimensions of length one can be squeezed out. For example:
483 | |||
484 | ||| [1, 3, 1, 1, 4] to [3, 4]
487 | ||| Remove dimensions of length one from a `Tensor` such that it has the desired shape. For example:
488 | |||
489 | ||| ```
490 | ||| x : Tensor [2, 1, 3, 1] S32
491 | ||| x = tensor [[[[4], [5], [6]]],
492 | ||| [[[7], [8], [9]]]]
493 | |||
494 | ||| y : Tensor [2, 1, 3] S32
495 | ||| y = squeeze x
496 | ||| ```
497 | ||| is
498 | ||| ```
499 | ||| y : Tensor [2, 1, 3] S32
500 | ||| y = tensor [[[4, 5, 6]],
501 | ||| [[7, 8, 9]]]
502 | ||| ```
503 | export
511 | ||| A `SliceOrIndex d` is a valid slice or index into a dimension of size `d`. See `slice` for
512 | ||| details.
513 | export
525 | ||| Index at `idx`. See `slice` for details.
531 | ||| Index at the specified index. See `slice` for details.
536 | ||| Slice from `from` (inclusive) to `to` (exclusive). See `slice` for details.
546 | ||| Slice `size` elements starting at the specified scalar `U64` index. See `slice` for details.
551 | ||| Slice across all indices along an axis. See `slice` for details.
556 | ||| A `MultiSlice shape` is a valid multi-dimensional slice into a tensor with shape `shape`.
557 | ||| See `slice` for details.
564 | ||| The shape of a tensor produced by slicing with the specified multi-dimensional slice. See
565 | ||| `Tensor.slice` for details.
574 | ||| Slice or index `Tensor` axes. Each axis can be sliced or indexed, and this can be done with
575 | ||| either static (`Nat`) or dynamic (scalar `U64`) indices.
576 | |||
577 | ||| **Static indices**
578 | |||
579 | ||| Static indices are `Nat`s. For example, for
580 | ||| ```
581 | ||| x : Tensor [5, 6] S32
582 | ||| x = tensor [[ 0, 1, 2, 3, 4, 5],
583 | ||| [ 6, 7, 8, 9, 10, 11],
584 | ||| [12, 13, 14, 15, 16, 17],
585 | ||| [18, 19, 20, 21, 22, 23],
586 | ||| [24, 25, 26, 27, 28, 29]]
587 | ||| ```
588 | ||| we can index as `slice [at 1] x` to get
589 | ||| ```
590 | ||| x : Tensor [6] S32
591 | ||| x = tensor [6, 7, 8, 9, 10, 11]
592 | ||| ```
593 | ||| or we can slice as `slice [2.to 4] x` to get
594 | ||| ```
595 | ||| x : Tensor [2, 6] S32
596 | ||| x = tensor [[12, 13, 14, 15, 16, 17],
597 | ||| [18, 19, 20, 21, 22, 23]]
598 | ||| ```
599 | ||| Note that in `2.to 4`, the 2 is inclusive, and the 4 exclusive, so we return indices 2 and 3.
600 | |||
601 | ||| **Dynamic indices**
602 | |||
603 | ||| Dynamic indices are scalar `U64` values, and the API works slightly differently because we
604 | ||| can't know the value of dynamic indices until the graph is executed. For indexing, with scalar
605 | ||| `U64` index `i` in `slice [at i] x`, `i` is clamped to be a valid index into that dimension.
606 | ||| For example, for `i = tensor 1`, `slice [at i] x` is
607 | ||| ```
608 | ||| x : Tensor [6] S32
609 | ||| x = tensor [6, 7, 8, 9, 10, 11]
610 | ||| ```
611 | ||| as in the static case. However, for `i = tensor 10`, `slice [at i] x` returns the last row
612 | ||| ```
613 | ||| x : Tensor [6] S32
614 | ||| x = tensor [24, 25, 26, 27, 28, 29]
615 | ||| ```
616 | ||| We can also slice by specifying a scalar `U64` start index, and a static size, as
617 | ||| `slice [i.size 2] x` with `i = tensor 2` to get
618 | ||| ```
619 | ||| x : Tensor [2, 6] S32
620 | ||| x = tensor [[12, 13, 14, 15, 16, 17],
621 | ||| [18, 19, 20, 21, 22, 23]]
622 | ||| ```
623 | ||| For a given slice `size`, the dynamic start index is clamped such that we always get `size`
624 | ||| elements along that axis. For example, `slice [i.size 2] x` with `i = tensor 4` is
625 | ||| ```
626 | ||| x : Tensor [2, 6] S32
627 | ||| x = tensor [[18, 19, 20, 21, 22, 23],
628 | ||| [24, 25, 26, 27, 28, 29]]
629 | ||| ```
630 | ||| which starts at index 3 rather than index 4.
631 | |||
632 | ||| **Mixed static, dynamic, slicing and indexing**
633 | |||
634 | ||| Each axis can only be sliced or indexed, and must use only static or dynamic indices. However,
635 | ||| across axes, we can mix these four arbitrarily. For example, with `slice [2.to 4, at 1] x` to
636 | ||| get
637 | ||| ```
638 | ||| x : Tensor [2] S32
639 | ||| x = tensor [13, 19]
640 | ||| ```
641 | ||| or with `i = tensor 2` in `slice [at 1, i.size 2] x` to get
642 | ||| ```
643 | ||| x : Tensor [2] S32
644 | ||| x = tensor [7, 8]
645 | ||| ```
646 | |||
647 | ||| Slices and indices apply to the leading axes of the tensor. For trailing axes omitted from the
648 | ||| multi-dimensional slice, the whole of the axis is returned. If we want to slice or index over
649 | ||| later axes and retain all indices in a leading axis, we can use the convenience function `all`,
650 | ||| as `slice [all, at 3] x` to get
651 | ||| ```
652 | ||| x : Tensor [5] S32
653 | ||| x = tensor [[3], [9], [15], [21], [27]]
654 | ||| ```
655 | ||| This is exactly the same as the more manual `slice [0.to 5, at 3] x` and
656 | ||| `slice [(tensor 0).size 5, at 3] x`.
657 | |||
658 | ||| @at The multi-dimensional slices and indices at which to slice the tensor.
659 | export
662 | let x = val0 $ Slice (mapd start (const 0) at) (mapd stop id at) (replicate (length shape) 1) x
663 | -- we shortcut DynamicSlice to allow autodiff for static slicing
667 | where
707 | ||| The starting indices of a slice with shape `sizes`, into a tensor with shape `bounds`.
708 | export
723 | ||| Scalar.
729 | ||| A `Nat` starting index. This is statically restricted to be in bounds.
739 | ||| A scalar `U64` starting index. This is dynamically truncated to be in bounds.
748 | ||| Replace a slice of a tensor. For example, for
749 | ||| ```
750 | ||| target : Tensor [3, 4] S32
751 | ||| target = tensor [[ 0, 1, 2, 3],
752 | ||| [ 4, 5, 6, 7],
753 | ||| [ 8, 9, 10, 11]]
754 | |||
755 | ||| update : Tensor [2, 2] S32
756 | ||| update = tensor [[12, 13],
757 | ||| [14, 15]]
758 | ||| ```
759 | ||| `updateSlice [0, 1] update target` is
760 | ||| ```
761 | ||| y : Tensor [3, 4] S32
762 | ||| y = tensor [[ 0, 12, 13, 3],
763 | ||| [ 4, 14, 15, 7],
764 | ||| [ 8, 9, 10, 11]]
765 | ||| ```
766 | ||| The starting index can be specified along each axis using either a `Nat` or a `U64` scalar.
767 | ||| Note that the updated slice will always be replaced by `update`, and lie fully within `target`.
768 | ||| This is checked statically for `Nat`. However, for `U64` scalar, the start index `at` is
769 | ||| truncated to the maximum index for which the slice remains within `target`. For example,
770 | ||| `updateSlice [0, (tensor $ Scalar 2)] update target` and
771 | ||| `updateSlice [0, (tensor $ Scalar 3)] update target`
772 | ||| ```
773 | ||| are both
774 | ||| ```
775 | ||| y : Tensor [3, 4] S32
776 | ||| y = tensor [[ 0, 1, 12, 13],
777 | ||| [ 4, 5, 14, 15],
778 | ||| [ 8, 9, 10, 11]]
779 | ||| ```
780 | |||
781 | ||| @at The starting indices of the slice to replace.
782 | ||| @update The tensor to replace the slice with.
783 | ||| @target The tensor in which to replace the slice.
784 | export
793 | where
800 | ||| Concatenate two `Tensor`s along the specified `axis`. For example,
801 | ||| `concat 0 (tensor [[1, 2], [3, 4]]) (tensor [[5, 6]])` and
802 | ||| `concat 1 (tensor [[3], [6]]) (tensor [[4, 5], [7, 8]])` are both
803 | ||| `tensor [[1, 2], [3, 4], [5, 6]]`.
804 | export
814 | ||| Transpose a matrix. For example, `(tensor [[1, 2], [3, 4]]).T` is `tensor [[1, 3], [2, 4]]`.
815 | export
819 | ||| Transpose axes of a tensor. This is a more general version of `(.T)`, in which you can
820 | ||| transpose any number of axes in a tensor of arbitrary rank. The i'th axis in the resulting
821 | ||| tensor corresponds to the `index i ordering`'th axis in the input tensor. For example, for
822 | ||| ```
823 | ||| x : Tensor [2, 3, 4] S32
824 | ||| x = tensor [[[ 0, 1, 2, 3],
825 | ||| [ 4, 5, 6, 7],
826 | ||| [ 8, 9, 10, 11]],
827 | ||| [[12, 13, 14, 15],
828 | ||| [16, 17, 18, 19],
829 | ||| [20, 21, 22, 23]]]
830 | ||| ```
831 | ||| `transpose [0, 2, 1] x` is
832 | ||| ```
833 | ||| x : Tensor [2, 4, 3] S32
834 | ||| x = tensor [[[ 0, 4, 8],
835 | ||| [ 1, 5, 9],
836 | ||| [ 2, 6, 10],
837 | ||| [ 3, 7, 11]],
838 | ||| [[12, 16, 20],
839 | ||| [13, 17, 21],
840 | ||| [14, 18, 22],
841 | ||| [15, 19, 23]]]
842 | ||| ```
843 | ||| `transpose [2, 0, 1] x` is
844 | ||| ```
845 | ||| x : Tensor [4, 2, 3] S32
846 | ||| x = tensor [[[ 0, 4, 8],
847 | ||| [12, 16, 20]],
848 | ||| [[ 1, 5, 9],
849 | ||| [13, 17, 21]],
850 | ||| [[ 2, 6, 10],
851 | ||| [14, 18, 22]],
852 | ||| [[ 3, 7, 11],
853 | ||| [15, 19, 23]]]
854 | ||| ```
855 | |||
856 | ||| In order to see what effect transposing a tensor has, it can help to bear in mind the following:
857 | ||| * if an element can be found with `slice [at 3, at 4, at 5] x` in the original tensor,
858 | ||| that same element can instead be found with `slice [at 5, at 3, at 4]` given a
859 | ||| `transpose [2, 0, 1]`. That is, transposing axes re-orders indices when indexing.
860 | ||| * with `transpose [2, 0, 1]`, traversing the first axis in the result is equivalent to
861 | ||| traversing the last axis in the input. Similarly, traversing the last axis in the result is
862 | ||| equivalent to traversing the second axis in the input.
863 | export
873 | ||| A `DimBroadcastable from to` proves that a dimension of size `from` can be broadcast to a
874 | ||| dimension of size `to`.
877 | ||| Proof that any dimension can be broadcast to itself. For example in shapes `[2, 3]` to
878 | ||| `[2, 3]`.
881 | ||| Proof that a dimension of length one can be broadcast to any size. For example in shapes
882 | ||| `[2, 1]` to `[2, 3]`
885 | ||| Proof that any dimension can be broadcast to zero. For example in shapes `[2, 3]` to `[2, 0]`.
889 | ||| A `Broadcastable from to` constitutes proof that the shape `from` can be broadcast to the
890 | ||| shape `to`.
893 | ||| Proof that a shape can be broadcast to itself. For example:
894 | |||
895 | ||| [] to []
896 | ||| [3, 4] to [3, 4]
897 | |||
898 | ||| Implementation note: we could have used `Broadcast [] []`, which would have resulted in more
899 | ||| atomic constructors for `Broadcastable`, but the author guesses that this implementation helps
900 | ||| the type checker avoid applications of `Match`.
903 | ||| Proof that a dimension of size `f` can be broadcast to size `t` if these dimensions
904 | ||| are `DimBroadcastable f t`. For example:
905 | |||
906 | ||| [2, 3] to [2, 3]
907 | ||| [2, 1] to [2, 3]
908 | ||| [2, 1] to [2, 0]
915 | ||| Proof that broadcasting can add outer dimensions i.e. nesting. For example:
916 | |||
917 | ||| [3] to [1, 3]
918 | ||| [3] to [5, 3]
921 | ||| A shape can be extended with any number of leading dimensions.
922 | |||
923 | ||| @leading The leading dimensions.
924 | export
929 | ||| A scalar can be broadcast to any shape.
930 | %hint
931 | export
935 | ||| Broadcast a `Tensor` to a new compatible shape. For example,
936 | ||| ```
937 | ||| x : Tensor [2, 3] S32
938 | ||| x = broadcast (tensor [4, 5, 6])
939 | ||| ```
940 | ||| is
941 | ||| ```
942 | ||| x : Tensor [2, 3] S32
943 | ||| x = tensor [[4, 5, 6], [4, 5, 6]]
944 | ||| ```
945 | export
953 | ||| A `Tensor` where every element has the specified value. For example,
954 | ||| ```
955 | ||| fives : Tensor [2, 3] S32
956 | ||| fives = fill 5
957 | ||| ```
958 | ||| is
959 | ||| ```
960 | ||| fives : Tensor [2, 3] S32
961 | ||| fives = tensor [[5, 5, 5],
962 | ||| [5, 5, 5]]
963 | ||| ```
964 | export
968 | ||| A constant where values increment from zero along the specified `axis`. For example,
969 | ||| ```
970 | ||| x : Tensor [3, 5] S32
971 | ||| x = iota 1
972 | ||| ```
973 | ||| is the same as
974 | ||| ```
975 | ||| x : Tensor [3, 5] S32
976 | ||| x = tensor [[0, 1, 2, 3, 4],
977 | ||| [0, 1, 2, 3, 4],
978 | ||| [0, 1, 2, 3, 4]]
979 | ||| ```
980 | ||| and
981 | ||| ```
982 | ||| x : Tensor [3, 5] S32
983 | ||| x = iota 0
984 | ||| ```
985 | ||| is the same as
986 | ||| ```
987 | ||| x : Tensor [3, 5] S32
988 | ||| x = tensor [[0, 0, 0, 0, 0],
989 | ||| [1, 1, 1, 1, 1],
990 | ||| [2, 2, 2, 2, 2]]
991 | ||| ```
992 | export
1002 | ||| A while-loop operating on a single tensor.
1003 | |||
1004 | ||| `while1` iteratively checks if the tensor satisfies `condition`, and if it does, updates it with
1005 | ||| `body`.
1006 | |||
1007 | ||| **Note:** The XLA plugins impose heuristic-based rules on variable capture in higher-order
1008 | ||| functions. We do not comprehensively understand these rules, but you *might* experience runtime
1009 | ||| errors if you capture variables in `condition` or `body`, especially variables other than
1010 | ||| constants, or variables that depend on parameters to enclosing (StableHLO) scopes.
1011 | |||
1012 | ||| @condition The guard condition for each iteration.
1013 | ||| @body The update step.
1014 | ||| @initial The initial tensor.
1024 | ||| A while-loop operating on two tensors.
1025 | |||
1026 | ||| `while2` iteratively checks if the tensors together satisfy `condition`, and if so, updates them
1027 | ||| with `body`.
1028 | |||
1029 | ||| **Note:** The XLA plugins impose heuristic-based rules on variable capture in higher-order
1030 | ||| functions. We do not comprehensively understand these rules, but you *might* experience runtime
1031 | ||| errors if you capture variables in `condition` or `body`, especially variables other than
1032 | ||| constants, or variables that depend on parameters to enclosing (StableHLO) scopes.
1033 | |||
1034 | ||| @condition The guard condition for each iteration.
1035 | ||| @body The update step.
1036 | ||| @initial One initial tensor.
1037 | ||| @initial' The other initial tensor.
1045 | res <- tag $ Concrete $ While !(mkFn1 [_, _] [_, _] condition) !(mkFn [_, _] [_, _] body) [i, i']
1048 | ||| Reduce elements along one `axis` of a `Tensor` according to a specified `reducer` `Monoid`.
1049 | ||| For example, if `x = tensor [[0, 1, 2], [3, 4, 5]]`, then reduce @{Sum} 0 x` produces
1050 | ||| `tensor [3, 5, 7]`, and `reduce @{Sum} 1 x` produces `tensor [3, 12]`.
1051 | |||
1052 | ||| **Note:** `Semigroup` doesn't use `Tag`, which limits the functions that can be used in
1053 | ||| `reduce`. However, the most commonly used semigroups don't need `Tag`, including `Sum`,
1054 | ||| `Prod`, `Min` and `Max`, so for ergonomics, we have opted to use `Monoid` as is. We can
1055 | ||| provide an overloaded variant if requested.
1056 | |||
1057 | ||| **Note:** The monoid should not depend on values bound to outer scopes, else runtime errors may
1058 | ||| occur.
1059 | |||
1060 | ||| @reducer How to reduce elements along the given `axis`.
1061 | ||| @axis The axis along which to reduce elements.
1062 | export
1078 | ||| Sort the elements of a `Tensor` along a specified `dimension` according to a scalar-wise
1079 | ||| ordering. For sorting function `f`, elements are sorted such that for consecutive sorted
1080 | ||| elements `a` and `b`, either `f a b` is true, or `f a b` *and* `f b a` are false.
1081 | |||
1082 | ||| **Note:** Sorting is not stable, meaning elements that compare equal according the ordering may
1083 | ||| be sorted in a different order to the order they appear in the input.
1084 | |||
1085 | ||| **Note:** `sort` is limited to use comparison function without `Tag`. However, since the most
1086 | ||| commonly-used functions, including (>), (<), (>=), and (<=), don't use `Tag`, we have opted to
1087 | ||| omit it for ergonomics. We can trivially provide an overloaded variant if requested.
1088 | |||
1089 | ||| **Note:** The comparison function should not depend on values bound to outer scopes, else
1090 | ||| runtime errors may occur.
1091 | |||
1092 | ||| For example, for `x = tensor [[1, 6, 4], [3, 2, 5]]`, `sort (<) 0 x` produces
1093 | ||| `tensor [[1, 2, 4], [3, 6, 5]]`, while `sort (<) 1 x` produces
1094 | ||| `tensor [[1, 4, 6], [2, 3, 5]]`.
1095 | export
1105 | ||| Reverse elements along the specified axes. For example, for
1106 | ||| ```
1107 | ||| x : Tensor [2, 3] S32
1108 | ||| x = tensor [[-2, -1, 0],
1109 | ||| [ 1, 2, 3]]
1110 | ||| ```
1111 | ||| `reverse [0] x` is
1112 | ||| ```
1113 | ||| x : Tensor [2, 3] S32
1114 | ||| x = tensor [[ 1, 2, 3],
1115 | ||| [-2, -1, 0]]
1116 | ||| ```
1117 | ||| `reverse [1] x` is
1118 | ||| ```
1119 | ||| x : Tensor [2, 3] S32
1120 | ||| x = tensor [[ 0, -1, -2],
1121 | ||| [ 3, 2, 1]]
1122 | ||| ```
1123 | ||| and `reverse [0, 1] x` is
1124 | ||| ```
1125 | ||| x : Tensor [2, 3] S32
1126 | ||| x = tensor [[ 3, 2, 1],
1127 | ||| [ 0, -1, -2]]
1128 | ||| ```
1129 | |||
1130 | ||| **Note:** This function requires `axes` is ordered simply so that elements are unique.
1131 | ||| The ordering itself is irrelevant to the implementation, but ensures uniqueness without using
1132 | ||| proofs of contradiction that can be difficult for Idris to construct.
1133 | export
1151 | ||| Element-wise equality. For example, `tensor [1, 2] /= tensor [1, 3]` is
1152 | ||| `tensor [True, False]`.
1153 | export
1157 | ||| Element-wise inequality. For example, `tensor [1, 2] /= tensor [1, 3]` is
1158 | ||| `tensor [False, True]`.
1159 | export
1163 | ||| Element-wise less than. For example, `tensor [1, 2, 3] < tensor [2, 2, 2]` is
1164 | ||| `tensor [True, False, False]`.
1165 | export
1169 | ||| Element-wise greater than. For example, `tensor [1, 2, 3] > tensor [2, 2, 2]` is
1170 | ||| `tensor [False, False, True]`.
1171 | export
1175 | ||| Element-wise less than or equal. For example, `tensor [1, 2, 3] <= tensor [2, 2, 2]`
1176 | ||| is `tensor [True, True, False]`.
1177 | export
1181 | ||| Element-wise greater than or equal. For example,
1182 | ||| `tensor [1, 2, 3] >= tensor [2, 2, 2]` is `tensor [False, True, True]`.
1183 | export
1187 | ||| Element-wise boolean and. For example,
1188 | ||| `tensor [True, True, False, False] && tensor [True, False, True, False]` is
1189 | ||| `tensor [True, False, False, False]`.
1190 | export
1195 | export
1200 | export
1204 | ||| Element-wise boolean or. For example,
1205 | ||| `tensor [True, True, False, False] || tensor [True, False, True, False]` is
1206 | ||| `tensor [True, True, True, False]`.
1207 | export
1212 | export
1217 | export
1221 | ||| Element-wise boolean negation. For example, `not (tensor [True, False])` is
1222 | ||| `tensor [False, True]`.
1223 | export
1227 | ||| Choose elements from two `Tensor`s based on a `Tensor` of predicates. For each element in the
1228 | ||| predicates, the output will use the corresponding element from `onTrue` if the element is
1229 | ||| truthy, else the element from `onFalse`. For example, for
1230 | ||| ```
1231 | ||| preds : Tensor [3] PRED
1232 | ||| preds = tensor [False, True, False]
1233 | |||
1234 | ||| onTrue : Tensor [3] S32
1235 | ||| onTrue = tensor [1, 2, 3]
1236 | |||
1237 | ||| onFalse : Tensor [3] S32
1238 | ||| onFalse = tensor [4, 5, 6]
1239 | ||| ```
1240 | ||| `select preds onTrue onFalse` is `tensor [4, 2, 6]`.
1241 | |||
1242 | ||| @onTrue The elements to choose where the predicate elements are truthy.
1243 | ||| @onFalse The elements to choose where the predicate elements are falsy.
1244 | export
1251 | ||| Use a scalar predicate to evaluate one of two branches. If the predicate is truthy,
1252 | ||| evaluate `onTrue`, else `onFalse`. Each branch is evaluated lazily; only one will be
1253 | ||| evaluated.
1254 | |||
1255 | ||| For example, for
1256 | ||| ```
1257 | ||| f : Tensor [] F64 -> Tag $ Tensor [] F64
1258 | ||| f x = if_ (x < 1.0) (pure $ cos x) (do x <- tag x; x * x)
1259 | ||| ```
1260 | ||| `f 0.0` produces `1.0`, and `f 4.0` produces `8.0`.
1261 | |||
1262 | ||| **Note:** Branches to `if_` are interpreted as constant StableHLO functions. The XLA plugins
1263 | ||| impose heuristic-based rules on variable capture in higher-order functions. We do not
1264 | ||| comprehensively understand these rules, but you *might* experience runtime errors if you capture
1265 | ||| variables in the branches, especially variables other than constants, or variables that depend
1266 | ||| on parameters to enclosing (StableHLO) scopes.
1267 | |||
1268 | ||| @onTrue The branch to evaluate if the predicate is truthy.
1269 | ||| @onFalse The branch to evaluate if the predicate is falsy.
1270 | export
1279 | ||| The identity tensor, with inferred shape and element type. For example,
1280 | ||| ```
1281 | ||| x : Tensor [2, 2] S32
1282 | ||| x = identity
1283 | ||| ```
1284 | ||| is
1285 | ||| ```
1286 | ||| x : Tensor [2, 2] S32
1287 | ||| x = tensor [[1, 0],
1288 | ||| [0, 1]]
1289 | ||| ```
1290 | export
1296 | -- see https://www.python.org/dev/peps/pep-0465/#precedence-and-associativity
1300 | ||| Vector dot product with a tensor of any rank. The vector dot product is with the first axis of
1301 | ||| the right-hand side tensor. For example `tensor [0, 1, 2] @@ tensor [-1, -3, -1]` is
1302 | ||| `-1`.
1303 | export
1308 | ||| Matrix multiplication with a matrix or vector. Contraction is along the last axis of the first
1309 | ||| and the first axis of the last. For example,
1310 | ||| ```
1311 | ||| x : Tensor [2, 3] S32
1312 | ||| x = tensor [[-1, -2, -3],
1313 | ||| [ 0, 1, 2]]
1314 | |||
1315 | ||| y : Tensor [3, 1] S32
1316 | ||| y = tensor [[4, 0, 5]]
1317 | |||
1318 | ||| z : Tensor [2, 1] S32
1319 | ||| z = x @@ y
1320 | ||| ```
1321 | ||| is
1322 | ||| ```
1323 | ||| z : Tensor [2, 1] S32
1324 | ||| z = tensor [-19, 10]
1325 | ||| ```
1326 | export
1332 | (MkTensor x) @@ (MkTensor x') = t0 $ DotGeneral [] [] [1] [0] (TensorType (n :: tl) dtype) x x'
1334 | ||| The output shape of a `dotGeneral` operation.
1342 | Shape
1350 | ||| Matrix multiplication.
1351 | |||
1352 | ||| This is a much more general version of `(@@)`, in which you can specify any number of batch
1353 | ||| and contracting axes. Matrix multiplication is done over each contracting axis.
1354 | ||| The operation is vectorized over batch axes. For each contracting axis on the left-hand
1355 | ||| operand, there is one contracting axis on the right-hand operand. These can be different axes
1356 | ||| in each operand. The same is true for each batch axis.
1357 | |||
1358 | ||| For example, we can vectorize over a typical rank-two matrix multiplication as follows: given
1359 | ||| two inputs tensors
1360 | ||| ```
1361 | ||| let x : Tensor [3, 4, 5, 6] F64
1362 | ||| y : Tensor [3, 4, 6, 7] F64
1363 | ||| ```
1364 | ||| we do
1365 | ||| ```
1366 | ||| let z : Tensor [3, 4, 5, 7] F64 = dotGeneral [0, 1] [0, 1] [3] [2] x y
1367 | ||| ```
1368 | ||| Here, we vectorized over the first two axes `[0, 1]`, and do standard matrix multiplication
1369 | ||| over the remaining axes by specifying the axes 3 and 2 respectively as contracting axes. Notice
1370 | ||| how the batch axes appear once each at the start of the output shape, and the contracting axis
1371 | ||| disappears. Remaining axes appear in order from left to right.
1372 | |||
1373 | ||| Note this API is somewhat of a quickfix to bring general matrix multiplication to the tensor
1374 | ||| API. It is not thoroughly tested. Expect it to change in the future.
1375 | export
1394 | ||| Element-wise addition. For example, `tensor [1, 2] + tensor [3, 4]` is
1395 | ||| `tensor [4, 6]`.
1396 | export
1401 | export
1406 | export
1411 | ||| Element-wise negation. For example, `- tensor [1, -2]` is `tensor [-1, 2]`.
1412 | export
1416 | ||| Element-wise subtraction. For example, `tensor [3, 4] - tensor [4, 2]` is
1417 | ||| `tensor [-1, 2]`.
1418 | export
1422 | ||| Element-wise multiplication. For example, `tensor [2, 3] * tensor [4, 5]` is
1423 | ||| `tensor [8, 15]`.
1424 | export
1429 | export
1434 | export
1439 | ||| Element-wise floating point division. For example, `tensor [2, 3] / tensor [4, 5]` is
1440 | ||| `tensor [0.5, 0.6]`.
1441 | export
1448 | ||| Element-wise division of natural numbers. For example,
1449 | ||| `div (tensor [13, 8]) [3, 4]` is `tensor [4, 2]`.
1450 | |||
1451 | ||| **Note:** Broadcasting a single value into a large `Literal` will be slower than for a `Tensor`.
1452 | ||| For this reason, if you're using a single common denominator, consider using `Scalarwise.div`.
1453 | export
1462 | ||| Overload of `div` for common denominator. The denominator is broadcast to match the numerator.
1463 | export
1473 | ||| Element-wise remainder for natural numbers. For example,
1474 | ||| `rem (tensor [13, 8]) [3, 4]` is `tensor [1, 0]`.
1475 | |||
1476 | ||| **Note:** Broadcasting a single value into a large `Literal` will be slower than for a
1477 | ||| `Tensor`. For this reason, if you're using a single common denominator, consider using
1478 | ||| `Scalarwise.rem`.
1479 | export
1488 | ||| Overload of `rem` for a common denominator. The denominator is broadcast to match the
1489 | ||| numerator.
1490 | export
1501 | ||| Each element in `base` raised to the power of the corresponding element in `exponent`.
1502 | ||| example, `tensor [2, 25, -9] ^ tensor [3, -0.5, 0.5]` is `tensor [8, 0.2, nan]`.
1503 | |||
1504 | ||| Note: The behaviour of this function is not well-defined at negative or positive infinity, or
1505 | ||| NaN.
1506 | |||
1507 | ||| Note: The first root is used.
1508 | export
1515 | ||| Element-wise absolute value. For example, `abs (tensor [-2, 3])` is `tensor [2, 3]`.
1516 | export
1520 | ||| The element-wise natural exponential. For example, `exp (tensor [-1, 0, 2])` is
1521 | ||| `tensor [1 / euler, 1, pow euler 2]`.
1522 | export
1526 | ||| The element-wise floor function. For example,
1527 | ||| `floor (tensor [-1.6, -1.5, -1.4, -1.0, 1.0, 1.4, 1.5, 1.6])` is
1528 | ||| `tensor [-2.0, -2.0, -2.0, -1.0, 1.0, 1.0, 1.0, 1.0]`.
1529 | export
1533 | ||| The element-wise ceiling function. For example,
1534 | ||| `ceil (tensor [-1.6, -1.5, -1.4, -1.0, 1.0, 1.4, 1.5, 1.6])` is
1535 | ||| `tensor [-1.0, -1.0, -1.0, -1.0, 1.0, 2.0, 2.0, 2.0]`.
1536 | export
1540 | ||| The element-wise natural logarithm. Negative inputs yield NaN output. For example,
1541 | ||| `log (tensor [1 / euler, 1, euler * euler])` is `tensor [-1, 0, 2]`.
1542 | export
1546 | ||| The element-wise logistic function equivalent to `1 / 1 + exp (-x)`.
1547 | export
1551 | ||| The element-wise sine.
1552 | export
1556 | ||| The element-wise cosine.
1557 | export
1561 | ||| The element-wise tangent.
1562 | export
1566 | ||| The element-wise inverse sine.
1567 | export
1571 | ||| The element-wise inverse cosine.
1572 | export
1576 | ||| The element-wise inverse tangent.
1577 | export
1581 | ||| The element-wise hyperbolic sine.
1582 | export
1586 | ||| The element-wise hyperbolic cosine.
1587 | export
1591 | ||| The element-wise hyperbolic tangent.
1592 | export
1596 | ||| The element-wise inverse hyperbolic sine.
1597 | export
1601 | ||| The element-wise inverse hyperbolic cosine.
1602 | export
1606 | ||| The element-wise inverse hyperbolic tangent.
1607 | export
1611 | ||| An approximation to the element-wise error function.
1612 | export
1619 | ||| The element-wise square. For example, `square (tensor [-2, 0, 3])`
1620 | ||| is `tensor [4, 0, 9]`.
1621 | export
1625 | ||| The element-wise square root. The first root is used. Negative inputs yield NaN output.
1626 | ||| For example, `sqrt (tensor [0, 9])` is `tensor [0, 3]`.
1627 | export
1631 | ||| The element-wise minimum of the first argument compared to the second. For example,
1632 | ||| `min (tensor [-3, -1, 3]) (tensor [-1, 0, 1])` is `tensor [-3, -1, 1]`.
1633 | export
1638 | export
1643 | export
1648 | ||| The element-wise maximum of the first argument compared to the second. For example,
1649 | ||| `max (tensor [-3, -1, 3]) (tensor [-1, 0, 1])` is `tensor [-1, 0, 3]`.
1650 | export
1655 | export
1660 | export
1665 | ||| The diagonal of a matrix as a vector. For example, for
1666 | ||| ```
1667 | ||| x : Tensor [3, 3] S32
1668 | ||| x = tensor [[0, 1, 2],
1669 | ||| [3, 4, 5],
1670 | ||| [6, 7, 8]]
1671 | ||| ```
1672 | ||| `diag x` is `tensor [0, 4, 8]`.
1673 | export
1712 | ||| The first index of the maximum value in a vector. For example,
1713 | ||| `argmax (tensor [-1, 3, -2, -2, 3])` produces `tensor 1`. If the vector contains NaN values,
1714 | ||| `argmax` returns the index of the first NaN.
1715 | export
1719 | ||| The first index of the minimum value in a vector. For example,
1720 | ||| `argmin (tensor [-1, 3, -2, -2, 3])` produces `tensor 2`. If the vector contains NaN values,
1721 | ||| `argmin` returns the index of the first NaN.
1722 | export
1726 | ||| Represents the upper- or lower-triangular component of a matrix.
1730 | ||| Get the upper- or lower-triangular component of a matrix, always including the matrix diagonal.
1731 | ||| Remaining elements will be zero. For example, for
1732 | ||| ```
1733 | ||| x : Tensor [3, 3] S32
1734 | ||| x = tensor [[1, 2, 3],
1735 | ||| [4, 5, 6],
1736 | ||| [7, 8, 9]]
1737 | ||| ```
1738 | ||| `triangle Lower x` produces
1739 | ||| ```
1740 | ||| x : Tensor [3, 3] S32
1741 | ||| x = tensor [[1, 0, 0],
1742 | ||| [4, 5, 0],
1743 | ||| [7, 8, 9]]
1744 | ||| ```
1745 | export
1759 | where
1765 | Refl
1767 | ||| Cholesky decomposition. Computes the lower triangular matrix `L` from the symmetric, positive
1768 | ||| semi-definite matrix `X` s.t. `X = L @@ L.T`. Values will be NaN if the input matrix is not
1769 | ||| positive semi-definite. The remaining matrix components - those not in the lower triangle or
1770 | ||| diagonal - will always be zero.
1771 | export
1778 | ||| Solve the set of linear equations `a @@ x = b` for `x` where `a` is a lower-triangular matrix.
1779 | ||| `a` is given by the lower-triangular elements of the first argument. Values in the
1780 | ||| upper-triangular part are ignored. If `a` is lower-triangular already,
1781 | ||| this is written `a |\ b`.
1782 | |||
1783 | ||| The operator is shaped like the lower-triangular portion of a matrix to signal that it uses
1784 | ||| this portion of its argument. This is in contrast to `(\|)`.
1785 | export
1789 | ||| Solve the set of linear equations `a @@ x = b` for `x` where `a` is an upper-triangular
1790 | ||| matrix. `a` is given by the upper-triangular elements of the first argument. Values in the
1791 | ||| lower-triangular part are ignored. If `a` is upper-triangular already, this is written
1792 | ||| `a \| b`.
1793 | |||
1794 | ||| The operator is shaped like the upper-triangular portion of a matrix to signal that it uses
1795 | ||| this portion of its argument. This is in contrast to `(|\)`.
1796 | export
1801 | ||| Solve the set of linear equations `a @@ x = b` for `x` where `a` is a lower-triangular matrix.
1802 | ||| `a` is given by the lower-triangular elements of the first argument. Values in the
1803 | ||| upper-triangular part are ignored. If `a` is lower-triangular already,
1804 | ||| this is written `a |\ b`.
1805 | |||
1806 | ||| The operator is shaped like the lower-triangular portion of a matrix to signal that it uses
1807 | ||| this portion of its argument. This is in contrast to `(\|)`.
1808 | export
1812 | ||| Solve the set of linear equations `a @@ x = b` for `x` where `a` is an upper-triangular
1813 | ||| matrix. `a` is given by the upper-triangular elements of the first argument. Values in the
1814 | ||| lower-triangular part are ignored. If `a` is upper-triangular already, this is written
1815 | ||| `a \| b`.
1816 | |||
1817 | ||| The operator is shaped like the upper-triangular portion of a matrix to signal that it uses
1818 | ||| this portion of its argument. This is in contrast to `(|\)`.
1819 | export
1823 | ||| Sum the elements along the diagonal of the input. For example,
1824 | ||| `trace (tensor [[-1, 5], [1, 4]])` produces `3`.
1825 | export
1832 | ||| A `Rand a` produces a pseudo-random value of type `a` from a `Tensor [2] U64` state.
1833 | ||| The state is updated every time a new value is generated.
1838 | ||| Generate independent and identically distributed (IID) uniform samples.
1839 | |||
1840 | ||| The generated samples are a deterministic function of the input key and state, but may vary
1841 | ||| between PJRT plugin and library version.
1842 | |||
1843 | ||| Example usage, multiplying two uniform samples
1844 | ||| ```
1845 | ||| x : Tag $ Tensor [3] U64
1846 | ||| x = let seed = tensor [1, 1] in evalStateT seed [| rng * rng |]
1847 | ||| ```
1848 | export
1854 | ||| Generate independent and identically distributed (IID) from the uniform distribution U(0, 1).
1855 | |||
1856 | ||| The generated samples are a deterministic function of the input key and state, but may vary
1857 | ||| between PJRT plugin and library version.
1858 | |||
1859 | ||| Example usage, multiplying two uniform samples
1860 | ||| ```
1861 | ||| x : Rand $ Tensor [3] F64
1862 | ||| x = [| uniform * uniform |]
1863 | ||| ```
1864 | export
1872 | ||| Generate independent and identically distributed (IID) samples from the standard normal
1873 | ||| distribution N(0, 1).
1874 | |||
1875 | ||| The generated samples are a deterministic function of the input key and state, but may vary
1876 | ||| between PJRT plugin and library version.
1877 | |||
1878 | ||| Example usage, multiplying two normal samples
1879 | ||| ```
1880 | ||| x : Rand $ Tensor [3] F64
1881 | ||| x = [| normal * normal |]
1882 | ||| ```
1883 | export