1 import Base 2 import ./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. 6 type Rows<-Element: Data> is Data: 7 Rows{r0: Element,r1: Element,r2: Element,r3: Element} 8 9 def filled(~Element: Data,+value: Element) -> Rows: 10 Rows{value,value,value,value} 11 12 def first(~Element: Data,values: Rows) -> Element: 13 Rows{a,b,c,d} = values 14 a 15 16 def second(~Element: Data,values: Rows) -> Element: 17 Rows{a,b,c,d} = values 18 b 19 20 def third(~Element: Data,values: Rows) -> Element: 21 Rows{a,b,c,d} = values 22 c 23 24 def fourth(~Element: Data,values: Rows) -> Element: 25 Rows{a,b,c,d} = values 26 d 27 28 # The lower or upper four rows of an eight-row weight tile. 29 def half(upper: Bool,tile: Tile.Tile8) -> Rows: 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 38 def map(~Element: Data,~Input: Data,~Weight: Data, 39 ~update: Element -> Input -> Weight -> Element, 40 accumulators: Rows,+input: Input,weights: Rows) -> Rows: 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)}