~/bend-docscommunity

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

type Vec4 source · line 40 · raw

Data

type VecT.Leaf source · line 454 · raw

Data

type VecT.Node source · line 457 · raw

@-p:Nat -> Data

type MatT.Leaf source · line 673 · raw

Data

type MatT.Rows source · line 676 · raw

@-p:Nat -> @-c:Nat -> Data

type MatT.Cols source · line 679 · raw

@-r:Nat -> @-q:Nat -> Data

type MatT.Quad source · line 682 · raw

@-p:Nat -> @-q:Nat -> Data

type Vec source · line 1316 · raw

@-m:Nat -> Data

type Mat source · line 1415 · raw

@-rows:Nat -> @-cols:Nat -> Data

type Weights source · line 1671 · raw

@-rows:Nat -> @-cols:Nat -> Data

type Flat source · line 1684 · raw

@-rows:Nat -> @-cols:Nat -> Type

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