bend_tensors.bend relies on unsafe/foreign
raw source on the hub · import 0x92882293385d0b92a8d4a4a676bbf076/bend_tensors.bend as Bend_tensors
bend_tensors: dense linear algebra with shapes in the types.
A Vec(n) holds 4 * 2^n floats and a Mat(r, c) 4 * 2^r rows of 4 * 2^c floats, both as balanced trees of 4x4 register blocks. The tree is the fork tree: every op below a node is a parallel let, and the matrix product recurses on the tree, cache-oblivious, down to a 64-multiply kernel. A shape mismatch is a checker error, not a runtime one.
Nothing here matches on a computed value, recurses mutually, or opens an Array: those are the rules the compiler makes fast code from. Read AGENTS.md before editing. This file is assembled from gen/ by gen/assemble.py; edit the parts, not this file. bend_tensors.bend is the release (CPU BLAS); bend_tensors_gpu.bend adds the GPU paths.
1 import
import Base
Laws
law VecT provedsource · line 450 · raw
@n:Nat -> Data
law MatT provedsource · line 668 · raw
@r:Nat -> @c:Nat -> Data
Types
type Blk source · line 34 · raw
Data
Blk@a00:F32 -> @a01:F32 -> @a02:F32 -> @a03:F32 -> @a10:F32 -> @a11:F32 -> @a12:F32 -> @a13:F32 -> @a20:F32 -> @a21:F32 -> @a22:F32 -> @a23:F32 -> @a30:F32 -> @a31:F32 -> @a32:F32 -> @a33:F32 -> Blk
type Vec4 source · line 40 · raw
Data
Vec4@x0:F32 -> @x1:F32 -> @x2:F32 -> @x3:F32 -> Vec4
type VecT.Leaf source · line 454 · raw
Data
VecL@v:Vec4 -> VecT.Leaf
type VecT.Node source · line 457 · raw
@-p:Nat -> Data
VecN@-p:Nat -> @l:VecT(p) -> @r:VecT(p) -> VecT.Node<p>
type MatT.Leaf source · line 673 · raw
Data
MatB@b:Blk -> MatT.Leaf
type MatT.Rows source · line 676 · raw
@-p:Nat -> @-c:Nat -> Data
MatR@-p:Nat -> @-c:Nat -> @top:MatT(p, c) -> @bot:MatT(p, c) -> MatT.Rows<p, c>
type MatT.Cols source · line 679 · raw
@-r:Nat -> @-q:Nat -> Data
MatC@-r:Nat -> @-q:Nat -> @left:MatT(r, q) -> @right:MatT(r, q) -> MatT.Cols<r, q>
type MatT.Quad source · line 682 · raw
@-p:Nat -> @-q:Nat -> Data
MatQ@-p:Nat -> @-q:Nat -> @tl:MatT(p, q) -> @tr:MatT(p, q) -> @bl:MatT(p, q) -> @br:MatT(p, q) -> MatT.Quad<p, q>
type Vec source · line 1316 · raw
@-m:Nat -> Data
VecS@-m:Nat -> @tree:VecT(VecT.depth(m)) -> Vec<m>
type Mat source · line 1415 · raw
@-rows:Nat -> @-cols:Nat -> Data
MatS@-rows:Nat -> @-cols:Nat -> @tree:MatT(VecT.depth(rows), VecT.depth(cols)) -> Mat<rows, cols>
type Weights source · line 1671 · raw
@-rows:Nat -> @-cols:Nat -> Data
W@-rows:Nat -> @-cols:Nat -> @id:U32 -> Weights<rows, cols>
type Flat source · line 1684 · raw
@-rows:Nat -> @-cols:Nat -> Type
FlatS@-rows:Nat -> @-cols:Nat -> @a:Array<F32> -> Flat<rows, cols>
Definitions
def F32.max.of source · line 19 · raw
@a:F32 -> @b:F32 -> F32
Base's F32.max and F32.show take + parameters, which a template slot does not accept; these take plain ones.
def F32.show.of source · line 22 · raw
@x:F32 -> String
def Vec4.full source · line 46 · raw
@+x:F32 -> Vec4
def Vec4.zeros source · line 49 · raw
Vec4
def Vec4.arange source · line 53 · raw
@+x:F32 -> Vec4
x, x + 1, x + 2, x + 3
def Vec4.add source · line 65 · raw
@a:Vec4 -> @b:Vec4 -> Vec4
def Vec4.sub source · line 70 · raw
@a:Vec4 -> @b:Vec4 -> Vec4
def Vec4.mul source · line 75 · raw
@a:Vec4 -> @b:Vec4 -> Vec4
def Vec4.scale source · line 80 · raw
@+k:F32 -> @v:Vec4 -> Vec4
def Vec4.sum source · line 86 · raw
@v:Vec4 -> F32
the sum, as (x0 + x1) + (x2 + x3): every reduction in this file pairs its terms the same way, so laws can equate them
def Vec4.dot source · line 90 · raw
@a:Vec4 -> @b:Vec4 -> F32
def Vec4.max source · line 95 · raw
@v:Vec4 -> F32
def Vec4.min source · line 99 · raw
@v:Vec4 -> F32
def Vec4.argmax.pick source · line 104 · raw
@c:Bool -> @+i:U32 -> @+x:F32 -> @+j:U32 -> @+y:F32 -> Pair(U32, F32)
the index (0-3) and value of the largest element; the first wins ties
def Vec4.argmax.two source · line 111 · raw
@ix:Pair(U32, F32) -> @jy:Pair(U32, F32) -> Pair(U32, F32)
def Vec4.argmax source · line 118 · raw
@v:Vec4 -> Pair(U32, F32)
def Vec4.to_list source · line 122 · raw
@v:Vec4 -> @acc:List<&2, F32> -> List<&2, F32>
def Vec4.from_list source · line 127 · raw
@xs:List<&2, F32> -> Vec4
the first four of xs, padded with 0.0, and the rest
def Vec4.show source · line 140 · raw
@v:Vec4 -> String
def Blk.full source · line 147 · raw
@+x:F32 -> Blk
def Blk.zeros source · line 153 · raw
Blk
def Blk.eye source · line 156 · raw
Blk
def Blk.add source · line 177 · raw
@m:Blk -> @n:Blk -> Blk
def Blk.sub source · line 185 · raw
@m:Blk -> @n:Blk -> Blk
def Blk.mul source · line 193 · raw
@m:Blk -> @n:Blk -> Blk
def Blk.scale source · line 201 · raw
@+k:F32 -> @m:Blk -> Blk
def Blk.transpose source · line 208 · raw
@m:Blk -> Blk
def Blk.matmul source · line 216 · raw
@m:Blk -> @n:Blk -> Blk
m * n: 64 multiply-adds, each cell as (a0 b0 + a1 b1) + (a2 b2 + a3 b3)
def Blk.matvec source · line 225 · raw
@m:Blk -> @v:Vec4 -> Vec4
m * v: each row dotted with v
def Blk.sum_rows source · line 231 · raw
@m:Blk -> Vec4
row i's sum, as (a_i0 + a_i1) + (a_i2 + a_i3)
def Blk.sum source · line 236 · raw
@m:Blk -> F32
the sum of every cell, as the sum of the row sums
def Blk.sum_cols source · line 240 · raw
@m:Blk -> Vec4
column j's sum, as (a_0j + a_1j) + (a_2j + a_3j): the row sums of the transpose
def Blk.max_rows source · line 244 · raw
@m:Blk -> Vec4
def Blk.add_row source · line 249 · raw
@m:Blk -> @v:Vec4 -> Blk
v added to every row
def Blk.sub_row source · line 258 · raw
@m:Blk -> @v:Vec4 -> Blk
v subtracted from every row
def Blk.sub_col source · line 267 · raw
@m:Blk -> @v:Vec4 -> Blk
row i subtracted by v_i (the column vector v broadcast along rows)
def Blk.scale_rows source · line 276 · raw
@m:Blk -> @v:Vec4 -> Blk
row i scaled by v_i
def Blk.to_list source · line 285 · raw
@m:Blk -> @acc:List<&2, F32> -> List<&2, F32>
the 16 cells in row-major order, before acc
def Blk.from_vec4s source · line 290 · raw
@v0:Vec4 -> @v1:Vec4 -> @v2:Vec4 -> @v3:Vec4 -> Blk
a block from its four rows
def Blk.from_rows source · line 301 · raw
@r0:List<&2, F32> -> @r1:List<&2, F32> -> @r2:List<&2, F32> -> @r3:List<&2, F32> -> Blk
a block from four rows of four; a short row pads with 0.0
def Blk.row source · line 304 · raw
@m:Blk -> @i:Nat -> Vec4
def Vec4.mask source · line 324 · raw
@k:Nat -> @v:Vec4 -> Vec4
elements at index >= k set to 0.0
def Vec4.max_upto source · line 338 · raw
@k:Nat -> @v:Vec4 -> F32
the largest of the first k elements
def Vec4.min_upto source · line 350 · raw
@k:Nat -> @v:Vec4 -> F32
the smallest of the first k elements
def Vec4.argmax_upto source · line 362 · raw
@k:Nat -> @v:Vec4 -> Pair(U32, F32)
the index and value of the largest of the first k elements
def Blk.mask_rows source · line 374 · raw
@k:Nat -> @m:Blk -> Blk
rows at index >= k set to 0.0
def Blk.mask_cols source · line 400 · raw
@k:Nat -> @m:Blk -> Blk
columns at index >= k set to 0.0
def Blk.mask source · line 426 · raw
@ki:Nat -> @kj:Nat -> @m:Blk -> Blk
rows at index >= ki and columns at index >= kj set to 0.0
def Blk.max_rows_upto source · line 430 · raw
@k:Nat -> @m:Blk -> Vec4
each row's largest among its first k columns
def VecT.size source · line 468 · raw
@+n:Nat -> Nat
the element count of a VecT(n): 4 * 2^n
def VecT.full source · line 476 · raw
@+n:Nat -> @+x:F32 -> VecT(n)
def VecT.zeros source · line 484 · raw
@+n:Nat -> VecT(n)
def VecT.ones source · line 487 · raw
@+n:Nat -> VecT(n)
def VecT.arange.from source · line 491 · raw
@+n:Nat -> @+x:F32 -> VecT(n)
x, x + 1, x + 2, ..
def VecT.arange source · line 501 · raw
@+n:Nat -> VecT(n)
0, 1, 2, ..
def VecT.add source · line 526 · raw
@+n:Nat -> @a:VecT(n) -> @b:VecT(n) -> VecT(n)
def VecT.sub source · line 529 · raw
@+n:Nat -> @a:VecT(n) -> @b:VecT(n) -> VecT(n)
def VecT.mul source · line 533 · raw
@+n:Nat -> @a:VecT(n) -> @b:VecT(n) -> VecT(n)
elementwise product
def VecT.exp source · line 536 · raw
@+n:Nat -> @v:VecT(n) -> VecT(n)
def VecT.scale source · line 539 · raw
@+n:Nat -> @+k:F32 -> @v:VecT(n) -> VecT(n)
def VecT.shift source · line 550 · raw
@+n:Nat -> @+k:F32 -> @v:VecT(n) -> VecT(n)
k added to every element
def VecT.sum source · line 562 · raw
@+n:Nat -> @v:VecT(n) -> F32
the sum, left half plus right half
def VecT.dot source · line 572 · raw
@+n:Nat -> @a:VecT(n) -> @b:VecT(n) -> F32
def VecT.max source · line 584 · raw
@+n:Nat -> @v:VecT(n) -> F32
def VecT.min source · line 594 · raw
@+n:Nat -> @v:VecT(n) -> F32
def VecT.argmax.two source · line 605 · raw
@+off:U32 -> @ix:Pair(U32, F32) -> @jy:Pair(U32, F32) -> Pair(U32, F32)
the two halves' winners, the right one's index offset by the half's size
def VecT.argmax source · line 611 · raw
@+n:Nat -> @v:VecT(n) -> Pair(U32, F32)
the index and value of the largest element; the first wins ties
def VecT.to_list.go source · line 626 · raw
@+n:Nat -> @+v:VecT(n) -> @acc:List<&2, F32> -> List<&2, F32>
the elements in order, before acc the tree is read borrowed (+v, matched in place), never consumed: a reader that consumes a shared tree makes the compiler copy it, and bend 2.0.16 miscompiles that copy when the depth is a literal (the bias of a model: memory faults in the loop; issues/shared_vec_loop_*)
def VecT.to_list source · line 633 · raw
@+n:Nat -> @+v:VecT(n) -> List<&2, F32>
def VecT.from_list source · line 637 · raw
@+n:Nat -> @+xs:List<&2, F32> -> VecT(n)
the first 4 * 2^n elements of xs, padded with 0.0
def VecT.softmax.fin source · line 646 · raw
@+n:Nat -> @+e:VecT(n) -> VecT(n)
def VecT.softmax source · line 650 · raw
@+n:Nat -> @+v:VecT(n) -> VecT(n)
exp(v - max v) / sum
def VecT.show source · line 653 · raw
@+n:Nat -> @v:VecT(n) -> String
def MatT.full source · line 696 · raw
@+r:Nat -> @+c:Nat -> @+x:F32 -> MatT(r, c)
def MatT.zeros source · line 710 · raw
@+r:Nat -> @+c:Nat -> MatT(r, c)
def MatT.ones source · line 713 · raw
@+r:Nat -> @+c:Nat -> MatT(r, c)
def MatT.eye source · line 717 · raw
@+n:Nat -> MatT(n, n)
the identity of MatT(n, n)
def MatT.add source · line 765 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @n:MatT(r, c) -> MatT(r, c)
def MatT.sub source · line 768 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @n:MatT(r, c) -> MatT(r, c)
def MatT.mul source · line 772 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @n:MatT(r, c) -> MatT(r, c)
elementwise (Hadamard) product; the matrix product is MatT.matmul
def MatT.exp source · line 775 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> MatT(r, c)
def MatT.scale source · line 778 · raw
@+r:Nat -> @+c:Nat -> @+k:F32 -> @m:MatT(r, c) -> MatT(r, c)
def MatT.transpose source · line 796 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> MatT(c, r)
def MatT.add4 source · line 815 · raw
@+p:Nat -> @+q:Nat -> @a0:MatT(p, q) -> @b0:MatT(p, q) -> @a1:MatT(p, q) -> @b1:MatT(p, q) -> @a2:MatT(p, q) -> @b2:MatT(p, q) -> @a3:MatT(p, q) -> @b3:MatT(p, q) -> MatT(1n+p, 1n+q)
the four quadrant sums of a product node, in one balanced fork
def MatT.add2r source · line 820 · raw
@+p:Nat -> @a0:MatT(p, 0n) -> @b0:MatT(p, 0n) -> @a1:MatT(p, 0n) -> @b1:MatT(p, 0n) -> MatT(1n+p, 0n)
def MatT.add2c source · line 824 · raw
@+q:Nat -> @a0:MatT(0n, q) -> @b0:MatT(0n, q) -> @a1:MatT(0n, q) -> @b1:MatT(0n, q) -> MatT(0n, 1n+q)
def MatT.matmul.sq source · line 830 · raw
@+d:Nat -> @+a:MatT(d, d) -> @+b:MatT(d, d) -> MatT(d, d)
a * b for square operands of one depth: the same recursion with one depth riding instead of three, which measures 3x faster per node
def MatT.matmul.any source · line 847 · raw
@+r:Nat -> @+k:Nat -> @+c:Nat -> @+a:MatT(r, k) -> @+b:MatT(k, c) -> MatT(r, c)
a * b for any shapes: MatT(r, k) times MatT(k, c) is MatT(r, c). A node forks its whole burst of products at once (eight at a quadrant), then joins them with a fork of adds. Both operands are shared through +, never copied. Three depths ride every call, which is what the square path below avoids.
def MatT.matmul source · line 894 · raw
@+r:Nat -> @+k:Nat -> @+c:Nat -> @+a:MatT(r, k) -> @+b:MatT(k, c) -> MatT(r, c)
a * b: MatT(r, k) times MatT(k, c) is MatT(r, c). For two square operands of one depth, MatT.matmul.sq is the same recursion with one depth riding instead of three, and 3x faster per node; a runtime dispatch to it is not possible without a cast, and any def that returns or rebuilds a MatT parameter makes the compiler reference-count every MatT node in the program (see AGENTS.md), so the choice is the caller's.
def VecT.add2 source · line 897 · raw
@+p:Nat -> @a0:VecT(p) -> @b0:VecT(p) -> @a1:VecT(p) -> @b1:VecT(p) -> VecT(1n+p)
def MatT.matvec source · line 902 · raw
@+r:Nat -> @+c:Nat -> @+m:MatT(r, c) -> @+v:VecT(c) -> VecT(r)
m * v: MatT(r, c) times VecT(c) is VecT(r)
def MatT.sum source · line 924 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> F32
the sum of every cell
def MatT.sum_rows source · line 943 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> VecT(r)
each row's sum: VecT(r)
def MatT.sum_cols source · line 962 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> VecT(c)
each column's sum: VecT(c)
def VecT.max2 source · line 980 · raw
@+p:Nat -> @a0:VecT(p) -> @b0:VecT(p) -> @a1:VecT(p) -> @b1:VecT(p) -> VecT(1n+p)
def MatT.max_rows source · line 985 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> VecT(r)
each row's largest element: VecT(r)
def MatT.add_row source · line 1004 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+v:VecT(c) -> MatT(r, c)
v added to every row: v is a VecT(c)
def MatT.sub_col source · line 1026 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+v:VecT(r) -> MatT(r, c)
row i minus v_i: v is a VecT(r), one scalar per row
def MatT.scale_rows source · line 1048 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+v:VecT(r) -> MatT(r, c)
row i times v_i: v is a VecT(r), one scalar per row
def MatT.softmax_rows.fin source · line 1069 · raw
@+r:Nat -> @+c:Nat -> @+e:MatT(r, c) -> MatT(r, c)
def MatT.softmax_rows source · line 1073 · raw
@+r:Nat -> @+c:Nat -> @+m:MatT(r, c) -> MatT(r, c)
softmax along each row: exp(row - max row) / sum
def MatT.rows_take source · line 1080 · raw
@+w:Nat -> @rows:List<&2, List<&2, F32>> -> List<&2, List<&2, F32>>
the first w of every row
def MatT.rows_drop source · line 1088 · raw
@+w:Nat -> @rows:List<&2, List<&2, F32>> -> List<&2, List<&2, F32>>
every row past its first w
def MatT.rows_cat source · line 1096 · raw
@xs:List<&2, List<&2, F32>> -> @ys:List<&2, List<&2, F32>> -> List<&2, List<&2, F32>>
the rows of xs side by side with the rows of ys
def MatT.from_rows.leaf source · line 1104 · raw
@rows:List<&2, List<&2, F32>> -> Blk
a leaf from up to four rows; missing rows and cells pad with 0.0
def MatT.from_rows source · line 1118 · raw
@+r:Nat -> @+c:Nat -> @+rows:List<&2, List<&2, F32>> -> MatT(r, c)
a MatT(r, c) from its rows, row-major; short or missing rows pad with 0.0
def MatT.to_rows source · line 1139 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> List<&2, List<&2, F32>>
the rows of a MatT(r, c), row-major
def MatT.chunks source · line 1156 · raw
@+n:Nat -> @+w:Nat -> @+xs:List<&2, F32> -> List<&2, List<&2, F32>>
xs cut into n rows of w
def MatT.from_list source · line 1164 · raw
@+r:Nat -> @+c:Nat -> @xs:List<&2, F32> -> MatT(r, c)
a MatT(r, c) from 4 * 2^r times 4 * 2^c floats in row-major order
def MatT.to_list source · line 1169 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> List<&2, F32>
the cells in row-major order
def MatT.show.row source · line 1172 · raw
@row:List<&2, F32> -> String
def MatT.show source · line 1175 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> String
def VecT.depth.go source · line 1192 · raw
@fuel:Nat -> @+n:Nat -> @+cap:Nat -> @+m:Nat -> @lt:Bool -> Nat
the smallest n with 4 * 2^n >= m; the fuel is m itself, log2(m) steps
def VecT.depth source · line 1202 · raw
@+m:Nat -> Nat
def VecT.mask source · line 1212 · raw
@+n:Nat -> @v:VecT(n) -> @+i0:Nat -> @+m:Nat -> VecT(n)
elements at index >= m set to 0.0
def VecT.max_upto source · line 1223 · raw
@+n:Nat -> @v:VecT(n) -> @+i0:Nat -> @+m:Nat -> F32
the largest element among the first m
def VecT.min_upto source · line 1235 · raw
@+n:Nat -> @v:VecT(n) -> @+i0:Nat -> @+m:Nat -> F32
def VecT.argmax_upto.join source · line 1248 · raw
@lt:Bool -> @+off:U32 -> @a:Pair(U32, F32) -> @b:Pair(U32, F32) -> Pair(U32, F32)
the right half's winner counts only when the right half starts before m
def VecT.argmax_upto source · line 1256 · raw
@+n:Nat -> @v:VecT(n) -> @+i0:Nat -> @+m:Nat -> Pair(U32, F32)
the index and value of the largest among the first m; the first wins ties
def MatT.mask source · line 1268 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+i0:Nat -> @+j0:Nat -> @+rows:Nat -> @+cols:Nat -> MatT(r, c)
rows at index >= rows and columns at index >= cols set to 0.0
def MatT.max_rows_upto source · line 1289 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+j0:Nat -> @+cols:Nat -> VecT(r)
each row's largest among its first cols columns; a padding row answers 0.0
def Vec.zeros source · line 1319 · raw
@+m:Nat -> Vec<m>
def Vec.full source · line 1322 · raw
@+m:Nat -> @+x:F32 -> Vec<m>
def Vec.ones source · line 1325 · raw
@+m:Nat -> Vec<m>
def Vec.arange source · line 1329 · raw
@+m:Nat -> Vec<m>
0, 1, .., m - 1
def Vec.from_list source · line 1333 · raw
@+m:Nat -> @xs:List<&2, F32> -> Vec<m>
the first m of xs, padded with 0.0
def Vec.to_list source · line 1337 · raw
@+m:Nat -> @+v:Vec<m> -> List<&2, F32>
read borrowed: a bias is shared by every pass of a model
def Vec.add source · line 1351 · raw
@+m:Nat -> @a:Vec<m> -> @b:Vec<m> -> Vec<m>
def Vec.sub source · line 1356 · raw
@+m:Nat -> @a:Vec<m> -> @b:Vec<m> -> Vec<m>
def Vec.mul source · line 1361 · raw
@+m:Nat -> @a:Vec<m> -> @b:Vec<m> -> Vec<m>
def Vec.exp source · line 1366 · raw
@+m:Nat -> @v:Vec<m> -> Vec<m>
def Vec.scale source · line 1369 · raw
@+m:Nat -> @+k:F32 -> @v:Vec<m> -> Vec<m>
def Vec.shift source · line 1373 · raw
@+m:Nat -> @+k:F32 -> @v:Vec<m> -> Vec<m>
def Vec.sum source · line 1377 · raw
@+m:Nat -> @v:Vec<m> -> F32
def Vec.dot source · line 1381 · raw
@+m:Nat -> @a:Vec<m> -> @b:Vec<m> -> F32
def Vec.max source · line 1386 · raw
@+m:Nat -> @v:Vec<m> -> F32
def Vec.min source · line 1390 · raw
@+m:Nat -> @v:Vec<m> -> F32
def Vec.argmax source · line 1394 · raw
@+m:Nat -> @v:Vec<m> -> Pair(U32, F32)
def Vec.mask source · line 1398 · raw
@+m:Nat -> @v:Vec<m> -> Vec<m>
def Vec.softmax.fin source · line 1402 · raw
@+m:Nat -> @+e:Vec<m> -> Vec<m>
def Vec.softmax source · line 1406 · raw
@+m:Nat -> @+v:Vec<m> -> Vec<m>
exp(v - max v) / sum, over the m elements
def Vec.show source · line 1409 · raw
@+m:Nat -> @v:Vec<m> -> String
def Mat.zeros source · line 1418 · raw
@+rows:Nat -> @+cols:Nat -> Mat<rows, cols>
def Mat.full source · line 1421 · raw
@+rows:Nat -> @+cols:Nat -> @+x:F32 -> Mat<rows, cols>
def Mat.ones source · line 1424 · raw
@+rows:Nat -> @+cols:Nat -> Mat<rows, cols>
def Mat.eye source · line 1427 · raw
@+n:Nat -> Mat<n, n>
def Mat.from_rows source · line 1431 · raw
@+rows:Nat -> @+cols:Nat -> @rs:List<&2, List<&2, F32>> -> Mat<rows, cols>
a matrix from its rows, row-major; short or missing rows pad with 0.0
def Mat.from_list source · line 1435 · raw
@+rows:Nat -> @+cols:Nat -> @xs:List<&2, F32> -> Mat<rows, cols>
a matrix from rows * cols floats in row-major order
def Mat.to_rows source · line 1438 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> List<&2, List<&2, F32>>
def Mat.to_list source · line 1442 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> List<&2, F32>
def Mat.add source · line 1454 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @n:Mat<rows, cols> -> Mat<rows, cols>
def Mat.sub source · line 1459 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @n:Mat<rows, cols> -> Mat<rows, cols>
def Mat.mul source · line 1465 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @n:Mat<rows, cols> -> Mat<rows, cols>
elementwise (Hadamard) product; the matrix product is Mat.matmul
def Mat.exp source · line 1470 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Mat<rows, cols>
def Mat.scale source · line 1473 · raw
@+rows:Nat -> @+cols:Nat -> @+k:F32 -> @m:Mat<rows, cols> -> Mat<rows, cols>
def Mat.transpose source · line 1477 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Mat<cols, rows>
def Mat.matmul source · line 1482 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @a:Mat<rows, k> -> @b:Mat<k, cols> -> Mat<rows, cols>
a * b: Mat<rows, k> times Mat<k, cols> is Mat<rows, cols>
def Mat.matmul.sq source · line 1488 · raw
@+n:Nat -> @a:Mat<n, n> -> @b:Mat<n, n> -> Mat<n, n>
a * b for two Mat<n, n>: the one-depth recursion, 3x faster per node
def Mat.matvec source · line 1494 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @v:Vec<cols> -> Vec<rows>
m * v: Mat<rows, cols> times Vec<cols> is Vec<rows>
def Mat.sum source · line 1499 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> F32
def Mat.sum_rows source · line 1503 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Vec<rows>
def Mat.sum_cols source · line 1507 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Vec<cols>
def Mat.max_rows source · line 1511 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Vec<rows>
def Mat.add_row source · line 1516 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @v:Vec<cols> -> Mat<rows, cols>
v added to every row. Masked: a padding row plus v is v, not 0.0.
def Mat.sub_col source · line 1522 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @v:Vec<rows> -> Mat<rows, cols>
row i minus v_i. Masked: a padding column minus v_i is -v_i, not 0.0.
def Mat.scale_rows source · line 1528 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @v:Vec<rows> -> Mat<rows, cols>
row i times v_i. Masked, so its law needs no fact about x * 0.0.
def Mat.mask source · line 1533 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Mat<rows, cols>
def Mat.softmax_rows.fin source · line 1537 · raw
@+rows:Nat -> @+cols:Nat -> @+e:Mat<rows, cols> -> Mat<rows, cols>
def Mat.softmax_rows source · line 1541 · raw
@+rows:Nat -> @+cols:Nat -> @+m:Mat<rows, cols> -> Mat<rows, cols>
softmax along each row over its cols columns
def Mat.show source · line 1544 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> String
def Mat.from_tree source · line 1549 · raw
@+rows:Nat -> @+cols:Nat -> @t:MatT(VecT.depth(rows), VecT.depth(cols)) -> Mat<rows, cols>
a Mat<rows, cols> around a tree, masked: what the IO products below answer, and what their padding law is about
def Vec4.Padded source · line 1562 · raw
@k:Nat -> @v:Vec4 -> Type
def VecT.Padded source · line 1575 · raw
@+n:Nat -> @v:VecT(n) -> @+i0:Nat -> @+m:Nat -> Type
def Blk.kcol source · line 1585 · raw
@ki:Nat -> @i:Nat -> @+kj:Nat -> Nat
row i of a block is padded past kj when i < ki, and entirely when not
def Blk.Padded source · line 1588 · raw
@+ki:Nat -> @+kj:Nat -> @b:Blk -> Type
def MatT.Padded source · line 1592 · raw
@+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @+i0:Nat -> @+j0:Nat -> @+rows:Nat -> @+cols:Nat -> Type
def Vec.Padded source · line 1607 · raw
@+m:Nat -> @v:Vec<m> -> Type
def Mat.Padded source · line 1611 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Type
def Weights.wrap source · line 1674 · raw
@-rows:Nat -> @-cols:Nat -> @id:U32 -> IO(Weights<rows, cols>)
def Weights.load source · line 1678 · raw
@+rows:Nat -> @+cols:Nat -> @path:String -> IO(Weights<rows, cols>)
rows * cols float32 from a file, as numpy's tofile writes a C-ordered array
def Flat.depth.go source · line 1688 · raw
@fuel:Nat -> @+d:Nat -> @+cap:Nat -> @+n:Nat -> @lt:Bool -> Nat
the smallest d with 2^d >= n; the fuel bounds the doubling steps
def Flat.depth source · line 1698 · raw
@+n:Nat -> Nat
def Flat.count source · line 1701 · raw
@+rows:Nat -> @+cols:Nat -> Nat
def Flat.full source · line 1707 · raw
@+rows:Nat -> @+cols:Nat -> @+x:F32 -> Flat<rows, cols>
def Flat.zeros source · line 1710 · raw
@+rows:Nat -> @+cols:Nat -> Flat<rows, cols>
def Flat.ones source · line 1713 · raw
@+rows:Nat -> @+cols:Nat -> Flat<rows, cols>
def Flat.fill.go source · line 1716 · raw
@xs:List<&2, F32> -> @+i:U32 -> @a:Array<F32> -> Array<F32>
def Flat.from_list source · line 1724 · raw
@+rows:Nat -> @+cols:Nat -> @xs:List<&2, F32> -> Flat<rows, cols>
the first rows * cols of xs, row-major, the rest 0.0
def Flat.wrap source · line 1727 · raw
@-rows:Nat -> @-cols:Nat -> @a:Array<F32> -> IO(Flat<rows, cols>)
def Flat.from_file source · line 1731 · raw
@+rows:Nat -> @+cols:Nat -> @path:String -> IO(Flat<rows, cols>)
rows * cols float32 from a file, row-major
def Weights.of_flat source · line 1735 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> IO(Weights<rows, cols>)
a Flat's floats copied into the weight registry; the Flat is consumed
def Flat.to_list.go source · line 1740 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @acc:List<&2, F32> -> List<&2, F32>
the cells in row-major order; i counts down from the last
def Flat.to_list.of source · line 1749 · raw
@n:Nat -> @+last:U32 -> @a:Array<F32> -> List<&2, F32>
def Flat.to_list source · line 1756 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> List<&2, F32>
def Vec.wrap source · line 1760 · raw
@+m:Nat -> @a:Array<F32> -> IO(Vec<m>)
def Vec.from_file source · line 1764 · raw
@+m:Nat -> @path:String -> IO(Vec<m>)
m float32 from a file, as a Vec (Data: share it, it is never consumed)
def Flat.clone.fin source · line 1767 · raw
@-rows:Nat -> @-cols:Nat -> @r:Pair(Array<F32>, Array<F32>) -> Pair(Flat<rows, cols>, Flat<rows, cols>)
def Flat.clone source · line 1772 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Pair(Flat<rows, cols>, Flat<rows, cols>)
two copies; open the pair in a def of your own (a do block cannot)
def Flat.clone.fst source · line 1776 · raw
@+rows:Nat -> @+cols:Nat -> @r:Pair(Flat<rows, cols>, Flat<rows, cols>) -> Flat<rows, cols>
def Flat.clone.snd source · line 1780 · raw
@+rows:Nat -> @+cols:Nat -> @r:Pair(Flat<rows, cols>, Flat<rows, cols>) -> Flat<rows, cols>
def Flat.to_rows source · line 1784 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> List<&2, List<&2, F32>>
def Flat.show source · line 1787 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> String
def Flat.exp source · line 1808 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
def F32.relu source · line 1811 · raw
@x:F32 -> F32
def Flat.relu source · line 1814 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
def F32.gelu source · line 1818 · raw
@x0:F32 -> F32
gelu, the tanh form: 0.5 x (1 + tanh(sqrt(2 / pi) (x + 0.044715 x^3)))
def Flat.gelu source · line 1822 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
def Flat.scale.step source · line 1825 · raw
@+k:F32 -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.scale.go source · line 1829 · raw
@n:Nat -> @+k:F32 -> @+i:U32 -> @a:Array<F32> -> Array<F32>
def Flat.scale source · line 1836 · raw
@+rows:Nat -> @+cols:Nat -> @+k:F32 -> @m:Flat<rows, cols> -> Flat<rows, cols>
def Flat.zip.fin source · line 1856 · raw
@-rows:Nat -> @-cols:Nat -> @ab:Pair(Array<F32>, Array<F32>) -> Flat<rows, cols>
def Flat.add source · line 1866 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> @n:Flat<rows, cols> -> Flat<rows, cols>
def Flat.sub source · line 1869 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> @n:Flat<rows, cols> -> Flat<rows, cols>
def Flat.mul source · line 1873 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> @n:Flat<rows, cols> -> Flat<rows, cols>
elementwise product; the matrix product is Flat.matmul
def Flat.mask_causal.step source · line 1878 · raw
@+idx:U32 -> @+i:U32 -> @+j:U32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
cells above the diagonal (j > i) set to -3.4e38, the most negative finite float, which a softmax turns into 0 with no inf - inf
def Flat.mask_causal.go source · line 1882 · raw
@n:Nat -> @+idx:U32 -> @+colsu:U32 -> @a:Array<F32> -> Array<F32>
def Flat.mask_causal source · line 1889 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
def Flat.add_row.step source · line 1898 · raw
@+idx:U32 -> @+y:F32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.add_row.row source · line 1903 · raw
@n:Nat -> @+idx:U32 -> @xs:List<&2, F32> -> @a:Array<F32> -> Array<F32>
the bias as a list, walked from its head for every row
def Flat.add_row.go source · line 1912 · raw
@n:Nat -> @+cols:Nat -> @+colsu:U32 -> @+base:U32 -> @+xs:List<&2, F32> -> @a:Array<F32> -> Array<F32>
def Flat.add_row source · line 1920 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> @+v:Vec<cols> -> Flat<rows, cols>
v added to every row; v is a Vec, Data, so it is shared, not consumed
def Flat.rowmax.go source · line 1925 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @+best:F32 -> Pair(Array<F32>, F32)
the largest cell of a row segment
def Flat.rowexp.step source · line 1935 · raw
@+i:U32 -> @+mx:F32 -> @r:Pair(Array<F32>, F32) -> @+acc:F32 -> Pair(Array<F32>, F32)
exp(x - mx) written back, the row's sum answered
def Flat.rowexp.go source · line 1940 · raw
@n:Nat -> @+i:U32 -> @+mx:F32 -> @r:Pair(Array<F32>, F32) -> Pair(Array<F32>, F32)
def Flat.rowscale.go source · line 1948 · raw
@n:Nat -> @+i:U32 -> @+k:F32 -> @a:Array<F32> -> Array<F32>
def Flat.softmax.row3 source · line 1956 · raw
@+n:Nat -> @+base:U32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
one row of softmax: max, exp and sum, scale
def Flat.softmax.row2 source · line 1960 · raw
@+n:Nat -> @+base:U32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.softmax.row source · line 1964 · raw
@+n:Nat -> @+base:U32 -> @a:Array<F32> -> Array<F32>
def Flat.softmax.go source · line 1971 · raw
@n:Nat -> @+cols:Nat -> @+colsu:U32 -> @+base:U32 -> @a:Array<F32> -> Array<F32>
def Flat.softmax_rows source · line 1979 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
softmax along each row
def F32.sqdev source · line 1986 · raw
@+x:F32 -> @+mean:F32 -> F32
layer norm over each row: (x - mean) / sqrt(var + eps), var the mean of the squared deviations; a pass for the sum, one for the squares, one to write
def Flat.rowsq.go source · line 1989 · raw
@n:Nat -> @+i:U32 -> @+mean:F32 -> @r:Pair(Array<F32>, F32) -> @+acc:F32 -> Pair(Array<F32>, F32)
def Flat.rowsum.go source · line 1998 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @+acc:F32 -> Pair(Array<F32>, F32)
def Flat.rownorm.step source · line 2007 · raw
@+i:U32 -> @+mean:F32 -> @+inv:F32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.rownorm.go source · line 2011 · raw
@n:Nat -> @+i:U32 -> @+mean:F32 -> @+inv:F32 -> @a:Array<F32> -> Array<F32>
def Flat.layer_norm.row3 source · line 2018 · raw
@+n:Nat -> @+base:U32 -> @+mean:F32 -> @+eps:F32 -> @+cnt:F32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.layer_norm.row2 source · line 2022 · raw
@+n:Nat -> @+p:Nat -> @+base:U32 -> @+eps:F32 -> @+cnt:F32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
def Flat.layer_norm.row source · line 2027 · raw
@+n:Nat -> @+base:U32 -> @+eps:F32 -> @a:Array<F32> -> Array<F32>
def Flat.layer_norm.go source · line 2034 · raw
@n:Nat -> @+cols:Nat -> @+colsu:U32 -> @+base:U32 -> @+eps:F32 -> @a:Array<F32> -> Array<F32>
def Flat.layer_norm_rows source · line 2041 · raw
@+rows:Nat -> @+cols:Nat -> @+eps:F32 -> @m:Flat<rows, cols> -> Flat<rows, cols>
def Flat.rowarg.pick source · line 2046 · raw
@c:Bool -> @+i:U32 -> @+x:F32 -> @+j:U32 -> @+y:F32 -> Pair(U32, F32)
the index of the largest cell of a row segment; the first wins ties
def Flat.rowarg.best source · line 2054 · raw
@+bj:U32 -> @+bx:F32 -> @+j:U32 -> @+x:F32 -> Pair(U32, F32)
the better of the best so far and cell j
def Flat.rowarg.go source · line 2057 · raw
@n:Nat -> @+i:U32 -> @+j:U32 -> @r:Pair(Array<F32>, F32) -> @best:Pair(U32, F32) -> Pair(Array<F32>, Pair(U32, F32))
def Flat.argmax.row source · line 2068 · raw
@+n:Nat -> @+base:U32 -> @a:Array<F32> -> Pair(Array<F32>, Pair(U32, F32))
def Flat.argmax.go source · line 2077 · raw
@n:Nat -> @+cols:Nat -> @+colsu:U32 -> @+base:U32 -> @r:Pair(Array<F32>, Pair(U32, F32)) -> @acc:List<&2, U32> -> List<&2, U32>
rows from the last down to the first, so the list comes out in row order; r is the row just done
def Flat.argmax.of source · line 2086 · raw
@+rows:Nat -> @+cols:Nat -> @a:Array<F32> -> List<&2, U32>
def Flat.argmax_rows source · line 2096 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> List<&2, U32>
each row's argmax, in row order; the matrix is consumed
def Flat.sum.go source · line 2104 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @+acc:F32 -> F32
def Flat.sum.of source · line 2113 · raw
@n:Nat -> @a:Array<F32> -> F32
def Flat.sum source · line 2120 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> F32
def Flat.mean source · line 2124 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> F32
def Flat.max.go source · line 2127 · raw
@n:Nat -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> @+best:F32 -> F32
def Flat.max.of source · line 2136 · raw
@n:Nat -> @a:Array<F32> -> F32
def Flat.max source · line 2143 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> F32
def Flat.transpose.step2 source · line 2150 · raw
@+dst:U32 -> @x:F32 -> @a:Array<F32> -> @b:Array<F32> -> Pair(Array<F32>, Array<F32>)
def Flat.transpose.step source · line 2153 · raw
@+dst:U32 -> @b:Array<F32> -> @r:Pair(Array<F32>, F32) -> Pair(Array<F32>, Array<F32>)
def Flat.transpose.go source · line 2158 · raw
@n:Nat -> @+idx:U32 -> @+rowsu:U32 -> @+colsu:U32 -> @ab:Pair(Array<F32>, Array<F32>) -> Pair(Array<F32>, Array<F32>)
cell (i, j) of a at idx = i * cols + j goes to j * rows + i in b
def Flat.transpose.fin source · line 2168 · raw
@-rows:Nat -> @-cols:Nat -> @ab:Pair(Array<F32>, Array<F32>) -> Flat<cols, rows>
def Flat.transpose source · line 2172 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<cols, rows>
def Flat.matmul.fin source · line 2184 · raw
@-rows:Nat -> @-cols:Nat -> @c:Array<F32> -> IO(Flat<rows, cols>)
def Flat.matmul.run source · line 2187 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @ta:U32 -> @tb:U32 -> @x:Array<F32> -> @y:Array<F32> -> IO(Flat<rows, cols>)
def Flat.matmul source · line 2190 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @a:Flat<rows, k> -> @b:Flat<k, cols> -> IO(Flat<rows, cols>)
def Flat.matmul_t source · line 2195 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @a:Flat<rows, k> -> @b:Flat<cols, k> -> IO(Flat<rows, cols>)
def Flat.matmul_w.run source · line 2200 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @ta:U32 -> @tb:U32 -> @x:Array<F32> -> @id:U32 -> IO(Flat<rows, cols>)
def Flat.matmul_w source · line 2203 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @a:Flat<rows, k> -> @w:Weights<k, cols> -> IO(Flat<rows, cols>)
def Flat.matmul_wt source · line 2208 · raw
@+rows:Nat -> @+k:Nat -> @+cols:Nat -> @a:Flat<rows, k> -> @w:Weights<cols, k> -> IO(Flat<rows, cols>)
def Flat.to_mat source · line 2216 · raw
@+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Mat<rows, cols>
def Mat.to_flat source · line 2219 · raw
@+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Flat<rows, cols>
Templates
template Vec4.map source · line 56 · raw
@-f:(@_:F32 -> F32) -> @v:Vec4 -> Vec4
template Vec4.zip source · line 60 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @a:Vec4 -> @b:Vec4 -> Vec4
template Blk.map source · line 162 · raw
@-f:(@_:F32 -> F32) -> @m:Blk -> Blk
template Blk.zip source · line 169 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @m:Blk -> @n:Blk -> Blk
template VecT.map source · line 504 · raw
@-f:(@_:F32 -> F32) -> @+n:Nat -> @v:VecT(n) -> VecT(n)
template VecT.zip source · line 514 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+n:Nat -> @a:VecT(n) -> @b:VecT(n) -> VecT(n)
template MatT.map source · line 725 · raw
@-f:(@_:F32 -> F32) -> @+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> MatT(r, c)
template MatT.zip source · line 743 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+r:Nat -> @+c:Nat -> @m:MatT(r, c) -> @n:MatT(r, c) -> MatT(r, c)
template Vec.map source · line 1342 · raw
@-f:(@_:F32 -> F32) -> @+m:Nat -> @v:Vec<m> -> Vec<m>
template Vec.zip source · line 1346 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+m:Nat -> @a:Vec<m> -> @b:Vec<m> -> Vec<m>
template Mat.map source · line 1445 · raw
@-f:(@_:F32 -> F32) -> @+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> Mat<rows, cols>
template Mat.zip source · line 1449 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+rows:Nat -> @+cols:Nat -> @m:Mat<rows, cols> -> @n:Mat<rows, cols> -> Mat<rows, cols>
template Flat.map.step source · line 1793 · raw
@-f:(@_:F32 -> F32) -> @+i:U32 -> @r:Pair(Array<F32>, F32) -> Array<F32>
template Flat.map.go source · line 1797 · raw
@-f:(@_:F32 -> F32) -> @n:Nat -> @+i:U32 -> @a:Array<F32> -> Array<F32>
template Flat.map source · line 1804 · raw
@-f:(@_:F32 -> F32) -> @+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> Flat<rows, cols>
template Flat.zip.step2 source · line 1840 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+i:U32 -> @x:F32 -> @a:Array<F32> -> @r:Pair(Array<F32>, F32) -> Pair(Array<F32>, Array<F32>)
template Flat.zip.step source · line 1844 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+i:U32 -> @b:Array<F32> -> @r:Pair(Array<F32>, F32) -> Pair(Array<F32>, Array<F32>)
template Flat.zip.go source · line 1848 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @n:Nat -> @+i:U32 -> @ab:Pair(Array<F32>, Array<F32>) -> Pair(Array<F32>, Array<F32>)
template Flat.zip source · line 1861 · raw
@-f:(@_:F32 -> @_:F32 -> F32) -> @+rows:Nat -> @+cols:Nat -> @m:Flat<rows, cols> -> @n:Flat<rows, cols> -> Flat<rows, cols>
f over the pairs of cells; both operands are consumed
Effects (foreign code)
effect Blas.sgemm source · line 1642 · raw
@m:U32 -> @n:U32 -> @k:U32 -> @ta:U32 -> @tb:U32 -> @a:Array<F32> -> @b:Array<F32> -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)
Effects ------- C = op(A) op(B) on row-major arrays. m, n, k are the result rows, the result columns and the inner size; ta and tb (0 or 1) transpose an operand as stored. Answers a fresh array of the smallest power-of-two size holding m * n. Blas.sgemm is the platform CPU BLAS (Accelerate, OpenBLAS), opened at runtime. The _w forms take the right operand as a registry weight (see Weights) instead of an array. The GPU build (bend_tensors_gpu.bend) adds Blas.sgemm_gpu: Metal Performance Shaders on macOS, cuBLAS on Linux.
foreign: effs/sgemm.c, effs/sgemm.js
effect Blas.sgemm_w source · line 1646 · raw
@m:U32 -> @n:U32 -> @k:U32 -> @ta:U32 -> @tb:U32 -> @a:Array<F32> -> @id:U32 -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)
foreign: effs/sgemm_w.c, effs/sgemm_w.js
effect Weights.load.eff source · line 1652 · raw
@path:String -> @n:U32 -> IO(Result<&1, &1, Pair(U32, String), U32>)
n float32 (little-endian, as numpy writes them) from a file, into the weight registry (answers the id) or into a fresh array
foreign: effs/weights_load.c, effs/weights_load.js
effect Weights.of_array.eff source · line 1656 · raw
@a:Array<F32> -> @n:U32 -> IO(Result<&1, &1, Pair(U32, String), U32>)
foreign: effs/weights_of_array.c, effs/weights_of_array.js
effect Flat.load.eff source · line 1660 · raw
@path:String -> @n:U32 -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)
foreign: effs/flat_load.c, effs/flat_load.js