kernel_rows.bend

stelliferous@0.0.3.0 · 43 lines · 0 definitions

1import Base
2import stelliferous@0.0.3.0/kernel_tile.bend as Tile
3
4# Four independent output rows share one input tile: half of an eight-row
5# weight block. This is a fixed product, not an indexed type or a list.
6type Rows<-Element: Data> is Data:
7  Rows{r0: Element,r1: Element,r2: Element,r3: Element}
8
9def filled(~Element: Data,+value: Element) -> Rows<Element>:
10  Rows{value,value,value,value}
11
12def first(~Element: Data,values: Rows<Element>) -> Element:
13  Rows{a,b,c,d} = values
14  a
15
16def second(~Element: Data,values: Rows<Element>) -> Element:
17  Rows{a,b,c,d} = values
18  b
19
20def third(~Element: Data,values: Rows<Element>) -> Element:
21  Rows{a,b,c,d} = values
22  c
23
24def fourth(~Element: Data,values: Rows<Element>) -> Element:
25  Rows{a,b,c,d} = values
26  d
27
28# The lower or upper four rows of an eight-row weight tile.
29def half(upper: Bool,tile: Tile.Tile8) -> Rows<F32>:
30  match upper:
31    case False{}:
32      Tile.Tile{a,b,c,d,e,f,g,h} = tile
33      Rows{a,b,c,d}
34    case True{}:
35      Tile.Tile{a,b,c,d,e,f,g,h} = tile
36      Rows{e,f,g,h}
37
38def map(~Element: Data,~Input: Data,~Weight: Data,
39  ~update: Element -> Input -> Weight -> Element,
40  accumulators: Rows<Element>,+input: Input,weights: Rows<Weight>) -> Rows<Element>:
41  Rows{a0,a1,a2,a3} = accumulators
42  Rows{w0,w1,w2,w3} = weights
43  Rows{update(a0,input,w0),update(a1,input,w1),update(a2,input,w2),update(a3,input,w3)}